@oh-my-pi/pi-coding-agent 17.2.9 → 17.2.11
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 +83 -0
- package/dist/{CHANGELOG-8yy8h3bc.md → CHANGELOG-d9xenpn9.md} +83 -0
- package/dist/cli.js +10208 -12596
- package/dist/types/capability/mcp.d.ts +11 -0
- package/dist/types/capability/skill.d.ts +6 -0
- package/dist/types/cli/args.d.ts +1 -0
- package/dist/types/cli/command-help.d.ts +3 -0
- package/dist/types/commands/share.d.ts +25 -0
- package/dist/types/commit/agentic/index.d.ts +3 -1
- package/dist/types/commit/execute.d.ts +32 -0
- package/dist/types/commit/index.d.ts +2 -1
- package/dist/types/commit/pipeline.d.ts +7 -1
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/model-resolver.d.ts +13 -0
- package/dist/types/config/settings-schema.d.ts +1 -34
- package/dist/types/discovery/agent-plugin-format.d.ts +143 -0
- package/dist/types/discovery/agent-plugins.d.ts +1 -0
- package/dist/types/discovery/contained-path.d.ts +34 -0
- package/dist/types/discovery/index.d.ts +1 -0
- package/dist/types/extensibility/custom-commands/types.d.ts +5 -5
- package/dist/types/extensibility/custom-tools/types.d.ts +3 -3
- package/dist/types/extensibility/extensions/loader.d.ts +9 -2
- package/dist/types/extensibility/extensions/types.d.ts +45 -8
- package/dist/types/extensibility/hooks/types.d.ts +5 -5
- package/dist/types/extensibility/shared-events.d.ts +3 -2
- package/dist/types/extensibility/skills.d.ts +5 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/main.d.ts +1 -1
- package/dist/types/mcp/transports/header-policy.d.ts +45 -0
- package/dist/types/mcp/types.d.ts +15 -0
- package/dist/types/modes/acp/acp-agent.d.ts +1 -1
- package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -1
- package/dist/types/modes/acp/acp-event-mapper.d.ts +1 -1
- package/dist/types/modes/acp/acp-mode.d.ts +1 -1
- package/dist/types/modes/components/agent-hub-projection.d.ts +38 -0
- package/dist/types/modes/components/agent-hub-renderer.d.ts +41 -0
- package/dist/types/modes/components/agent-hub.d.ts +14 -5
- package/dist/types/modes/components/agent-transcript-viewer.d.ts +2 -0
- package/dist/types/modes/components/chat-transcript-builder.d.ts +2 -0
- package/dist/types/modes/components/custom-editor.d.ts +1 -2
- package/dist/types/modes/components/model-browser.d.ts +9 -1
- package/dist/types/modes/components/status-line/types.d.ts +2 -0
- package/dist/types/modes/components/tool-execution.d.ts +2 -0
- package/dist/types/modes/interactive-mode.d.ts +8 -1
- package/dist/types/modes/utils/transcript-render-helpers.d.ts +3 -2
- package/dist/types/registry/agent-registry.d.ts +47 -0
- package/dist/types/registry/persisted-agents.d.ts +3 -1
- package/dist/types/secrets/index.d.ts +23 -1
- package/dist/types/session/agent-session-events.d.ts +2 -2
- package/dist/types/session/agent-session.d.ts +4 -2
- package/dist/types/session/messages.d.ts +1 -0
- package/dist/types/session/prewalk.d.ts +3 -1
- package/dist/types/session/session-entries.d.ts +10 -0
- package/dist/types/session/session-loader.d.ts +11 -1
- package/dist/types/session/session-manager.d.ts +9 -1
- package/dist/types/session/session-tools.d.ts +18 -1
- package/dist/types/session/turn-recovery.d.ts +7 -2
- package/dist/types/slash-commands/acp-builtins.d.ts +1 -1
- package/dist/types/slash-commands/available-commands.d.ts +1 -1
- package/dist/types/task/executor.d.ts +6 -0
- package/dist/types/task/index.d.ts +4 -3
- package/dist/types/task/read-only-policy.d.ts +3 -0
- package/dist/types/task/structured-subagent.d.ts +2 -0
- package/dist/types/task/types.d.ts +4 -0
- package/dist/types/tools/bash.d.ts +3 -3
- package/dist/types/tools/browser/launch.d.ts +2 -1
- package/dist/types/tools/browser/tab-worker.d.ts +2 -2
- package/dist/types/tools/path-utils.d.ts +1 -0
- package/dist/types/tools/read.d.ts +1 -5
- package/dist/types/tools/run-scope.d.ts +27 -1
- package/dist/types/tools/shell-tokenize.d.ts +16 -0
- package/dist/types/tools/terminal-output.d.ts +1 -1
- package/dist/types/utils/turndown.d.ts +1 -1
- package/dist/types/vibe/runtime.d.ts +2 -3
- package/dist/types/web/scrapers/readthedocs.d.ts +0 -3
- package/dist/types/web/search/providers/browser-headers.d.ts +2 -3
- package/examples/custom-tools/README.md +1 -1
- package/examples/extensions/README.md +1 -1
- package/examples/extensions/api-demo.ts +5 -6
- package/examples/extensions/chalk-logger.ts +1 -1
- package/examples/extensions/hello.ts +2 -2
- package/examples/extensions/reload-runtime.ts +1 -1
- package/examples/extensions/tools.ts +2 -2
- package/examples/extensions/with-deps/index.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/package.json +15 -31
- package/scripts/bundle-dist.ts +1 -11
- package/scripts/legacy-pi-virtual-module.ts +4 -1
- package/src/advisor/runtime.ts +54 -0
- package/src/capability/mcp.ts +11 -0
- package/src/capability/skill.ts +6 -0
- package/src/cli/agents-cli.ts +1 -1
- package/src/cli/args.ts +24 -2
- package/src/cli/auth-broker-cli.ts +1 -1
- package/src/cli/auth-gateway-cli.ts +1 -1
- package/src/cli/bench-cli.ts +1 -1
- package/src/cli/claude-trace-cli.ts +1 -1
- package/src/cli/command-help.ts +4 -0
- package/src/cli/config-cli.ts +1 -1
- package/src/cli/dry-balance-cli.ts +1 -1
- package/src/cli/file-processor.ts +1 -1
- package/src/cli/flag-tables.ts +4 -0
- package/src/cli/gallery-cli.ts +1 -1
- package/src/cli/grep-cli.ts +1 -1
- package/src/cli/grievances-cli.ts +1 -1
- package/src/cli/help-extra.ts +1 -1
- package/src/cli/models-cli.ts +1 -1
- package/src/cli/plugin-cli.ts +1 -1
- package/src/cli/read-cli.ts +1 -1
- package/src/cli/setup-cli.ts +1 -1
- package/src/cli/shell-cli.ts +1 -1
- package/src/cli/ssh-cli.ts +1 -1
- package/src/cli/stats-cli.ts +1 -1
- package/src/cli/tiny-models-cli.ts +1 -1
- package/src/cli/ttsr-cli.ts +1 -1
- package/src/cli/update-cli.ts +1 -1
- package/src/cli/usage-cli.ts +1 -1
- package/src/cli/web-search-cli.ts +1 -1
- package/src/cli/worktree-cli.ts +1 -1
- package/src/cli-commands.ts +5 -0
- package/src/commands/commit.ts +16 -3
- package/src/commands/say.ts +1 -1
- package/src/commands/share.ts +71 -0
- package/src/commands/token.ts +1 -1
- package/src/commit/agentic/agent.ts +1 -1
- package/src/commit/agentic/index.ts +39 -21
- package/src/commit/cli.ts +1 -1
- package/src/commit/execute.ts +56 -0
- package/src/commit/index.ts +2 -1
- package/src/commit/pipeline.ts +20 -7
- package/src/config/model-discovery.ts +1 -1
- package/src/config/model-registry.ts +21 -1
- package/src/config/model-resolver.ts +54 -7
- package/src/config/settings-schema.ts +2 -33
- package/src/config/settings.ts +46 -0
- package/src/discovery/agent-plugin-format.ts +551 -0
- package/src/discovery/agent-plugins.ts +341 -0
- package/src/discovery/agents.ts +4 -2
- package/src/discovery/builtin-rules/ts-no-inline-cast-access.md +5 -4
- package/src/discovery/builtin-rules/ts-no-tiny-functions.md +1 -1
- package/src/discovery/claude-plugins.ts +21 -5
- package/src/discovery/contained-path.ts +78 -0
- package/src/discovery/helpers.ts +23 -9
- package/src/discovery/index.ts +1 -0
- package/src/discovery/omp-plugins.ts +20 -7
- package/src/eval/py/runner.py +38 -1
- package/src/exec/non-interactive-env.ts +1 -0
- package/src/extensibility/custom-commands/loader.ts +4 -4
- package/src/extensibility/custom-commands/types.ts +5 -5
- package/src/extensibility/custom-tools/loader.ts +4 -4
- package/src/extensibility/custom-tools/types.ts +3 -3
- package/src/extensibility/extensions/loader.ts +85 -20
- package/src/extensibility/extensions/runner.ts +6 -0
- package/src/extensibility/extensions/types.ts +51 -8
- package/src/extensibility/hooks/loader.ts +4 -5
- package/src/extensibility/hooks/types.ts +5 -5
- package/src/extensibility/plugins/legacy-pi-compat.ts +53 -0
- package/src/extensibility/plugins/marketplace/manager.ts +2 -1
- package/src/extensibility/shared-events.ts +3 -2
- package/src/extensibility/skills.ts +9 -0
- package/src/index.ts +2 -2
- package/src/internal-urls/memory-protocol.ts +5 -1
- package/src/internal-urls/skill-protocol.ts +14 -0
- package/src/internal-urls/vault-protocol.ts +2 -2
- package/src/launch/client.ts +11 -1
- package/src/launch/protocol.ts +7 -2
- package/src/launch/terminal-output.ts +1 -1
- package/src/main.ts +88 -23
- package/src/markit/converters/docx.ts +1 -1
- package/src/markit/converters/epub.ts +1 -1
- package/src/markit/converters/pptx.ts +1 -1
- package/src/markit/converters/xlsx.ts +1 -1
- package/src/mcp/config.ts +3 -0
- package/src/mcp/manager.ts +12 -9
- package/src/mcp/transports/header-policy.ts +95 -0
- package/src/mcp/transports/http.ts +35 -52
- package/src/mcp/transports/sse.ts +20 -27
- package/src/mcp/types.ts +15 -0
- package/src/modes/acp/acp-agent.ts +20 -9
- package/src/modes/acp/acp-client-bridge.ts +1 -1
- package/src/modes/acp/acp-event-mapper.ts +1 -1
- package/src/modes/acp/acp-mode.ts +1 -1
- package/src/modes/components/agent-dashboard.ts +2 -0
- package/src/modes/components/agent-hub-projection.ts +248 -0
- package/src/modes/components/agent-hub-renderer.ts +194 -0
- package/src/modes/components/agent-hub.ts +674 -207
- package/src/modes/components/agent-transcript-viewer.ts +3 -0
- package/src/modes/components/assistant-message.ts +1 -1
- package/src/modes/components/chat-transcript-builder.ts +3 -0
- package/src/modes/components/custom-editor.ts +0 -9
- package/src/modes/components/extensions/inspector-panel.ts +11 -6
- package/src/modes/components/footer.ts +1 -3
- package/src/modes/components/model-browser.ts +11 -3
- package/src/modes/components/model-hub.ts +4 -1
- package/src/modes/components/status-line/component.ts +1 -0
- package/src/modes/components/status-line/segments.ts +10 -7
- package/src/modes/components/status-line/types.ts +2 -0
- package/src/modes/components/tool-execution.ts +13 -16
- package/src/modes/components/tree-selector.ts +62 -3
- package/src/modes/controllers/command-controller.ts +4 -1
- package/src/modes/controllers/event-controller.ts +44 -20
- package/src/modes/controllers/extension-ui-controller.ts +2 -2
- package/src/modes/controllers/input-controller.ts +20 -2
- package/src/modes/controllers/mcp-command-controller.ts +81 -20
- package/src/modes/controllers/selector-controller.ts +41 -49
- package/src/modes/controllers/streaming-reveal.ts +1 -1
- package/src/modes/interactive-mode.ts +13 -2
- package/src/modes/rpc/rpc-mode.ts +2 -2
- package/src/modes/runtime-init.ts +1 -1
- package/src/modes/theme/theme.ts +2 -2
- package/src/modes/utils/transcript-render-helpers.ts +4 -2
- package/src/modes/utils/ui-helpers.ts +1 -0
- package/src/prompts/tools/computer.md +1 -1
- package/src/registry/agent-lifecycle.ts +14 -7
- package/src/registry/agent-registry.ts +65 -2
- package/src/registry/persisted-agents.ts +341 -16
- package/src/sdk.ts +6 -49
- package/src/secrets/index.ts +52 -1
- package/src/session/agent-session-events.ts +2 -2
- package/src/session/agent-session.ts +54 -16
- package/src/session/messages.ts +1 -0
- package/src/session/prewalk.ts +57 -17
- package/src/session/session-context.ts +3 -5
- package/src/session/session-entries.ts +10 -0
- package/src/session/session-handoff.ts +5 -1
- package/src/session/session-listing.ts +1 -1
- package/src/session/session-loader.ts +74 -8
- package/src/session/session-manager.ts +22 -2
- package/src/session/session-paths.ts +57 -9
- package/src/session/session-tools.ts +65 -4
- package/src/session/todo-tracker.ts +11 -1
- package/src/session/turn-recovery.ts +96 -74
- package/src/slash-commands/acp-builtins.ts +1 -1
- package/src/slash-commands/available-commands.ts +1 -1
- package/src/slash-commands/builtin-registry.ts +12 -8
- package/src/task/executor.ts +70 -20
- package/src/task/index.ts +30 -34
- package/src/task/isolation-runner.ts +24 -11
- package/src/task/persisted-revive.ts +12 -5
- package/src/task/read-only-policy.ts +27 -0
- package/src/task/structured-subagent.ts +14 -4
- package/src/task/types.ts +4 -0
- package/src/tools/auto-generated-guard.ts +1 -1
- package/src/tools/bash-interactive.ts +4 -4
- package/src/tools/bash-skill-urls.ts +15 -0
- package/src/tools/bash.ts +16 -17
- package/src/tools/browser/cmux/cmux-tab.ts +66 -18
- package/src/tools/browser/launch.ts +41 -12
- package/src/tools/browser/readable.ts +9 -9
- package/src/tools/browser/tab-supervisor.ts +12 -3
- package/src/tools/browser/tab-worker-entry.ts +1 -1
- package/src/tools/browser/tab-worker.ts +101 -12
- package/src/tools/debug.ts +1 -1
- package/src/tools/fetch.ts +1 -1
- package/src/tools/jtd-to-json-schema.ts +123 -21
- package/src/tools/path-utils.ts +9 -2
- package/src/tools/read.ts +21 -9
- package/src/tools/run-scope.ts +290 -4
- package/src/tools/shell-tokenize.ts +98 -0
- package/src/tools/terminal-output.ts +1 -1
- package/src/tools/todo.ts +1 -1
- package/src/utils/clipboard.ts +10 -2
- package/src/utils/external-editor.ts +4 -2
- package/src/utils/jj.ts +1 -1
- package/src/utils/turndown.ts +1 -2
- package/src/vibe/runtime.ts +5 -5
- package/src/web/scrapers/arxiv.ts +1 -1
- package/src/web/scrapers/go-pkg.ts +1 -1
- package/src/web/scrapers/iacr.ts +1 -1
- package/src/web/scrapers/readthedocs.ts +2 -1
- package/src/web/scrapers/twitter.ts +2 -2
- package/src/web/scrapers/types.ts +1 -1
- package/src/web/scrapers/wikipedia.ts +1 -1
- package/src/web/search/providers/browser-headers.ts +12 -39
- package/src/web/search/providers/codex.ts +3 -26
- package/src/web/search/providers/ecosia.ts +1 -1
- package/src/web/search/providers/exa.ts +1 -1
- package/src/web/search/providers/google.ts +1 -1
- package/src/web/search/providers/mojeek.ts +1 -1
- package/src/web/search/providers/startpage.ts +1 -1
- package/src/markit/converters/mammoth.d.ts +0 -24
|
@@ -28,6 +28,7 @@ import { type Skill, skillCapability } from "../capability/skill";
|
|
|
28
28
|
import { type SlashCommand, slashCommandCapability } from "../capability/slash-command";
|
|
29
29
|
import { type CustomTool, toolCapability } from "../capability/tool";
|
|
30
30
|
import type { LoadContext, LoadResult } from "../capability/types";
|
|
31
|
+
import { legacyProviderAllowed } from "./agent-plugin-format";
|
|
31
32
|
import {
|
|
32
33
|
buildRuleFromMarkdown,
|
|
33
34
|
createSourceMeta,
|
|
@@ -44,12 +45,24 @@ const DESCRIPTION =
|
|
|
44
45
|
"Sub-discovery (skills, hooks, tools, commands, rules, prompts, .mcp.json) inside extension packages";
|
|
45
46
|
const PRIORITY = 90;
|
|
46
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Extension roots this legacy provider may process for a given surface. Roots
|
|
50
|
+
* whose root `plugin.json` targets the Agent Plugins standard keep their
|
|
51
|
+
* portable components (skills, MCP) exclusive to the `agent-plugins` provider;
|
|
52
|
+
* fatally invalid Agent Plugins packages are skipped entirely.
|
|
53
|
+
*/
|
|
54
|
+
async function allowedRoots(ctx: LoadContext, surface: "skills" | "mcp" | "other"): Promise<OmpExtensionRoot[]> {
|
|
55
|
+
const roots = await listOmpExtensionRoots(ctx);
|
|
56
|
+
const flags = await Promise.all(roots.map(root => legacyProviderAllowed(root.path, surface)));
|
|
57
|
+
return roots.filter((_, i) => flags[i]);
|
|
58
|
+
}
|
|
59
|
+
|
|
47
60
|
// =============================================================================
|
|
48
61
|
// Skills
|
|
49
62
|
// =============================================================================
|
|
50
63
|
|
|
51
64
|
async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
|
|
52
|
-
const roots = await
|
|
65
|
+
const roots = await allowedRoots(ctx, "skills");
|
|
53
66
|
const results = await Promise.all(
|
|
54
67
|
roots.map(root =>
|
|
55
68
|
scanSkillsFromDir(ctx, {
|
|
@@ -71,7 +84,7 @@ async function loadSkills(ctx: LoadContext): Promise<LoadResult<Skill>> {
|
|
|
71
84
|
// =============================================================================
|
|
72
85
|
|
|
73
86
|
async function loadSlashCommands(ctx: LoadContext): Promise<LoadResult<SlashCommand>> {
|
|
74
|
-
const roots = await
|
|
87
|
+
const roots = await allowedRoots(ctx, "other");
|
|
75
88
|
const results = await Promise.all(
|
|
76
89
|
roots.map(root =>
|
|
77
90
|
loadFilesFromDir<SlashCommand>(ctx, path.join(root.path, "commands"), PROVIDER_ID, root.level, {
|
|
@@ -97,7 +110,7 @@ async function loadSlashCommands(ctx: LoadContext): Promise<LoadResult<SlashComm
|
|
|
97
110
|
// =============================================================================
|
|
98
111
|
|
|
99
112
|
async function loadRules(ctx: LoadContext): Promise<LoadResult<Rule>> {
|
|
100
|
-
const roots = await
|
|
113
|
+
const roots = await allowedRoots(ctx, "other");
|
|
101
114
|
const results = await Promise.all(
|
|
102
115
|
roots.map(root =>
|
|
103
116
|
loadFilesFromDir<Rule>(ctx, path.join(root.path, "rules"), PROVIDER_ID, root.level, {
|
|
@@ -118,7 +131,7 @@ async function loadRules(ctx: LoadContext): Promise<LoadResult<Rule>> {
|
|
|
118
131
|
// =============================================================================
|
|
119
132
|
|
|
120
133
|
async function loadPrompts(ctx: LoadContext): Promise<LoadResult<Prompt>> {
|
|
121
|
-
const roots = await
|
|
134
|
+
const roots = await allowedRoots(ctx, "other");
|
|
122
135
|
const results = await Promise.all(
|
|
123
136
|
roots.map(root =>
|
|
124
137
|
loadFilesFromDir<Prompt>(ctx, path.join(root.path, "prompts"), PROVIDER_ID, root.level, {
|
|
@@ -145,7 +158,7 @@ async function loadPrompts(ctx: LoadContext): Promise<LoadResult<Prompt>> {
|
|
|
145
158
|
const HOOK_TYPES: ReadonlyArray<"pre" | "post"> = ["pre", "post"];
|
|
146
159
|
|
|
147
160
|
async function loadHooks(ctx: LoadContext): Promise<LoadResult<Hook>> {
|
|
148
|
-
const roots = await
|
|
161
|
+
const roots = await allowedRoots(ctx, "other");
|
|
149
162
|
const tasks: Array<{ root: OmpExtensionRoot; hookType: "pre" | "post" }> = [];
|
|
150
163
|
for (const root of roots) {
|
|
151
164
|
for (const hookType of HOOK_TYPES) {
|
|
@@ -183,7 +196,7 @@ async function loadHooks(ctx: LoadContext): Promise<LoadResult<Hook>> {
|
|
|
183
196
|
const TOOL_EXTENSIONS = ["json", "md", "ts", "js", "sh", "bash", "py"];
|
|
184
197
|
|
|
185
198
|
async function loadTools(ctx: LoadContext): Promise<LoadResult<CustomTool>> {
|
|
186
|
-
const roots = await
|
|
199
|
+
const roots = await allowedRoots(ctx, "other");
|
|
187
200
|
const perRoot = await Promise.all(
|
|
188
201
|
roots.map(async root => {
|
|
189
202
|
const toolsDir = path.join(root.path, "tools");
|
|
@@ -276,7 +289,7 @@ interface RawMcpServer {
|
|
|
276
289
|
}
|
|
277
290
|
|
|
278
291
|
async function loadMCPServers(ctx: LoadContext): Promise<LoadResult<MCPServer>> {
|
|
279
|
-
const roots = await
|
|
292
|
+
const roots = await allowedRoots(ctx, "mcp");
|
|
280
293
|
const items: MCPServer[] = [];
|
|
281
294
|
const warnings: string[] = [];
|
|
282
295
|
|
package/src/eval/py/runner.py
CHANGED
|
@@ -40,6 +40,7 @@ import os
|
|
|
40
40
|
import re
|
|
41
41
|
import runpy
|
|
42
42
|
import shlex
|
|
43
|
+
import shutil
|
|
43
44
|
import signal
|
|
44
45
|
import subprocess
|
|
45
46
|
import sys
|
|
@@ -576,8 +577,10 @@ class _BoundedLineScanner:
|
|
|
576
577
|
def _magic_pip(args: str) -> None:
|
|
577
578
|
argv = shlex.split(args) if args else ["--help"]
|
|
578
579
|
cmd = [sys.executable, "-m", "pip", *argv]
|
|
580
|
+
# stdin=DEVNULL: see _run_shell_body.
|
|
579
581
|
proc = subprocess.Popen(
|
|
580
582
|
cmd,
|
|
583
|
+
stdin=subprocess.DEVNULL,
|
|
581
584
|
stdout=subprocess.PIPE,
|
|
582
585
|
stderr=subprocess.STDOUT,
|
|
583
586
|
)
|
|
@@ -737,9 +740,37 @@ def _magic_run(args: str) -> None:
|
|
|
737
740
|
_STATE.user_ns[name] = value
|
|
738
741
|
|
|
739
742
|
|
|
743
|
+
def _resolve_bash() -> str:
|
|
744
|
+
if os.name != "nt":
|
|
745
|
+
return "/bin/bash"
|
|
746
|
+
# Prefer Git Bash over WSL's System32 bash.exe, which runs inside a
|
|
747
|
+
# separate Linux environment and does not share the Windows filesystem
|
|
748
|
+
# layout or PATH.
|
|
749
|
+
for env_var, suffix in (
|
|
750
|
+
("ProgramFiles", r"Git\bin\bash.exe"),
|
|
751
|
+
("ProgramFiles(x86)", r"Git\bin\bash.exe"),
|
|
752
|
+
("LOCALAPPDATA", r"Programs\Git\bin\bash.exe"),
|
|
753
|
+
):
|
|
754
|
+
root = os.environ.get(env_var)
|
|
755
|
+
if root:
|
|
756
|
+
candidate = os.path.join(root, suffix)
|
|
757
|
+
if os.path.isfile(candidate):
|
|
758
|
+
return candidate
|
|
759
|
+
found = shutil.which("bash")
|
|
760
|
+
if found and "system32" not in found.lower():
|
|
761
|
+
return found
|
|
762
|
+
# WSL's System32 bash.exe runs in a separate Linux environment, so
|
|
763
|
+
# silently falling back to it would execute the cell somewhere the user
|
|
764
|
+
# did not intend; fail loudly instead.
|
|
765
|
+
raise RuntimeError(
|
|
766
|
+
"%%bash requires a POSIX bash, but none was found. "
|
|
767
|
+
"Install Git for Windows or add a non-WSL bash to PATH."
|
|
768
|
+
)
|
|
769
|
+
|
|
770
|
+
|
|
740
771
|
@cell_magic("bash")
|
|
741
772
|
def _magic_cell_bash(args: str, body: str) -> int:
|
|
742
|
-
return _run_shell_body(body, shell_arg=
|
|
773
|
+
return _run_shell_body(body, shell_arg=_resolve_bash())
|
|
743
774
|
|
|
744
775
|
|
|
745
776
|
@cell_magic("capture")
|
|
@@ -780,8 +811,12 @@ def _magic_cell_writefile(args: str, body: str) -> str:
|
|
|
780
811
|
|
|
781
812
|
|
|
782
813
|
def _run_shell_body(body: str, *, shell_arg: str) -> int:
|
|
814
|
+
# stdin=DEVNULL: children must not inherit the runner's stdin, which is
|
|
815
|
+
# the host's NDJSON control channel (a reading child would steal frames,
|
|
816
|
+
# and inheriting the pipe deadlocks nested interpreters on Windows).
|
|
783
817
|
proc = subprocess.Popen(
|
|
784
818
|
[shell_arg, "-c", body],
|
|
819
|
+
stdin=subprocess.DEVNULL,
|
|
785
820
|
stdout=subprocess.PIPE,
|
|
786
821
|
stderr=subprocess.STDOUT,
|
|
787
822
|
)
|
|
@@ -821,9 +856,11 @@ class _ShellResult(list):
|
|
|
821
856
|
|
|
822
857
|
|
|
823
858
|
def __omp_shell(cmd: str) -> _ShellResult:
|
|
859
|
+
# stdin=DEVNULL: see _run_shell_body.
|
|
824
860
|
proc = subprocess.Popen(
|
|
825
861
|
cmd,
|
|
826
862
|
shell=True,
|
|
863
|
+
stdin=subprocess.DEVNULL,
|
|
827
864
|
stdout=subprocess.PIPE,
|
|
828
865
|
stderr=subprocess.STDOUT,
|
|
829
866
|
)
|
|
@@ -24,6 +24,7 @@ export const NON_INTERACTIVE_ENV: Readonly<Record<string, string>> = {
|
|
|
24
24
|
GIT_TERMINAL_PROMPT: "0",
|
|
25
25
|
SSH_ASKPASS: "/usr/bin/false",
|
|
26
26
|
CI: "1",
|
|
27
|
+
AGENT: "1",
|
|
27
28
|
// Package manager defaults for unattended execution.
|
|
28
29
|
npm_config_yes: "true",
|
|
29
30
|
npm_config_update_notifier: "false",
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as fs from "node:fs";
|
|
8
8
|
import * as path from "node:path";
|
|
9
|
-
import
|
|
10
|
-
import * as
|
|
9
|
+
import { type } from "@oh-my-pi/omptype";
|
|
10
|
+
import * as zod from "@oh-my-pi/omptype/zod";
|
|
11
11
|
import { getAgentDir, getProjectDir, isEnoent, logger } from "@oh-my-pi/pi-utils";
|
|
12
12
|
import { getConfigDirs } from "../../config";
|
|
13
13
|
import { execCommand } from "../../exec/exec";
|
|
@@ -187,8 +187,8 @@ export async function loadCustomCommands(options: LoadCustomCommandsOptions = {}
|
|
|
187
187
|
exec: (command: string, args: string[], execOptions) =>
|
|
188
188
|
execCommand(command, args, execOptions?.cwd ?? cwd, execOptions),
|
|
189
189
|
typebox,
|
|
190
|
-
arktype,
|
|
191
|
-
zod
|
|
190
|
+
arktype: type,
|
|
191
|
+
zod,
|
|
192
192
|
pi: PiCodingAgent,
|
|
193
193
|
};
|
|
194
194
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Unlike markdown commands which expand to prompts, custom commands can execute
|
|
6
6
|
* arbitrary logic with full access to the hook context.
|
|
7
7
|
*/
|
|
8
|
-
import type
|
|
8
|
+
import type { type as ArkType } from "@oh-my-pi/omptype";
|
|
9
9
|
import type * as TypeBox from "@oh-my-pi/omptype/typebox";
|
|
10
10
|
import type * as zod from "@oh-my-pi/omptype/zod";
|
|
11
11
|
import type { ExecOptions, ExecResult, HookCommandContext } from "../../extensibility/hooks/types";
|
|
@@ -23,11 +23,11 @@ export interface CustomCommandAPI {
|
|
|
23
23
|
cwd: string;
|
|
24
24
|
/** Execute a shell command */
|
|
25
25
|
exec(command: string, args: string[], options?: ExecOptions): Promise<ExecResult>;
|
|
26
|
-
/** Injected
|
|
26
|
+
/** Injected TypeBox shim (legacy/compat). */
|
|
27
27
|
typebox: typeof TypeBox;
|
|
28
|
-
/** Injected
|
|
29
|
-
arktype: typeof
|
|
30
|
-
/** Injected
|
|
28
|
+
/** Injected omptype schema builder for custom commands. */
|
|
29
|
+
arktype: typeof ArkType;
|
|
30
|
+
/** Injected Zod-compatible omptype builder for custom commands. */
|
|
31
31
|
zod: typeof zod;
|
|
32
32
|
/** Injected pi-coding-agent exports */
|
|
33
33
|
pi: typeof PiCodingAgent;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Custom tool loader - loads TypeScript tool modules using native Bun import.
|
|
3
3
|
*
|
|
4
|
-
* Dependencies
|
|
5
|
-
*
|
|
4
|
+
* Dependencies are injected through CustomToolAPI so tools loaded from user
|
|
5
|
+
* directories do not depend on workspace module resolution.
|
|
6
6
|
*/
|
|
7
7
|
import * as path from "node:path";
|
|
8
8
|
import { type } from "@oh-my-pi/omptype";
|
|
9
|
-
import * as
|
|
9
|
+
import * as zod from "@oh-my-pi/omptype/zod";
|
|
10
10
|
import type { AgentToolResult } from "@oh-my-pi/pi-agent-core";
|
|
11
11
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
12
12
|
import { toolCapability } from "../../capability/tool";
|
|
@@ -149,7 +149,7 @@ export class CustomToolLoader {
|
|
|
149
149
|
logger,
|
|
150
150
|
typebox,
|
|
151
151
|
arktype: type,
|
|
152
|
-
zod
|
|
152
|
+
zod,
|
|
153
153
|
pi,
|
|
154
154
|
pushPendingAction: action => {
|
|
155
155
|
if (!pushPendingAction) {
|
|
@@ -30,7 +30,7 @@ import type { LocalProtocolOptions } from "../../internal-urls/local-protocol";
|
|
|
30
30
|
import type { Theme } from "../../modes/theme/theme";
|
|
31
31
|
import type { ReadonlySessionManager } from "../../session/session-manager";
|
|
32
32
|
import type { TodoItem } from "../../tools/todo";
|
|
33
|
-
import type {
|
|
33
|
+
import type { RetryErrorUpdate } from "../shared-events";
|
|
34
34
|
|
|
35
35
|
/** Alias for clarity */
|
|
36
36
|
export type CustomToolUIContext = HookUIContext;
|
|
@@ -70,7 +70,7 @@ export interface CustomToolAPI {
|
|
|
70
70
|
typebox: typeof TypeBox;
|
|
71
71
|
/** Injected arktype module for arktype-authored custom tools. */
|
|
72
72
|
arktype: typeof ArkType;
|
|
73
|
-
/** Injected
|
|
73
|
+
/** Injected Zod-compatible omptype builder for custom tools. */
|
|
74
74
|
zod: typeof zod;
|
|
75
75
|
/** Injected pi-coding-agent exports */
|
|
76
76
|
pi: typeof PiCodingAgent;
|
|
@@ -139,7 +139,7 @@ export type CustomToolSessionEvent =
|
|
|
139
139
|
success: boolean;
|
|
140
140
|
attempt: number;
|
|
141
141
|
finalError?: string;
|
|
142
|
-
|
|
142
|
+
retryErrors?: RetryErrorUpdate[];
|
|
143
143
|
}
|
|
144
144
|
| {
|
|
145
145
|
reason: "ttsr_triggered";
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import type * as fs1 from "node:fs";
|
|
5
5
|
import * as fs from "node:fs/promises";
|
|
6
6
|
import * as path from "node:path";
|
|
7
|
-
import {
|
|
8
|
-
import * as
|
|
7
|
+
import { type } from "@oh-my-pi/omptype";
|
|
8
|
+
import * as zod from "@oh-my-pi/omptype/zod";
|
|
9
9
|
import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
|
|
10
10
|
import type {
|
|
11
11
|
ImageContent,
|
|
@@ -46,6 +46,7 @@ import type {
|
|
|
46
46
|
ProviderConfig,
|
|
47
47
|
RegisteredCommand,
|
|
48
48
|
ToolDefinition,
|
|
49
|
+
ToolInfo,
|
|
49
50
|
} from "./types";
|
|
50
51
|
|
|
51
52
|
installLegacyPiSpecifierShim();
|
|
@@ -72,6 +73,15 @@ export class ExtensionRuntime implements IExtensionRuntime {
|
|
|
72
73
|
flagValues = new Map<string, boolean | string>();
|
|
73
74
|
pendingProviderRegistrations: Array<{ name: string; config: ProviderConfig; sourceId: string }> = [];
|
|
74
75
|
|
|
76
|
+
registerProvider(name: string, config: ProviderConfig, sourceId: string): void {
|
|
77
|
+
this.pendingProviderRegistrations.push({ name, config, sourceId });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
unregisterProvider(name: string): void {
|
|
81
|
+
const remaining = this.pendingProviderRegistrations.filter(registration => registration.name !== name);
|
|
82
|
+
this.pendingProviderRegistrations.splice(0, this.pendingProviderRegistrations.length, ...remaining);
|
|
83
|
+
}
|
|
84
|
+
|
|
75
85
|
sendMessage(): void {
|
|
76
86
|
throw new ExtensionRuntimeNotInitializedError();
|
|
77
87
|
}
|
|
@@ -92,7 +102,7 @@ export class ExtensionRuntime implements IExtensionRuntime {
|
|
|
92
102
|
throw new ExtensionRuntimeNotInitializedError();
|
|
93
103
|
}
|
|
94
104
|
|
|
95
|
-
getAllTools():
|
|
105
|
+
getAllTools(): ToolInfo[] {
|
|
96
106
|
throw new ExtensionRuntimeNotInitializedError();
|
|
97
107
|
}
|
|
98
108
|
|
|
@@ -141,8 +151,8 @@ export class ExtensionRuntime implements IExtensionRuntime {
|
|
|
141
151
|
class ConcreteExtensionAPI implements ExtensionAPI, IExtensionRuntime {
|
|
142
152
|
readonly logger = logger;
|
|
143
153
|
readonly typebox = TypeBox;
|
|
144
|
-
readonly arktype =
|
|
145
|
-
readonly zod =
|
|
154
|
+
readonly arktype = type;
|
|
155
|
+
readonly zod = zod;
|
|
146
156
|
readonly flagValues = new Map<string, boolean | string>();
|
|
147
157
|
readonly pendingProviderRegistrations: Array<{
|
|
148
158
|
name: string;
|
|
@@ -245,7 +255,7 @@ class ConcreteExtensionAPI implements ExtensionAPI, IExtensionRuntime {
|
|
|
245
255
|
return this.runtime.getActiveTools();
|
|
246
256
|
}
|
|
247
257
|
|
|
248
|
-
getAllTools():
|
|
258
|
+
getAllTools(): ToolInfo[] {
|
|
249
259
|
return this.runtime.getAllTools();
|
|
250
260
|
}
|
|
251
261
|
|
|
@@ -289,7 +299,11 @@ class ConcreteExtensionAPI implements ExtensionAPI, IExtensionRuntime {
|
|
|
289
299
|
}
|
|
290
300
|
|
|
291
301
|
registerProvider(name: string, config: ProviderConfig): void {
|
|
292
|
-
this.runtime.
|
|
302
|
+
this.runtime.registerProvider(name, config, this.extension.path);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
unregisterProvider(name: string): void {
|
|
306
|
+
this.runtime.unregisterProvider(name, this.extension.path);
|
|
293
307
|
}
|
|
294
308
|
}
|
|
295
309
|
|
|
@@ -310,12 +324,37 @@ function createExtension(extensionPath: string, resolvedPath: string): Extension
|
|
|
310
324
|
};
|
|
311
325
|
}
|
|
312
326
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
327
|
+
/**
|
|
328
|
+
* Runs an extension factory with provider registration rollback on failure.
|
|
329
|
+
* Restores the complete registration queue when the factory throws because an
|
|
330
|
+
* extension may unregister entries queued by an earlier extension.
|
|
331
|
+
*/
|
|
332
|
+
async function runExtensionFactory(
|
|
333
|
+
factory: ExtensionFactory,
|
|
334
|
+
api: ExtensionAPI,
|
|
317
335
|
runtime: IExtensionRuntime,
|
|
318
|
-
): Promise<
|
|
336
|
+
): Promise<void> {
|
|
337
|
+
const providerRegistrationCheckpoint = [...runtime.pendingProviderRegistrations];
|
|
338
|
+
|
|
339
|
+
try {
|
|
340
|
+
await factory(api);
|
|
341
|
+
} catch (error) {
|
|
342
|
+
runtime.pendingProviderRegistrations.splice(
|
|
343
|
+
0,
|
|
344
|
+
runtime.pendingProviderRegistrations.length,
|
|
345
|
+
...providerRegistrationCheckpoint,
|
|
346
|
+
);
|
|
347
|
+
throw error;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
interface ImportedExtensionModule {
|
|
352
|
+
factory: ExtensionFactory | null;
|
|
353
|
+
resolvedPath: string;
|
|
354
|
+
error: string | null;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
async function importExtensionModule(extensionPath: string, cwd: string): Promise<ImportedExtensionModule> {
|
|
319
358
|
const resolvedPath = resolvePath(extensionPath, cwd);
|
|
320
359
|
try {
|
|
321
360
|
const module = (await withHostGuard(() => loadLegacyPiModule(resolvedPath))) as LoadedExtensionModule;
|
|
@@ -323,16 +362,34 @@ async function loadExtension(
|
|
|
323
362
|
|
|
324
363
|
if (typeof factory !== "function") {
|
|
325
364
|
return {
|
|
326
|
-
|
|
365
|
+
factory: null,
|
|
366
|
+
resolvedPath,
|
|
327
367
|
error: `Extension does not export a valid factory function: ${extensionPath}`,
|
|
328
368
|
};
|
|
329
369
|
}
|
|
330
370
|
|
|
331
|
-
|
|
371
|
+
return { factory, resolvedPath, error: null };
|
|
372
|
+
} catch (err) {
|
|
373
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
374
|
+
return { factory: null, resolvedPath, error: `Failed to load extension: ${message}` };
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
async function bindExtension(
|
|
379
|
+
extensionPath: string,
|
|
380
|
+
imported: ImportedExtensionModule,
|
|
381
|
+
cwd: string,
|
|
382
|
+
eventBus: EventBus,
|
|
383
|
+
runtime: IExtensionRuntime,
|
|
384
|
+
): Promise<{ extension: Extension | null; error: string | null }> {
|
|
385
|
+
const factory = imported.factory;
|
|
386
|
+
if (imported.error !== null || factory === null) {
|
|
387
|
+
return { extension: null, error: imported.error };
|
|
388
|
+
}
|
|
389
|
+
try {
|
|
390
|
+
const extension = createExtension(extensionPath, imported.resolvedPath);
|
|
332
391
|
const api = new ConcreteExtensionAPI(PiCodingAgent, extension, runtime, cwd, eventBus);
|
|
333
|
-
await withHostGuard(
|
|
334
|
-
await factory(api);
|
|
335
|
-
});
|
|
392
|
+
await withHostGuard(() => runExtensionFactory(factory, api, runtime));
|
|
336
393
|
|
|
337
394
|
return { extension, error: null };
|
|
338
395
|
} catch (err) {
|
|
@@ -353,12 +410,17 @@ export async function loadExtensionFromFactory(
|
|
|
353
410
|
): Promise<Extension> {
|
|
354
411
|
const extension = createExtension(name, name);
|
|
355
412
|
const api = new ConcreteExtensionAPI(PiCodingAgent, extension, runtime, cwd, eventBus);
|
|
356
|
-
await factory
|
|
413
|
+
await runExtensionFactory(factory, api, runtime);
|
|
357
414
|
return extension;
|
|
358
415
|
}
|
|
359
416
|
|
|
360
417
|
/**
|
|
361
418
|
* Load extensions from paths.
|
|
419
|
+
*
|
|
420
|
+
* Module import (the dominant cold-start cost — file I/O plus module
|
|
421
|
+
* evaluation) runs concurrently across extensions; factory binding then runs
|
|
422
|
+
* sequentially in the original path order, so registration semantics
|
|
423
|
+
* (last-wins collisions, shared runtime flag defaults) stay deterministic.
|
|
362
424
|
*/
|
|
363
425
|
export async function loadExtensions(paths: string[], cwd: string, eventBus?: EventBus): Promise<LoadExtensionsResult> {
|
|
364
426
|
const extensions: Extension[] = [];
|
|
@@ -366,8 +428,11 @@ export async function loadExtensions(paths: string[], cwd: string, eventBus?: Ev
|
|
|
366
428
|
const resolvedEventBus = eventBus ?? new EventBus();
|
|
367
429
|
const runtime = new ExtensionRuntime();
|
|
368
430
|
|
|
369
|
-
|
|
370
|
-
|
|
431
|
+
const imported = await Promise.all(paths.map(extPath => importExtensionModule(extPath, cwd)));
|
|
432
|
+
|
|
433
|
+
for (let i = 0; i < paths.length; i++) {
|
|
434
|
+
const extPath = paths[i]!;
|
|
435
|
+
const { extension, error } = await bindExtension(extPath, imported[i]!, cwd, resolvedEventBus, runtime);
|
|
371
436
|
|
|
372
437
|
if (error) {
|
|
373
438
|
errors.push({ path: extPath, error });
|
|
@@ -530,6 +530,12 @@ export class ExtensionRunner {
|
|
|
530
530
|
this.runtime.setServiceTier = actions.setServiceTier ?? throwUnsupportedServiceTierAction;
|
|
531
531
|
this.runtime.getSessionName = actions.getSessionName;
|
|
532
532
|
this.runtime.setSessionName = actions.setSessionName;
|
|
533
|
+
this.runtime.registerProvider = (name, config, sourceId) => {
|
|
534
|
+
this.modelRegistry.registerProvider(name, config, sourceId);
|
|
535
|
+
};
|
|
536
|
+
this.runtime.unregisterProvider = name => {
|
|
537
|
+
this.modelRegistry.unregisterProvider(name);
|
|
538
|
+
};
|
|
533
539
|
|
|
534
540
|
// Context actions (required)
|
|
535
541
|
this.#getModel = contextActions.getModel;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - Interact with the user via UI primitives
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type {
|
|
11
|
+
import type { type as ArkType } from "@oh-my-pi/omptype";
|
|
12
12
|
import type * as TypeBox from "@oh-my-pi/omptype/typebox";
|
|
13
13
|
import type * as zod from "@oh-my-pi/omptype/zod";
|
|
14
14
|
import type {
|
|
@@ -596,6 +596,36 @@ export interface ToolDefinition<TParams extends TSchema = TSchema, TDetails = un
|
|
|
596
596
|
) => Component;
|
|
597
597
|
}
|
|
598
598
|
|
|
599
|
+
/** Whether a tool's source is scoped to the user, the project, or a transient runtime session. */
|
|
600
|
+
export type SourceScope = "user" | "project" | "temporary";
|
|
601
|
+
|
|
602
|
+
/** Whether a tool's source came from an installed package or a top-level (loose) file. */
|
|
603
|
+
export type SourceOrigin = "package" | "top-level";
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Provenance metadata describing where a registered tool came from. Mirrors the
|
|
607
|
+
* `@earendil-works/pi-coding-agent` `SourceInfo` contract so extensions authored
|
|
608
|
+
* against upstream pi (e.g. gentle-pi) can read `sourceInfo.source` unchanged.
|
|
609
|
+
*/
|
|
610
|
+
export interface SourceInfo {
|
|
611
|
+
/** Synthetic or on-disk identifier for the tool's origin (e.g. `<builtin:read>`). */
|
|
612
|
+
path: string;
|
|
613
|
+
/** Origin class: `"builtin"`, `"sdk"`, `"mcp"`, or `"extension"`. */
|
|
614
|
+
source: string;
|
|
615
|
+
scope: SourceScope;
|
|
616
|
+
origin: SourceOrigin;
|
|
617
|
+
baseDir?: string;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/** Tool metadata returned by {@link ExtensionAPI.getAllTools}: identity, schema, and source provenance. */
|
|
621
|
+
export interface ToolInfo {
|
|
622
|
+
name: string;
|
|
623
|
+
description: string;
|
|
624
|
+
parameters: TSchema;
|
|
625
|
+
promptGuidelines?: string[];
|
|
626
|
+
sourceInfo: SourceInfo;
|
|
627
|
+
}
|
|
628
|
+
|
|
599
629
|
// ============================================================================
|
|
600
630
|
// Resource Events
|
|
601
631
|
// ============================================================================
|
|
@@ -1109,12 +1139,13 @@ export interface ExtensionAPI {
|
|
|
1109
1139
|
/** File logger for error/warning/debug messages */
|
|
1110
1140
|
logger: typeof PiLogger;
|
|
1111
1141
|
|
|
1112
|
-
/** Injected
|
|
1142
|
+
/** Injected TypeBox shim for legacy `Type.Object(...)` parameter authoring. */
|
|
1113
1143
|
typebox: typeof TypeBox;
|
|
1114
1144
|
|
|
1115
|
-
/** Injected
|
|
1116
|
-
arktype: typeof
|
|
1117
|
-
|
|
1145
|
+
/** Injected omptype schema builder for extension tools. */
|
|
1146
|
+
arktype: typeof ArkType;
|
|
1147
|
+
|
|
1148
|
+
/** Injected Zod-compatible omptype builder for extension tools. */
|
|
1118
1149
|
zod: typeof zod;
|
|
1119
1150
|
|
|
1120
1151
|
/** Injected pi-coding-agent exports for accessing SDK utilities */
|
|
@@ -1267,8 +1298,8 @@ export interface ExtensionAPI {
|
|
|
1267
1298
|
/** Get the list of currently active tool names. */
|
|
1268
1299
|
getActiveTools(): string[];
|
|
1269
1300
|
|
|
1270
|
-
/** Get all configured tools (built-in + extension tools). */
|
|
1271
|
-
getAllTools():
|
|
1301
|
+
/** Get all configured tools (built-in + extension tools) with schema and source metadata. */
|
|
1302
|
+
getAllTools(): ToolInfo[];
|
|
1272
1303
|
|
|
1273
1304
|
/** Set the active tools by name. */
|
|
1274
1305
|
setActiveTools(toolNames: string[]): Promise<void>;
|
|
@@ -1342,6 +1373,14 @@ export interface ExtensionAPI {
|
|
|
1342
1373
|
*/
|
|
1343
1374
|
registerProvider(name: string, config: ProviderConfig): void;
|
|
1344
1375
|
|
|
1376
|
+
/**
|
|
1377
|
+
* Unregister a provider previously registered by an extension.
|
|
1378
|
+
*
|
|
1379
|
+
* Removes extension-provided models and restores overridden built-in models.
|
|
1380
|
+
* Has no effect when the provider is not registered.
|
|
1381
|
+
*/
|
|
1382
|
+
unregisterProvider(name: string): void;
|
|
1383
|
+
|
|
1345
1384
|
/** Shared event bus for extension communication. */
|
|
1346
1385
|
events: EventBus;
|
|
1347
1386
|
}
|
|
@@ -1464,7 +1503,7 @@ export type AppendEntryHandler = <T = unknown>(customType: string, data?: T) =>
|
|
|
1464
1503
|
|
|
1465
1504
|
export type GetActiveToolsHandler = () => string[];
|
|
1466
1505
|
|
|
1467
|
-
export type GetAllToolsHandler = () =>
|
|
1506
|
+
export type GetAllToolsHandler = () => ToolInfo[];
|
|
1468
1507
|
|
|
1469
1508
|
export type GetCommandsHandler = () => SlashCommandInfo[];
|
|
1470
1509
|
|
|
@@ -1485,6 +1524,10 @@ export interface ExtensionRuntimeState {
|
|
|
1485
1524
|
flagValues: Map<string, boolean | string>;
|
|
1486
1525
|
/** Provider registrations queued during extension loading, processed during session initialization */
|
|
1487
1526
|
pendingProviderRegistrations: Array<{ name: string; config: ProviderConfig; sourceId: string }>;
|
|
1527
|
+
/** Queue a provider registration until initialization, then apply it immediately. */
|
|
1528
|
+
registerProvider(name: string, config: ProviderConfig, sourceId: string): void;
|
|
1529
|
+
/** Remove a queued or initialized provider registration. */
|
|
1530
|
+
unregisterProvider(name: string, sourceId: string): void;
|
|
1488
1531
|
}
|
|
1489
1532
|
|
|
1490
1533
|
/** Action implementations for ExtensionAPI methods. */
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Hook loader - loads TypeScript hook modules using native Bun import.
|
|
3
3
|
*/
|
|
4
4
|
import * as path from "node:path";
|
|
5
|
-
import
|
|
6
|
-
import * as
|
|
5
|
+
import { type } from "@oh-my-pi/omptype";
|
|
6
|
+
import * as zod from "@oh-my-pi/omptype/zod";
|
|
7
7
|
import { logger } from "@oh-my-pi/pi-utils";
|
|
8
8
|
import { hookCapability } from "../../capability/hook";
|
|
9
9
|
import type { Hook } from "../../discovery";
|
|
@@ -122,9 +122,8 @@ async function createHookAPI(
|
|
|
122
122
|
},
|
|
123
123
|
logger,
|
|
124
124
|
typebox,
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
zod: zodModule,
|
|
125
|
+
arktype: type,
|
|
126
|
+
zod,
|
|
128
127
|
pi: PiCodingAgent,
|
|
129
128
|
} as HookAPI;
|
|
130
129
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { type as ArkType } from "@oh-my-pi/omptype";
|
|
2
2
|
import type * as TypeBox from "@oh-my-pi/omptype/typebox";
|
|
3
3
|
import type * as zod from "@oh-my-pi/omptype/zod";
|
|
4
4
|
import type { ImageContent, Message, Model, TextContent } from "@oh-my-pi/pi-ai";
|
|
@@ -582,11 +582,11 @@ export interface HookAPI {
|
|
|
582
582
|
|
|
583
583
|
/** File logger for error/warning/debug messages */
|
|
584
584
|
logger: typeof PiLogger;
|
|
585
|
-
/** Injected
|
|
585
|
+
/** Injected TypeBox shim (legacy/compat — prefer `arktype`). */
|
|
586
586
|
typebox: typeof TypeBox;
|
|
587
|
-
/** Injected
|
|
588
|
-
arktype: typeof
|
|
589
|
-
/** Injected
|
|
587
|
+
/** Injected omptype schema builder for hooks. */
|
|
588
|
+
arktype: typeof ArkType;
|
|
589
|
+
/** Injected Zod-compatible omptype builder for hooks. */
|
|
590
590
|
zod: typeof zod;
|
|
591
591
|
/** Injected pi-coding-agent exports */
|
|
592
592
|
pi: typeof PiCodingAgent;
|