@oh-my-pi/pi-coding-agent 17.1.2 → 17.1.4
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 +63 -0
- package/dist/cli.js +3806 -3798
- package/dist/types/cli/__tests__/auth-gateway-catalog.test.d.ts +1 -0
- package/dist/types/cli/auth-gateway-cli.d.ts +8 -0
- package/dist/types/cli/update-cli.d.ts +41 -0
- package/dist/types/cli/usage-cli.d.ts +4 -2
- package/dist/types/commands/update.d.ts +1 -0
- package/dist/types/config/model-registry.d.ts +19 -0
- package/dist/types/config/settings-schema.d.ts +30 -7
- package/dist/types/cursor.d.ts +47 -1
- package/dist/types/eval/js/process-entry.d.ts +2 -1
- package/dist/types/eval/js/worker-core.d.ts +4 -1
- package/dist/types/extensibility/extensions/runner.d.ts +1 -0
- package/dist/types/extensibility/legacy-pi-ai-shim.d.ts +4 -0
- package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +4 -0
- package/dist/types/extensibility/legacy-pi-tui-shim.d.ts +15 -7
- package/dist/types/extensibility/shared-events.d.ts +2 -0
- package/dist/types/modes/components/assistant-message.d.ts +9 -0
- package/dist/types/modes/components/custom-editor.d.ts +12 -8
- package/dist/types/plan-mode/approved-plan.d.ts +3 -2
- package/dist/types/secrets/obfuscator.d.ts +7 -31
- package/dist/types/session/agent-session.d.ts +19 -4
- package/dist/types/session/prewalk.d.ts +2 -1
- package/dist/types/session/session-advisors.d.ts +8 -0
- package/dist/types/session/session-metadata.d.ts +29 -0
- package/dist/types/session/turn-recovery.d.ts +5 -5
- package/dist/types/stt/sherpa-runtime.d.ts +38 -0
- package/dist/types/thinking.d.ts +24 -0
- package/dist/types/tools/auto-generated-guard.d.ts +5 -2
- package/dist/types/tools/bash.d.ts +5 -4
- package/dist/types/tools/computer/exposure.d.ts +8 -0
- package/dist/types/tools/computer/supervisor.d.ts +1 -1
- package/dist/types/tools/computer/worker-entry.d.ts +1 -1
- package/dist/types/tools/computer/worker.d.ts +1 -1
- package/dist/types/tools/computer.d.ts +6 -0
- package/dist/types/tools/memory-render.d.ts +1 -4
- package/dist/types/tools/shell-tokenize.d.ts +14 -0
- package/dist/types/tools/todo.d.ts +7 -1
- package/package.json +12 -12
- package/src/advisor/__tests__/advisor.test.ts +80 -10
- package/src/advisor/runtime.ts +27 -1
- package/src/cli/__tests__/auth-gateway-catalog.test.ts +111 -0
- package/src/cli/auth-gateway-cli.ts +63 -16
- package/src/cli/config-cli.ts +25 -7
- package/src/cli/update-cli.ts +229 -29
- package/src/cli/usage-cli.ts +144 -15
- package/src/cli.ts +21 -15
- package/src/commands/update.ts +6 -0
- package/src/config/__tests__/model-registry.test.ts +42 -7
- package/src/config/model-registry.ts +67 -4
- package/src/config/settings-schema.ts +39 -8
- package/src/config/settings.ts +24 -2
- package/src/cursor.ts +153 -0
- package/src/dap/session.ts +70 -11
- package/src/edit/hashline/filesystem.ts +1 -1
- package/src/edit/modes/patch.ts +1 -1
- package/src/eval/__tests__/js-context-manager.test.ts +9 -1
- package/src/eval/__tests__/process-entry-import.test.ts +111 -1
- package/src/eval/js/process-entry.ts +9 -5
- package/src/eval/js/worker-core.ts +6 -2
- package/src/exec/bash-executor.ts +4 -2
- package/src/extensibility/extensions/runner.ts +23 -8
- package/src/extensibility/legacy-pi-ai-shim.ts +9 -0
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +14 -2
- package/src/extensibility/legacy-pi-tui-shim.ts +33 -0
- package/src/extensibility/shared-events.ts +2 -0
- package/src/main.ts +22 -1
- package/src/modes/acp/acp-agent.ts +6 -0
- package/src/modes/components/assistant-message.ts +88 -11
- package/src/modes/components/chat-transcript-builder.ts +2 -0
- package/src/modes/components/custom-editor.test.ts +170 -0
- package/src/modes/components/custom-editor.ts +79 -29
- package/src/modes/components/settings-defs.ts +5 -1
- package/src/modes/controllers/event-controller.ts +96 -4
- package/src/modes/controllers/selector-controller.ts +14 -0
- package/src/modes/interactive-mode.ts +34 -8
- package/src/modes/utils/context-usage.ts +19 -2
- package/src/modes/utils/interactive-context-helpers.ts +1 -0
- package/src/plan-mode/approved-plan.ts +18 -10
- package/src/prompts/system/custom-system-prompt.md +1 -1
- package/src/prompts/system/system-prompt.md +10 -1
- package/src/prompts/tools/ast-edit.md +1 -1
- package/src/sdk.ts +4 -0
- package/src/secrets/obfuscator.ts +36 -126
- package/src/session/agent-session.ts +69 -60
- package/src/session/prewalk.ts +8 -3
- package/src/session/session-advisors.ts +67 -3
- package/src/session/session-metadata.ts +53 -0
- package/src/session/session-provider-boundary.ts +0 -1
- package/src/session/session-tools.ts +35 -1
- package/src/session/stream-guards.ts +1 -1
- package/src/session/turn-recovery.ts +36 -19
- package/src/slash-commands/builtin-registry.ts +49 -7
- package/src/stt/asr-worker.ts +2 -37
- package/src/stt/sherpa-runtime.ts +71 -0
- package/src/task/executor.ts +6 -5
- package/src/thinking.ts +39 -0
- package/src/tools/auto-generated-guard.ts +18 -5
- package/src/tools/bash.ts +43 -15
- package/src/tools/computer/exposure.ts +38 -0
- package/src/tools/computer/supervisor.ts +61 -13
- package/src/tools/computer/worker-entry.ts +28 -19
- package/src/tools/computer/worker.ts +3 -7
- package/src/tools/computer.ts +65 -10
- package/src/tools/gh-cache-invalidation.ts +2 -82
- package/src/tools/memory-render.ts +11 -2
- package/src/tools/render-utils.ts +8 -3
- package/src/tools/shell-tokenize.ts +83 -0
- package/src/tools/todo.ts +44 -17
- package/src/tools/write.ts +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Api, type Model } from "@oh-my-pi/pi-ai";
|
|
1
2
|
export type AuthGatewayAction = "serve" | "token" | "status" | "check";
|
|
2
3
|
export interface AuthGatewayCommandArgs {
|
|
3
4
|
action: AuthGatewayAction;
|
|
@@ -22,5 +23,12 @@ export interface AuthGatewayCommandArgs {
|
|
|
22
23
|
};
|
|
23
24
|
}
|
|
24
25
|
declare const ACTIONS: readonly AuthGatewayAction[];
|
|
26
|
+
/**
|
|
27
|
+
* Index resolvable models by the request ids clients may send: the
|
|
28
|
+
* provider-qualified `provider/id` (always) and the bare `id` (first-write-wins
|
|
29
|
+
* fallback for legacy clients). Scoped to providers the gateway holds broker
|
|
30
|
+
* credentials for, since only those are routable.
|
|
31
|
+
*/
|
|
32
|
+
export declare function indexModelsByRequestId(models: readonly Model<Api>[], providersWithCreds: ReadonlySet<string>): Map<string, Model<Api>>;
|
|
25
33
|
export declare function runAuthGatewayCommand(cmd: AuthGatewayCommandArgs): Promise<void>;
|
|
26
34
|
export { ACTIONS as AUTH_GATEWAY_ACTIONS };
|
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
export interface ReleaseBinaryAsset {
|
|
2
|
+
url: string;
|
|
3
|
+
size: number;
|
|
4
|
+
digest: string;
|
|
5
|
+
}
|
|
6
|
+
type Fetch = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
7
|
+
/**
|
|
8
|
+
* Select and validate the binary asset from GitHub release metadata.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveReleaseBinaryAsset(release: unknown, expectedTag: string, binaryName: string): ReleaseBinaryAsset;
|
|
11
|
+
export interface VerifiedBinaryDownloadOptions {
|
|
12
|
+
url: string;
|
|
13
|
+
targetPath: string;
|
|
14
|
+
expectedSize: number;
|
|
15
|
+
expectedDigest: string;
|
|
16
|
+
fetchImpl?: Fetch;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Download a binary and verify its GitHub-reported size and SHA-256 digest.
|
|
20
|
+
*/
|
|
21
|
+
export declare function downloadVerifiedBinary(options: VerifiedBinaryDownloadOptions): Promise<void>;
|
|
1
22
|
/** Result from running the installed binary and parsing its reported version. */
|
|
2
23
|
export interface InstalledVersionVerification {
|
|
3
24
|
ok: boolean;
|
|
@@ -27,6 +48,13 @@ interface UpdateMethodResolutionOptions {
|
|
|
27
48
|
miseBinDirs?: readonly string[];
|
|
28
49
|
miseDataDir?: string;
|
|
29
50
|
npmBinDir?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Whether the resolved omp path is a plain file (the standalone binary)
|
|
53
|
+
* rather than a package-manager symlink. Stops a binary install from being
|
|
54
|
+
* misrouted to npm/bun when the global bin dir overlaps the installer's
|
|
55
|
+
* target directory.
|
|
56
|
+
*/
|
|
57
|
+
ompIsRegularFile?: boolean;
|
|
30
58
|
}
|
|
31
59
|
export declare function resolveUpdateMethodForTest(ompPath: string, bunBinDir: string | undefined, options?: UpdateMethodResolutionOptions): UpdateMethod;
|
|
32
60
|
interface BunInstallCachePruneResult {
|
|
@@ -44,6 +72,10 @@ interface BunInstallCachePruneResult {
|
|
|
44
72
|
*/
|
|
45
73
|
export declare function pruneBunInstallCache(cacheDir: string, packageNames?: Set<string>): Promise<BunInstallCachePruneResult>;
|
|
46
74
|
export declare function resolveBunGlobalNodeModulesDirFromLocations(globalBinDir: string | undefined, cacheDir: string | undefined): string | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Run the resolved omp binary and check if it reports the expected version.
|
|
77
|
+
*/
|
|
78
|
+
declare function verifyInstalledVersion(expectedVersion: string): Promise<InstalledVersionVerification>;
|
|
47
79
|
/**
|
|
48
80
|
* Best-effort removal of binary-update backups left by earlier runs.
|
|
49
81
|
*
|
|
@@ -95,6 +127,15 @@ export declare function buildNpmInstallArgs(expectedVersion: string, nativeTag?:
|
|
|
95
127
|
export declare function buildHomebrewUpdateArgs(force: boolean): string[];
|
|
96
128
|
export declare function buildMiseUpgradeArgs(): string[];
|
|
97
129
|
export declare function buildMiseForceInstallArgs(expectedVersion: string): string[];
|
|
130
|
+
/**
|
|
131
|
+
* Download a release binary to a target path, replacing an existing file.
|
|
132
|
+
*/
|
|
133
|
+
export declare function updateViaBinaryAt(targetPath: string, expectedVersion: string, options?: {
|
|
134
|
+
binaryName?: string;
|
|
135
|
+
fetchImpl?: Fetch;
|
|
136
|
+
githubToken?: string;
|
|
137
|
+
verifyInstalledVersion?: typeof verifyInstalledVersion;
|
|
138
|
+
}): Promise<void>;
|
|
98
139
|
/**
|
|
99
140
|
* Run the update command.
|
|
100
141
|
*/
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* credentials produced no usage report are listed too, so the output
|
|
8
8
|
* always covers the full credential pool.
|
|
9
9
|
*/
|
|
10
|
-
import { type UsageHistoryEntry, type UsageReport } from "@oh-my-pi/pi-ai";
|
|
10
|
+
import { type DisabledCredentialSummary, type UsageHistoryEntry, type UsageReport } from "@oh-my-pi/pi-ai";
|
|
11
11
|
export interface UsageCommandArgs {
|
|
12
12
|
action?: string;
|
|
13
13
|
json?: boolean;
|
|
@@ -29,6 +29,8 @@ export interface UsageAccountIdentity {
|
|
|
29
29
|
/** Organization/workspace the credential is scoped to (Anthropic multi-subscription). */
|
|
30
30
|
orgId?: string;
|
|
31
31
|
orgName?: string;
|
|
32
|
+
/** Epoch ms of the interactive login that minted the OAuth grant (see `OAuthCredentials.authorizedAt`). */
|
|
33
|
+
authorizedAt?: number;
|
|
32
34
|
}
|
|
33
35
|
/**
|
|
34
36
|
* Minimal-reveal masks for identity strings (`--redact`).
|
|
@@ -76,7 +78,7 @@ export declare function computeProviderWindowStats(reports: UsageReport[]): Prov
|
|
|
76
78
|
* with a bar, amounts, and reset times; unattributed credentials trail
|
|
77
79
|
* each provider section as "no usage data" rows.
|
|
78
80
|
*/
|
|
79
|
-
export declare function formatUsageBreakdown(reports: UsageReport[], accounts: UsageAccountIdentity[], nowMs: number, redaction?: Map<string, string
|
|
81
|
+
export declare function formatUsageBreakdown(reports: UsageReport[], accounts: UsageAccountIdentity[], nowMs: number, redaction?: Map<string, string>, disabled?: DisabledCredentialSummary[]): string;
|
|
80
82
|
/**
|
|
81
83
|
* Render recorded usage-limit history: per provider, per account, one
|
|
82
84
|
* peak-per-bucket sparkline per limit window plus latest/peak percentages.
|
|
@@ -55,6 +55,16 @@ export interface ProviderDiscoveryState {
|
|
|
55
55
|
models: string[];
|
|
56
56
|
error?: string;
|
|
57
57
|
}
|
|
58
|
+
/** Authentication material returned to legacy extensions for one model request. */
|
|
59
|
+
export type ResolvedRequestAuth = {
|
|
60
|
+
ok: true;
|
|
61
|
+
apiKey?: string;
|
|
62
|
+
headers?: Record<string, string>;
|
|
63
|
+
env?: Record<string, string>;
|
|
64
|
+
} | {
|
|
65
|
+
ok: false;
|
|
66
|
+
error: string;
|
|
67
|
+
};
|
|
58
68
|
/**
|
|
59
69
|
* Model registry - loads and manages models, resolves API keys via AuthStorage.
|
|
60
70
|
*/
|
|
@@ -71,6 +81,13 @@ export declare class ModelRegistry {
|
|
|
71
81
|
* `tryLoad()` runs.
|
|
72
82
|
*/
|
|
73
83
|
constructor(authStorage: AuthStorage, modelsPath?: string, options?: {
|
|
84
|
+
/**
|
|
85
|
+
* Gateway mode: ignore local `models.yml` entirely (provider overrides,
|
|
86
|
+
* config API keys, custom models, custom discovery). A broker-backed
|
|
87
|
+
* gateway serves only bundled + broker-discovered catalog metadata and
|
|
88
|
+
* must never apply client-side credential or routing overrides.
|
|
89
|
+
*/
|
|
90
|
+
ignoreLocalModelConfig?: boolean;
|
|
74
91
|
fetch?: FetchImpl;
|
|
75
92
|
});
|
|
76
93
|
/**
|
|
@@ -178,6 +195,8 @@ export declare class ModelRegistry {
|
|
|
178
195
|
getApiKey(model: Model<Api>, sessionId?: string, options?: {
|
|
179
196
|
signal?: AbortSignal;
|
|
180
197
|
}): Promise<string | undefined>;
|
|
198
|
+
/** Resolve request authentication through the historical Pi extension facade. */
|
|
199
|
+
getApiKeyAndHeaders(model: Model<Api>): Promise<ResolvedRequestAuth>;
|
|
181
200
|
/**
|
|
182
201
|
* Get API key for a provider (e.g., "openai").
|
|
183
202
|
*
|
|
@@ -85,33 +85,44 @@ export type AnyUiMetadata = UiBase & {
|
|
|
85
85
|
secret?: boolean;
|
|
86
86
|
ordered?: boolean;
|
|
87
87
|
};
|
|
88
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Marks a setting whose value is a credential.
|
|
90
|
+
*
|
|
91
|
+
* Lives at the top level rather than inside `ui` so it can also describe a
|
|
92
|
+
* setting the settings panel never shows and therefore cannot carry
|
|
93
|
+
* `ui.secret`. Read it through `isCredential`, which is the single accessor
|
|
94
|
+
* both the CLI and the settings panel consult.
|
|
95
|
+
*/
|
|
96
|
+
interface CredentialMarker {
|
|
97
|
+
credential?: true;
|
|
98
|
+
}
|
|
99
|
+
interface BooleanDef extends CredentialMarker {
|
|
89
100
|
type: "boolean";
|
|
90
101
|
default: boolean | undefined;
|
|
91
102
|
ui?: UiBoolean;
|
|
92
103
|
}
|
|
93
|
-
interface StringDef {
|
|
104
|
+
interface StringDef extends CredentialMarker {
|
|
94
105
|
type: "string";
|
|
95
106
|
default: string | undefined;
|
|
96
107
|
ui?: UiString;
|
|
97
108
|
}
|
|
98
|
-
interface NumberDef {
|
|
109
|
+
interface NumberDef extends CredentialMarker {
|
|
99
110
|
type: "number";
|
|
100
111
|
default: number | undefined;
|
|
101
112
|
ui?: UiNumber;
|
|
102
113
|
}
|
|
103
|
-
interface EnumDef<T extends readonly string[]> {
|
|
114
|
+
interface EnumDef<T extends readonly string[]> extends CredentialMarker {
|
|
104
115
|
type: "enum";
|
|
105
116
|
values: T;
|
|
106
117
|
default: T[number];
|
|
107
118
|
ui?: UiEnum<T>;
|
|
108
119
|
}
|
|
109
|
-
interface ArrayDef<T> {
|
|
120
|
+
interface ArrayDef<T> extends CredentialMarker {
|
|
110
121
|
type: "array";
|
|
111
122
|
default: T[];
|
|
112
123
|
ui?: UiArray;
|
|
113
124
|
}
|
|
114
|
-
interface RecordDef<T> {
|
|
125
|
+
interface RecordDef<T> extends CredentialMarker {
|
|
115
126
|
type: "record";
|
|
116
127
|
default: Record<string, T>;
|
|
117
128
|
ui?: UiBase;
|
|
@@ -139,6 +150,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
139
150
|
readonly "auth.broker.token": {
|
|
140
151
|
readonly type: "string";
|
|
141
152
|
readonly default: undefined;
|
|
153
|
+
readonly credential: true;
|
|
142
154
|
};
|
|
143
155
|
readonly autoResume: {
|
|
144
156
|
readonly type: "boolean";
|
|
@@ -2843,6 +2855,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
2843
2855
|
};
|
|
2844
2856
|
readonly "mnemopi.embeddingApiKey": {
|
|
2845
2857
|
readonly type: "string";
|
|
2858
|
+
readonly credential: true;
|
|
2846
2859
|
readonly default: undefined;
|
|
2847
2860
|
readonly ui: {
|
|
2848
2861
|
readonly tab: "memory";
|
|
@@ -2890,6 +2903,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
2890
2903
|
};
|
|
2891
2904
|
readonly "mnemopi.llmApiKey": {
|
|
2892
2905
|
readonly type: "string";
|
|
2906
|
+
readonly credential: true;
|
|
2893
2907
|
readonly default: undefined;
|
|
2894
2908
|
readonly ui: {
|
|
2895
2909
|
readonly tab: "memory";
|
|
@@ -2947,6 +2961,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
2947
2961
|
};
|
|
2948
2962
|
readonly "hindsight.apiToken": {
|
|
2949
2963
|
readonly type: "string";
|
|
2964
|
+
readonly credential: true;
|
|
2950
2965
|
readonly default: undefined;
|
|
2951
2966
|
readonly ui: {
|
|
2952
2967
|
readonly tab: "memory";
|
|
@@ -2954,7 +2969,6 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
2954
2969
|
readonly label: "Hindsight API Token";
|
|
2955
2970
|
readonly description: "Bearer token for authenticated Hindsight servers";
|
|
2956
2971
|
readonly condition: "hindsightActive";
|
|
2957
|
-
readonly secret: true;
|
|
2958
2972
|
};
|
|
2959
2973
|
};
|
|
2960
2974
|
readonly "hindsight.bankId": {
|
|
@@ -5798,6 +5812,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
5798
5812
|
readonly "searxng.token": {
|
|
5799
5813
|
readonly type: "string";
|
|
5800
5814
|
readonly default: undefined;
|
|
5815
|
+
readonly credential: true;
|
|
5801
5816
|
};
|
|
5802
5817
|
readonly "searxng.basicUsername": {
|
|
5803
5818
|
readonly type: "string";
|
|
@@ -5806,6 +5821,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
5806
5821
|
readonly "searxng.basicPassword": {
|
|
5807
5822
|
readonly type: "string";
|
|
5808
5823
|
readonly default: undefined;
|
|
5824
|
+
readonly credential: true;
|
|
5809
5825
|
};
|
|
5810
5826
|
readonly "searxng.categories": {
|
|
5811
5827
|
readonly type: "string";
|
|
@@ -5866,6 +5882,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
5866
5882
|
readonly "dev.autoqaPush.token": {
|
|
5867
5883
|
readonly type: "string";
|
|
5868
5884
|
readonly default: undefined;
|
|
5885
|
+
readonly credential: true;
|
|
5869
5886
|
};
|
|
5870
5887
|
/**
|
|
5871
5888
|
* User decision on sharing automatic `report_tool_issue` grievances.
|
|
@@ -5964,6 +5981,12 @@ export type SettingValue<P extends SettingPath> = Schema[P] extends {
|
|
|
5964
5981
|
export declare function getDefault<P extends SettingPath>(path: P): SettingValue<P>;
|
|
5965
5982
|
/** Check if a path has UI metadata (should appear in settings panel) */
|
|
5966
5983
|
export declare function hasUi(path: SettingPath): boolean;
|
|
5984
|
+
/**
|
|
5985
|
+
* Whether a setting holds a credential and must never be printed or exported
|
|
5986
|
+
* without an explicit request. Drives both CLI redaction and settings-panel
|
|
5987
|
+
* masking, so the two cannot disagree.
|
|
5988
|
+
*/
|
|
5989
|
+
export declare function isCredential(path: SettingPath): boolean;
|
|
5967
5990
|
/** Get UI metadata for a path (undefined if no UI) */
|
|
5968
5991
|
export declare function getUi(path: SettingPath): AnyUiMetadata | undefined;
|
|
5969
5992
|
/** Get all paths for a specific tab */
|
package/dist/types/cursor.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AgentEvent, AgentTool, AgentToolContext } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import type { CursorMcpCall, CursorShellStreamCallbacks, CursorExecHandlers as ICursorExecHandlers, ToolResultMessage } from "@oh-my-pi/pi-ai";
|
|
2
|
+
import type { CursorMcpCall, CursorShellStreamCallbacks, CursorTodoSnapshot, CursorExecHandlers as ICursorExecHandlers, ToolResultMessage } from "@oh-my-pi/pi-ai";
|
|
3
|
+
import type { TodoPhase } from "./tools/todo.js";
|
|
3
4
|
interface CursorExecBridgeOptions {
|
|
4
5
|
cwd: string;
|
|
5
6
|
getCwd?: () => string;
|
|
@@ -16,6 +17,18 @@ interface CursorExecBridgeOptions {
|
|
|
16
17
|
* callers with a restricted tool set (advisors) opt out.
|
|
17
18
|
*/
|
|
18
19
|
allowNativeDelete?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Mirror Cursor's server-owned todo list into local session state. Cursor
|
|
22
|
+
* resolves `update_todos` / `read_todos` remotely, so without this bridge
|
|
23
|
+
* the provider's list and the local `todo` state diverge silently.
|
|
24
|
+
*/
|
|
25
|
+
setTodoPhases?: (phases: TodoPhase[]) => void;
|
|
26
|
+
getTodoPhases?: () => TodoPhase[];
|
|
27
|
+
/**
|
|
28
|
+
* Persist the mirrored list to the session branch so it survives reloads.
|
|
29
|
+
* Cursor emits no local `todo` toolResult, so nothing else records it.
|
|
30
|
+
*/
|
|
31
|
+
persistTodoPhases?: (phases: TodoPhase[]) => void;
|
|
19
32
|
}
|
|
20
33
|
export declare class CursorExecHandlers implements ICursorExecHandlers {
|
|
21
34
|
private options;
|
|
@@ -28,6 +41,39 @@ export declare class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
28
41
|
shell(args: Parameters<NonNullable<ICursorExecHandlers["shell"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
29
42
|
shellStream(args: Parameters<NonNullable<ICursorExecHandlers["shellStream"]>>[0], callbacks: CursorShellStreamCallbacks): Promise<ToolResultMessage<unknown>>;
|
|
30
43
|
diagnostics(args: Parameters<NonNullable<ICursorExecHandlers["diagnostics"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
44
|
+
/**
|
|
45
|
+
* Settle a completed native Cursor todo call, mirroring its list when the
|
|
46
|
+
* server supplied an authoritative one.
|
|
47
|
+
*
|
|
48
|
+
* Cursor's snapshot is a flat list, so tasks already known locally keep
|
|
49
|
+
* their phase and only their status is updated; unknown tasks land in a
|
|
50
|
+
* single fallback phase. Statuses come straight from the server snapshot —
|
|
51
|
+
* no local normalization, or an all-pending remote list would gain a
|
|
52
|
+
* phantom in-progress task the remote list does not have.
|
|
53
|
+
*
|
|
54
|
+
* The snapshot is also persisted to the session branch. Every other
|
|
55
|
+
* provider's todo state survives a reload because `todo` runs locally and
|
|
56
|
+
* its `toolResult` (carrying `details.phases`) lands in the branch, which
|
|
57
|
+
* `#syncTodoPhasesFromBranch` replays. Cursor resolves the tool remotely and
|
|
58
|
+
* emits no such result, so without an explicit entry the list is in-memory
|
|
59
|
+
* only and every reload, rewind, compaction, or session switch drops it.
|
|
60
|
+
*
|
|
61
|
+
* This ALWAYS settles the call and returns the result to persist, even when
|
|
62
|
+
* nothing is mirrored. Two reasons it cannot bail out early:
|
|
63
|
+
*
|
|
64
|
+
* - the interactive card leaves `pendingTools` only on a matching
|
|
65
|
+
* `tool_execution_end`, so staying silent leaves it animating forever;
|
|
66
|
+
* - an unpaired `toolCall` is stripped as dangling by `buildSessionContext`,
|
|
67
|
+
* erasing the interaction from every rebuilt transcript.
|
|
68
|
+
*
|
|
69
|
+
* A `null` snapshot means nothing may be mirrored — a server `error`, or a
|
|
70
|
+
* benign refusal: a filtered, truncated, or empty read, or a snapshot the
|
|
71
|
+
* local model cannot represent. Local state is left untouched, and the result
|
|
72
|
+
* carries no `details` (text `"Todo snapshot not mirrored"`): `event-controller`
|
|
73
|
+
* feeds `details.phases` straight into `setTodos`, so echoing the current list
|
|
74
|
+
* back would let a call that changed nothing overwrite live UI state.
|
|
75
|
+
*/
|
|
76
|
+
todoSync(snapshot: CursorTodoSnapshot | null, toolCallId: string, error?: string | null): ToolResultMessage;
|
|
31
77
|
mcp(call: CursorMcpCall): Promise<ToolResultMessage<unknown>>;
|
|
32
78
|
}
|
|
33
79
|
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { type RejectionInterceptor } from "./worker-core.js";
|
|
1
2
|
import type { WorkerInbound, WorkerOutbound } from "./worker-protocol.js";
|
|
2
3
|
/** Start the JavaScript evaluator inside a subprocess IPC transport. */
|
|
3
4
|
export declare function startJsEvalProcess(transport: {
|
|
4
5
|
send(message: WorkerOutbound): void;
|
|
5
6
|
onMessage(handler: (message: WorkerInbound) => void): () => void;
|
|
6
|
-
}): void;
|
|
7
|
+
}, interceptUnhandledRejections: RejectionInterceptor): void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Transport } from "./worker-protocol.js";
|
|
2
|
+
export type RejectionInterceptor = (handler: (reason: unknown) => boolean) => () => void;
|
|
2
3
|
export type WorkerCoreOptions = {
|
|
3
4
|
mode: "isolated";
|
|
4
5
|
/**
|
|
@@ -9,9 +10,11 @@ export type WorkerCoreOptions = {
|
|
|
9
10
|
* mutate the host's own cwd on the inline fallback.
|
|
10
11
|
*/
|
|
11
12
|
chdir?: (cwd: string) => void;
|
|
13
|
+
/** Share the subprocess host's fatal-rejection guard when one is installed. */
|
|
14
|
+
interceptUnhandledRejections?: RejectionInterceptor;
|
|
12
15
|
} | {
|
|
13
16
|
mode: "inline";
|
|
14
|
-
interceptUnhandledRejections
|
|
17
|
+
interceptUnhandledRejections: RejectionInterceptor;
|
|
15
18
|
};
|
|
16
19
|
export declare class WorkerCore {
|
|
17
20
|
#private;
|
|
@@ -86,6 +86,7 @@ export declare class ExtensionRunner {
|
|
|
86
86
|
* {@link onError} via {@link emit}'s normal isolation.
|
|
87
87
|
*/
|
|
88
88
|
emitCredentialDisabled(event: CredentialDisabledEvent): Promise<void>;
|
|
89
|
+
/** Emits a session stop pass that can be cancelled with the active settle signal. */
|
|
89
90
|
emitSessionStop(event: Omit<SessionStopEvent, "type">): Promise<SessionStopEventResult | undefined>;
|
|
90
91
|
getUIContext(): ExtensionUIContext;
|
|
91
92
|
hasUI(): boolean;
|
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
* `types.ts` via the `export *` below — pi-ai still exports both as types,
|
|
20
20
|
* only the runtime `Type` builder and `StringEnum()` helper were removed.
|
|
21
21
|
*/
|
|
22
|
+
import type { Api, Model } from "@oh-my-pi/pi-ai";
|
|
23
|
+
import type { Effort } from "@oh-my-pi/pi-catalog/effort";
|
|
22
24
|
import { calculateCost, getBundledModel, getBundledModels, getBundledProviders, modelsAreEqual } from "@oh-my-pi/pi-catalog/models";
|
|
23
25
|
import { type TSchema, Type } from "./typebox.js";
|
|
24
26
|
export interface StringEnumOptions<T extends string> {
|
|
@@ -28,6 +30,8 @@ export interface StringEnumOptions<T extends string> {
|
|
|
28
30
|
[key: string]: unknown;
|
|
29
31
|
}
|
|
30
32
|
export declare function StringEnum<T extends string | number>(values: readonly T[] | Record<string, T>, options?: StringEnumOptions<any>): TSchema;
|
|
33
|
+
/** Clamp a historical Pi thinking level against OMP's model metadata. */
|
|
34
|
+
export declare function clampThinkingLevel<TApi extends Api>(model: Model<TApi>, level: Effort | "off"): Effort | "off";
|
|
31
35
|
export * from "@oh-my-pi/pi-ai";
|
|
32
36
|
/**
|
|
33
37
|
* Compatibility re-exports for catalog symbols that pi-ai historically exposed
|
|
@@ -17,6 +17,7 @@ import type { PromptTemplate } from "../config/prompt-templates.js";
|
|
|
17
17
|
import { Settings } from "../config/settings.js";
|
|
18
18
|
import type { CreateAgentSessionOptions, CreateAgentSessionResult, LoadExtensionsResult } from "../sdk.js";
|
|
19
19
|
import { EventBus } from "../utils/event-bus.js";
|
|
20
|
+
import { ExtensionRuntime } from "./extensions/loader.js";
|
|
20
21
|
import type { ExtensionFactory, ToolDefinition } from "./extensions/types.js";
|
|
21
22
|
import type { Skill } from "./skills.js";
|
|
22
23
|
export interface BashSpawnContext {
|
|
@@ -272,6 +273,8 @@ export interface ResourceLoader {
|
|
|
272
273
|
/** @internal — used by the shim's createAgentSession to detect its own loaders. */
|
|
273
274
|
readonly __ompLegacyPiLoader?: true;
|
|
274
275
|
}
|
|
276
|
+
/** Create a pre-initialization runtime for legacy extension resource loaders. */
|
|
277
|
+
export declare function createExtensionRuntime(): ExtensionRuntime;
|
|
275
278
|
export declare class DefaultResourceLoader implements ResourceLoader {
|
|
276
279
|
#private;
|
|
277
280
|
readonly __ompLegacyPiLoader: true;
|
|
@@ -372,6 +375,7 @@ export { getProjectDir } from "@oh-my-pi/pi-utils";
|
|
|
372
375
|
* canonical helper.
|
|
373
376
|
*/
|
|
374
377
|
export declare function getPackageDir(): string;
|
|
378
|
+
export { estimateTokens } from "@oh-my-pi/pi-agent-core/compaction";
|
|
375
379
|
export * from "../index.js";
|
|
376
380
|
export { formatBytes as formatSize } from "../tools/render-utils.js";
|
|
377
381
|
export { copyToClipboard } from "../utils/clipboard.js";
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
+
export * from "@oh-my-pi/pi-tui";
|
|
2
|
+
export { decodePrintableKey as decodeKittyPrintable } from "@oh-my-pi/pi-tui";
|
|
3
|
+
/** Report canonical terminal capabilities through the legacy Pi TUI shape. */
|
|
4
|
+
export declare function getCapabilities(): {
|
|
5
|
+
images: "kitty" | "iterm2" | null;
|
|
6
|
+
trueColor: boolean;
|
|
7
|
+
hyperlinks: boolean;
|
|
8
|
+
};
|
|
1
9
|
/**
|
|
2
|
-
*
|
|
3
|
-
* `@earendil-works/pi-tui` or `@mariozechner/pi-tui`.
|
|
10
|
+
* Delete one Kitty graphics image by id, matching the legacy Pi TUI helper.
|
|
4
11
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
12
|
+
* Returns the bare control sequence exactly like upstream Pi: legacy callers
|
|
13
|
+
* (e.g. pi-sprite) apply their own tmux passthrough wrapping, so wrapping here
|
|
14
|
+
* would double-wrap under tmux and the outer terminal would drop the command.
|
|
8
15
|
*/
|
|
9
|
-
export
|
|
10
|
-
|
|
16
|
+
export declare function deleteKittyImage(imageId: number): string;
|
|
17
|
+
/** Delete every Kitty graphics image using the legacy Pi TUI bare sequence. */
|
|
18
|
+
export declare function deleteAllKittyImages(): string;
|
|
@@ -88,6 +88,8 @@ export interface SessionStopEvent {
|
|
|
88
88
|
session_id: string;
|
|
89
89
|
session_file?: string;
|
|
90
90
|
stop_hook_active: boolean;
|
|
91
|
+
/** Cancels handler waiting when the active settle pass is aborted. */
|
|
92
|
+
signal: AbortSignal;
|
|
91
93
|
}
|
|
92
94
|
/** Preparation data for tree navigation (used by session_before_tree event) */
|
|
93
95
|
export interface TreePreparation {
|
|
@@ -33,6 +33,15 @@ export declare class AssistantMessageComponent extends Container {
|
|
|
33
33
|
* pinned in the banner above the editor. Re-renders so the change is visible.
|
|
34
34
|
*/
|
|
35
35
|
setErrorPinned(pinned: boolean): void;
|
|
36
|
+
/**
|
|
37
|
+
* Expand or collapse the inline turn-ending error block so Ctrl+O
|
|
38
|
+
* (tool-output expansion) can reveal a long provider error's hidden tail.
|
|
39
|
+
* Only re-renders when the current message carries a truncatable error, so
|
|
40
|
+
* toggling expansion across the transcript skips ordinary turns. Works even
|
|
41
|
+
* while the error is pinned in the banner: the inline block is drawn (in full)
|
|
42
|
+
* when expanded so the complete body is reachable without sending a message.
|
|
43
|
+
*/
|
|
44
|
+
setExpanded(expanded: boolean): void;
|
|
36
45
|
isTranscriptBlockFinalized(): boolean;
|
|
37
46
|
/**
|
|
38
47
|
* Settled leading rows for mid-stream native-scrollback commits (see
|
|
@@ -26,15 +26,21 @@ export declare const SPACE_HOLD_RELEASE_MS = 250;
|
|
|
26
26
|
* read directly via `pbpaste`/PowerShell).
|
|
27
27
|
*/
|
|
28
28
|
export declare function extractPastePathsFromText(text: string): string[] | undefined;
|
|
29
|
-
export declare function extractBracketedPastePaths(data: string): string[] | undefined;
|
|
30
|
-
export declare function extractBracketedImagePastePaths(data: string): string[] | undefined;
|
|
31
29
|
/**
|
|
32
30
|
* Same shape as {@link extractBracketedImagePastePaths} but operates on a
|
|
33
31
|
* payload that has already been stripped of the `\x1b[200~` / `\x1b[201~`
|
|
34
32
|
* markers — used by the assembled-paste router in {@link CustomEditor.handleInput}
|
|
35
33
|
* so split bracketed pastes get the same image-path detection as single-chunk ones.
|
|
34
|
+
*
|
|
35
|
+
* When the segment splitter fails (an unescaped space in a real path breaks
|
|
36
|
+
* its every-segment-is-a-path invariant), falls back to
|
|
37
|
+
* {@link extractWholeTextImagePath}, so a dropped macOS screenshot
|
|
38
|
+
* (`Screenshot 2026-06-25 at 1.23.45 PM.png`) attaches as an image instead of
|
|
39
|
+
* degrading to literal text (#6578).
|
|
36
40
|
*/
|
|
37
41
|
export declare function extractImagePastePathsFromText(text: string): string[] | undefined;
|
|
42
|
+
export declare function extractBracketedPastePaths(data: string): string[] | undefined;
|
|
43
|
+
export declare function extractBracketedImagePastePaths(data: string): string[] | undefined;
|
|
38
44
|
export declare function extractBracketedImagePastePath(data: string): string | undefined;
|
|
39
45
|
/**
|
|
40
46
|
* Return a single image file path when `text` is exactly one explicit path
|
|
@@ -52,12 +58,10 @@ export declare function extractBracketedImagePastePath(data: string): string | u
|
|
|
52
58
|
* ambiguous multi-path clipboard text like `/tmp/a.png /tmp/b.png`
|
|
53
59
|
* still falls through to the text fallback instead of being mis-loaded
|
|
54
60
|
* as one giant path).
|
|
55
|
-
* 2.
|
|
56
|
-
* (every segment must look like an explicit path; an unescaped
|
|
57
|
-
* a real path breaks that).
|
|
58
|
-
*
|
|
59
|
-
* fragment ("see /tmp/x.png") never hijacks the smart fallback. This
|
|
60
|
-
* is what recovers macOS screenshot filenames like
|
|
61
|
+
* 2. {@link extractWholeTextImagePath} — only reached when the splitter
|
|
62
|
+
* failed (every segment must look like an explicit path; an unescaped
|
|
63
|
+
* space in a real path breaks that). This is what recovers macOS
|
|
64
|
+
* screenshot filenames like
|
|
61
65
|
* `/Users/me/Desktop/Screenshot 2026-06-25 at 1.23.45 PM.png`.
|
|
62
66
|
*/
|
|
63
67
|
export declare function extractImagePathFromText(text: string): string | undefined;
|
|
@@ -63,6 +63,7 @@ export interface ResolvedApprovedPlan {
|
|
|
63
63
|
}
|
|
64
64
|
/** Locate the plan file the agent wrote and finalize its title — without
|
|
65
65
|
* renaming anything. Tries, in order: the slug derived from `extra.title`
|
|
66
|
-
* (`local://<slug>-plan.md`),
|
|
67
|
-
*
|
|
66
|
+
* (`local://<slug>-plan.md`), a state plan that the artifact scan can't see,
|
|
67
|
+
* scanned plan files newest-to-oldest, then the state plan path as a final
|
|
68
|
+
* fallback. Throws a `ToolError` guiding the agent when none exist. */
|
|
68
69
|
export declare function resolveApprovedPlan(input: ResolveApprovedPlanInput): Promise<ResolvedApprovedPlan>;
|
|
@@ -88,28 +88,12 @@ export declare class SecretObfuscator {
|
|
|
88
88
|
#private;
|
|
89
89
|
constructor(entries: SecretEntry[], key?: string);
|
|
90
90
|
hasSecrets(): boolean;
|
|
91
|
-
/** Whether stored-session restoration can resolve keyed or legacy placeholders. */
|
|
92
|
-
hasStoredSecrets(): boolean;
|
|
93
91
|
/** Obfuscate all secrets in text. Bidirectional placeholders for obfuscate mode, one-way for replace. */
|
|
94
92
|
obfuscate(text: string, sharedRegexSecretValues?: ReadonlySet<string>): string;
|
|
95
|
-
/**
|
|
96
|
-
* Deobfuscate keyed placeholders back to original secrets for LIVE paths
|
|
97
|
-
* (provider output, tool-call arguments). Replace-mode is NOT reversed, and
|
|
98
|
-
* legacy index-derived aliases are intentionally ignored so a prompt-injected
|
|
99
|
-
* model cannot synthesize one to recover a secret.
|
|
100
|
-
*/
|
|
93
|
+
/** Deobfuscate keyed placeholders for provider output, tool-call arguments, replay, and display. */
|
|
101
94
|
deobfuscate(text: string): string;
|
|
102
|
-
/**
|
|
103
|
-
* Deobfuscate stored session content for replay/display. Identical to
|
|
104
|
-
* {@link deobfuscate} but additionally honors legacy index-derived aliases so
|
|
105
|
-
* sessions persisted before keyed placeholders still resume correctly. Use
|
|
106
|
-
* only for trusted on-disk session content, never for live model output.
|
|
107
|
-
*/
|
|
108
|
-
deobfuscateStored(text: string): string;
|
|
109
95
|
/** Deep-walk an object, deobfuscating string values for LIVE paths (keyed placeholders only). */
|
|
110
96
|
deobfuscateObject<T>(obj: T): T;
|
|
111
|
-
/** Deep-walk stored session content, deobfuscating string values incl. legacy aliases. */
|
|
112
|
-
deobfuscateStoredObject<T>(obj: T): T;
|
|
113
97
|
/** Deep-walk an object, obfuscating all string values. */
|
|
114
98
|
obfuscateObject<T>(obj: T): T;
|
|
115
99
|
collectRegexSecretValuesForObfuscation(text: string): Set<string>;
|
|
@@ -119,31 +103,23 @@ export declare class SecretObfuscator {
|
|
|
119
103
|
* Restore secret placeholders for local display. Only message kinds the model
|
|
120
104
|
* itself authored from obfuscated context carry placeholders — assistant
|
|
121
105
|
* content and the LLM-written branch/compaction summaries. User, developer, and
|
|
122
|
-
* tool-result messages are persisted with their literal text, so
|
|
123
|
-
*
|
|
124
|
-
* walked.
|
|
125
|
-
*
|
|
126
|
-
* Legacy index-derived aliases (`#XXXX#`) are unkeyed and trivially guessable,
|
|
127
|
-
* so a prompt-injected model can plant one in any record it influences. Every
|
|
128
|
-
* agent-feeding path (resume, history rewrite, branch switch) therefore restores
|
|
129
|
-
* keyed placeholders ONLY (`allowLegacyAliases` false), leaving legacy tokens
|
|
130
|
-
* inert; display-only transcripts that are never re-obfuscated opt in via
|
|
131
|
-
* `allowLegacyAliases`.
|
|
106
|
+
* tool-result messages are persisted with their literal text, so operator-authored
|
|
107
|
+
* placeholder-shaped text must survive untouched; those roles are never walked.
|
|
132
108
|
*/
|
|
133
|
-
export declare function deobfuscateSessionContext(sessionContext: SessionContext, obfuscator: SecretObfuscator | undefined
|
|
134
|
-
export declare function deobfuscateAgentMessages(obfuscator: SecretObfuscator, messages: AgentMessage[]
|
|
109
|
+
export declare function deobfuscateSessionContext(sessionContext: SessionContext, obfuscator: SecretObfuscator | undefined): SessionContext;
|
|
110
|
+
export declare function deobfuscateAgentMessages(obfuscator: SecretObfuscator, messages: AgentMessage[]): AgentMessage[];
|
|
135
111
|
/**
|
|
136
112
|
* Restore placeholders in assistant content: visible text and tool-call
|
|
137
113
|
* arguments/intent/rawBlock. Thinking and signatures are opaque
|
|
138
114
|
* provider-replay/hidden-reasoning data and pass through byte-identical.
|
|
139
115
|
*/
|
|
140
|
-
export declare function deobfuscateAssistantContent(obfuscator: SecretObfuscator, content: AssistantMessage["content"]
|
|
116
|
+
export declare function deobfuscateAssistantContent(obfuscator: SecretObfuscator, content: AssistantMessage["content"]): AssistantMessage["content"];
|
|
141
117
|
/**
|
|
142
118
|
* Restore placeholders inside a tool call's arguments. Arguments are arbitrary
|
|
143
119
|
* model-authored JSON, so tool-call arguments are the ONLY place a recursive
|
|
144
120
|
* JSON walk runs.
|
|
145
121
|
*/
|
|
146
|
-
export declare function deobfuscateToolArguments(obfuscator: SecretObfuscator, args: Record<string, unknown
|
|
122
|
+
export declare function deobfuscateToolArguments(obfuscator: SecretObfuscator, args: Record<string, unknown>): Record<string, unknown>;
|
|
147
123
|
/** Redact secrets inside a tool call's arguments (same JSON-walk exception as {@link deobfuscateToolArguments}). */
|
|
148
124
|
export declare function obfuscateToolArguments(obfuscator: SecretObfuscator, args: Record<string, unknown>, sharedRegexSecretValues?: ReadonlySet<string>): Record<string, unknown>;
|
|
149
125
|
/**
|