@code-yeongyu/senpi 2026.8.21 → 2026.8.22
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 +48 -0
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +5 -4
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/extensions/builtin/permission-system/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/permission-system/index.js +7 -11
- package/dist/core/extensions/builtin/permission-system/index.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +2 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +79 -31
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +40 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +8 -3
- package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +15 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/stream-retry.d.ts +21 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/stream-retry.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/stream-retry.js +36 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/stream-retry.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/types.d.ts +10 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/types.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent/types.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +6 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +166 -26
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
- package/dist/modes/interactive/split-trailing-assistant-text.d.ts +0 -7
- package/dist/modes/interactive/split-trailing-assistant-text.d.ts.map +0 -1
- package/dist/modes/interactive/split-trailing-assistant-text.js +0 -19
- package/dist/modes/interactive/split-trailing-assistant-text.js.map +0 -1
|
@@ -12,6 +12,46 @@
|
|
|
12
12
|
|
|
13
13
|
### Removed
|
|
14
14
|
|
|
15
|
+
## [2026.8.22] - 2026-08-22
|
|
16
|
+
|
|
17
|
+
### Breaking Changes
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- Ruby and Julia eval cells now wait for the subprocess `ready` signal before execution timeouts begin, so interpreter startup under load cannot time out a state-setting cell and silently restart the kernel before the next cell runs.
|
|
26
|
+
|
|
27
|
+
### Removed
|
|
28
|
+
|
|
29
|
+
## [2026.8.21-3] - 2026-08-21
|
|
30
|
+
|
|
31
|
+
### Breaking Changes
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
|
|
37
|
+
### Fixed
|
|
38
|
+
|
|
39
|
+
### Removed
|
|
40
|
+
|
|
41
|
+
## [2026.8.21-2] - 2026-08-21
|
|
42
|
+
|
|
43
|
+
### Breaking Changes
|
|
44
|
+
|
|
45
|
+
### Added
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
- `js` eval cells now accept `local://` paths in `read()` and `write()` like every other kernel. The session manager computed the session local root only after its `language === "js"` early return, so the JavaScript kernel was constructed without `localRoots` or `artifactsDir` and every `local://` helper call failed with `Protocol paths are not supported by write()`, even though the JavaScript prelude documents `local://` as the session local root. `py`/`rb`/`jl` behavior is unchanged.
|
|
52
|
+
|
|
53
|
+
### Removed
|
|
54
|
+
|
|
15
55
|
## [2026.8.21] - 2026-08-21
|
|
16
56
|
|
|
17
57
|
### Breaking Changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi-codemode",
|
|
3
|
-
"version": "2026.8.
|
|
3
|
+
"version": "2026.8.22",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Source-only senpi extension package for codemode evaluation tools",
|
|
6
6
|
"type": "module",
|
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@babel/parser": "8.0.4",
|
|
34
|
-
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.
|
|
34
|
+
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.22",
|
|
35
35
|
"typebox": "1.3.16"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@code-yeongyu/senpi": "2026.8.
|
|
38
|
+
"@code-yeongyu/senpi": "2026.8.22"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@code-yeongyu/senpi": "2026.8.
|
|
41
|
+
"@code-yeongyu/senpi": "2026.8.22"
|
|
42
42
|
},
|
|
43
43
|
"keywords": [
|
|
44
44
|
"senpi",
|
|
@@ -196,19 +196,24 @@ class DefaultCodemodeSessionManager implements CodemodeSessionManager {
|
|
|
196
196
|
if (!bridge) throw new Error("codemode bridge server is not running");
|
|
197
197
|
const configuredPoolWidth = this.#options.settings.parallelPoolWidth;
|
|
198
198
|
const parallelPoolWidth = Number.isFinite(configuredPoolWidth) ? Math.max(1, Math.trunc(configuredPoolWidth)) : 1;
|
|
199
|
+
// localRoots must be computed BEFORE the js branch: the JS kernel resolves local://
|
|
200
|
+
// from its worker init connection exactly like the subprocess kernels resolve it from
|
|
201
|
+
// theirs. Computing it after the early return left js cells with no local root at all.
|
|
202
|
+
const localRoots =
|
|
203
|
+
this.#options.localRoots ??
|
|
204
|
+
(this.#options.artifactsDir ? { local: join(this.#options.artifactsDir, "local") } : undefined);
|
|
199
205
|
if (language === "js") {
|
|
200
206
|
return new JavaScriptKernel({
|
|
201
207
|
sessionId: this.#options.sessionId,
|
|
202
208
|
cwd: this.#options.cwd,
|
|
203
209
|
parallelPoolWidth,
|
|
204
210
|
onMessage,
|
|
211
|
+
...(localRoots ? { localRoots: { ...localRoots } } : {}),
|
|
212
|
+
...(this.#options.artifactsDir ? { artifactsDir: this.#options.artifactsDir } : {}),
|
|
205
213
|
});
|
|
206
214
|
}
|
|
207
215
|
const detected = this.#options.availability[language].detected;
|
|
208
216
|
if (!detected.ok) throw new Error(`No ${language} interpreter is available`);
|
|
209
|
-
const localRoots =
|
|
210
|
-
this.#options.localRoots ??
|
|
211
|
-
(this.#options.artifactsDir ? { local: join(this.#options.artifactsDir, "local") } : undefined);
|
|
212
217
|
const connection = {
|
|
213
218
|
port: bridge.port,
|
|
214
219
|
token: bridge.token,
|
|
@@ -26,6 +26,7 @@ export class SubprocessKernel {
|
|
|
26
26
|
private readonly onMessage?: (message: KernelToHostMessage) => void;
|
|
27
27
|
private readonly runs = new SubprocessRunQueue();
|
|
28
28
|
private process: SubprocessProcess | null = null;
|
|
29
|
+
private processReady = false;
|
|
29
30
|
private retirementPromise: Promise<void> | null = null;
|
|
30
31
|
private retirementProcess: SubprocessProcess | null = null;
|
|
31
32
|
private retirementFailure: Error | null = null;
|
|
@@ -109,7 +110,7 @@ export class SubprocessKernel {
|
|
|
109
110
|
|
|
110
111
|
private pumpRuns(): void {
|
|
111
112
|
const process = this.process;
|
|
112
|
-
if (this.closed || this.runs.active || !process || process.isRetiring) return;
|
|
113
|
+
if (this.closed || this.runs.active || !process || process.isRetiring || !this.processReady) return;
|
|
113
114
|
const run = this.runs.startNext(performance.now());
|
|
114
115
|
if (!run) return;
|
|
115
116
|
const timeoutMs = run.input.timeoutMs;
|
|
@@ -142,6 +143,7 @@ export class SubprocessKernel {
|
|
|
142
143
|
},
|
|
143
144
|
});
|
|
144
145
|
this.process = process;
|
|
146
|
+
this.processReady = false;
|
|
145
147
|
try {
|
|
146
148
|
process.send(
|
|
147
149
|
encodeBridgeFrame({ type: "init", sessionId: this.options.sessionId, connection: this.options.connection }),
|
|
@@ -165,6 +167,17 @@ export class SubprocessKernel {
|
|
|
165
167
|
|
|
166
168
|
private handleMessage(process: SubprocessProcess, message: KernelToHostMessage): void {
|
|
167
169
|
if (!this.accepts(process)) return;
|
|
170
|
+
if (message.type === "ready") {
|
|
171
|
+
this.processReady = true;
|
|
172
|
+
this.runs.handleMessage(message, this.onMessage);
|
|
173
|
+
this.pumpRuns();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (message.type === "init-failed") {
|
|
177
|
+
this.runs.handleMessage(message, this.onMessage);
|
|
178
|
+
this.failClosed(new KernelStartupError(message.error.message));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
168
181
|
if (this.runs.handleMessage(message, this.onMessage)) this.pumpRuns();
|
|
169
182
|
}
|
|
170
183
|
|
|
@@ -176,6 +189,7 @@ export class SubprocessKernel {
|
|
|
176
189
|
return;
|
|
177
190
|
}
|
|
178
191
|
this.process = null;
|
|
192
|
+
this.processReady = false;
|
|
179
193
|
this.failClosed(new KernelExitedError(signal ?? code ?? "unknown"));
|
|
180
194
|
}
|
|
181
195
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@earendil-works/pi-agent-core",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "2026.8.
|
|
4
|
+
"version": "2026.8.22",
|
|
5
5
|
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"prepublishOnly": "npm run build"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.
|
|
40
|
-
"@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.8.
|
|
39
|
+
"@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.22",
|
|
40
|
+
"@earendil-works/pi-telemetry": "npm:@code-yeongyu/senpi-telemetry@2026.8.22",
|
|
41
41
|
"diff": "9.0.0",
|
|
42
42
|
"ignore": "7.0.6",
|
|
43
43
|
"typebox": "1.3.16",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type CursorStreamRetryCause = "stall" | "transport" | "clean-end";
|
|
2
|
+
export declare class CursorRetryableStreamError extends Error {
|
|
3
|
+
readonly retryCause: CursorStreamRetryCause;
|
|
4
|
+
constructor(message: string, retryCause: CursorStreamRetryCause, options?: ErrorOptions);
|
|
5
|
+
}
|
|
6
|
+
export declare function isCursorRetryableStreamError(error: unknown): error is CursorRetryableStreamError;
|
|
7
|
+
export declare function cursorStreamRetryDelayMs(options: {
|
|
8
|
+
attempt: number;
|
|
9
|
+
baseDelayMs?: number;
|
|
10
|
+
fixedDelayMs?: number;
|
|
11
|
+
random?: () => number;
|
|
12
|
+
}): number;
|
|
13
|
+
export declare function shouldRetryCursorStream(options: {
|
|
14
|
+
error: unknown;
|
|
15
|
+
retries: number;
|
|
16
|
+
maxRetries: number;
|
|
17
|
+
sawTurnEnded: boolean;
|
|
18
|
+
aborted: boolean;
|
|
19
|
+
}): boolean;
|
|
20
|
+
export declare function waitForCursorStreamRetry(delayMs: number, signal?: AbortSignal): Promise<void>;
|
|
21
|
+
//# sourceMappingURL=stream-retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-retry.d.ts","sourceRoot":"","sources":["../../../src/api/cursor-agent/stream-retry.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,CAAC;AAEzE,qBAAa,0BAA2B,SAAQ,KAAK;IACpD,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;gBAEhC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,sBAAsB,EAAE,OAAO,CAAC,EAAE,YAAY;CAKvF;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,0BAA0B,CAEhG;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB,GAAG,MAAM,CAMT;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAChD,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CACjB,GAAG,OAAO,CAOV;AAED,wBAAsB,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAanG"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export class CursorRetryableStreamError extends Error {
|
|
2
|
+
constructor(message, retryCause, options) {
|
|
3
|
+
super(message, options);
|
|
4
|
+
this.name = "CursorRetryableStreamError";
|
|
5
|
+
this.retryCause = retryCause;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export function isCursorRetryableStreamError(error) {
|
|
9
|
+
return error instanceof CursorRetryableStreamError;
|
|
10
|
+
}
|
|
11
|
+
export function cursorStreamRetryDelayMs(options) {
|
|
12
|
+
if (options.fixedDelayMs !== undefined)
|
|
13
|
+
return Math.max(0, options.fixedDelayMs);
|
|
14
|
+
const baseDelayMs = options.baseDelayMs ?? 1000;
|
|
15
|
+
const backoffMs = Math.min(baseDelayMs * 2 ** options.attempt, 60_000);
|
|
16
|
+
const jitter = Math.floor(backoffMs * 0.2 * (options.random ?? Math.random)());
|
|
17
|
+
return backoffMs + jitter;
|
|
18
|
+
}
|
|
19
|
+
export function shouldRetryCursorStream(options) {
|
|
20
|
+
return (!options.sawTurnEnded &&
|
|
21
|
+
!options.aborted &&
|
|
22
|
+
options.retries < options.maxRetries &&
|
|
23
|
+
isCursorRetryableStreamError(options.error));
|
|
24
|
+
}
|
|
25
|
+
export async function waitForCursorStreamRetry(delayMs, signal) {
|
|
26
|
+
if (delayMs <= 0 || signal?.aborted)
|
|
27
|
+
return;
|
|
28
|
+
await new Promise((resolve) => {
|
|
29
|
+
const timer = setTimeout(resolve, delayMs);
|
|
30
|
+
signal?.addEventListener("abort", () => {
|
|
31
|
+
clearTimeout(timer);
|
|
32
|
+
resolve();
|
|
33
|
+
}, { once: true });
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=stream-retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream-retry.js","sourceRoot":"","sources":["../../../src/api/cursor-agent/stream-retry.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAGpD,YAAY,OAAe,EAAE,UAAkC,EAAE,OAAsB;QACtF,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;QACzC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC9B,CAAC;CACD;AAED,MAAM,UAAU,4BAA4B,CAAC,KAAc;IAC1D,OAAO,KAAK,YAAY,0BAA0B,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,OAKxC;IACA,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACjF,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC;IAChD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC/E,OAAO,SAAS,GAAG,MAAM,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,OAMvC;IACA,OAAO,CACN,CAAC,OAAO,CAAC,YAAY;QACrB,CAAC,OAAO,CAAC,OAAO;QAChB,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,UAAU;QACpC,4BAA4B,CAAC,OAAO,CAAC,KAAK,CAAC,CAC3C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,OAAe,EAAE,MAAoB;IACnF,IAAI,OAAO,IAAI,CAAC,IAAI,MAAM,EAAE,OAAO;QAAE,OAAO;IAC5C,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACnC,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC3C,MAAM,EAAE,gBAAgB,CACvB,OAAO,EACP,GAAG,EAAE;YACJ,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,EAAE,CAAC;QACX,CAAC,EACD,EAAE,IAAI,EAAE,IAAI,EAAE,CACd,CAAC;IACH,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["export type CursorStreamRetryCause = \"stall\" | \"transport\" | \"clean-end\";\n\nexport class CursorRetryableStreamError extends Error {\n\treadonly retryCause: CursorStreamRetryCause;\n\n\tconstructor(message: string, retryCause: CursorStreamRetryCause, options?: ErrorOptions) {\n\t\tsuper(message, options);\n\t\tthis.name = \"CursorRetryableStreamError\";\n\t\tthis.retryCause = retryCause;\n\t}\n}\n\nexport function isCursorRetryableStreamError(error: unknown): error is CursorRetryableStreamError {\n\treturn error instanceof CursorRetryableStreamError;\n}\n\nexport function cursorStreamRetryDelayMs(options: {\n\tattempt: number;\n\tbaseDelayMs?: number;\n\tfixedDelayMs?: number;\n\trandom?: () => number;\n}): number {\n\tif (options.fixedDelayMs !== undefined) return Math.max(0, options.fixedDelayMs);\n\tconst baseDelayMs = options.baseDelayMs ?? 1000;\n\tconst backoffMs = Math.min(baseDelayMs * 2 ** options.attempt, 60_000);\n\tconst jitter = Math.floor(backoffMs * 0.2 * (options.random ?? Math.random)());\n\treturn backoffMs + jitter;\n}\n\nexport function shouldRetryCursorStream(options: {\n\terror: unknown;\n\tretries: number;\n\tmaxRetries: number;\n\tsawTurnEnded: boolean;\n\taborted: boolean;\n}): boolean {\n\treturn (\n\t\t!options.sawTurnEnded &&\n\t\t!options.aborted &&\n\t\toptions.retries < options.maxRetries &&\n\t\tisCursorRetryableStreamError(options.error)\n\t);\n}\n\nexport async function waitForCursorStreamRetry(delayMs: number, signal?: AbortSignal): Promise<void> {\n\tif (delayMs <= 0 || signal?.aborted) return;\n\tawait new Promise<void>((resolve) => {\n\t\tconst timer = setTimeout(resolve, delayMs);\n\t\tsignal?.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve();\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t});\n}\n"]}
|
|
@@ -118,5 +118,15 @@ export interface CursorAgentOptions extends StreamOptions {
|
|
|
118
118
|
* variant request shape.
|
|
119
119
|
*/
|
|
120
120
|
thinkingSelection?: ThinkingSelection;
|
|
121
|
+
/** Override stream health bounds for deterministic provider integration tests. */
|
|
122
|
+
streamHealthFailThresholdMs?: number;
|
|
123
|
+
/** @deprecated Accepted for compatibility; heartbeat/checkpoint frames are always liveness. */
|
|
124
|
+
streamHealthHeartbeatOnlyThresholdMs?: number;
|
|
125
|
+
/** Maximum pre-completion stall/transport retries (default 10). */
|
|
126
|
+
streamStallMaxRetries?: number;
|
|
127
|
+
/** Fixed retry delay for tests; production uses exponential backoff plus jitter. */
|
|
128
|
+
streamStallRetryDelayMs?: number;
|
|
129
|
+
/** Override the post-turn exec drain bound for deterministic tests. */
|
|
130
|
+
turnEndDrainTimeoutMs?: number;
|
|
121
131
|
}
|
|
122
132
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/api/cursor-agent/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/api/cursor-agent/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/api/cursor-agent/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG","sourcesContent":["/**\n * Cursor exec-channel handler contracts.\n *\n * The Cursor agent protocol is server-driven: mid-turn, the server sends\n * `ExecServerMessage` frames asking the CLIENT to run a tool and blocks until\n * the reply arrives on the same stream. The host (coding-agent) supplies\n * these handlers; the `cursor-agent` API dispatches frames onto them, sends\n * their protobuf answers back on the wire, synthesizes already-resolved\n * `toolCall` blocks into the assistant message, and pairs each with a\n * `ToolResultMessage` delivered through {@link CursorToolResultHandler}.\n *\n * Everything here is type-only over the generated protobuf shapes, so it is\n * safe to import from browser-reachable modules.\n */\n\nimport type { StreamOptions, ThinkingSelection, ToolResultMessage } from \"../../types.ts\";\nimport type {\n\tDeleteArgs,\n\tDeleteResult,\n\tDiagnosticsArgs,\n\tDiagnosticsResult,\n\tGrepArgs,\n\tGrepResult,\n\tLsArgs,\n\tLsResult,\n\tMcpResult,\n\tPiBashExecArgs,\n\tPiBashExecResult,\n\tPiEditExecArgs,\n\tPiEditExecResult,\n\tPiFindExecArgs,\n\tPiFindExecResult,\n\tPiGrepExecArgs,\n\tPiGrepExecResult,\n\tPiLsExecArgs,\n\tPiLsExecResult,\n\tPiReadExecArgs,\n\tPiReadExecResult,\n\tPiWriteExecArgs,\n\tPiWriteExecResult,\n\tReadArgs,\n\tReadResult,\n\tShellArgs,\n\tShellResult,\n\tWriteArgs,\n\tWriteResult,\n} from \"./gen/agent_pb.ts\";\n\n/**\n * The three return forms an exec handler may use: a wire result with an\n * optional transcript pairing, a bare wire result, or a bare\n * `ToolResultMessage` from which the wire result is derived.\n */\nexport type CursorExecHandlerResult<T> = { result: T; toolResult?: ToolResultMessage } | T | ToolResultMessage;\n\n/**\n * Optional rewrite of a Cursor exec-channel tool result.\n * May return a Promise. Returning `undefined` keeps the original result.\n */\nexport type CursorToolResultHandler = (\n\tresult: ToolResultMessage,\n) => ToolResultMessage | undefined | Promise<ToolResultMessage | undefined>;\n\n/**\n * Identifies the synthesized assistant block a Cursor exec call was filed\n * under, so paths that produce no handler `toolResult` can still pair one.\n */\nexport interface CursorExecPairing {\n\ttoolCallId: string;\n\ttoolName: string;\n}\n\nexport interface CursorMcpCall {\n\tname: string;\n\tproviderIdentifier: string;\n\ttoolName: string;\n\ttoolCallId: string;\n\targs: Record<string, unknown>;\n\trawArgs: Record<string, Uint8Array>;\n\t/**\n\t * The frame asks only whether this call would be permitted — it must not\n\t * run. The server sends it to resolve a smart-mode approval decision ahead\n\t * of the real invocation; executing here would fire a side-effecting tool\n\t * the user has not yet been asked about (and fire it twice once the real\n\t * call arrives).\n\t */\n\tapprovalOnly?: boolean;\n}\n\nexport interface CursorShellStreamCallbacks {\n\tonStdout(data: string): void;\n\tonStderr(data: string): void;\n}\n\n/**\n * A modern Pi exec frame plus the call id the dispatcher minted for it.\n *\n * Unlike the legacy exec args (`ReadArgs`, `ShellArgs`, ...), the Pi frames\n * carry no `tool_call_id` field: the id rides the streamed `ToolCall`\n * envelope instead. The exec channel has no access to that envelope, so the\n * dispatcher mints an id and hands it to the handler, keeping the synthesized\n * transcript block and its paired `toolResult` on the same key.\n */\nexport interface CursorPiCall<TArgs> {\n\targs: TArgs;\n\ttoolCallId: string;\n}\n\nexport interface CursorExecHandlers {\n\tread?: (args: ReadArgs) => Promise<CursorExecHandlerResult<ReadResult>>;\n\tls?: (args: LsArgs) => Promise<CursorExecHandlerResult<LsResult>>;\n\tgrep?: (args: GrepArgs) => Promise<CursorExecHandlerResult<GrepResult>>;\n\twrite?: (args: WriteArgs) => Promise<CursorExecHandlerResult<WriteResult>>;\n\tdelete?: (args: DeleteArgs) => Promise<CursorExecHandlerResult<DeleteResult>>;\n\tshell?: (args: ShellArgs) => Promise<CursorExecHandlerResult<ShellResult>>;\n\tshellStream?: (\n\t\targs: ShellArgs,\n\t\tcallbacks: CursorShellStreamCallbacks,\n\t) => Promise<CursorExecHandlerResult<ShellResult>>;\n\tdiagnostics?: (args: DiagnosticsArgs) => Promise<CursorExecHandlerResult<DiagnosticsResult>>;\n\tmcp?: (call: CursorMcpCall) => Promise<CursorExecHandlerResult<McpResult>>;\n\t/**\n\t * Answers \"would this MCP call be permitted\", without running it.\n\t *\n\t * `true` only when the host's policy resolves to a definite allow. A\n\t * pending prompt is `false`: it can only be answered interactively at\n\t * execution time. When no handler is registered the provider refuses,\n\t * since it cannot decide.\n\t */\n\tmcpApprovalPreflight?: (call: CursorMcpCall) => Promise<boolean>;\n\t/**\n\t * Modern Cursor CLI Pi tool frames (`ExecServerMessage` 45-51). They are a\n\t * distinct frame family from the legacy `readArgs`/`shellArgs`/... set:\n\t * different args, different result oneofs, and no `tool_call_id`.\n\t */\n\tpiRead?: (call: CursorPiCall<PiReadExecArgs>) => Promise<CursorExecHandlerResult<PiReadExecResult>>;\n\tpiBash?: (call: CursorPiCall<PiBashExecArgs>) => Promise<CursorExecHandlerResult<PiBashExecResult>>;\n\tpiEdit?: (call: CursorPiCall<PiEditExecArgs>) => Promise<CursorExecHandlerResult<PiEditExecResult>>;\n\tpiWrite?: (call: CursorPiCall<PiWriteExecArgs>) => Promise<CursorExecHandlerResult<PiWriteExecResult>>;\n\tpiGrep?: (call: CursorPiCall<PiGrepExecArgs>) => Promise<CursorExecHandlerResult<PiGrepExecResult>>;\n\tpiFind?: (call: CursorPiCall<PiFindExecArgs>) => Promise<CursorExecHandlerResult<PiFindExecResult>>;\n\tpiLs?: (call: CursorPiCall<PiLsExecArgs>) => Promise<CursorExecHandlerResult<PiLsExecResult>>;\n\tonToolResult?: CursorToolResultHandler;\n}\n\n/** Stream options accepted by the `cursor-agent` API. */\nexport interface CursorAgentOptions extends StreamOptions {\n\t/** Optional server-side system prompt override (RunRequest.customSystemPrompt). */\n\tcustomSystemPrompt?: string;\n\t/** Conversation id override; defaults to `sessionId`, else a random UUID per stream. */\n\tconversationId?: string;\n\t/** Cursor exec/MCP tool handlers supplied by the host. */\n\texecHandlers?: CursorExecHandlers;\n\t/** Receives every exec-channel tool result for transcript pairing. */\n\tonToolResult?: CursorToolResultHandler;\n\t/**\n\t * Provenance-bearing thinking selection rendered into\n\t * `RequestedModel.parameters`; absent selections keep the representative\n\t * variant request shape.\n\t */\n\tthinkingSelection?: ThinkingSelection;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/api/cursor-agent/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG","sourcesContent":["/**\n * Cursor exec-channel handler contracts.\n *\n * The Cursor agent protocol is server-driven: mid-turn, the server sends\n * `ExecServerMessage` frames asking the CLIENT to run a tool and blocks until\n * the reply arrives on the same stream. The host (coding-agent) supplies\n * these handlers; the `cursor-agent` API dispatches frames onto them, sends\n * their protobuf answers back on the wire, synthesizes already-resolved\n * `toolCall` blocks into the assistant message, and pairs each with a\n * `ToolResultMessage` delivered through {@link CursorToolResultHandler}.\n *\n * Everything here is type-only over the generated protobuf shapes, so it is\n * safe to import from browser-reachable modules.\n */\n\nimport type { StreamOptions, ThinkingSelection, ToolResultMessage } from \"../../types.ts\";\nimport type {\n\tDeleteArgs,\n\tDeleteResult,\n\tDiagnosticsArgs,\n\tDiagnosticsResult,\n\tGrepArgs,\n\tGrepResult,\n\tLsArgs,\n\tLsResult,\n\tMcpResult,\n\tPiBashExecArgs,\n\tPiBashExecResult,\n\tPiEditExecArgs,\n\tPiEditExecResult,\n\tPiFindExecArgs,\n\tPiFindExecResult,\n\tPiGrepExecArgs,\n\tPiGrepExecResult,\n\tPiLsExecArgs,\n\tPiLsExecResult,\n\tPiReadExecArgs,\n\tPiReadExecResult,\n\tPiWriteExecArgs,\n\tPiWriteExecResult,\n\tReadArgs,\n\tReadResult,\n\tShellArgs,\n\tShellResult,\n\tWriteArgs,\n\tWriteResult,\n} from \"./gen/agent_pb.ts\";\n\n/**\n * The three return forms an exec handler may use: a wire result with an\n * optional transcript pairing, a bare wire result, or a bare\n * `ToolResultMessage` from which the wire result is derived.\n */\nexport type CursorExecHandlerResult<T> = { result: T; toolResult?: ToolResultMessage } | T | ToolResultMessage;\n\n/**\n * Optional rewrite of a Cursor exec-channel tool result.\n * May return a Promise. Returning `undefined` keeps the original result.\n */\nexport type CursorToolResultHandler = (\n\tresult: ToolResultMessage,\n) => ToolResultMessage | undefined | Promise<ToolResultMessage | undefined>;\n\n/**\n * Identifies the synthesized assistant block a Cursor exec call was filed\n * under, so paths that produce no handler `toolResult` can still pair one.\n */\nexport interface CursorExecPairing {\n\ttoolCallId: string;\n\ttoolName: string;\n}\n\nexport interface CursorMcpCall {\n\tname: string;\n\tproviderIdentifier: string;\n\ttoolName: string;\n\ttoolCallId: string;\n\targs: Record<string, unknown>;\n\trawArgs: Record<string, Uint8Array>;\n\t/**\n\t * The frame asks only whether this call would be permitted — it must not\n\t * run. The server sends it to resolve a smart-mode approval decision ahead\n\t * of the real invocation; executing here would fire a side-effecting tool\n\t * the user has not yet been asked about (and fire it twice once the real\n\t * call arrives).\n\t */\n\tapprovalOnly?: boolean;\n}\n\nexport interface CursorShellStreamCallbacks {\n\tonStdout(data: string): void;\n\tonStderr(data: string): void;\n}\n\n/**\n * A modern Pi exec frame plus the call id the dispatcher minted for it.\n *\n * Unlike the legacy exec args (`ReadArgs`, `ShellArgs`, ...), the Pi frames\n * carry no `tool_call_id` field: the id rides the streamed `ToolCall`\n * envelope instead. The exec channel has no access to that envelope, so the\n * dispatcher mints an id and hands it to the handler, keeping the synthesized\n * transcript block and its paired `toolResult` on the same key.\n */\nexport interface CursorPiCall<TArgs> {\n\targs: TArgs;\n\ttoolCallId: string;\n}\n\nexport interface CursorExecHandlers {\n\tread?: (args: ReadArgs) => Promise<CursorExecHandlerResult<ReadResult>>;\n\tls?: (args: LsArgs) => Promise<CursorExecHandlerResult<LsResult>>;\n\tgrep?: (args: GrepArgs) => Promise<CursorExecHandlerResult<GrepResult>>;\n\twrite?: (args: WriteArgs) => Promise<CursorExecHandlerResult<WriteResult>>;\n\tdelete?: (args: DeleteArgs) => Promise<CursorExecHandlerResult<DeleteResult>>;\n\tshell?: (args: ShellArgs) => Promise<CursorExecHandlerResult<ShellResult>>;\n\tshellStream?: (\n\t\targs: ShellArgs,\n\t\tcallbacks: CursorShellStreamCallbacks,\n\t) => Promise<CursorExecHandlerResult<ShellResult>>;\n\tdiagnostics?: (args: DiagnosticsArgs) => Promise<CursorExecHandlerResult<DiagnosticsResult>>;\n\tmcp?: (call: CursorMcpCall) => Promise<CursorExecHandlerResult<McpResult>>;\n\t/**\n\t * Answers \"would this MCP call be permitted\", without running it.\n\t *\n\t * `true` only when the host's policy resolves to a definite allow. A\n\t * pending prompt is `false`: it can only be answered interactively at\n\t * execution time. When no handler is registered the provider refuses,\n\t * since it cannot decide.\n\t */\n\tmcpApprovalPreflight?: (call: CursorMcpCall) => Promise<boolean>;\n\t/**\n\t * Modern Cursor CLI Pi tool frames (`ExecServerMessage` 45-51). They are a\n\t * distinct frame family from the legacy `readArgs`/`shellArgs`/... set:\n\t * different args, different result oneofs, and no `tool_call_id`.\n\t */\n\tpiRead?: (call: CursorPiCall<PiReadExecArgs>) => Promise<CursorExecHandlerResult<PiReadExecResult>>;\n\tpiBash?: (call: CursorPiCall<PiBashExecArgs>) => Promise<CursorExecHandlerResult<PiBashExecResult>>;\n\tpiEdit?: (call: CursorPiCall<PiEditExecArgs>) => Promise<CursorExecHandlerResult<PiEditExecResult>>;\n\tpiWrite?: (call: CursorPiCall<PiWriteExecArgs>) => Promise<CursorExecHandlerResult<PiWriteExecResult>>;\n\tpiGrep?: (call: CursorPiCall<PiGrepExecArgs>) => Promise<CursorExecHandlerResult<PiGrepExecResult>>;\n\tpiFind?: (call: CursorPiCall<PiFindExecArgs>) => Promise<CursorExecHandlerResult<PiFindExecResult>>;\n\tpiLs?: (call: CursorPiCall<PiLsExecArgs>) => Promise<CursorExecHandlerResult<PiLsExecResult>>;\n\tonToolResult?: CursorToolResultHandler;\n}\n\n/** Stream options accepted by the `cursor-agent` API. */\nexport interface CursorAgentOptions extends StreamOptions {\n\t/** Optional server-side system prompt override (RunRequest.customSystemPrompt). */\n\tcustomSystemPrompt?: string;\n\t/** Conversation id override; defaults to `sessionId`, else a random UUID per stream. */\n\tconversationId?: string;\n\t/** Cursor exec/MCP tool handlers supplied by the host. */\n\texecHandlers?: CursorExecHandlers;\n\t/** Receives every exec-channel tool result for transcript pairing. */\n\tonToolResult?: CursorToolResultHandler;\n\t/**\n\t * Provenance-bearing thinking selection rendered into\n\t * `RequestedModel.parameters`; absent selections keep the representative\n\t * variant request shape.\n\t */\n\tthinkingSelection?: ThinkingSelection;\n\t/** Override stream health bounds for deterministic provider integration tests. */\n\tstreamHealthFailThresholdMs?: number;\n\t/** @deprecated Accepted for compatibility; heartbeat/checkpoint frames are always liveness. */\n\tstreamHealthHeartbeatOnlyThresholdMs?: number;\n\t/** Maximum pre-completion stall/transport retries (default 10). */\n\tstreamStallMaxRetries?: number;\n\t/** Fixed retry delay for tests; production uses exponential backoff plus jitter. */\n\tstreamStallRetryDelayMs?: number;\n\t/** Override the post-turn exec drain bound for deterministic tests. */\n\tturnEndDrainTimeoutMs?: number;\n}\n"]}
|
|
@@ -24,6 +24,12 @@ import type { CursorAgentOptions, CursorExecHandlerResult, CursorExecHandlers, C
|
|
|
24
24
|
export type { CursorAgentOptions, CursorExecHandlerResult, CursorExecHandlers, CursorExecPairing, CursorMcpCall, CursorPiCall, CursorShellStreamCallbacks, CursorToolResultHandler, } from "./cursor-agent/types.ts";
|
|
25
25
|
export declare const CURSOR_API_URL = "https://api2.cursor.sh";
|
|
26
26
|
export declare const CURSOR_CLIENT_VERSION = "cli-2026.07.23-e383d2b";
|
|
27
|
+
/** Maximum inbound silence before a Cursor turn without turnEnded is failed. */
|
|
28
|
+
export declare const CURSOR_STREAM_HEALTH_FAIL_THRESHOLD_MS = 30000;
|
|
29
|
+
/** @deprecated Heartbeats and checkpoints count as inbound liveness without a separate deadline. */
|
|
30
|
+
export declare const CURSOR_STREAM_HEALTH_HEARTBEAT_ONLY_THRESHOLD_MS: number;
|
|
31
|
+
/** Maximum time allowed to drain exec handlers after turnEnded. */
|
|
32
|
+
export declare const CURSOR_TURN_END_DRAIN_TIMEOUT_MS = 5000;
|
|
27
33
|
/** Reduce caller-supplied headers to what this HTTP/2 request can legally carry. */
|
|
28
34
|
export declare function sanitizeCursorCallerHeaders(headers: Record<string, string> | undefined): Record<string, string>;
|
|
29
35
|
export declare function frameConnectMessage(data: Uint8Array, flags?: number): Buffer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cursor-agent.d.ts","sourceRoot":"","sources":["../../src/api/cursor-agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AAIpC,OAAO,KAAK,EAEX,gBAAgB,EAGhB,OAAO,EAEP,mBAAmB,EACnB,cAAc,EACd,WAAW,EACX,eAAe,EACf,IAAI,EACJ,QAAQ,EACR,iBAAiB,EACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAGN,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AA0BvE,OAAO,EAIN,KAAK,kBAAkB,EAcvB,KAAK,0BAA0B,EA+D/B,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"cursor-agent.d.ts","sourceRoot":"","sources":["../../src/api/cursor-agent.ts"],"names":[],"mappings":"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"}
|