@oh-my-pi/pi-coding-agent 13.3.14 → 13.4.1
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 +69 -9
- package/examples/sdk/README.md +22 -0
- package/package.json +7 -7
- package/src/capability/index.ts +1 -11
- package/src/commit/analysis/index.ts +4 -4
- package/src/config/settings-schema.ts +18 -15
- package/src/config/settings.ts +2 -20
- package/src/discovery/index.ts +1 -11
- package/src/exa/index.ts +1 -10
- package/src/extensibility/custom-commands/index.ts +2 -15
- package/src/extensibility/custom-tools/index.ts +3 -18
- package/src/extensibility/custom-tools/loader.ts +28 -5
- package/src/extensibility/custom-tools/types.ts +18 -1
- package/src/extensibility/extensions/index.ts +9 -130
- package/src/extensibility/extensions/types.ts +2 -1
- package/src/extensibility/hooks/index.ts +3 -14
- package/src/extensibility/plugins/index.ts +6 -31
- package/src/index.ts +28 -220
- package/src/internal-urls/docs-index.generated.ts +3 -2
- package/src/internal-urls/index.ts +11 -16
- package/src/mcp/index.ts +11 -37
- package/src/mcp/transports/index.ts +2 -2
- package/src/modes/components/extensions/index.ts +3 -3
- package/src/modes/components/index.ts +35 -40
- package/src/modes/rpc/rpc-mode.ts +1 -7
- package/src/patch/index.ts +4 -20
- package/src/prompts/system/system-prompt.md +3 -3
- package/src/prompts/tools/ast-edit.md +30 -0
- package/src/prompts/tools/{ast-find.md → ast-grep.md} +10 -12
- package/src/prompts/tools/bash.md +2 -2
- package/src/prompts/tools/hashline.md +2 -0
- package/src/prompts/tools/resolve.md +8 -0
- package/src/sdk.ts +27 -7
- package/src/session/agent-session.ts +24 -33
- package/src/session/session-manager.ts +0 -30
- package/src/stt/index.ts +3 -3
- package/src/task/types.ts +2 -2
- package/src/tools/ast-edit.ts +480 -0
- package/src/tools/{ast-find.ts → ast-grep.ts} +195 -86
- package/src/tools/bash.ts +3 -2
- package/src/tools/gemini-image.ts +3 -3
- package/src/tools/index.ts +55 -57
- package/src/tools/pending-action.ts +49 -0
- package/src/tools/render-utils.ts +10 -0
- package/src/tools/renderers.ts +6 -4
- package/src/tools/resolve.ts +156 -0
- package/src/web/search/index.ts +6 -4
- package/src/web/search/providers/anthropic.ts +2 -2
- package/src/web/search/providers/base.ts +3 -0
- package/src/web/search/providers/exa.ts +11 -5
- package/src/web/search/providers/gemini.ts +112 -24
- package/src/patch/normative.ts +0 -72
- package/src/prompts/tools/ast-replace.md +0 -37
- package/src/tools/ast-replace.ts +0 -300
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,66 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [13.4.1] - 2026-03-01
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Pending resolve reminders now trigger as soon as a preview action is queued, before the next assistant turn, with regression coverage in `agent-session-resolve-reminder` tests
|
|
10
|
+
|
|
11
|
+
## [13.4.0] - 2026-03-01
|
|
12
|
+
|
|
13
|
+
### Breaking Changes
|
|
14
|
+
|
|
15
|
+
- `ast_grep` parameter `pattern` (string) replaced by `patterns` (string[])
|
|
16
|
+
- `ast_edit` parameters `pattern` + `rewrite` replaced by `ops: Array<{ pat: string; out: string }>`
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Added `resolve` tool to apply or discard pending preview actions with required reasoning
|
|
21
|
+
- AST edit now registers pending actions after preview, allowing explicit apply/discard workflow via `resolve` tool
|
|
22
|
+
- Custom tools can register pending actions via `pushPendingAction(action)` in `CustomToolAPI`, enabling the `resolve` workflow for custom preview-apply flows
|
|
23
|
+
- `deferrable?: boolean` field added to `AgentTool`, `CustomTool`, and `ToolDefinition` interfaces; tools that set it signal they may stage pending actions
|
|
24
|
+
- `HIDDEN_TOOLS` and `ResolveTool` exported from `@oh-my-pi/pi-coding-agent` SDK for manual tool composition
|
|
25
|
+
- `PendingActionStore` now uses a LIFO stack (`push`/`peek`/`pop`); multiple deferrable tools can stage actions that resolve in reverse order of registration
|
|
26
|
+
- Added `gemini`, `codex`, and `synthetic` as supported values for the `providers.webSearch` setting
|
|
27
|
+
- `ast_grep` tool now accepts a `patterns` array (replaces single `pattern`); multiple patterns run in one native pass and results are merged before offset/limit
|
|
28
|
+
- `ast_edit` tool now accepts an `ops` array of `{ pat, out }` entries (replaces `pattern` + `rewrite`); duplicate patterns are rejected upfront
|
|
29
|
+
- AST find output now uses `>>` prefix on match-start lines and pads line numbers; directory-tree grouping with `# dir` / `## └─ file` headers for directory-scoped searches
|
|
30
|
+
- AST replace output now renders diff-style (`-before` / `+after`) change previews grouped by directory
|
|
31
|
+
- Both AST tools now report `scopePath`, `files`, and per-file match/replacement counts in tool details
|
|
32
|
+
- Task item `id` max length raised from 32 to 48 characters
|
|
33
|
+
- Anthropic web search provider now uses `buildAnthropicSearchHeaders` (dedicated search header builder separate from inference headers)
|
|
34
|
+
- Gemini web search provider: endpoint fallback (daily → sandbox) with retry on 429/5xx
|
|
35
|
+
- Gemini web search now injects Antigravity system instruction and aligned request metadata (`requestType`, `userAgent`, `requestId`) for Antigravity credentials
|
|
36
|
+
- `buildGeminiRequestTools()` helper for composable Gemini tool configuration (googleSearch, codeExecution, urlContext)
|
|
37
|
+
- Web search schema exposes `max_tokens`, `temperature`, and `num_search_results` as tool parameters
|
|
38
|
+
- Web search provider fallback: when an explicit provider is unavailable, resolves the auto chain instead of returning empty results
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- Simplified `resolve` tool output rendering to use inline highlighted format instead of boxed layout
|
|
43
|
+
- Updated `resolve` tool to parse source tool name from label using colon separator for cleaner display
|
|
44
|
+
- `resolve` tool is now conditionally injected: included only when at least one active tool has `deferrable: true` (previously always included)
|
|
45
|
+
- `discoverAndLoadCustomTools` / `loadCustomTools` accept an optional `pendingActionStore` parameter to wire `pushPendingAction` for custom tools
|
|
46
|
+
- AST edit tool no longer accepts `preview` parameter; all AST edit calls now return previews by default
|
|
47
|
+
- AST edit workflow changed: preview is always shown, then use `resolve` tool to apply or discard changes
|
|
48
|
+
- Agent now suggests calling `resolve` tool after AST edit preview with system reminder
|
|
49
|
+
- `ast_grep`: `include_meta` parameter removed; metavariable captures are now always included in output
|
|
50
|
+
- `ast_edit`: `dry_run` renamed to `preview`; `max_files` removed from schema and capped globally via `$PI_MAX_AST_FILES` (default 1000); `max_replacements` renamed to `limit`
|
|
51
|
+
- `ast_grep` and `ast_edit`: parse errors in tool output are now capped at `PARSE_ERRORS_LIMIT` (20); excess errors are summarised as `N / total parse issues` rather than flooding the context
|
|
52
|
+
- Updated `ast_grep` and `ast_edit` tool prompt examples to use concise, idiomatic patterns
|
|
53
|
+
|
|
54
|
+
### Removed
|
|
55
|
+
|
|
56
|
+
- Removed `normativeRewrite` setting that rewrote tool call arguments to normalized format in session history
|
|
57
|
+
- Removed `buildNormativeUpdateInput()` helper and normative patch transformation logic
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
|
|
61
|
+
- `ast_edit` no longer rejects empty `out` values; an empty string now deletes matched nodes
|
|
62
|
+
- `ast_edit` no longer trims `pat` and `out` values, preserving intentional whitespace
|
|
63
|
+
- `gemini_image` tool: corrected `responseModalities` values from `'Image'`/`'Text'` to uppercase `'IMAGE'`/`'TEXT'` matching the API enum
|
|
64
|
+
|
|
5
65
|
## [13.3.14] - 2026-02-28
|
|
6
66
|
|
|
7
67
|
### Added
|
|
@@ -9,7 +69,7 @@
|
|
|
9
69
|
- Expanded AST tool language support from 7 to all 25 ast-grep tree-sitter languages (Bash, C, C++, C#, CSS, Elixir, Go, Haskell, HCL, HTML, Java, JavaScript, JSON, Kotlin, Lua, Nix, PHP, Python, Ruby, Rust, Scala, Solidity, Swift, TSX, TypeScript, YAML)
|
|
10
70
|
- AST find now emits all lines of multiline matches with hashline tags (LINE#HASH:content) consistent with read/grep output
|
|
11
71
|
- Added AST pattern syntax reference (metavariables, wildcards, variadics) to system prompt
|
|
12
|
-
- Added examples and scoping guidance to ast-
|
|
72
|
+
- Added examples and scoping guidance to ast-grep and ast-edit tool prompts
|
|
13
73
|
- Added `provider-schema-compatibility.test.ts`: integration test that instantiates every builtin and hidden tool, runs their parameter schemas through `adaptSchemaForStrict`, `sanitizeSchemaForGoogle`, and `prepareSchemaForCCA`, and asserts zero violations against each provider's compatibility rules
|
|
14
74
|
|
|
15
75
|
### Fixed
|
|
@@ -28,9 +88,9 @@
|
|
|
28
88
|
|
|
29
89
|
### Added
|
|
30
90
|
|
|
31
|
-
- Added `
|
|
32
|
-
- Added `
|
|
33
|
-
- Added `
|
|
91
|
+
- Added `ast_grep` tool for structural code search using AST matching via ast-grep, enabling syntax-aware pattern discovery across codebases
|
|
92
|
+
- Added `ast_edit` tool for structural AST-aware rewrites via ast-grep, enabling safe syntax-level codemods without text-based fragility
|
|
93
|
+
- Added `astGrep.enabled` and `astEdit.enabled` settings to control availability of AST tools
|
|
34
94
|
- Added system prompt guidance to prefer AST tools over bash text manipulation (grep/sed/awk/perl) for syntax-aware operations
|
|
35
95
|
- Extracted prompt formatting logic into reusable `formatPromptContent()` utility with configurable render phases and formatting options
|
|
36
96
|
- Added `type_definition` action to navigate to symbol type definitions with source context
|
|
@@ -57,10 +117,10 @@
|
|
|
57
117
|
- Updated HTML parsing API calls from `node-html-parser` to `linkedom` across all web scrapers (arXiv, IACR, Go pkg, Read the Docs, Twitter, Wikipedia)
|
|
58
118
|
- Changed element text extraction from `.text` property to `.textContent` property for compatibility with linkedom DOM API
|
|
59
119
|
- Optimized document link extraction to use regex-based parsing with deduplication and a 20-link limit instead of full DOM traversal
|
|
60
|
-
- Unified `path` parameter in
|
|
61
|
-
- Removed `strictness` parameter from
|
|
62
|
-
- Removed `fail_on_parse_error` parameter from
|
|
63
|
-
- Updated
|
|
120
|
+
- Unified `path` parameter in ast_grep and ast_edit tools to accept files, directories, or glob patterns directly, eliminating the separate `glob` parameter
|
|
121
|
+
- Removed `strictness` parameter from ast_grep and ast_edit tools
|
|
122
|
+
- Removed `fail_on_parse_error` parameter from ast_edit tool (now always false)
|
|
123
|
+
- Updated ast_grep and ast_edit prompt guidance to clarify that `path` accepts glob patterns and no longer requires separate glob specification
|
|
64
124
|
- Refactored prompt template rendering to use unified `formatPromptContent()` function with phase-aware formatting (pre-render vs post-render)
|
|
65
125
|
- Updated `format-prompts.ts` script to use centralized prompt formatting utility instead of inline implementation
|
|
66
126
|
- Replaced `column` parameter with `symbol` parameter for more intuitive position specification
|
|
@@ -5362,4 +5422,4 @@ Initial public release.
|
|
|
5362
5422
|
- Git branch display in footer
|
|
5363
5423
|
- Message queueing during streaming responses
|
|
5364
5424
|
- OAuth integration for Gmail and Google Calendar access
|
|
5365
|
-
- HTML export with syntax highlighting and collapsible sections
|
|
5425
|
+
- HTML export with syntax highlighting and collapsible sections
|
package/examples/sdk/README.md
CHANGED
|
@@ -45,7 +45,9 @@ import {
|
|
|
45
45
|
ModelRegistry,
|
|
46
46
|
SessionManager,
|
|
47
47
|
BUILTIN_TOOLS,
|
|
48
|
+
HIDDEN_TOOLS,
|
|
48
49
|
createTools,
|
|
50
|
+
ResolveTool,
|
|
49
51
|
} from "@oh-my-pi/pi-coding-agent";
|
|
50
52
|
|
|
51
53
|
// Auth and models setup
|
|
@@ -104,6 +106,26 @@ session.subscribe((event) => {
|
|
|
104
106
|
await session.prompt("Hello");
|
|
105
107
|
```
|
|
106
108
|
|
|
109
|
+
## Resolve preview workflow (AST edit apply/discard)
|
|
110
|
+
|
|
111
|
+
`ast_edit` now always returns a preview. To finalize, call hidden `resolve` with a required reason.
|
|
112
|
+
|
|
113
|
+
- `action: "apply"` → commit pending preview changes
|
|
114
|
+
- `action: "discard"` → drop pending preview changes
|
|
115
|
+
- `reason: string` is required for both paths
|
|
116
|
+
|
|
117
|
+
`createAgentSession()` / `createTools()` include `resolve` automatically, even when filtering `toolNames`.
|
|
118
|
+
If you are composing tools manually, use `HIDDEN_TOOLS.resolve` (or `ResolveTool`) and wire the same `pendingActionStore`.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
const tools = await createTools(toolSession, ["ast_edit"]); // resolve is auto-included
|
|
122
|
+
const resolveTool = tools.find(t => t.name === "resolve") as ResolveTool;
|
|
123
|
+
|
|
124
|
+
await resolveTool.execute("call-1", {
|
|
125
|
+
action: "apply",
|
|
126
|
+
reason: "Preview matches expected replacements",
|
|
127
|
+
});
|
|
128
|
+
```
|
|
107
129
|
## Options
|
|
108
130
|
|
|
109
131
|
| Option | Default | Description |
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-coding-agent",
|
|
4
|
-
"version": "13.
|
|
4
|
+
"version": "13.4.1",
|
|
5
5
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
6
6
|
"homepage": "https://github.com/can1357/oh-my-pi",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -41,12 +41,12 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@mozilla/readability": "^0.6",
|
|
44
|
-
"@oh-my-pi/omp-stats": "13.
|
|
45
|
-
"@oh-my-pi/pi-agent-core": "13.
|
|
46
|
-
"@oh-my-pi/pi-ai": "13.
|
|
47
|
-
"@oh-my-pi/pi-natives": "13.
|
|
48
|
-
"@oh-my-pi/pi-tui": "13.
|
|
49
|
-
"@oh-my-pi/pi-utils": "13.
|
|
44
|
+
"@oh-my-pi/omp-stats": "13.4.1",
|
|
45
|
+
"@oh-my-pi/pi-agent-core": "13.4.1",
|
|
46
|
+
"@oh-my-pi/pi-ai": "13.4.1",
|
|
47
|
+
"@oh-my-pi/pi-natives": "13.4.1",
|
|
48
|
+
"@oh-my-pi/pi-tui": "13.4.1",
|
|
49
|
+
"@oh-my-pi/pi-utils": "13.4.1",
|
|
50
50
|
"@sinclair/typebox": "^0.34",
|
|
51
51
|
"@xterm/headless": "^6.0",
|
|
52
52
|
"ajv": "^8.18",
|
package/src/capability/index.ts
CHANGED
|
@@ -419,14 +419,4 @@ export function cacheStats(): { content: number; dir: number } {
|
|
|
419
419
|
// Re-exports
|
|
420
420
|
// =============================================================================
|
|
421
421
|
|
|
422
|
-
export type
|
|
423
|
-
Capability,
|
|
424
|
-
CapabilityInfo,
|
|
425
|
-
CapabilityResult,
|
|
426
|
-
LoadContext,
|
|
427
|
-
LoadOptions,
|
|
428
|
-
LoadResult,
|
|
429
|
-
Provider,
|
|
430
|
-
ProviderInfo,
|
|
431
|
-
SourceMeta,
|
|
432
|
-
} from "./types";
|
|
422
|
+
export type * from "./types";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
1
|
+
export * from "./conventional";
|
|
2
|
+
export * from "./scope";
|
|
3
|
+
export * from "./summary";
|
|
4
|
+
export * from "./validation";
|
|
@@ -254,15 +254,6 @@ export const SETTINGS_SCHEMA = {
|
|
|
254
254
|
submenu: true,
|
|
255
255
|
},
|
|
256
256
|
},
|
|
257
|
-
normativeRewrite: {
|
|
258
|
-
type: "boolean",
|
|
259
|
-
default: false,
|
|
260
|
-
ui: {
|
|
261
|
-
tab: "agent",
|
|
262
|
-
label: "Normative rewrite",
|
|
263
|
-
description: "Rewrite tool call arguments to normalized format in session history",
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
257
|
repeatToolDescriptions: {
|
|
267
258
|
type: "boolean",
|
|
268
259
|
default: false,
|
|
@@ -455,18 +446,18 @@ export const SETTINGS_SCHEMA = {
|
|
|
455
446
|
submenu: true,
|
|
456
447
|
},
|
|
457
448
|
},
|
|
458
|
-
"
|
|
449
|
+
"astGrep.enabled": {
|
|
459
450
|
type: "boolean",
|
|
460
451
|
default: true,
|
|
461
|
-
ui: { tab: "tools", label: "Enable AST
|
|
452
|
+
ui: { tab: "tools", label: "Enable AST Grep", description: "Enable the ast_grep tool for structural AST search" },
|
|
462
453
|
},
|
|
463
|
-
"
|
|
454
|
+
"astEdit.enabled": {
|
|
464
455
|
type: "boolean",
|
|
465
456
|
default: true,
|
|
466
457
|
ui: {
|
|
467
458
|
tab: "tools",
|
|
468
|
-
label: "Enable AST
|
|
469
|
-
description: "Enable the
|
|
459
|
+
label: "Enable AST Edit",
|
|
460
|
+
description: "Enable the ast_edit tool for structural AST rewrites",
|
|
470
461
|
},
|
|
471
462
|
},
|
|
472
463
|
"notebook.enabled": {
|
|
@@ -737,7 +728,19 @@ export const SETTINGS_SCHEMA = {
|
|
|
737
728
|
// ─────────────────────────────────────────────────────────────────────────
|
|
738
729
|
"providers.webSearch": {
|
|
739
730
|
type: "enum",
|
|
740
|
-
values: [
|
|
731
|
+
values: [
|
|
732
|
+
"auto",
|
|
733
|
+
"exa",
|
|
734
|
+
"brave",
|
|
735
|
+
"jina",
|
|
736
|
+
"kimi",
|
|
737
|
+
"zai",
|
|
738
|
+
"perplexity",
|
|
739
|
+
"anthropic",
|
|
740
|
+
"gemini",
|
|
741
|
+
"codex",
|
|
742
|
+
"synthetic",
|
|
743
|
+
] as const,
|
|
741
744
|
default: "auto",
|
|
742
745
|
ui: { tab: "services", label: "Web search provider", description: "Provider for web search tool", submenu: true },
|
|
743
746
|
},
|
package/src/config/settings.ts
CHANGED
|
@@ -41,26 +41,8 @@ import {
|
|
|
41
41
|
} from "./settings-schema";
|
|
42
42
|
|
|
43
43
|
// Re-export types that callers need
|
|
44
|
-
export type
|
|
45
|
-
|
|
46
|
-
BranchSummarySettings,
|
|
47
|
-
CommitSettings,
|
|
48
|
-
CompactionSettings,
|
|
49
|
-
ContextPromotionSettings,
|
|
50
|
-
ExaSettings,
|
|
51
|
-
GroupPrefix,
|
|
52
|
-
GroupTypeMap,
|
|
53
|
-
MemoriesSettings,
|
|
54
|
-
RetrySettings,
|
|
55
|
-
SettingPath,
|
|
56
|
-
SettingValue,
|
|
57
|
-
SkillsSettings,
|
|
58
|
-
StatusLineSettings,
|
|
59
|
-
ThinkingBudgetsSettings,
|
|
60
|
-
TodoCompletionSettings,
|
|
61
|
-
TtsrSettings,
|
|
62
|
-
} from "./settings-schema";
|
|
63
|
-
export { getDefault, getEnumValues, getPathsForTab, getType, getUi, hasUi } from "./settings-schema";
|
|
44
|
+
export type * from "./settings-schema";
|
|
45
|
+
export * from "./settings-schema";
|
|
64
46
|
|
|
65
47
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
66
48
|
// Types
|
package/src/discovery/index.ts
CHANGED
|
@@ -76,14 +76,4 @@ export type { SSHHost } from "../capability/ssh";
|
|
|
76
76
|
export type { SystemPrompt } from "../capability/system-prompt";
|
|
77
77
|
export type { CustomTool } from "../capability/tool";
|
|
78
78
|
// Re-export types
|
|
79
|
-
export type
|
|
80
|
-
Capability,
|
|
81
|
-
CapabilityInfo,
|
|
82
|
-
CapabilityResult,
|
|
83
|
-
LoadContext,
|
|
84
|
-
LoadOptions,
|
|
85
|
-
LoadResult,
|
|
86
|
-
Provider,
|
|
87
|
-
ProviderInfo,
|
|
88
|
-
SourceMeta,
|
|
89
|
-
} from "../capability/types";
|
|
79
|
+
export type * from "../capability/types";
|
package/src/exa/index.ts
CHANGED
|
@@ -27,16 +27,7 @@ export const exaTools: CustomTool<any, ExaRenderDetails>[] = [
|
|
|
27
27
|
|
|
28
28
|
export { companyTool } from "./company";
|
|
29
29
|
export { linkedinTool } from "./linkedin";
|
|
30
|
-
export
|
|
31
|
-
callExaTool,
|
|
32
|
-
callWebsetsTool,
|
|
33
|
-
createMCPToolFromServer,
|
|
34
|
-
fetchMCPToolSchema,
|
|
35
|
-
findApiKey,
|
|
36
|
-
formatSearchResults,
|
|
37
|
-
isSearchResponse,
|
|
38
|
-
MCPWrappedTool,
|
|
39
|
-
} from "./mcp-client";
|
|
30
|
+
export * from "./mcp-client";
|
|
40
31
|
export { renderExaCall, renderExaResult } from "./render";
|
|
41
32
|
export { researcherTools } from "./researcher";
|
|
42
33
|
// Re-export individual modules for selective importing
|
|
@@ -1,15 +1,2 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
type DiscoverCustomCommandsResult,
|
|
4
|
-
discoverCustomCommands,
|
|
5
|
-
type LoadCustomCommandsOptions,
|
|
6
|
-
loadCustomCommands,
|
|
7
|
-
} from "./loader";
|
|
8
|
-
export type {
|
|
9
|
-
CustomCommand,
|
|
10
|
-
CustomCommandAPI,
|
|
11
|
-
CustomCommandFactory,
|
|
12
|
-
CustomCommandSource,
|
|
13
|
-
CustomCommandsLoadResult,
|
|
14
|
-
LoadedCustomCommand,
|
|
15
|
-
} from "./types";
|
|
1
|
+
export * from "./loader";
|
|
2
|
+
export type * from "./types";
|
|
@@ -2,21 +2,6 @@
|
|
|
2
2
|
* Custom tools module.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
export type
|
|
7
|
-
|
|
8
|
-
AgentToolUpdateCallback,
|
|
9
|
-
CustomTool,
|
|
10
|
-
CustomToolAPI,
|
|
11
|
-
CustomToolContext,
|
|
12
|
-
CustomToolFactory,
|
|
13
|
-
CustomToolResult,
|
|
14
|
-
CustomToolSessionEvent,
|
|
15
|
-
CustomToolsLoadResult,
|
|
16
|
-
CustomToolUIContext,
|
|
17
|
-
ExecResult,
|
|
18
|
-
LoadedCustomTool,
|
|
19
|
-
RenderResultOptions,
|
|
20
|
-
ToolLoadError,
|
|
21
|
-
} from "./types";
|
|
22
|
-
export { CustomToolAdapter } from "./wrapper";
|
|
5
|
+
export * from "./loader";
|
|
6
|
+
export type * from "./types";
|
|
7
|
+
export * from "./wrapper";
|
|
@@ -14,6 +14,7 @@ import type { ExecOptions } from "../../exec/exec";
|
|
|
14
14
|
import { execCommand } from "../../exec/exec";
|
|
15
15
|
import type { HookUIContext } from "../../extensibility/hooks/types";
|
|
16
16
|
import { getAllPluginToolPaths } from "../../extensibility/plugins/loader";
|
|
17
|
+
import type { PendingActionStore } from "../../tools/pending-action";
|
|
17
18
|
import { createNoOpUIContext, resolvePath } from "../utils";
|
|
18
19
|
import type { CustomToolAPI, CustomToolFactory, LoadedCustomTool, ToolLoadError } from "./types";
|
|
19
20
|
|
|
@@ -84,7 +85,7 @@ export class CustomToolLoader {
|
|
|
84
85
|
#sharedApi: CustomToolAPI;
|
|
85
86
|
#seenNames: Set<string>;
|
|
86
87
|
|
|
87
|
-
constructor(cwd: string, builtInToolNames: string[]) {
|
|
88
|
+
constructor(cwd: string, builtInToolNames: string[], pendingActionStore?: PendingActionStore) {
|
|
88
89
|
this.#sharedApi = {
|
|
89
90
|
cwd,
|
|
90
91
|
exec: (command: string, args: string[], options?: ExecOptions) =>
|
|
@@ -94,6 +95,18 @@ export class CustomToolLoader {
|
|
|
94
95
|
logger,
|
|
95
96
|
typebox,
|
|
96
97
|
pi: piCodingAgent,
|
|
98
|
+
pushPendingAction: action => {
|
|
99
|
+
if (!pendingActionStore) {
|
|
100
|
+
throw new Error("Pending action store unavailable for custom tools in this runtime.");
|
|
101
|
+
}
|
|
102
|
+
pendingActionStore.push({
|
|
103
|
+
label: action.label,
|
|
104
|
+
sourceToolName: action.sourceToolName ?? "custom_tool",
|
|
105
|
+
apply: action.apply,
|
|
106
|
+
reject: action.reject,
|
|
107
|
+
details: action.details,
|
|
108
|
+
});
|
|
109
|
+
},
|
|
97
110
|
};
|
|
98
111
|
this.#seenNames = new Set<string>(builtInToolNames);
|
|
99
112
|
}
|
|
@@ -138,8 +151,13 @@ export class CustomToolLoader {
|
|
|
138
151
|
* @param cwd - Current working directory for resolving relative paths
|
|
139
152
|
* @param builtInToolNames - Names of built-in tools to check for conflicts
|
|
140
153
|
*/
|
|
141
|
-
export async function loadCustomTools(
|
|
142
|
-
|
|
154
|
+
export async function loadCustomTools(
|
|
155
|
+
pathsWithSources: ToolPathWithSource[],
|
|
156
|
+
cwd: string,
|
|
157
|
+
builtInToolNames: string[],
|
|
158
|
+
pendingActionStore?: PendingActionStore,
|
|
159
|
+
) {
|
|
160
|
+
const loader = new CustomToolLoader(cwd, builtInToolNames, pendingActionStore);
|
|
143
161
|
await loader.load(pathsWithSources);
|
|
144
162
|
return {
|
|
145
163
|
tools: loader.tools,
|
|
@@ -160,7 +178,12 @@ export async function loadCustomTools(pathsWithSources: ToolPathWithSource[], cw
|
|
|
160
178
|
* @param cwd - Current working directory
|
|
161
179
|
* @param builtInToolNames - Names of built-in tools to check for conflicts
|
|
162
180
|
*/
|
|
163
|
-
export async function discoverAndLoadCustomTools(
|
|
181
|
+
export async function discoverAndLoadCustomTools(
|
|
182
|
+
configuredPaths: string[],
|
|
183
|
+
cwd: string,
|
|
184
|
+
builtInToolNames: string[],
|
|
185
|
+
pendingActionStore?: PendingActionStore,
|
|
186
|
+
) {
|
|
164
187
|
const allPathsWithSources: ToolPathWithSource[] = [];
|
|
165
188
|
const seen = new Set<string>();
|
|
166
189
|
|
|
@@ -193,5 +216,5 @@ export async function discoverAndLoadCustomTools(configuredPaths: string[], cwd:
|
|
|
193
216
|
addPath(resolvePath(configPath, cwd), { provider: "config", providerName: "Config", level: "project" });
|
|
194
217
|
}
|
|
195
218
|
|
|
196
|
-
return loadCustomTools(allPathsWithSources, cwd, builtInToolNames);
|
|
219
|
+
return loadCustomTools(allPathsWithSources, cwd, builtInToolNames, pendingActionStore);
|
|
197
220
|
}
|
|
@@ -26,6 +26,20 @@ export type { AgentToolResult, AgentToolUpdateCallback };
|
|
|
26
26
|
// Re-export for backward compatibility
|
|
27
27
|
export type { ExecOptions, ExecResult } from "../../exec/exec";
|
|
28
28
|
|
|
29
|
+
/** Pending action entry consumed by the hidden resolve tool */
|
|
30
|
+
export interface CustomToolPendingAction {
|
|
31
|
+
/** Human-readable preview label shown in resolve flow */
|
|
32
|
+
label: string;
|
|
33
|
+
/** Apply callback invoked when resolve(action="apply") is called */
|
|
34
|
+
apply(reason: string): Promise<AgentToolResult<unknown>>;
|
|
35
|
+
/** Optional reject callback invoked when resolve(action="discard") is called */
|
|
36
|
+
reject?(reason: string): Promise<AgentToolResult<unknown> | undefined>;
|
|
37
|
+
/** Optional details metadata stored with the pending action */
|
|
38
|
+
details?: unknown;
|
|
39
|
+
/** Optional source tool name shown by resolve renderer (defaults to "custom_tool") */
|
|
40
|
+
sourceToolName?: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
29
43
|
/** API passed to custom tool factory (stable across session changes) */
|
|
30
44
|
export interface CustomToolAPI {
|
|
31
45
|
/** Current working directory */
|
|
@@ -42,6 +56,8 @@ export interface CustomToolAPI {
|
|
|
42
56
|
typebox: typeof import("@sinclair/typebox");
|
|
43
57
|
/** Injected pi-coding-agent exports */
|
|
44
58
|
pi: typeof import("../..");
|
|
59
|
+
/** Push a preview action that can later be resolved with the hidden resolve tool */
|
|
60
|
+
pushPendingAction(action: CustomToolPendingAction): void;
|
|
45
61
|
}
|
|
46
62
|
|
|
47
63
|
/**
|
|
@@ -162,7 +178,8 @@ export interface CustomTool<TParams extends TSchema = TSchema, TDetails = any> {
|
|
|
162
178
|
parameters: TParams;
|
|
163
179
|
/** If true, tool is excluded unless explicitly listed in --tools or agent's tools field */
|
|
164
180
|
hidden?: boolean;
|
|
165
|
-
|
|
181
|
+
/** If true, tool may stage deferred changes that require explicit resolve/discard. */
|
|
182
|
+
deferrable?: boolean;
|
|
166
183
|
/**
|
|
167
184
|
* Execute the tool.
|
|
168
185
|
* @param toolCallId - Unique ID for this tool call
|
|
@@ -3,134 +3,13 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export type { SlashCommandInfo, SlashCommandLocation, SlashCommandSource } from "../slash-commands";
|
|
6
|
-
export {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
SwitchSessionHandler,
|
|
14
|
-
} from "./runner";
|
|
15
|
-
export { ExtensionRunner } from "./runner";
|
|
16
|
-
export type {
|
|
17
|
-
AgentEndEvent,
|
|
18
|
-
AgentStartEvent,
|
|
19
|
-
// Re-exports
|
|
20
|
-
AgentToolResult,
|
|
21
|
-
AgentToolUpdateCallback,
|
|
22
|
-
AppAction,
|
|
23
|
-
AppendEntryHandler,
|
|
24
|
-
// Events - Tool (ToolCallEvent types)
|
|
25
|
-
BashToolCallEvent,
|
|
26
|
-
BashToolResultEvent,
|
|
27
|
-
BeforeAgentStartEvent,
|
|
28
|
-
BeforeAgentStartEventResult,
|
|
29
|
-
// Events - Agent
|
|
30
|
-
ContextEvent,
|
|
31
|
-
// Event Results
|
|
32
|
-
ContextEventResult,
|
|
33
|
-
ContextUsage,
|
|
34
|
-
CustomToolCallEvent,
|
|
35
|
-
CustomToolResultEvent,
|
|
36
|
-
EditToolCallEvent,
|
|
37
|
-
EditToolResultEvent,
|
|
38
|
-
ExecOptions,
|
|
39
|
-
ExecResult,
|
|
40
|
-
Extension,
|
|
41
|
-
ExtensionActions,
|
|
42
|
-
ExtensionAPI,
|
|
43
|
-
ExtensionCommandContext,
|
|
44
|
-
ExtensionCommandContextActions,
|
|
45
|
-
// Context
|
|
46
|
-
ExtensionContext,
|
|
47
|
-
ExtensionContextActions,
|
|
48
|
-
// Errors
|
|
49
|
-
ExtensionError,
|
|
50
|
-
ExtensionEvent,
|
|
51
|
-
ExtensionFactory,
|
|
52
|
-
ExtensionFlag,
|
|
53
|
-
ExtensionHandler,
|
|
54
|
-
ExtensionShortcut,
|
|
55
|
-
ExtensionUIContext,
|
|
56
|
-
ExtensionUIDialogOptions,
|
|
57
|
-
FindToolCallEvent,
|
|
58
|
-
FindToolResultEvent,
|
|
59
|
-
GetActiveToolsHandler,
|
|
60
|
-
GetAllToolsHandler,
|
|
61
|
-
GetCommandsHandler,
|
|
62
|
-
GetThinkingLevelHandler,
|
|
63
|
-
GrepToolCallEvent,
|
|
64
|
-
GrepToolResultEvent,
|
|
65
|
-
// Events - Input
|
|
66
|
-
InputEvent,
|
|
67
|
-
InputEventResult,
|
|
68
|
-
KeybindingsManager,
|
|
69
|
-
LoadExtensionsResult,
|
|
70
|
-
// Events - Message
|
|
71
|
-
MessageEndEvent,
|
|
72
|
-
// Message Rendering
|
|
73
|
-
MessageRenderer,
|
|
74
|
-
MessageRenderOptions,
|
|
75
|
-
MessageStartEvent,
|
|
76
|
-
MessageUpdateEvent,
|
|
77
|
-
// Provider Registration
|
|
78
|
-
ProviderConfig,
|
|
79
|
-
ProviderModelConfig,
|
|
80
|
-
ReadToolCallEvent,
|
|
81
|
-
ReadToolResultEvent,
|
|
82
|
-
// Commands
|
|
83
|
-
RegisteredCommand,
|
|
84
|
-
RegisteredTool,
|
|
85
|
-
// Events - Resources
|
|
86
|
-
ResourcesDiscoverEvent,
|
|
87
|
-
ResourcesDiscoverResult,
|
|
88
|
-
SendMessageHandler,
|
|
89
|
-
SendUserMessageHandler,
|
|
90
|
-
SessionBeforeBranchEvent,
|
|
91
|
-
SessionBeforeBranchResult,
|
|
92
|
-
SessionBeforeCompactEvent,
|
|
93
|
-
SessionBeforeCompactResult,
|
|
94
|
-
SessionBeforeSwitchEvent,
|
|
95
|
-
SessionBeforeSwitchResult,
|
|
96
|
-
SessionBeforeTreeEvent,
|
|
97
|
-
SessionBeforeTreeResult,
|
|
98
|
-
SessionBranchEvent,
|
|
99
|
-
SessionCompactEvent,
|
|
100
|
-
SessionCompactingEvent,
|
|
101
|
-
SessionCompactingResult,
|
|
102
|
-
SessionEvent,
|
|
103
|
-
SessionShutdownEvent,
|
|
104
|
-
// Events - Session
|
|
105
|
-
SessionStartEvent,
|
|
106
|
-
SessionSwitchEvent,
|
|
107
|
-
SessionTreeEvent,
|
|
108
|
-
SetActiveToolsHandler,
|
|
109
|
-
SetModelHandler,
|
|
110
|
-
SetThinkingLevelHandler,
|
|
111
|
-
TerminalInputHandler,
|
|
112
|
-
// Events - Tool
|
|
113
|
-
ToolCallEvent,
|
|
114
|
-
ToolCallEventResult,
|
|
115
|
-
// Tools
|
|
116
|
-
ToolDefinition,
|
|
117
|
-
// Events - Tool Execution
|
|
118
|
-
ToolExecutionEndEvent,
|
|
119
|
-
ToolExecutionStartEvent,
|
|
120
|
-
ToolExecutionUpdateEvent,
|
|
121
|
-
ToolRenderResultOptions,
|
|
122
|
-
ToolResultEvent,
|
|
123
|
-
ToolResultEventResult,
|
|
124
|
-
TreePreparation,
|
|
125
|
-
TurnEndEvent,
|
|
126
|
-
TurnStartEvent,
|
|
127
|
-
UserBashEvent,
|
|
128
|
-
UserBashEventResult,
|
|
129
|
-
UserPythonEvent,
|
|
130
|
-
UserPythonEventResult,
|
|
131
|
-
WriteToolCallEvent,
|
|
132
|
-
WriteToolResultEvent,
|
|
133
|
-
} from "./types";
|
|
6
|
+
export {
|
|
7
|
+
discoverAndLoadExtensions,
|
|
8
|
+
ExtensionRuntimeNotInitializedError,
|
|
9
|
+
loadExtensionFromFactory,
|
|
10
|
+
loadExtensions,
|
|
11
|
+
} from "./loader";
|
|
12
|
+
export * from "./runner";
|
|
134
13
|
// Type guards
|
|
135
|
-
export
|
|
136
|
-
export
|
|
14
|
+
export * from "./types";
|
|
15
|
+
export * from "./wrapper";
|
|
@@ -290,7 +290,8 @@ export interface ToolDefinition<TParams extends TSchema = TSchema, TDetails = un
|
|
|
290
290
|
parameters: TParams;
|
|
291
291
|
/** If true, tool is excluded unless explicitly listed in --tools or agent's tools field */
|
|
292
292
|
hidden?: boolean;
|
|
293
|
-
|
|
293
|
+
/** If true, tool may stage deferred changes that require explicit resolve/discard. */
|
|
294
|
+
deferrable?: boolean;
|
|
294
295
|
/** Execute the tool. */
|
|
295
296
|
execute(
|
|
296
297
|
toolCallId: string,
|
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
// biome-ignore assist/source/organizeImports: biome is not smart
|
|
2
1
|
export type { ReadonlySessionManager, UsageStatistics } from "../../session/session-manager";
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
type AppendEntryHandler,
|
|
7
|
-
type BranchHandler,
|
|
8
|
-
type LoadedHook,
|
|
9
|
-
type LoadHooksResult,
|
|
10
|
-
type NavigateTreeHandler,
|
|
11
|
-
type NewSessionHandler,
|
|
12
|
-
type SendMessageHandler,
|
|
13
|
-
} from "./loader";
|
|
14
|
-
export { execCommand, HookRunner, type HookErrorListener } from "./runner";
|
|
15
|
-
export { HookToolWrapper } from "./tool-wrapper";
|
|
2
|
+
export * from "./loader";
|
|
3
|
+
export * from "./runner";
|
|
4
|
+
export * from "./tool-wrapper";
|
|
16
5
|
export * from "./types";
|