@oh-my-pi/pi-coding-agent 17.2.10 → 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 +40 -0
- package/dist/{CHANGELOG-rhwzpexa.md → CHANGELOG-d9xenpn9.md} +40 -0
- package/dist/cli.js +3025 -3016
- package/dist/types/capability/mcp.d.ts +11 -0
- package/dist/types/capability/skill.d.ts +6 -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/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-tools/types.d.ts +2 -2
- package/dist/types/extensibility/extensions/loader.d.ts +7 -0
- package/dist/types/extensibility/extensions/types.d.ts +11 -0
- package/dist/types/extensibility/shared-events.d.ts +3 -2
- package/dist/types/extensibility/skills.d.ts +5 -0
- package/dist/types/mcp/transports/header-policy.d.ts +45 -0
- package/dist/types/mcp/types.d.ts +15 -0
- package/dist/types/modes/components/agent-hub.d.ts +2 -0
- 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/status-line/types.d.ts +2 -0
- package/dist/types/modes/components/tool-execution.d.ts +2 -0
- package/dist/types/modes/utils/transcript-render-helpers.d.ts +3 -2
- 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 +1 -1
- package/dist/types/session/messages.d.ts +1 -0
- package/dist/types/session/prewalk.d.ts +3 -1
- package/dist/types/session/session-tools.d.ts +8 -0
- package/dist/types/session/turn-recovery.d.ts +7 -2
- package/dist/types/task/index.d.ts +2 -0
- package/dist/types/tools/shell-tokenize.d.ts +16 -0
- package/package.json +13 -13
- package/scripts/legacy-pi-virtual-module.ts +4 -1
- package/src/capability/mcp.ts +11 -0
- package/src/capability/skill.ts +6 -0
- package/src/cli/command-help.ts +4 -0
- package/src/cli/gallery-cli.ts +1 -1
- package/src/cli-commands.ts +5 -0
- package/src/commands/commit.ts +16 -3
- package/src/commands/share.ts +71 -0
- package/src/commit/agentic/index.ts +39 -21
- 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/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/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/exec/non-interactive-env.ts +1 -0
- package/src/extensibility/custom-tools/types.ts +2 -2
- package/src/extensibility/extensions/loader.ts +78 -14
- package/src/extensibility/extensions/runner.ts +6 -0
- package/src/extensibility/extensions/types.ts +12 -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/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/main.ts +3 -2
- 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 +15 -4
- package/src/modes/components/agent-dashboard.ts +2 -0
- package/src/modes/components/agent-hub.ts +5 -0
- package/src/modes/components/agent-transcript-viewer.ts +3 -0
- package/src/modes/components/chat-transcript-builder.ts +3 -0
- package/src/modes/components/custom-editor.ts +0 -9
- package/src/modes/components/status-line/component.ts +1 -0
- package/src/modes/components/status-line/segments.ts +6 -4
- 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 +15 -15
- package/src/modes/controllers/input-controller.ts +20 -2
- package/src/modes/controllers/selector-controller.ts +1 -0
- package/src/modes/utils/transcript-render-helpers.ts +4 -2
- package/src/modes/utils/ui-helpers.ts +1 -0
- 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 +33 -14
- 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-handoff.ts +5 -1
- package/src/session/session-tools.ts +37 -3
- package/src/session/todo-tracker.ts +11 -1
- package/src/session/turn-recovery.ts +94 -72
- package/src/slash-commands/builtin-registry.ts +12 -8
- package/src/task/index.ts +21 -6
- package/src/tools/bash-skill-urls.ts +15 -0
- package/src/tools/bash.ts +10 -11
- package/src/tools/debug.ts +1 -1
- package/src/tools/jtd-to-json-schema.ts +123 -21
- package/src/tools/read.ts +5 -4
- package/src/tools/shell-tokenize.ts +98 -0
- package/src/web/search/providers/exa.ts +1 -1
|
@@ -24,12 +24,23 @@ export interface MCPServer {
|
|
|
24
24
|
args?: string[];
|
|
25
25
|
/** Environment variables */
|
|
26
26
|
env?: Record<string, string>;
|
|
27
|
+
/**
|
|
28
|
+
* `literal`: env values are opaque plugin package data (Agent Plugins
|
|
29
|
+
* §§4.1/9.2) — exempt from env-name lookup and `!command` resolution.
|
|
30
|
+
*/
|
|
31
|
+
envPolicy?: "literal";
|
|
27
32
|
/** Working directory for stdio transport */
|
|
28
33
|
cwd?: string;
|
|
29
34
|
/** URL (for HTTP/SSE transport) */
|
|
30
35
|
url?: string;
|
|
31
36
|
/** HTTP headers (for HTTP transport) */
|
|
32
37
|
headers?: Record<string, string>;
|
|
38
|
+
/**
|
|
39
|
+
* `origin-locked`: configured headers are literal package data pinned to the
|
|
40
|
+
* configured URL's origin (Agent Plugins §7.2.1) — never expanded, never
|
|
41
|
+
* forwarded cross-origin, and client-generated headers win case-insensitively.
|
|
42
|
+
*/
|
|
43
|
+
headerPolicy?: "origin-locked";
|
|
33
44
|
/** Authentication configuration */
|
|
34
45
|
auth?: {
|
|
35
46
|
type: "oauth" | "apikey";
|
|
@@ -35,6 +35,12 @@ export interface Skill {
|
|
|
35
35
|
content: string;
|
|
36
36
|
/** Parsed frontmatter */
|
|
37
37
|
frontmatter?: SkillFrontmatter;
|
|
38
|
+
/**
|
|
39
|
+
* Filesystem-resolved plugin root this skill was packaged in (Agent Plugins
|
|
40
|
+
* §4.1). When set, every `skill://` resource access must realpath-resolve
|
|
41
|
+
* within this directory; symlinks may target other files inside it.
|
|
42
|
+
*/
|
|
43
|
+
containRoot?: string;
|
|
38
44
|
/** Source level */
|
|
39
45
|
level: "user" | "project";
|
|
40
46
|
/** Source metadata */
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Share a saved session as an encrypted link without launching the agent.
|
|
3
|
+
*
|
|
4
|
+
* `omp share <session>` accepts a session id (prefix) or a path to a session
|
|
5
|
+
* `.jsonl` and uploads the sealed snapshot exactly like the `/share` slash
|
|
6
|
+
* command, honoring `share.serverUrl`, `share.store`, and
|
|
7
|
+
* `share.redactSecrets`.
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from "@oh-my-pi/pi-utils/cli";
|
|
10
|
+
export default class Share extends Command {
|
|
11
|
+
static description: string;
|
|
12
|
+
static args: {
|
|
13
|
+
session: import("@oh-my-pi/pi-utils/cli").ArgDescriptor & {
|
|
14
|
+
description: string;
|
|
15
|
+
required: true;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
static flags: {
|
|
19
|
+
gist: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
|
|
20
|
+
description: string;
|
|
21
|
+
default: boolean;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
run(): Promise<void>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared commit-execution helpers for the agentic and legacy `omp commit`
|
|
3
|
+
* pipelines: readable failure reporting for refusing git hooks and a push
|
|
4
|
+
* wrapper that keeps a requested `--push` honest.
|
|
5
|
+
*/
|
|
6
|
+
import * as git from "../utils/git.js";
|
|
7
|
+
/**
|
|
8
|
+
* A commit or push failure that has already been reported to the user with a
|
|
9
|
+
* readable message. It is thrown so the CLI exits non-zero without the runtime
|
|
10
|
+
* dumping a stack trace — in a bundled build that trace is several kilobytes of
|
|
11
|
+
* minified source, which buries the one line the user needs (issue #7834).
|
|
12
|
+
*
|
|
13
|
+
* `runCommitCommand`'s caller (`commands/commit.ts`) maps this to exit code 1.
|
|
14
|
+
*/
|
|
15
|
+
export declare class CommitAbortedError extends Error {
|
|
16
|
+
constructor();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Print a git-command failure — most often a `pre-commit`/`commit-msg` hook
|
|
20
|
+
* that exited non-zero — as an indented message under `context`, then abort.
|
|
21
|
+
*
|
|
22
|
+
* @param context Label for the failed step, e.g. `"Commit 1 of 2 failed"`.
|
|
23
|
+
* @param error The failure to surface; its captured stderr/stdout is shown.
|
|
24
|
+
* @param note Optional trailing status line (split-plan progress, recovery).
|
|
25
|
+
*/
|
|
26
|
+
export declare function abortOnGitFailure(context: string, error: git.GitCommandError, note?: string): never;
|
|
27
|
+
/**
|
|
28
|
+
* Push the current branch, reporting a refused push (missing upstream, rejected
|
|
29
|
+
* ref) through {@link abortOnGitFailure} instead of letting the raw
|
|
30
|
+
* `GitCommandError` escape. Prints the success line on completion.
|
|
31
|
+
*/
|
|
32
|
+
export declare function pushOrAbort(cwd: string): Promise<void>;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { CommitCommandArgs } from "./types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Execute the omp commit pipeline for staged changes.
|
|
4
|
+
*
|
|
5
|
+
* Returns whether the commit was generated by the mechanical fallback rather
|
|
6
|
+
* than by the commit agent, so callers can signal a degraded outcome (issue
|
|
7
|
+
* #7835). The legacy pipeline has no fallback: model failures throw.
|
|
4
8
|
*/
|
|
5
|
-
export declare function runCommitCommand(args: CommitCommandArgs): Promise<
|
|
9
|
+
export declare function runCommitCommand(args: CommitCommandArgs): Promise<{
|
|
10
|
+
usedFallback: boolean;
|
|
11
|
+
}>;
|
|
@@ -227,6 +227,10 @@ export declare class ModelRegistry {
|
|
|
227
227
|
* Remove custom API/OAuth registrations for a specific extension source.
|
|
228
228
|
*/
|
|
229
229
|
clearSourceRegistrations(sourceId: string): void;
|
|
230
|
+
/**
|
|
231
|
+
* Remove one extension-registered provider and restore its static models.
|
|
232
|
+
*/
|
|
233
|
+
unregisterProvider(providerName: string): void;
|
|
230
234
|
/**
|
|
231
235
|
* Remove registrations for extension sources that are no longer active.
|
|
232
236
|
*/
|
|
@@ -5981,17 +5981,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
5981
5981
|
readonly tab: "providers";
|
|
5982
5982
|
readonly group: "Services";
|
|
5983
5983
|
readonly label: "Exa";
|
|
5984
|
-
readonly description: "
|
|
5985
|
-
};
|
|
5986
|
-
};
|
|
5987
|
-
readonly "exa.enableSearch": {
|
|
5988
|
-
readonly type: "boolean";
|
|
5989
|
-
readonly default: true;
|
|
5990
|
-
readonly ui: {
|
|
5991
|
-
readonly tab: "providers";
|
|
5992
|
-
readonly group: "Services";
|
|
5993
|
-
readonly label: "Exa Search";
|
|
5994
|
-
readonly description: "Enable Exa basic search, deep search, code search, and crawl tools";
|
|
5984
|
+
readonly description: "Enable the Exa web search provider";
|
|
5995
5985
|
};
|
|
5996
5986
|
};
|
|
5997
5987
|
readonly "exa.searchDelayMs": {
|
|
@@ -6004,26 +5994,6 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
6004
5994
|
readonly description: "Minimum delay between Exa web search requests in milliseconds; set 0 to disable pacing";
|
|
6005
5995
|
};
|
|
6006
5996
|
};
|
|
6007
|
-
readonly "exa.enableResearcher": {
|
|
6008
|
-
readonly type: "boolean";
|
|
6009
|
-
readonly default: false;
|
|
6010
|
-
readonly ui: {
|
|
6011
|
-
readonly tab: "providers";
|
|
6012
|
-
readonly group: "Services";
|
|
6013
|
-
readonly label: "Exa Researcher";
|
|
6014
|
-
readonly description: "Enable the Exa researcher tool for AI-powered deep research";
|
|
6015
|
-
};
|
|
6016
|
-
};
|
|
6017
|
-
readonly "exa.enableWebsets": {
|
|
6018
|
-
readonly type: "boolean";
|
|
6019
|
-
readonly default: false;
|
|
6020
|
-
readonly ui: {
|
|
6021
|
-
readonly tab: "providers";
|
|
6022
|
-
readonly group: "Services";
|
|
6023
|
-
readonly label: "Exa Websets";
|
|
6024
|
-
readonly description: "Enable Exa webset management and enrichment tools";
|
|
6025
|
-
};
|
|
6026
|
-
};
|
|
6027
5997
|
readonly "searxng.endpoint": {
|
|
6028
5998
|
readonly type: "string";
|
|
6029
5999
|
readonly default: undefined;
|
|
@@ -6329,10 +6299,7 @@ export interface TtsrSettings {
|
|
|
6329
6299
|
}
|
|
6330
6300
|
export interface ExaSettings {
|
|
6331
6301
|
enabled: boolean;
|
|
6332
|
-
enableSearch: boolean;
|
|
6333
6302
|
searchDelayMs: number;
|
|
6334
|
-
enableResearcher: boolean;
|
|
6335
|
-
enableWebsets: boolean;
|
|
6336
6303
|
}
|
|
6337
6304
|
export interface StatusLineSettings {
|
|
6338
6305
|
preset: StatusLinePreset;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/** Canonical `plugin.json` `$schema` identifier for Agent Plugins 1.0.0 (spec §5.2). */
|
|
2
|
+
export declare const AGENT_PLUGIN_MANIFEST_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json";
|
|
3
|
+
/** Canonical `mcp.json` `$schema` identifier for Agent Plugins 1.0.0 (spec §7.2.1). */
|
|
4
|
+
export declare const AGENT_PLUGIN_MCP_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json";
|
|
5
|
+
/** Validated portable manifest fields from a plugin's root `plugin.json` (spec §5). */
|
|
6
|
+
export interface AgentPluginManifest {
|
|
7
|
+
name: string;
|
|
8
|
+
version?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
author?: {
|
|
11
|
+
name?: string;
|
|
12
|
+
email?: string;
|
|
13
|
+
url?: string;
|
|
14
|
+
};
|
|
15
|
+
homepage?: string;
|
|
16
|
+
repository?: string;
|
|
17
|
+
license?: string;
|
|
18
|
+
keywords?: string[];
|
|
19
|
+
/**
|
|
20
|
+
* Client-owned data keyed by reverse-domain namespace. Member values are
|
|
21
|
+
* opaque: this client implements no namespace, and §8.1/§11.1 require
|
|
22
|
+
* ignoring unimplemented namespaces without validating their values.
|
|
23
|
+
*/
|
|
24
|
+
extensions?: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Outcome of parsing a candidate `plugin.json`:
|
|
28
|
+
* - `none` — the document does not target Agent Plugins (no recognized `$schema`);
|
|
29
|
+
* legacy plugin conventions may still apply to the directory.
|
|
30
|
+
* - `valid` — a conformant manifest; `warnings` carries the non-fatal violations
|
|
31
|
+
* the spec requires reporting (unknown top-level fields, non-object `extensions`).
|
|
32
|
+
* - `invalid` — the document targets Agent Plugins but violates the closed schema
|
|
33
|
+
* fatally; the plugin must be rejected and none of its components loaded (spec §5.2).
|
|
34
|
+
*/
|
|
35
|
+
export type AgentPluginManifestResult = {
|
|
36
|
+
status: "none";
|
|
37
|
+
} | {
|
|
38
|
+
status: "valid";
|
|
39
|
+
manifest: AgentPluginManifest;
|
|
40
|
+
warnings: string[];
|
|
41
|
+
} | {
|
|
42
|
+
status: "invalid";
|
|
43
|
+
reason: string;
|
|
44
|
+
};
|
|
45
|
+
/** Enforce the plugin `name` constraints from spec §5.5. */
|
|
46
|
+
export declare function isValidAgentPluginName(name: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Validate `SKILL.md` frontmatter against the Agent Skills specification
|
|
49
|
+
* (https://agentskills.io/specification), the source of truth for skill
|
|
50
|
+
* validity under Agent Plugins §7.1, mirroring the official skills-ref
|
|
51
|
+
* reference validator: the frontmatter schema is CLOSED to its six fields and
|
|
52
|
+
* any unexpected key rejects the skill. Returns the first violation, or `null`
|
|
53
|
+
* when the skill conforms. Frontmatter keys must be raw (unnormalized).
|
|
54
|
+
*/
|
|
55
|
+
export declare function validateAgentSkillFrontmatter(frontmatter: Record<string, unknown>, dirName: string): string | null;
|
|
56
|
+
/**
|
|
57
|
+
* Parse and validate a root `plugin.json` document against the closed
|
|
58
|
+
* Agent Plugins 1.0.0 manifest schema (spec §5.2–§5.5, §8.1).
|
|
59
|
+
*/
|
|
60
|
+
export declare function parseAgentPluginManifest(raw: string): AgentPluginManifestResult;
|
|
61
|
+
/**
|
|
62
|
+
* Expand `${PLUGIN_ROOT}` and `${PLUGIN_DATA}` in a configuration value
|
|
63
|
+
* (spec §9.2). Single non-recursive pass; replacement text is never rescanned,
|
|
64
|
+
* and no other placeholder or environment-variable expansion is performed.
|
|
65
|
+
*/
|
|
66
|
+
export declare function expandAgentPluginPlaceholders(value: string, pluginRoot: string, pluginData: string): string;
|
|
67
|
+
/** A validated `mcp.json` server entry, resolved to launch-ready values. */
|
|
68
|
+
export interface AgentPluginMcpServer {
|
|
69
|
+
name: string;
|
|
70
|
+
transport: "stdio" | "http" | "sse";
|
|
71
|
+
/** Absolute path for `./`-relative commands; bare executable token otherwise. */
|
|
72
|
+
command?: string;
|
|
73
|
+
args?: string[];
|
|
74
|
+
/** Expanded configured env plus the client-supplied `PLUGIN_ROOT`/`PLUGIN_DATA`. */
|
|
75
|
+
env?: Record<string, string>;
|
|
76
|
+
/** Absolute working directory; defaults to the plugin root for stdio servers. */
|
|
77
|
+
cwd?: string;
|
|
78
|
+
url?: string;
|
|
79
|
+
headers?: Record<string, string>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Outcome of parsing a plugin's `mcp.json`:
|
|
83
|
+
* - `disabled` — the top-level document is invalid, so MCP is disabled for the
|
|
84
|
+
* plugin while other component types keep loading (spec §7.2.2 rule 2).
|
|
85
|
+
* - `ok` — the document is valid; individually invalid server entries are
|
|
86
|
+
* skipped with a warning (spec §7.2.2 rule 3).
|
|
87
|
+
*/
|
|
88
|
+
export type AgentPluginMcpResult = {
|
|
89
|
+
status: "disabled";
|
|
90
|
+
reason: string;
|
|
91
|
+
} | {
|
|
92
|
+
status: "ok";
|
|
93
|
+
servers: AgentPluginMcpServer[];
|
|
94
|
+
warnings: string[];
|
|
95
|
+
};
|
|
96
|
+
export interface AgentPluginMcpOptions {
|
|
97
|
+
/** Filesystem-resolved plugin root. */
|
|
98
|
+
pluginRoot: string;
|
|
99
|
+
/** Client-managed persistent data directory for this plugin (spec §9.1). */
|
|
100
|
+
pluginData: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Parse and validate a plugin's `mcp.json` against the closed Agent Plugins
|
|
104
|
+
* 1.0.0 MCP configuration (spec §7.2), resolving stdio commands and working
|
|
105
|
+
* directories against the plugin root and expanding plugin variables.
|
|
106
|
+
*/
|
|
107
|
+
export declare function parseAgentPluginMcp(raw: string, options: AgentPluginMcpOptions): Promise<AgentPluginMcpResult>;
|
|
108
|
+
/**
|
|
109
|
+
* Classification of a plugin root directory against the Agent Plugins standard:
|
|
110
|
+
* - `none` — no Agent Plugins manifest; legacy plugin conventions govern.
|
|
111
|
+
* - `standard` — a valid Agent Plugin; the standard governs its portable
|
|
112
|
+
* components (skills and MCP servers). `realRoot` is the filesystem-resolved
|
|
113
|
+
* plugin root every package path is contained within.
|
|
114
|
+
* - `invalid` — the root claims Agent Plugins conformance but its manifest is
|
|
115
|
+
* fatally invalid; no component may be discovered or executed (spec §11.3).
|
|
116
|
+
*/
|
|
117
|
+
export type AgentPluginRootStatus = {
|
|
118
|
+
kind: "none";
|
|
119
|
+
} | {
|
|
120
|
+
kind: "standard";
|
|
121
|
+
manifest: AgentPluginManifest;
|
|
122
|
+
warnings: string[];
|
|
123
|
+
realRoot: string;
|
|
124
|
+
} | {
|
|
125
|
+
kind: "invalid";
|
|
126
|
+
reason: string;
|
|
127
|
+
};
|
|
128
|
+
/** Drop cached classifications (tests, or after plugin installs outside the shared registry flow). */
|
|
129
|
+
export declare function clearAgentPluginRootCache(): void;
|
|
130
|
+
/**
|
|
131
|
+
* Determine whether a plugin root is governed by the Agent Plugins standard.
|
|
132
|
+
* Results are cached per root path; the cache clears with the shared plugin
|
|
133
|
+
* roots cache and via {@link clearAgentPluginRootCache}.
|
|
134
|
+
*/
|
|
135
|
+
export declare function classifyAgentPluginRoot(rootPath: string): Promise<AgentPluginRootStatus>;
|
|
136
|
+
/**
|
|
137
|
+
* Whether a legacy plugin provider (claude-plugins, omp-plugins) may process a
|
|
138
|
+
* root for the given surface. Roots governed by the Agent Plugins standard keep
|
|
139
|
+
* their portable components (`skills`, `mcp`) exclusive to the standard loader,
|
|
140
|
+
* while client-specific surfaces (commands, hooks, tools, …) still load from
|
|
141
|
+
* hybrid packages. Fatally invalid Agent Plugins packages are rejected entirely.
|
|
142
|
+
*/
|
|
143
|
+
export declare function legacyProviderAllowed(rootPath: string, surface: "skills" | "mcp" | "other"): Promise<boolean>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Lexical containment: `target` is `base` itself or a descendant of it. */
|
|
2
|
+
export declare function isContained(base: string, target: string): boolean;
|
|
3
|
+
/** Resolve symlinks and equivalents; `null` when the path is missing or unresolvable. */
|
|
4
|
+
export declare function realpathIfExists(p: string): Promise<string | null>;
|
|
5
|
+
/** Outcome of resolving a fixed package path without reading it. */
|
|
6
|
+
export type ContainedPathResolution = {
|
|
7
|
+
status: "missing";
|
|
8
|
+
} | {
|
|
9
|
+
status: "outside";
|
|
10
|
+
} | {
|
|
11
|
+
status: "ok";
|
|
12
|
+
realPath: string;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Resolve a fixed package path WITHOUT reading it: symlinks and equivalent
|
|
16
|
+
* mechanisms are resolved first, and a path escaping the filesystem-resolved
|
|
17
|
+
* plugin root is rejected before any I/O could consume outside content.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveContainedPath(realBase: string, target: string): Promise<ContainedPathResolution>;
|
|
20
|
+
/**
|
|
21
|
+
* Verify a package path stays within the filesystem-resolved plugin root:
|
|
22
|
+
* lexically, and — when the target exists — after resolving symlinks. Unlike
|
|
23
|
+
* {@link resolveContainedPath}, a missing target passes. ONLY for configured
|
|
24
|
+
* paths that are validated but never read or executed at load time (stdio
|
|
25
|
+
* `command`, `cwd` — including `${PLUGIN_DATA}` paths created after
|
|
26
|
+
* validation); access paths MUST use {@link resolveContainedPath} instead,
|
|
27
|
+
* which fails closed on unresolvable targets.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isContainedResolved(realBase: string, target: string): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Sync variant of {@link resolveContainedPath} for synchronous callsites
|
|
32
|
+
* (bash `skill://` expansion).
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveContainedPathSync(realBase: string, target: string): ContainedPathResolution;
|
|
@@ -18,6 +18,7 @@ import "../capability/slash-command.js";
|
|
|
18
18
|
import "../capability/ssh.js";
|
|
19
19
|
import "../capability/system-prompt.js";
|
|
20
20
|
import "../capability/tool.js";
|
|
21
|
+
import "./agent-plugins.js";
|
|
21
22
|
import "./agents-md.js";
|
|
22
23
|
import "./builtin.js";
|
|
23
24
|
import "./builtin-defaults.js";
|
|
@@ -22,7 +22,7 @@ import type { LocalProtocolOptions } from "../../internal-urls/local-protocol.js
|
|
|
22
22
|
import type { Theme } from "../../modes/theme/theme.js";
|
|
23
23
|
import type { ReadonlySessionManager } from "../../session/session-manager.js";
|
|
24
24
|
import type { TodoItem } from "../../tools/todo.js";
|
|
25
|
-
import type {
|
|
25
|
+
import type { RetryErrorUpdate } from "../shared-events.js";
|
|
26
26
|
/** Alias for clarity */
|
|
27
27
|
export type CustomToolUIContext = HookUIContext;
|
|
28
28
|
export type { ExecOptions, ExecResult } from "../../exec/exec.js";
|
|
@@ -119,7 +119,7 @@ export type CustomToolSessionEvent = {
|
|
|
119
119
|
success: boolean;
|
|
120
120
|
attempt: number;
|
|
121
121
|
finalError?: string;
|
|
122
|
-
|
|
122
|
+
retryErrors?: RetryErrorUpdate[];
|
|
123
123
|
} | {
|
|
124
124
|
reason: "ttsr_triggered";
|
|
125
125
|
rules: Rule[];
|
|
@@ -16,6 +16,8 @@ export declare class ExtensionRuntime implements IExtensionRuntime {
|
|
|
16
16
|
config: ProviderConfig;
|
|
17
17
|
sourceId: string;
|
|
18
18
|
}>;
|
|
19
|
+
registerProvider(name: string, config: ProviderConfig, sourceId: string): void;
|
|
20
|
+
unregisterProvider(name: string): void;
|
|
19
21
|
sendMessage(): void;
|
|
20
22
|
sendUserMessage(): void;
|
|
21
23
|
appendEntry(): void;
|
|
@@ -38,6 +40,11 @@ export declare class ExtensionRuntime implements IExtensionRuntime {
|
|
|
38
40
|
export declare function loadExtensionFromFactory(factory: ExtensionFactory, cwd: string, eventBus: EventBus, runtime: IExtensionRuntime, name?: string): Promise<Extension>;
|
|
39
41
|
/**
|
|
40
42
|
* Load extensions from paths.
|
|
43
|
+
*
|
|
44
|
+
* Module import (the dominant cold-start cost — file I/O plus module
|
|
45
|
+
* evaluation) runs concurrently across extensions; factory binding then runs
|
|
46
|
+
* sequentially in the original path order, so registration semantics
|
|
47
|
+
* (last-wins collisions, shared runtime flag defaults) stay deterministic.
|
|
41
48
|
*/
|
|
42
49
|
export declare function loadExtensions(paths: string[], cwd: string, eventBus?: EventBus): Promise<LoadExtensionsResult>;
|
|
43
50
|
/**
|
|
@@ -918,6 +918,13 @@ export interface ExtensionAPI {
|
|
|
918
918
|
* });
|
|
919
919
|
*/
|
|
920
920
|
registerProvider(name: string, config: ProviderConfig): void;
|
|
921
|
+
/**
|
|
922
|
+
* Unregister a provider previously registered by an extension.
|
|
923
|
+
*
|
|
924
|
+
* Removes extension-provided models and restores overridden built-in models.
|
|
925
|
+
* Has no effect when the provider is not registered.
|
|
926
|
+
*/
|
|
927
|
+
unregisterProvider(name: string): void;
|
|
921
928
|
/** Shared event bus for extension communication. */
|
|
922
929
|
events: EventBus;
|
|
923
930
|
}
|
|
@@ -1042,6 +1049,10 @@ export interface ExtensionRuntimeState {
|
|
|
1042
1049
|
config: ProviderConfig;
|
|
1043
1050
|
sourceId: string;
|
|
1044
1051
|
}>;
|
|
1052
|
+
/** Queue a provider registration until initialization, then apply it immediately. */
|
|
1053
|
+
registerProvider(name: string, config: ProviderConfig, sourceId: string): void;
|
|
1054
|
+
/** Remove a queued or initialized provider registration. */
|
|
1055
|
+
unregisterProvider(name: string, sourceId: string): void;
|
|
1045
1056
|
}
|
|
1046
1057
|
/** Action implementations for ExtensionAPI methods. */
|
|
1047
1058
|
export interface ExtensionActions {
|
|
@@ -200,7 +200,8 @@ export interface AutoRetryStartEvent {
|
|
|
200
200
|
errorMessage: string;
|
|
201
201
|
errorId?: number;
|
|
202
202
|
}
|
|
203
|
-
|
|
203
|
+
/** Persisted retry error whose transcript presentation changed when the retry saga settled. */
|
|
204
|
+
export interface RetryErrorUpdate {
|
|
204
205
|
entryId: string;
|
|
205
206
|
persistenceKey?: string;
|
|
206
207
|
note: string;
|
|
@@ -212,7 +213,7 @@ export interface AutoRetryEndEvent {
|
|
|
212
213
|
success: boolean;
|
|
213
214
|
attempt: number;
|
|
214
215
|
finalError?: string;
|
|
215
|
-
|
|
216
|
+
retryErrors?: RetryErrorUpdate[];
|
|
216
217
|
}
|
|
217
218
|
/** Fired when TTSR rule matching interrupts generation */
|
|
218
219
|
export interface TtsrTriggeredEvent {
|
|
@@ -13,6 +13,11 @@ export interface Skill {
|
|
|
13
13
|
* prompt's `<skills>` listing.
|
|
14
14
|
*/
|
|
15
15
|
hide?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Filesystem-resolved plugin root for Agent Plugin skills (spec §4.1):
|
|
18
|
+
* every `skill://` resource access must realpath-resolve within it.
|
|
19
|
+
*/
|
|
20
|
+
containRoot?: string;
|
|
16
21
|
/** Source metadata for display */
|
|
17
22
|
_source?: SourceMeta;
|
|
18
23
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP header precedence and redirect-origin policy for remote MCP transports.
|
|
3
|
+
*
|
|
4
|
+
* Two invariants, applied at every transport fetch:
|
|
5
|
+
*
|
|
6
|
+
* 1. Client-generated headers (protocol headers like `Content-Type`, `Accept`,
|
|
7
|
+
* `Mcp-Session-Id`, and authorization) take precedence over configured
|
|
8
|
+
* headers with the same case-insensitive name. Configured headers can never
|
|
9
|
+
* corrupt the MCP wire protocol via casing tricks.
|
|
10
|
+
* 2. Origin-locked servers (Agent Plugins §7.2.1) never forward configured
|
|
11
|
+
* headers to a different origin: redirects are followed manually and
|
|
12
|
+
* configured headers are attached only when the hop targets the configured
|
|
13
|
+
* origin. Method-changing redirects of non-GET requests are refused.
|
|
14
|
+
*/
|
|
15
|
+
/** Header buckets for one MCP HTTP request. */
|
|
16
|
+
export interface MCPHeaderSources {
|
|
17
|
+
/** Client-generated HTTP/MCP/authorization headers; win case-insensitively. */
|
|
18
|
+
generated: Record<string, string>;
|
|
19
|
+
/** Configured headers from the server entry (package or user config). */
|
|
20
|
+
configured?: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Merge configured headers under client-generated ones: a configured entry is
|
|
24
|
+
* dropped when a generated header with the same case-insensitive name exists.
|
|
25
|
+
*/
|
|
26
|
+
export declare function mergeMCPHeaders({ generated, configured }: MCPHeaderSources): Record<string, string>;
|
|
27
|
+
/**
|
|
28
|
+
* Set a client-generated header, removing any existing entry with the same
|
|
29
|
+
* case-insensitive name so the generated value is the only one sent.
|
|
30
|
+
*/
|
|
31
|
+
export declare function setGeneratedHeader(headers: Record<string, string>, name: string, value: string): void;
|
|
32
|
+
export interface MCPFetchInit {
|
|
33
|
+
method: "GET" | "POST" | "DELETE";
|
|
34
|
+
body?: string;
|
|
35
|
+
signal?: AbortSignal;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Fetch an MCP endpoint with header precedence and, for origin-locked servers,
|
|
39
|
+
* manual redirect handling that strips configured headers on cross-origin hops.
|
|
40
|
+
*
|
|
41
|
+
* Non-locked servers keep the platform default redirect behavior. Locked
|
|
42
|
+
* non-GET requests only follow 307/308 (method-preserving); a 301/302/303
|
|
43
|
+
* redirect of a JSON-RPC POST is a connection error, never a silent GET.
|
|
44
|
+
*/
|
|
45
|
+
export declare function mcpFetch(url: string, init: MCPFetchInit, sources: MCPHeaderSources, originLocked: boolean): Promise<Response>;
|
|
@@ -82,6 +82,13 @@ export interface MCPStdioServerConfig extends MCPServerConfigBase {
|
|
|
82
82
|
command: string;
|
|
83
83
|
args?: string[];
|
|
84
84
|
env?: Record<string, string>;
|
|
85
|
+
/**
|
|
86
|
+
* `literal`: env values are opaque plugin package data (Agent Plugins
|
|
87
|
+
* §§4.1/9.2) — no env-name lookup, no `!command` execution, no dropping of
|
|
88
|
+
* empty values. The provider already applied the only permitted expansion
|
|
89
|
+
* (`${PLUGIN_ROOT}`/`${PLUGIN_DATA}`).
|
|
90
|
+
*/
|
|
91
|
+
envPolicy?: "literal";
|
|
85
92
|
cwd?: string;
|
|
86
93
|
}
|
|
87
94
|
/** HTTP server configuration (Streamable HTTP transport) */
|
|
@@ -89,12 +96,20 @@ export interface MCPHttpServerConfig extends MCPServerConfigBase {
|
|
|
89
96
|
type: "http";
|
|
90
97
|
url: string;
|
|
91
98
|
headers?: Record<string, string>;
|
|
99
|
+
/**
|
|
100
|
+
* `origin-locked`: configured headers are literal package data pinned to the
|
|
101
|
+
* configured URL's origin (Agent Plugins §7.2.1) — never expanded, never
|
|
102
|
+
* forwarded cross-origin, and client-generated headers win case-insensitively.
|
|
103
|
+
*/
|
|
104
|
+
headerPolicy?: "origin-locked";
|
|
92
105
|
}
|
|
93
106
|
/** SSE server configuration (deprecated, use HTTP) */
|
|
94
107
|
export interface MCPSseServerConfig extends MCPServerConfigBase {
|
|
95
108
|
type: "sse";
|
|
96
109
|
url: string;
|
|
97
110
|
headers?: Record<string, string>;
|
|
111
|
+
/** See {@link MCPHttpServerConfig.headerPolicy}. */
|
|
112
|
+
headerPolicy?: "origin-locked";
|
|
98
113
|
}
|
|
99
114
|
export type MCPServerConfig = MCPStdioServerConfig | MCPHttpServerConfig | MCPSseServerConfig;
|
|
100
115
|
export declare const MCP_CONFIG_SCHEMA_URL = "https://raw.githubusercontent.com/can1357/oh-my-pi/main/packages/coding-agent/src/config/mcp-schema.json";
|
|
@@ -56,6 +56,8 @@ export interface AgentHubDeps {
|
|
|
56
56
|
ui?: TUI;
|
|
57
57
|
/** Tool lookup for transcript renderers (labels, custom render functions). */
|
|
58
58
|
getTool?: (name: string) => AgentTool | undefined;
|
|
59
|
+
/** Whether the active registry entry came from a built-in factory. */
|
|
60
|
+
isBuiltInTool?: (name: string) => boolean;
|
|
59
61
|
/** Extension message renderers for custom messages in the transcript. */
|
|
60
62
|
getMessageRenderer?: (customType: string) => MessageRenderer | undefined;
|
|
61
63
|
/** Cwd used by tool renderers for path shortening; defaults to the project dir. */
|
|
@@ -17,6 +17,8 @@ export interface AgentTranscriptViewerDeps {
|
|
|
17
17
|
lifecycle?: () => AgentLifecycleManager;
|
|
18
18
|
ui: TUI;
|
|
19
19
|
getTool?: (name: string) => AgentTool | undefined;
|
|
20
|
+
/** Whether the active registry entry came from a built-in factory. */
|
|
21
|
+
isBuiltInTool?: (name: string) => boolean;
|
|
20
22
|
getMessageRenderer?: (customType: string) => MessageRenderer | undefined;
|
|
21
23
|
cwd: string;
|
|
22
24
|
hideThinkingBlock?: () => boolean;
|
|
@@ -19,6 +19,8 @@ import { TranscriptContainer } from "./transcript-container.js";
|
|
|
19
19
|
export interface ChatTranscriptBuilderDeps {
|
|
20
20
|
ui: TUI;
|
|
21
21
|
getTool?: (name: string) => AgentTool | undefined;
|
|
22
|
+
/** Whether the active registry entry came from a built-in factory. */
|
|
23
|
+
isBuiltInTool?: (name: string) => boolean;
|
|
22
24
|
getMessageRenderer?: (customType: string) => MessageRenderer | undefined;
|
|
23
25
|
cwd: string;
|
|
24
26
|
hideThinkingBlock?: () => boolean;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ImageContent } from "@oh-my-pi/pi-ai";
|
|
2
2
|
import { Editor, type KeyId, TUI } from "@oh-my-pi/pi-tui";
|
|
3
3
|
import type { AppKeybinding } from "../../config/keybindings.js";
|
|
4
|
-
type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.clear" | "app.exit" | "app.suspend" | "app.display.reset" | "app.thinking.cycle" | "app.model.cycleForward" | "app.model.cycleBackward" | "app.model.select" | "app.model.selectTemporary" | "app.tools.
|
|
4
|
+
type ConfigurableEditorAction = Extract<AppKeybinding, "app.interrupt" | "app.clear" | "app.exit" | "app.suspend" | "app.display.reset" | "app.thinking.cycle" | "app.model.cycleForward" | "app.model.cycleBackward" | "app.model.select" | "app.model.selectTemporary" | "app.tools.toggleVisibility" | "app.thinking.toggle" | "app.editor.external" | "app.history.search" | "app.message.dequeue" | "app.retry" | "app.clipboard.pasteImage" | "app.clipboard.pasteTextRaw" | "app.clipboard.copyPrompt">;
|
|
5
5
|
/** Max gap (ms) between two spaces for the later one to count as OS key auto-repeat rather than a
|
|
6
6
|
* deliberate press. OS auto-repeat is fast; a deliberate tap (even a fast one) is slower. */
|
|
7
7
|
export declare const SPACE_REPEAT_MAX_GAP_MS = 120;
|
|
@@ -140,7 +140,6 @@ export declare class CustomEditor extends Editor {
|
|
|
140
140
|
onCycleModelForward?: () => void;
|
|
141
141
|
onCycleModelBackward?: () => void;
|
|
142
142
|
onSelectModel?: () => void;
|
|
143
|
-
onExpandTools?: () => void;
|
|
144
143
|
onToggleToolActivity?: () => void;
|
|
145
144
|
onToggleThinking?: () => void;
|
|
146
145
|
onExternalEditor?: () => void;
|
|
@@ -52,6 +52,8 @@ export interface SegmentContext {
|
|
|
52
52
|
session: AgentSession;
|
|
53
53
|
/** Focused subagent id while the view is proxied at its session, undefined otherwise. */
|
|
54
54
|
focusedAgentId?: string | undefined;
|
|
55
|
+
/** Effective `statusLine.sessionAccent`; `false` disables hash-derived accent colors, while `true` or omission enables them. */
|
|
56
|
+
sessionAccent?: boolean;
|
|
55
57
|
activeRepo: ActiveRepoContext | null;
|
|
56
58
|
width: number;
|
|
57
59
|
options: StatusLineSegmentOptions;
|
|
@@ -28,6 +28,8 @@ export interface ToolExecutionOptions {
|
|
|
28
28
|
/** Session-persistent edit clipboard register, forked per preview frame. */
|
|
29
29
|
clipboard?: Clipboard;
|
|
30
30
|
showImages?: boolean;
|
|
31
|
+
/** Allow the name-keyed renderer registry only when the active tool is the built-in implementation. */
|
|
32
|
+
useBuiltInRenderer?: boolean;
|
|
31
33
|
editFuzzyThreshold?: number;
|
|
32
34
|
editAllowFuzzy?: boolean;
|
|
33
35
|
/** Live-region probe used to settle detached task progress once the block
|