@oh-my-pi/pi-coding-agent 17.1.8 → 17.2.0
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 +92 -0
- package/dist/{CHANGELOG-vt8ene9g.md → CHANGELOG-be1f2t8h.md} +92 -0
- package/dist/cli.js +9986 -9776
- package/dist/{template-dys3vk5b.js → template-8vdv6xb4.js} +1 -1
- package/dist/types/advisor/runtime.d.ts +8 -2
- package/dist/types/advisor/transcript-recorder.d.ts +15 -0
- package/dist/types/auto-thinking/classifier.d.ts +9 -2
- package/dist/types/cli/args.d.ts +2 -0
- package/dist/types/cli/session-picker.d.ts +14 -7
- package/dist/types/collab/guest.d.ts +21 -2
- package/dist/types/commands/launch.d.ts +6 -0
- package/dist/types/config/settings-schema.d.ts +63 -8
- package/dist/types/cursor-bridge-tools.d.ts +54 -0
- package/dist/types/cursor.d.ts +193 -8
- package/dist/types/edit/edit-clipboard.d.ts +19 -0
- package/dist/types/edit/hashline/diff.d.ts +9 -1
- package/dist/types/edit/index.d.ts +8 -1
- package/dist/types/edit/streaming.d.ts +8 -1
- package/dist/types/extensibility/extensions/runner.d.ts +19 -2
- package/dist/types/extensibility/extensions/types.d.ts +25 -1
- package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +2 -0
- package/dist/types/internal-urls/local-protocol.d.ts +3 -2
- package/dist/types/launch/terminal-output-worker-client.d.ts +5 -0
- package/dist/types/launch/terminal-output-worker-protocol.d.ts +14 -0
- package/dist/types/launch/terminal-output-worker.d.ts +1 -0
- package/dist/types/lsp/client.d.ts +2 -0
- package/dist/types/main.d.ts +2 -0
- package/dist/types/mcp/manager.d.ts +33 -4
- package/dist/types/modes/components/codex-reset-fireworks.d.ts +51 -0
- package/dist/types/modes/components/read-tool-group.d.ts +12 -0
- package/dist/types/modes/components/session-selector.d.ts +6 -0
- package/dist/types/modes/components/status-line/component.d.ts +23 -0
- package/dist/types/modes/components/tool-execution.d.ts +16 -7
- package/dist/types/modes/components/usage-row.d.ts +2 -0
- package/dist/types/modes/controllers/mcp-command-controller.d.ts +26 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +2 -1
- package/dist/types/modes/interactive-mode.d.ts +4 -2
- package/dist/types/modes/rpc/rpc-client.d.ts +7 -0
- package/dist/types/modes/rpc/rpc-types.d.ts +16 -0
- package/dist/types/modes/theme/theme.d.ts +12 -1
- package/dist/types/modes/types.d.ts +2 -1
- package/dist/types/sdk.d.ts +1 -0
- package/dist/types/session/agent-session-events.d.ts +2 -0
- package/dist/types/session/agent-session-types.d.ts +36 -1
- package/dist/types/session/agent-session.d.ts +4 -2
- package/dist/types/session/claude-session-store.d.ts +13 -0
- package/dist/types/session/codex-session-store.d.ts +14 -0
- package/dist/types/session/credential-pin.d.ts +58 -0
- package/dist/types/session/foreign-session-import.d.ts +15 -0
- package/dist/types/session/foreign-session-jsonl.d.ts +9 -0
- package/dist/types/session/foreign-session-store.d.ts +23 -0
- package/dist/types/session/session-advisors.d.ts +47 -2
- package/dist/types/session/session-entries.d.ts +19 -1
- package/dist/types/session/session-handoff.d.ts +4 -1
- package/dist/types/session/session-loader.d.ts +2 -0
- package/dist/types/session/session-maintenance.d.ts +1 -1
- package/dist/types/session/session-manager.d.ts +21 -0
- package/dist/types/session/session-tools.d.ts +25 -1
- package/dist/types/session/turn-recovery.d.ts +10 -4
- package/dist/types/system-prompt.d.ts +2 -1
- package/dist/types/task/executor.d.ts +11 -2
- package/dist/types/task/render.d.ts +7 -0
- package/dist/types/thinking.d.ts +18 -6
- package/dist/types/tools/acp-bridge.d.ts +28 -5
- package/dist/types/tools/grep.d.ts +17 -1
- package/dist/types/tools/hub/launch.d.ts +5 -1
- package/dist/types/tools/index.d.ts +4 -1
- package/dist/types/tools/path-utils.d.ts +19 -0
- package/dist/types/tools/read.d.ts +2 -0
- package/dist/types/tools/xdev.d.ts +2 -1
- package/dist/types/utils/changelog.d.ts +19 -0
- package/dist/types/utils/git.d.ts +10 -0
- package/dist/types/utils/jj.d.ts +11 -4
- package/dist/types/web/search/types.d.ts +2 -2
- package/package.json +12 -12
- package/src/advisor/runtime.ts +138 -12
- package/src/advisor/transcript-recorder.ts +56 -0
- package/src/auto-thinking/classifier.ts +48 -10
- package/src/cli/args.ts +6 -0
- package/src/cli/flag-tables.ts +2 -0
- package/src/cli/gallery-fixtures/fs.ts +25 -0
- package/src/cli/session-picker.ts +34 -17
- package/src/cli/ttsr-cli.ts +19 -1
- package/src/cli.ts +9 -0
- package/src/collab/guest.ts +37 -4
- package/src/collab/host.ts +1 -0
- package/src/commands/launch.ts +6 -0
- package/src/config/model-registry.ts +103 -25
- package/src/config/settings-schema.ts +65 -6
- package/src/config/settings.ts +25 -0
- package/src/cursor-bridge-tools.ts +81 -0
- package/src/cursor.ts +463 -12
- package/src/edit/edit-clipboard.ts +23 -0
- package/src/edit/hashline/diff.ts +49 -10
- package/src/edit/hashline/execute.ts +38 -6
- package/src/edit/hashline/filesystem.ts +27 -3
- package/src/edit/index.ts +12 -2
- package/src/edit/renderer.ts +4 -4
- package/src/edit/streaming.ts +17 -2
- package/src/export/html/template.js +1 -1
- package/src/extensibility/extensions/runner.ts +70 -0
- package/src/extensibility/extensions/types.ts +30 -0
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +12 -13
- package/src/internal-urls/local-protocol.ts +3 -2
- package/src/internal-urls/mcp-protocol.ts +4 -1
- package/src/launch/terminal-output-worker-client.ts +53 -0
- package/src/launch/terminal-output-worker-protocol.ts +11 -0
- package/src/launch/terminal-output-worker.ts +23 -0
- package/src/lsp/client.ts +18 -3
- package/src/lsp/index.ts +4 -0
- package/src/lsp/render.ts +1 -1
- package/src/main.ts +127 -56
- package/src/mcp/manager.ts +120 -18
- package/src/modes/acp/acp-agent.ts +15 -9
- package/src/modes/components/chat-transcript-builder.ts +30 -11
- package/src/modes/components/codex-reset-fireworks.ts +369 -0
- package/src/modes/components/read-tool-group.ts +159 -17
- package/src/modes/components/session-selector.ts +19 -3
- package/src/modes/components/status-line/component.ts +381 -54
- package/src/modes/components/tool-execution.ts +78 -31
- package/src/modes/components/usage-row.ts +10 -5
- package/src/modes/controllers/event-controller.ts +26 -4
- package/src/modes/controllers/mcp-command-controller.ts +68 -3
- package/src/modes/controllers/selector-controller.ts +94 -36
- package/src/modes/controllers/tan-command-controller.ts +14 -0
- package/src/modes/interactive-mode.ts +31 -17
- package/src/modes/rpc/rpc-client.ts +18 -0
- package/src/modes/rpc/rpc-mode.ts +16 -1
- package/src/modes/rpc/rpc-types.ts +11 -0
- package/src/modes/theme/theme.ts +151 -6
- package/src/modes/types.ts +2 -1
- package/src/modes/utils/ui-helpers.ts +38 -21
- package/src/prompts/system/auto-thinking-difficulty.md +4 -2
- package/src/prompts/system/plan-mode-active.md +2 -2
- package/src/prompts/system/system-prompt.md +3 -0
- package/src/prompts/system/xdev-mount-notice.md +1 -1
- package/src/prompts/tools/bash.md +15 -17
- package/src/prompts/tools/checkpoint.md +1 -1
- package/src/prompts/tools/glob.md +7 -6
- package/src/prompts/tools/grep.md +7 -6
- package/src/sdk.ts +178 -15
- package/src/session/agent-session-events.ts +1 -0
- package/src/session/agent-session-types.ts +40 -1
- package/src/session/agent-session.ts +302 -175
- package/src/session/claude-session-store.ts +426 -0
- package/src/session/codex-session-store.ts +673 -0
- package/src/session/credential-pin.ts +93 -0
- package/src/session/foreign-session-import.ts +52 -0
- package/src/session/foreign-session-jsonl.ts +29 -0
- package/src/session/foreign-session-store.ts +26 -0
- package/src/session/model-controls.ts +11 -3
- package/src/session/session-advisors.ts +140 -16
- package/src/session/session-entries.ts +21 -1
- package/src/session/session-handoff.ts +20 -3
- package/src/session/session-loader.ts +25 -9
- package/src/session/session-maintenance.ts +59 -11
- package/src/session/session-manager.ts +61 -0
- package/src/session/session-tools.ts +107 -5
- package/src/session/settings-stream-fn.ts +1 -0
- package/src/session/turn-recovery.ts +97 -51
- package/src/slash-commands/builtin-registry.ts +131 -3
- package/src/system-prompt.ts +3 -2
- package/src/task/executor.ts +17 -4
- package/src/task/render.ts +20 -4
- package/src/thinking.ts +29 -10
- package/src/tools/acp-bridge.ts +52 -8
- package/src/tools/browser.ts +5 -0
- package/src/tools/checkpoint.ts +0 -13
- package/src/tools/grep.ts +64 -8
- package/src/tools/hub/launch.ts +10 -15
- package/src/tools/index.ts +28 -4
- package/src/tools/path-utils.ts +88 -0
- package/src/tools/read.ts +3 -0
- package/src/tools/write.ts +9 -3
- package/src/tools/xdev.ts +39 -14
- package/src/utils/changelog.ts +144 -4
- package/src/utils/git.ts +61 -14
- package/src/utils/jj.ts +19 -13
- package/src/web/search/providers/codex.ts +34 -0
- package/src/web/search/types.ts +1 -1
|
@@ -395,7 +395,7 @@
|
|
|
395
395
|
}
|
|
396
396
|
|
|
397
397
|
// Apply filter mode
|
|
398
|
-
const isSettingsEntry = ['label', 'custom', 'model_change', 'thinking_level_change', 'mode_change', 'ttsr_injection', 'session_init'].includes(entry.type);
|
|
398
|
+
const isSettingsEntry = ['label', 'custom', 'model_change', 'thinking_level_change', 'mode_change', 'ttsr_injection', 'session_init', 'credential_pin'].includes(entry.type);
|
|
399
399
|
let passesFilter = true;
|
|
400
400
|
|
|
401
401
|
switch (filterMode) {
|
|
@@ -38,7 +38,7 @@ export interface AdvisorRuntimeHost {
|
|
|
38
38
|
* recovery path must never replay the full primary transcript.
|
|
39
39
|
* Optional: hosts that omit it get no proactive maintenance.
|
|
40
40
|
*/
|
|
41
|
-
maintainContext?(incomingTokens: number): Promise<boolean>;
|
|
41
|
+
maintainContext?(incomingTokens: number, signal: AbortSignal): Promise<boolean>;
|
|
42
42
|
/**
|
|
43
43
|
* Called immediately before each `agent.prompt(batch)` cycle. Lets the host
|
|
44
44
|
* clear per-update advisor state — currently the one-advise-per-update gate
|
|
@@ -55,7 +55,7 @@ export interface AdvisorRuntimeHost {
|
|
|
55
55
|
* failed prompt's appended turns before rollback. Errors thrown here are
|
|
56
56
|
* logged and swallowed.
|
|
57
57
|
*/
|
|
58
|
-
onTurnError?(error: unknown, failedMessages: readonly AgentMessage[]): Promise<boolean | undefined> | boolean | undefined;
|
|
58
|
+
onTurnError?(error: unknown, failedMessages: readonly AgentMessage[], signal: AbortSignal): Promise<boolean | undefined> | boolean | undefined;
|
|
59
59
|
/** Called after a successful advisor turn so the host can finish fallback lifecycle reporting. */
|
|
60
60
|
onTurnSuccess?(): Promise<void> | void;
|
|
61
61
|
/** Surface a non-recovering advisor failure to the host UI without adding model-visible context. */
|
|
@@ -64,6 +64,8 @@ export interface AdvisorRuntimeHost {
|
|
|
64
64
|
* recovery (credential switch, fallback chain) declined. Cleared only by
|
|
65
65
|
* an explicit reset (`/new`, config rebuild, session restart). */
|
|
66
66
|
notifyQuotaExhausted?(): void;
|
|
67
|
+
/** Stable identity for the live advisor model. Used to restore full transcript rendering after a model switch. */
|
|
68
|
+
getModelIdentity?(): string;
|
|
67
69
|
}
|
|
68
70
|
/** Signals that an advisor response was discarded before it could become model-visible context. */
|
|
69
71
|
export declare class AdvisorOutputQuarantinedError extends Error {
|
|
@@ -116,6 +118,10 @@ export declare class AdvisorRuntime {
|
|
|
116
118
|
*/
|
|
117
119
|
waitForCatchup(maxMs: number, threshold: number, signal?: AbortSignal): Promise<boolean>;
|
|
118
120
|
dispose(): void;
|
|
121
|
+
/** Stop new advisor work and wait only for the active prompt's recorder-visible events. */
|
|
122
|
+
pauseForSessionTransition(): Promise<void>;
|
|
123
|
+
/** Continue queued work after a session transition rolls back or preserves the conversation. */
|
|
124
|
+
resumeAfterSessionTransition(): void;
|
|
119
125
|
/**
|
|
120
126
|
* Re-prime the advisor after a history rewrite (compaction, session
|
|
121
127
|
* switch/resume, branch). Clears the advisor's own (non-persisted) context
|
|
@@ -14,6 +14,21 @@ export declare const ADVISOR_TRANSCRIPT_FILENAME = "__advisor.jsonl";
|
|
|
14
14
|
export declare function advisorTranscriptFilename(slug: string): string;
|
|
15
15
|
/** Whether a filename is any advisor transcript (`__advisor.jsonl` or `__advisor.<slug>.jsonl`). */
|
|
16
16
|
export declare function isAdvisorTranscriptName(name: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Sum the advisor spend already persisted next to a primary session transcript,
|
|
19
|
+
* keyed by advisor slug.
|
|
20
|
+
*
|
|
21
|
+
* The ledger a session keeps in memory only covers the current process, so a
|
|
22
|
+
* resumed session would report zero until the next advisor turn. The recorded
|
|
23
|
+
* transcripts are the durable copy of exactly the same finalized messages, so
|
|
24
|
+
* they are read back through the shared loader - no lock, no writer, and no
|
|
25
|
+
* second parser to keep in step with the session format.
|
|
26
|
+
*
|
|
27
|
+
* Only the session's own advisors count: subagent advisors write to
|
|
28
|
+
* `<session>/<SubId>/__advisor.jsonl`, and their spend belongs to the subagent,
|
|
29
|
+
* not to this roster. Hence the scan stays at the top level of the directory.
|
|
30
|
+
*/
|
|
31
|
+
export declare function loadAdvisorTranscriptCosts(sessionFile: string | undefined): Promise<Map<string, number>>;
|
|
17
32
|
/**
|
|
18
33
|
* Append-only persister for an advisor agent's transcript.
|
|
19
34
|
*
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* {@link Effort}, clamped into the active model's supported range (never below
|
|
6
6
|
* {@link Effort.Low}). Two backends, selected by `providers.autoThinkingModel`:
|
|
7
7
|
*
|
|
8
|
-
* - `online` (default): a smol model classifies into `low|medium|high|xhigh
|
|
8
|
+
* - `online` (default): a smol model classifies into `low|medium|high|xhigh`,
|
|
9
|
+
* plus `max` when the target model exposes that tier.
|
|
9
10
|
* - a local key: an on-device memory model classifies into the coarser
|
|
10
11
|
* `trivial|moderate|hard` scheme (3-class is more reliable than 4-way ordinal
|
|
11
12
|
* on sub-2B models), mapped to `low|high|xhigh`.
|
|
@@ -31,7 +32,13 @@ export interface ClassifyDifficultyDeps {
|
|
|
31
32
|
* @throws when the backend cannot produce a usable classification.
|
|
32
33
|
*/
|
|
33
34
|
export declare function classifyDifficulty(promptText: string, deps: ClassifyDifficultyDeps): Promise<Effort | undefined>;
|
|
34
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Map an online level keyword to an {@link Effort}; earliest match wins.
|
|
37
|
+
*
|
|
38
|
+
* `max` is only offered to the classifier when the target model exposes that
|
|
39
|
+
* tier, but it is always parsed: an unsupported `max` is snapped back down by
|
|
40
|
+
* {@link clampAutoThinkingEffort} rather than failing the turn.
|
|
41
|
+
*/
|
|
35
42
|
export declare function parseDifficultyLevel(text: string): Effort | undefined;
|
|
36
43
|
/** Map the local 3-way bucket keyword to an {@link Effort}; earliest match wins. */
|
|
37
44
|
export declare function parseDifficultyBucket(text: string): Effort | undefined;
|
package/dist/types/cli/args.d.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import type { SessionInfo } from "../session/session-listing.js";
|
|
2
|
+
/** Presentation and capability controls for the standalone session picker. */
|
|
3
|
+
export interface SessionPickerOptions {
|
|
4
|
+
allSessions?: SessionInfo[];
|
|
5
|
+
title?: string;
|
|
6
|
+
scopeLabel?: string | false;
|
|
7
|
+
showCwd?: boolean;
|
|
8
|
+
allowDelete?: boolean;
|
|
9
|
+
allowGlobalScope?: boolean;
|
|
10
|
+
historySearch?: boolean;
|
|
11
|
+
}
|
|
2
12
|
/**
|
|
3
13
|
* Show the TUI session selector and return the selected session, or null if
|
|
4
|
-
* cancelled.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* is loaded lazily via `SessionManager.listAll`.
|
|
14
|
+
* cancelled. The default OMP picker supports deletion, transcript-history
|
|
15
|
+
* search, and an all-projects scope; foreign import pickers disable those
|
|
16
|
+
* source-owned capabilities.
|
|
8
17
|
*/
|
|
9
|
-
export declare function selectSession(sessions: SessionInfo[], options?:
|
|
10
|
-
allSessions?: SessionInfo[];
|
|
11
|
-
}): Promise<SessionInfo | null>;
|
|
18
|
+
export declare function selectSession(sessions: SessionInfo[], options?: SessionPickerOptions): Promise<SessionInfo | null>;
|
|
@@ -10,6 +10,7 @@ export interface GuestIdleReconcilerCtx {
|
|
|
10
10
|
statusLine: {
|
|
11
11
|
markActivityEnd: () => void;
|
|
12
12
|
};
|
|
13
|
+
statusContainer: Pick<InteractiveModeContext["statusContainer"], "disposeChildren">;
|
|
13
14
|
loadingAnimation: {
|
|
14
15
|
stop: () => void;
|
|
15
16
|
} | undefined;
|
|
@@ -17,8 +18,8 @@ export interface GuestIdleReconcilerCtx {
|
|
|
17
18
|
/**
|
|
18
19
|
* Close the guest UI state held open by an earlier `agent_start` whose
|
|
19
20
|
* matching `agent_end` never reached us — most often because a reconnect
|
|
20
|
-
* dropped the event mid-stream.
|
|
21
|
-
* `state
|
|
21
|
+
* dropped the event mid-stream. Reached via {@link reconcileGuestSnapshotHostState}
|
|
22
|
+
* (the live `state`-frame and welcome/resync reconciler) when the host reports `isStreaming === false`:
|
|
22
23
|
* folds the in-flight active-time window into the per-session meter (so
|
|
23
24
|
* `time_spent` stops ticking) and stops the `Working…` loader if one is
|
|
24
25
|
* still animating. No-op when the host is still streaming.
|
|
@@ -32,7 +33,25 @@ export interface GuestSnapshotActivityReconcilerCtx extends GuestIdleReconcilerC
|
|
|
32
33
|
statusLine: GuestIdleReconcilerCtx["statusLine"] & {
|
|
33
34
|
markActivityStart: () => void;
|
|
34
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* Start (or re-attach) the live "Working…" loader. Mirrors
|
|
38
|
+
* `InteractiveModeContext.ensureLoadingAnimation`, which is what
|
|
39
|
+
* `EventController` calls on `agent_start`. Required so a guest that
|
|
40
|
+
* missed an earlier `agent_start` (a reconnect dropped it mid-stream)
|
|
41
|
+
* starts its spinner when the host later reports it is streaming.
|
|
42
|
+
*/
|
|
43
|
+
ensureLoadingAnimation: InteractiveModeContext["ensureLoadingAnimation"];
|
|
44
|
+
autoCompactionLoader: InteractiveModeContext["autoCompactionLoader"];
|
|
45
|
+
retryLoader: InteractiveModeContext["retryLoader"];
|
|
35
46
|
}
|
|
47
|
+
/** Status-area state which cannot outlive removal of its child components. */
|
|
48
|
+
export interface GuestTransientStatusCtx {
|
|
49
|
+
statusContainer: Pick<InteractiveModeContext["statusContainer"], "clear">;
|
|
50
|
+
autoCompactionLoader: InteractiveModeContext["autoCompactionLoader"];
|
|
51
|
+
retryLoader: InteractiveModeContext["retryLoader"];
|
|
52
|
+
}
|
|
53
|
+
/** Stop and forget status-area loaders before detaching their components. */
|
|
54
|
+
export declare function clearGuestTransientStatus(ctx: GuestTransientStatusCtx): void;
|
|
36
55
|
export declare function reconcileGuestSnapshotHostState(ctx: GuestSnapshotActivityReconcilerCtx, isStreaming: boolean): void;
|
|
37
56
|
export declare class CollabGuestLink {
|
|
38
57
|
#private;
|
|
@@ -88,6 +88,12 @@ export default class Index extends Command {
|
|
|
88
88
|
char: string;
|
|
89
89
|
description: string;
|
|
90
90
|
};
|
|
91
|
+
"from-claude": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
|
|
92
|
+
description: string;
|
|
93
|
+
};
|
|
94
|
+
"from-codex": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
|
|
95
|
+
description: string;
|
|
96
|
+
};
|
|
91
97
|
"session-dir": import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"string"> & {
|
|
92
98
|
description: string;
|
|
93
99
|
};
|
|
@@ -839,6 +839,16 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
839
839
|
readonly description: "Render Mermaid fenced code blocks as ASCII diagrams";
|
|
840
840
|
};
|
|
841
841
|
};
|
|
842
|
+
readonly "tui.codexResetFireworks": {
|
|
843
|
+
readonly type: "boolean";
|
|
844
|
+
readonly default: false;
|
|
845
|
+
readonly ui: {
|
|
846
|
+
readonly tab: "appearance";
|
|
847
|
+
readonly group: "Display";
|
|
848
|
+
readonly label: "Codex Reset Fireworks";
|
|
849
|
+
readonly description: "Celebrate unscheduled Codex weekly usage resets and newly banked saved resets with a top-third fireworks overlay that remains until Escape";
|
|
850
|
+
};
|
|
851
|
+
};
|
|
842
852
|
readonly "tui.titleState": {
|
|
843
853
|
readonly type: "boolean";
|
|
844
854
|
readonly default: true;
|
|
@@ -1796,14 +1806,28 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
1796
1806
|
}];
|
|
1797
1807
|
};
|
|
1798
1808
|
};
|
|
1799
|
-
readonly
|
|
1800
|
-
readonly type: "
|
|
1801
|
-
readonly
|
|
1809
|
+
readonly "startup.changelogMode": {
|
|
1810
|
+
readonly type: "enum";
|
|
1811
|
+
readonly values: readonly ["summary", "expanded", "hidden"];
|
|
1812
|
+
readonly default: "summary";
|
|
1802
1813
|
readonly ui: {
|
|
1803
1814
|
readonly tab: "interaction";
|
|
1804
1815
|
readonly group: "Startup & Updates";
|
|
1805
|
-
readonly label: "
|
|
1806
|
-
readonly description: "
|
|
1816
|
+
readonly label: "Startup Changelog";
|
|
1817
|
+
readonly description: "Choose whether update notes start as a summary, full details, or stay hidden";
|
|
1818
|
+
readonly options: readonly [{
|
|
1819
|
+
readonly value: "summary";
|
|
1820
|
+
readonly label: "Summary";
|
|
1821
|
+
readonly description: "Show release and change counts with a /changelog hint";
|
|
1822
|
+
}, {
|
|
1823
|
+
readonly value: "expanded";
|
|
1824
|
+
readonly label: "Expanded";
|
|
1825
|
+
readonly description: "Show the recent release notes in full";
|
|
1826
|
+
}, {
|
|
1827
|
+
readonly value: "hidden";
|
|
1828
|
+
readonly label: "Hidden";
|
|
1829
|
+
readonly description: "Do not show release notes on startup";
|
|
1830
|
+
}];
|
|
1807
1831
|
};
|
|
1808
1832
|
};
|
|
1809
1833
|
readonly "magicKeywords.enabled": {
|
|
@@ -4147,6 +4171,16 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
4147
4171
|
readonly description: "Enable the browser tool for scripted Chromium automation (puppeteer)";
|
|
4148
4172
|
};
|
|
4149
4173
|
};
|
|
4174
|
+
readonly "browser.cdpUrl": {
|
|
4175
|
+
readonly type: "string";
|
|
4176
|
+
readonly default: undefined;
|
|
4177
|
+
readonly ui: {
|
|
4178
|
+
readonly tab: "tools";
|
|
4179
|
+
readonly group: "Grep & Browser";
|
|
4180
|
+
readonly label: "Browser CDP URL";
|
|
4181
|
+
readonly description: "Default HTTP CDP discovery endpoint (for example http://127.0.0.1:9222) to attach to instead of launching a browser. Explicit app.cdp_url or app.path on the tool call take precedence.";
|
|
4182
|
+
};
|
|
4183
|
+
};
|
|
4150
4184
|
readonly "browser.headless": {
|
|
4151
4185
|
readonly type: "boolean";
|
|
4152
4186
|
readonly default: true;
|
|
@@ -4717,7 +4751,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
4717
4751
|
readonly tab: "tasks";
|
|
4718
4752
|
readonly group: "Subagents";
|
|
4719
4753
|
readonly label: "Soft Subagent Request Budget";
|
|
4720
|
-
readonly description: "Soft per-subagent request budget (assistant requests per run). Crossing it injects a wrap-up steering notice (see task.softRequestBudgetNotice); at 1.5x the budget the run is force-stopped and the agent must yield its partial findings. 0 disables the guard. Bundled scout/sonic agents
|
|
4754
|
+
readonly description: "Soft per-subagent request budget (assistant requests per run). Crossing it injects a wrap-up steering notice (see task.softRequestBudgetNotice); at 1.5x the budget the run is force-stopped and the agent must yield its partial findings. 0 disables the guard. Bundled scout/sonic agents cap out at a lower built-in budget, so a value below that cap still applies to them.";
|
|
4721
4755
|
readonly options: readonly [{
|
|
4722
4756
|
readonly value: "0";
|
|
4723
4757
|
readonly label: "Disabled";
|
|
@@ -4970,7 +5004,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
4970
5004
|
} | {
|
|
4971
5005
|
readonly value: "exa";
|
|
4972
5006
|
readonly label: "Exa";
|
|
4973
|
-
readonly description: "
|
|
5007
|
+
readonly description: "API via /login exa or EXA_API_KEY; explicit keyless fallback via MCP";
|
|
4974
5008
|
} | {
|
|
4975
5009
|
readonly value: "tinyfish";
|
|
4976
5010
|
readonly label: "TinyFish";
|
|
@@ -5074,7 +5108,7 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
5074
5108
|
} | {
|
|
5075
5109
|
readonly value: "exa";
|
|
5076
5110
|
readonly label: "Exa";
|
|
5077
|
-
readonly description: "
|
|
5111
|
+
readonly description: "API via /login exa or EXA_API_KEY; explicit keyless fallback via MCP";
|
|
5078
5112
|
} | {
|
|
5079
5113
|
readonly value: "tinyfish";
|
|
5080
5114
|
readonly label: "TinyFish";
|
|
@@ -5580,6 +5614,27 @@ export declare const SETTINGS_SCHEMA: {
|
|
|
5580
5614
|
})[];
|
|
5581
5615
|
};
|
|
5582
5616
|
};
|
|
5617
|
+
readonly "providers.autoThinkingMaxEffort": {
|
|
5618
|
+
readonly type: "enum";
|
|
5619
|
+
readonly values: readonly ["xhigh", "max"];
|
|
5620
|
+
readonly default: "xhigh";
|
|
5621
|
+
readonly ui: {
|
|
5622
|
+
readonly tab: "model";
|
|
5623
|
+
readonly group: "Thinking";
|
|
5624
|
+
readonly label: "Auto Thinking Ceiling";
|
|
5625
|
+
readonly description: "Highest effort the `auto` classifier may resolve. `xhigh` keeps the classifier one tier below the top, so only an explicit `ultrathink` reaches `max`; `max` lets a turn the classifier judges exceptional bill the top tier on models that expose it.";
|
|
5626
|
+
readonly condition: "autoThinkingActive";
|
|
5627
|
+
readonly options: readonly [{
|
|
5628
|
+
readonly value: "xhigh";
|
|
5629
|
+
readonly label: "xhigh";
|
|
5630
|
+
readonly description: "Classifier stops at xhigh (default)";
|
|
5631
|
+
}, {
|
|
5632
|
+
readonly value: "max";
|
|
5633
|
+
readonly label: "max";
|
|
5634
|
+
readonly description: "Classifier may resolve max where the model supports it";
|
|
5635
|
+
}];
|
|
5636
|
+
};
|
|
5637
|
+
};
|
|
5583
5638
|
readonly "features.unexpectedStopDetection": {
|
|
5584
5639
|
readonly type: "boolean";
|
|
5585
5640
|
readonly default: false;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-call tools the Cursor exec bridge needs but the model-facing registry
|
|
3
|
+
* cannot supply.
|
|
4
|
+
*
|
|
5
|
+
* Both bridge callsites — the primary session and the advisor roster — build
|
|
6
|
+
* the same instances, and both must apply the session's approval wrapper. A
|
|
7
|
+
* raw tool here silently escapes the gate every registry call goes through, so
|
|
8
|
+
* the construction lives in one place rather than being repeated per callsite.
|
|
9
|
+
*/
|
|
10
|
+
import type { AgentTool } from "@oh-my-pi/pi-agent-core";
|
|
11
|
+
import type { ExtensionRunner } from "./extensibility/extensions/index.js";
|
|
12
|
+
import type { GrepToolOptions, ToolSession } from "./tools/index.js";
|
|
13
|
+
/**
|
|
14
|
+
* Build the bridge's `createGrepTool` factory for one tool session.
|
|
15
|
+
*
|
|
16
|
+
* A `pi_grep` frame carries its own context width and total match cap. Neither
|
|
17
|
+
* is expressible in the model-facing `grep` schema — context comes from
|
|
18
|
+
* `grep.contextBefore`/`grep.contextAfter`, fixed when the shared instance is
|
|
19
|
+
* constructed — so honoring them needs a fresh tool per call.
|
|
20
|
+
*
|
|
21
|
+
* The result is wrapped exactly like a registry tool: the approval gate runs on
|
|
22
|
+
* every call site, and a per-call instance is no exception.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createBridgeGrepFactory(session: ToolSession, extensionRunner: ExtensionRunner): (options: GrepToolOptions) => AgentTool;
|
|
25
|
+
/**
|
|
26
|
+
* Build the `replace`-mode `edit` the bridge answers `pi_edit` with.
|
|
27
|
+
*
|
|
28
|
+
* `PiEditExecArgs` carries `old_text`/`new_text` pairs, which is exactly
|
|
29
|
+
* `replace`'s schema and nothing else's. The session's own instance follows the
|
|
30
|
+
* configured `edit.mode` — `hashline` by default, whose schema is a single
|
|
31
|
+
* `input` string — so a frame handed that instance fails validation instead of
|
|
32
|
+
* editing the file.
|
|
33
|
+
*
|
|
34
|
+
* Callers MUST gate this on the session having actually granted `edit`: the
|
|
35
|
+
* tool is constructed rather than looked up, so building one unconditionally
|
|
36
|
+
* hands a restricted agent a mutating tool it was denied (issue #5680).
|
|
37
|
+
*/
|
|
38
|
+
export declare function createBridgeEditTool(session: ToolSession, extensionRunner: ExtensionRunner): AgentTool;
|
|
39
|
+
/**
|
|
40
|
+
* The tool map the exec bridge should run, given the map a caller granted.
|
|
41
|
+
*
|
|
42
|
+
* `pi_edit` needs a `replace`-mode instance, but only when `edit` was granted:
|
|
43
|
+
* the tool is constructed rather than looked up, so substituting
|
|
44
|
+
* unconditionally would hand a restricted roster a mutating tool it was denied
|
|
45
|
+
* (issue #5680). The granted map is never mutated: an unsubstituted result is a
|
|
46
|
+
* copy, so a caller without an `edit` grant cannot accidentally gain one.
|
|
47
|
+
*
|
|
48
|
+
* The advisor roster passes its granted map here; the primary session keeps its
|
|
49
|
+
* instance out of the registry entirely (Cursor does not advertise `edit`) and
|
|
50
|
+
* serves it through the bridge's `getEditReplaceTool` accessor instead — not
|
|
51
|
+
* the `getTool` fallback, which doubles as the agent loop's resolver for
|
|
52
|
+
* unadvertised calls and must stay device-only.
|
|
53
|
+
*/
|
|
54
|
+
export declare function bridgeToolMap(granted: ReadonlyMap<string, AgentTool>, createEditTool: (() => AgentTool | undefined) | undefined): Map<string, AgentTool>;
|
package/dist/types/cursor.d.ts
CHANGED
|
@@ -1,23 +1,69 @@
|
|
|
1
1
|
import type { AgentEvent, AgentTool, AgentToolContext } from "@oh-my-pi/pi-agent-core";
|
|
2
|
-
import type { CursorMcpCall, CursorShellStreamCallbacks, CursorTodoSnapshot, CursorExecHandlers as ICursorExecHandlers, ToolResultMessage } from "@oh-my-pi/pi-ai";
|
|
2
|
+
import type { CursorMcpCall, CursorMcpResource, CursorMcpResourceContent, CursorShellStreamCallbacks, CursorTodoSnapshot, CursorExecHandlers as ICursorExecHandlers, ToolResultMessage } from "@oh-my-pi/pi-ai";
|
|
3
|
+
import type { MCPResourceReadResult } from "./mcp/types.js";
|
|
3
4
|
import type { TodoPhase } from "./tools/todo.js";
|
|
5
|
+
/**
|
|
6
|
+
* A tool instance the bridge can run, matching the erased shape the session's
|
|
7
|
+
* tool registry stores. The concrete tools have narrower `execute` parameter
|
|
8
|
+
* types than the default `AgentTool`, which only unify through this alias.
|
|
9
|
+
*/
|
|
10
|
+
type CursorBridgeTool = AgentTool<any, any, any>;
|
|
11
|
+
/**
|
|
12
|
+
* The live MCP connections Cursor's resource frames are answered from.
|
|
13
|
+
*
|
|
14
|
+
* Named so every construction site can hand over the same adapter; a session
|
|
15
|
+
* and its advisors share one set of connections.
|
|
16
|
+
*/
|
|
17
|
+
export interface CursorMcpResourceAdapter {
|
|
18
|
+
serverNames(): string[];
|
|
19
|
+
getServerResources(name: string): Promise<{
|
|
20
|
+
resources: {
|
|
21
|
+
uri: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
mimeType?: string;
|
|
25
|
+
}[];
|
|
26
|
+
} | undefined>;
|
|
27
|
+
readServerResource(name: string, uri: string): Promise<MCPResourceReadResult | undefined>;
|
|
28
|
+
}
|
|
4
29
|
interface CursorExecBridgeOptions {
|
|
5
30
|
cwd: string;
|
|
6
31
|
getCwd?: () => string;
|
|
7
32
|
tools: Map<string, AgentTool>;
|
|
8
33
|
/** Resolves execution overrides (mounted-device permission wrappers) before the canonical map. */
|
|
9
34
|
getExecutableTool?: (name: string) => AgentTool | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* The `replace`-mode `edit` instance `pi_edit` must run, when the session
|
|
37
|
+
* granted `edit` at all.
|
|
38
|
+
*
|
|
39
|
+
* `PiEditExecArgs` is that mode's schema verbatim, and the session's own
|
|
40
|
+
* `edit` may be in any mode — `hashline` by default — whose schema rejects
|
|
41
|
+
* `old_text`/`new_text` outright. {@link tools} therefore cannot be trusted
|
|
42
|
+
* for this one frame: a session that starts on another provider keeps its
|
|
43
|
+
* configured instance in the map (only Cursor sessions move `edit` out), and
|
|
44
|
+
* switching to Cursor later does not rebuild the roster.
|
|
45
|
+
*/
|
|
46
|
+
getEditReplaceTool?: () => CursorBridgeTool | undefined;
|
|
10
47
|
getToolContext?: () => AgentToolContext | undefined;
|
|
11
48
|
emitEvent?: (event: AgentEvent) => void;
|
|
12
49
|
/**
|
|
13
|
-
* Whether
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
50
|
+
* Whether frames that mutate the filesystem WITHOUT running a registry tool
|
|
51
|
+
* may do so: the native `delete` frame, and a `read_mcp_resource` carrying
|
|
52
|
+
* `download_path`. Both write or remove workspace files directly instead of
|
|
53
|
+
* consulting {@link tools}, so a background read-only advisor could touch
|
|
54
|
+
* files it was never granted a mutating tool for (issue #5680 review).
|
|
55
|
+
*
|
|
56
|
+
* This is a grant, not a policy: it answers "did the session hand this
|
|
57
|
+
* channel a file-writing tool", which callers derive from their own roster
|
|
58
|
+
* before any bridge-specific rewriting. The primary Cursor session moves
|
|
59
|
+
* `edit` out of {@link tools} and serves it through
|
|
60
|
+
* {@link getEditReplaceTool}, so reading the map here would deny an
|
|
61
|
+
* edit-only session. Defaults to allowed
|
|
62
|
+
* to preserve the primary agent's behavior; callers with a restricted tool
|
|
63
|
+
* set (advisors) opt out. The user's approval policy is resolved separately,
|
|
64
|
+
* per call.
|
|
19
65
|
*/
|
|
20
|
-
|
|
66
|
+
allowDirectFileMutation?: boolean;
|
|
21
67
|
/**
|
|
22
68
|
* Mirror Cursor's server-owned todo list into local session state. Cursor
|
|
23
69
|
* resolves `update_todos` / `read_todos` remotely, so without this bridge
|
|
@@ -30,18 +76,148 @@ interface CursorExecBridgeOptions {
|
|
|
30
76
|
* Cursor emits no local `todo` toolResult, so nothing else records it.
|
|
31
77
|
*/
|
|
32
78
|
persistTodoPhases?: (phases: TodoPhase[]) => void;
|
|
79
|
+
/**
|
|
80
|
+
* Build a `grep` tool honoring a frame's own context width and match cap.
|
|
81
|
+
*
|
|
82
|
+
* The modern `pi_grep` frame carries both, and the shared `grep` instance
|
|
83
|
+
* is fixed to the session settings at construction — so without this the
|
|
84
|
+
* two fields are silently dropped. Callers that cannot supply it keep the
|
|
85
|
+
* shared instance and the session's defaults.
|
|
86
|
+
*
|
|
87
|
+
* The returned tool is executed as-is. Callers whose registry tools carry an
|
|
88
|
+
* approval wrapper MUST apply the same wrapper here, or a frame supplying
|
|
89
|
+
* either field silently escapes the approval gate that every other call
|
|
90
|
+
* goes through.
|
|
91
|
+
*/
|
|
92
|
+
createGrepTool?(options: {
|
|
93
|
+
context?: number;
|
|
94
|
+
totalMatchLimit?: number;
|
|
95
|
+
}): CursorBridgeTool | undefined;
|
|
96
|
+
/**
|
|
97
|
+
* The session's live MCP connections, for Cursor's resource frames.
|
|
98
|
+
*
|
|
99
|
+
* `list_mcp_resources` / `read_mcp_resource` ask what this client's servers
|
|
100
|
+
* advertise. Without this the bridge answers an empty catalog and
|
|
101
|
+
* `not_found`, hiding resources the session is in fact connected to.
|
|
102
|
+
*
|
|
103
|
+
* `getServerResources` is async because a server's catalog loads in the
|
|
104
|
+
* background after its tools register: a frame arriving in that window would
|
|
105
|
+
* otherwise read the not-yet-populated cache and report an empty catalog,
|
|
106
|
+
* which is indistinguishable from a server that advertises nothing.
|
|
107
|
+
*/
|
|
108
|
+
mcpResources?: CursorMcpResourceAdapter;
|
|
33
109
|
}
|
|
34
110
|
export declare class CursorExecHandlers implements ICursorExecHandlers {
|
|
35
111
|
private options;
|
|
36
112
|
constructor(options: CursorExecBridgeOptions);
|
|
113
|
+
/**
|
|
114
|
+
* Modern Cursor builds paginate the legacy `read` frame with
|
|
115
|
+
* `offset`/`limit`, exactly as `pi_read` does. Dropping them returns the
|
|
116
|
+
* whole file (or its own truncation) for every page, so a model walking a
|
|
117
|
+
* large file never advances. Composed with the same helper, so both frames
|
|
118
|
+
* translate a range identically.
|
|
119
|
+
*/
|
|
37
120
|
read(args: Parameters<NonNullable<ICursorExecHandlers["read"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
38
121
|
ls(args: Parameters<NonNullable<ICursorExecHandlers["ls"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
122
|
+
/**
|
|
123
|
+
* Modern Cursor builds paginate this frame with `offset`. The local `grep`
|
|
124
|
+
* paginates by file through `skip`, which is the same unit its own
|
|
125
|
+
* "use skip=N for the next page" advice counts in — so an unforwarded
|
|
126
|
+
* offset re-runs the identical search and returns page one forever.
|
|
127
|
+
*/
|
|
39
128
|
grep(args: Parameters<NonNullable<ICursorExecHandlers["grep"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
40
129
|
write(args: Parameters<NonNullable<ICursorExecHandlers["write"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
41
130
|
delete(args: Parameters<NonNullable<ICursorExecHandlers["delete"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
42
131
|
shell(args: Parameters<NonNullable<ICursorExecHandlers["shell"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
43
132
|
shellStream(args: Parameters<NonNullable<ICursorExecHandlers["shellStream"]>>[0], callbacks: CursorShellStreamCallbacks): Promise<ToolResultMessage<unknown>>;
|
|
44
133
|
diagnostics(args: Parameters<NonNullable<ICursorExecHandlers["diagnostics"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
134
|
+
/**
|
|
135
|
+
* Modern Cursor CLI Pi tool frames (`ExecServerMessage` 45-51).
|
|
136
|
+
*
|
|
137
|
+
* These are a separate frame family from the legacy `read`/`shell`/... set,
|
|
138
|
+
* not aliases: different args, different result oneofs, and no `tool_call_id`
|
|
139
|
+
* (the provider mints one and passes it in `call.toolCallId`). Each maps onto
|
|
140
|
+
* the local tool with matching semantics, so the same approval, sandboxing
|
|
141
|
+
* and event plumbing applies as for a model-issued call.
|
|
142
|
+
*/
|
|
143
|
+
/**
|
|
144
|
+
* `offset`/`limit` are a 1-indexed start line plus a line count (verified
|
|
145
|
+
* against the reference `LocalPiReadExecutor`), which is exactly the local
|
|
146
|
+
* `read` tool's `:N+K` inline selector — the tool takes no range kwargs, so
|
|
147
|
+
* the range has to be composed onto the path or ranged reads silently
|
|
148
|
+
* return the whole file.
|
|
149
|
+
*/
|
|
150
|
+
piRead(call: Parameters<NonNullable<ICursorExecHandlers["piRead"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
151
|
+
piBash(call: Parameters<NonNullable<ICursorExecHandlers["piBash"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
152
|
+
/**
|
|
153
|
+
* `PiEditExecArgs` is the local `edit` tool's replace mode verbatim: a path
|
|
154
|
+
* plus `old_text`/`new_text` pairs. The tool's schema is snake_case, so the
|
|
155
|
+
* proto's camelCase accessors are mapped back on the way in.
|
|
156
|
+
*
|
|
157
|
+
* The replace-mode instance is requested explicitly rather than resolved
|
|
158
|
+
* from {@link CursorExecBridgeOptions.tools}: the registry's `edit` is in
|
|
159
|
+
* the session's configured mode, whose schema rejects these arguments.
|
|
160
|
+
*/
|
|
161
|
+
piEdit(call: Parameters<NonNullable<ICursorExecHandlers["piEdit"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
162
|
+
piWrite(call: Parameters<NonNullable<ICursorExecHandlers["piWrite"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
163
|
+
/**
|
|
164
|
+
* `literal` makes the pattern a fixed string; the local tool is regex-only,
|
|
165
|
+
* so the pattern is escaped on the way in (same translation the legacy pi
|
|
166
|
+
* shim does).
|
|
167
|
+
*
|
|
168
|
+
* `context` and `limit` are not expressible in the model-facing schema —
|
|
169
|
+
* context width comes from settings fixed at tool construction — so the
|
|
170
|
+
* frame's values are honored by building a per-call `grep` through
|
|
171
|
+
* {@link CursorExecBridgeOptions.createGrepTool}. Both are `optional int32`,
|
|
172
|
+
* so a present `0` context means "no context lines", not "use the default".
|
|
173
|
+
* Without the factory the shared instance runs with session defaults.
|
|
174
|
+
*/
|
|
175
|
+
piGrep(call: Parameters<NonNullable<ICursorExecHandlers["piGrep"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
176
|
+
/**
|
|
177
|
+
* `pi_find` is a filename search, which is the local `glob` tool — not
|
|
178
|
+
* `grep`. Its `pattern` is a glob, joined onto `path` because `glob` takes a
|
|
179
|
+
* single combined path spec.
|
|
180
|
+
*
|
|
181
|
+
* `limit` is `optional int32`, so `0` is present rather than unset; the
|
|
182
|
+
* reference clamps it with `Math.max(1, limit ?? 1000)`, and an unset limit
|
|
183
|
+
* leaves the local tool's own default in place.
|
|
184
|
+
*/
|
|
185
|
+
piFind(call: Parameters<NonNullable<ICursorExecHandlers["piFind"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
186
|
+
/**
|
|
187
|
+
* Redirected to `read`, which lists directories — same as the legacy `ls`.
|
|
188
|
+
* The frame's entry `limit` is not mapped; see {@link piLsPath}.
|
|
189
|
+
*/
|
|
190
|
+
piLs(call: Parameters<NonNullable<ICursorExecHandlers["piLs"]>>[0]): Promise<ToolResultMessage<unknown>>;
|
|
191
|
+
/**
|
|
192
|
+
* The resources this client's MCP servers advertise.
|
|
193
|
+
*
|
|
194
|
+
* Cursor addresses a later read by `server`, so every entry carries the name
|
|
195
|
+
* it came from. An absent `server` filter means "all of them".
|
|
196
|
+
*/
|
|
197
|
+
listMcpResources({ server }: {
|
|
198
|
+
server?: string;
|
|
199
|
+
}): Promise<CursorMcpResource[]>;
|
|
200
|
+
/**
|
|
201
|
+
* Read one resource, or `null` when the server or uri is unknown.
|
|
202
|
+
*
|
|
203
|
+
* MCP returns a list of content items; the wire carries exactly one text or
|
|
204
|
+
* blob. Text items are joined, since a multi-part text resource is one
|
|
205
|
+
* document; otherwise the first blob stands in. `blob` arrives base64 and
|
|
206
|
+
* the wire wants bytes.
|
|
207
|
+
*
|
|
208
|
+
* A `downloadPath` frame is a different contract: write the bytes to that
|
|
209
|
+
* workspace-relative path and answer with the path alone, so a large binary
|
|
210
|
+
* lands on disk instead of in the model's context. That makes it a workspace
|
|
211
|
+
* mutation reached without a registry tool, so it is gated exactly like the
|
|
212
|
+
* native `delete` frame — on the session actually granting a file-writing
|
|
213
|
+
* tool, and on the user's `write`-tier policy. The gate runs before the read
|
|
214
|
+
* so a refused download never fetches the resource either.
|
|
215
|
+
*/
|
|
216
|
+
readMcpResource({ server, uri, downloadPath, }: {
|
|
217
|
+
server: string;
|
|
218
|
+
uri: string;
|
|
219
|
+
downloadPath?: string;
|
|
220
|
+
}): Promise<CursorMcpResourceContent | null>;
|
|
45
221
|
/**
|
|
46
222
|
* Settle a completed native Cursor todo call, mirroring its list when the
|
|
47
223
|
* server supplied an authoritative one.
|
|
@@ -76,5 +252,14 @@ export declare class CursorExecHandlers implements ICursorExecHandlers {
|
|
|
76
252
|
*/
|
|
77
253
|
todoSync(snapshot: CursorTodoSnapshot | null, toolCallId: string, error?: string | null): ToolResultMessage;
|
|
78
254
|
mcp(call: CursorMcpCall): Promise<ToolResultMessage<unknown>>;
|
|
255
|
+
/**
|
|
256
|
+
* Resolve an MCP call's approval without running it.
|
|
257
|
+
*
|
|
258
|
+
* Same resolution the wrapper applies at execution time, minus the
|
|
259
|
+
* execution: an unknown tool is not approvable, and a `prompt` is not an
|
|
260
|
+
* approval — the frame has no way to carry an interactive question, and the
|
|
261
|
+
* user is asked for real when the call itself arrives.
|
|
262
|
+
*/
|
|
263
|
+
mcpApprovalPreflight(call: CursorMcpCall): Promise<boolean>;
|
|
79
264
|
}
|
|
80
265
|
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-bound edit clipboard register.
|
|
3
|
+
*
|
|
4
|
+
* `CUT`/`PASTE` hashline ops share one {@link Clipboard} per session so
|
|
5
|
+
* content captured by one edit call can be pasted by a later one (and across
|
|
6
|
+
* files within one call). The executor works on a fork per batch and commits
|
|
7
|
+
* it back only after every write lands — see `executeHashlineSingle`.
|
|
8
|
+
*/
|
|
9
|
+
import type { Clipboard } from "@oh-my-pi/hashline";
|
|
10
|
+
interface EditClipboardOwner {
|
|
11
|
+
editClipboard?: Clipboard;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Look up (or lazily create) the clipboard register attached to a session.
|
|
15
|
+
* Storage lives on `session.editClipboard` so it ages out exactly with the
|
|
16
|
+
* session itself.
|
|
17
|
+
*/
|
|
18
|
+
export declare function getEditClipboard(session: EditClipboardOwner): Clipboard;
|
|
19
|
+
export {};
|