pi-cursor-sdk 0.1.27 → 0.1.28
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 +10 -0
- package/README.md +4 -4
- package/docs/cursor-live-smoke-checklist.md +4 -4
- package/docs/cursor-model-ux-spec.md +1 -1
- package/docs/cursor-native-tool-visual-audit.md +3 -3
- package/docs/cursor-testing-lessons.md +3 -3
- package/package.json +4 -4
- package/src/cursor-provider-errors.ts +18 -2
- package/src/cursor-sdk-process-error-guard.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.1.28 - 2026-05-29
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Update the local pi validation baseline to `@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, and `@earendil-works/pi-tui` `0.78.0` after reviewing the 0.78.0 changelog; peer dependency ranges remain minimum-only at `>=0.76.0` (#108).
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Prevent Cursor SDK ConnectRPC network resets such as `ConnectError: [aborted] read ECONNRESET` from escaping as process-level uncaught exceptions during active Cursor turns; pi now surfaces the existing scrubbed retry guidance and remains available for the next turn (#107).
|
|
14
|
+
|
|
5
15
|
## 0.1.27 - 2026-05-29
|
|
6
16
|
|
|
7
17
|
### Changed
|
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ If pi started without a key, run `/cursor-refresh-models` after `/login` to refr
|
|
|
34
34
|
- pi 0.76.0 or newer
|
|
35
35
|
- a Cursor SDK API key saved through `/login`, available as `CURSOR_API_KEY`, or passed with pi's `--api-key`
|
|
36
36
|
|
|
37
|
-
No global `@cursor/sdk` install is required. This package depends on exact `@cursor/sdk@1.0.16`, so normal package installation brings in the SDK version this extension was built and tested against. This package declares a pi **minimum** of 0.76.0 with no maximum peer version, so users who update pi before this extension is republished are not blocked from trying the existing extension. The current validation baseline is pi 0.
|
|
37
|
+
No global `@cursor/sdk` install is required. This package depends on exact `@cursor/sdk@1.0.16`, so normal package installation brings in the SDK version this extension was built and tested against. This package declares a pi **minimum** of 0.76.0 with no maximum peer version, so users who update pi before this extension is republished are not blocked from trying the existing extension. The current validation baseline is pi 0.78.0 plus Cursor SDK 1.0.16; older pi or Cursor SDK compatibility paths are not maintained.
|
|
38
38
|
|
|
39
39
|
## Install
|
|
40
40
|
|
|
@@ -293,7 +293,7 @@ On bootstrap sends, a compact **callable tool surfaces** block is injected into
|
|
|
293
293
|
|
|
294
294
|
### Maintainer live smoke release gate
|
|
295
295
|
|
|
296
|
-
For Cursor provider/runtime changes, follow the manual [Cursor live smoke checklist](docs/cursor-live-smoke-checklist.md) before release. For a faster minimal-surface pass first, see [Cursor dogfood checklist](docs/cursor-dogfood-checklist.md). See [Cursor testing lessons](docs/cursor-testing-lessons.md) for auth.json seeding, isolated `/tmp` harness layout, JSONL replay-error scans, and other regression traps. Assume every runtime surface is in scope. The checklist uses real `pi -e . --cursor-no-fast --model cursor/composer-2.5` runs with temporary session dirs, pi 0.
|
|
296
|
+
For Cursor provider/runtime changes, follow the manual [Cursor live smoke checklist](docs/cursor-live-smoke-checklist.md) before release. For a faster minimal-surface pass first, see [Cursor dogfood checklist](docs/cursor-dogfood-checklist.md). See [Cursor testing lessons](docs/cursor-testing-lessons.md) for auth.json seeding, isolated `/tmp` harness layout, JSONL replay-error scans, and other regression traps. Assume every runtime surface is in scope. The checklist uses real `pi -e . --cursor-no-fast --model cursor/composer-2.5` runs with temporary session dirs, pi 0.78.0 `--session-id`, sealed smoke-runner PATH/env wrappers, Cursor SDK `plan` mode, and mandatory visual TUI card/color inspection. The canonical visual path is `npm run smoke:visual`: offscreen PTY capture rendered through a browser/xterm view and saved as PNG screenshots with Playwright, or with `agent_browser` from the generated HTML when available. Its default matrix is native replay only: native replay registration is forced on, Cursor setting sources are disabled, the pi bridge is off, overlapping built-in pi tools are not exposed, and inherited Cursor SDK event-debug artifact env is cleared; `--event-debug` writes to a deterministic debug directory under the visual output directory. The visible TUI/output, rendered screenshots, scrubbed diagnostics, and persisted JSONL must agree. Do not mark a release ready with optional, deferred, mostly-passing, or unobserved smoke checks outstanding.
|
|
297
297
|
|
|
298
298
|
### Maintainer Cursor SDK event capture
|
|
299
299
|
|
|
@@ -333,7 +333,7 @@ When a Cursor run fails after auth is configured, pi now surfaces scrubbed provi
|
|
|
333
333
|
|
|
334
334
|
Aborted runs now include a likely cause when determinable, for example `Cancelled: prompt interrupted.` for user cancel or `Cancelled: Cursor SDK run was cancelled.` for SDK-side cancellation.
|
|
335
335
|
|
|
336
|
-
Network
|
|
336
|
+
Network failures from the Cursor SDK connect layer (for example `ConnectError: read ETIMEDOUT` or `ConnectError: [aborted] read ECONNRESET`) surface as a scrubbed retry hint instead of crashing pi. Check your connection and retry; persistent failures may indicate a transient Cursor service or network issue.
|
|
337
337
|
|
|
338
338
|
You can also restart pi with a key in the same shell or launcher that starts pi:
|
|
339
339
|
|
|
@@ -440,7 +440,7 @@ This usually needs session JSONL to classify. Common cases:
|
|
|
440
440
|
- **Stale replay routing / plan-strip:** Error `toolResult` or error assistant messages contain `Tool grep/cursor/find/ls not found`, or provider debug shows `inactive_trace` after plan-mode execute stripped active tools — tracked in **#52** (distinct from model text echo and #55).
|
|
441
441
|
- **Replay vs execution:** `cursor-replay-*` IDs and neutral **Cursor MCP** activity cards are display-only recorded Cursor results; they do not re-run browser/MCP work. See [Cursor native tool replay](docs/cursor-native-tool-replay.md).
|
|
442
442
|
- **Run failure / discarded tools:** A red toast with scrubbed detail may indicate an SDK failure (#55). Started-but-never-completed Cursor tools surface neutral **Cursor … did not complete** activity cards with a bounded reason when the run failed/aborted, produced no assistant text, or involved external/side-effectful tools. Incomplete fast local discovery starts (`read`, `grep`, `glob`, `ls`) are debug-only after a successful text-producing run so stale SDK start events do not create red post-answer cards; maintainer debug for the same gap remains in **#52** (`PI_CURSOR_SDK_EVENT_DEBUG=1`).
|
|
443
|
-
- **Hard network crash:** pi exited with uncaught `ConnectError` /
|
|
443
|
+
- **Hard network crash:** pi exited with an uncaught Cursor SDK `ConnectError` instead of showing a scrubbed retry/auth error — capture the stack/session tail as a process-guard regression, not #40 text echo.
|
|
444
444
|
|
|
445
445
|
Capture `pi --version`, extension version, model, flags, the exact prompt, and a redacted session dir before filing bugs.
|
|
446
446
|
|
|
@@ -65,8 +65,8 @@ The replay scan flags only error `toolResult` / error assistant messages with `T
|
|
|
65
65
|
|
|
66
66
|
Pass criteria:
|
|
67
67
|
|
|
68
|
-
- `pi --version` reports pi 0.
|
|
69
|
-
- `npm ls` shows `@cursor/sdk@1.0.16` and local `@earendil-works/*@0.
|
|
68
|
+
- `pi --version` reports pi 0.78.0 for this cutover baseline.
|
|
69
|
+
- `npm ls` shows `@cursor/sdk@1.0.16` and local `@earendil-works/*@0.78.0` packages.
|
|
70
70
|
- `cursor/composer-2.5` appears in the model list.
|
|
71
71
|
- No Cursor key or auth token is printed.
|
|
72
72
|
- If neither `~/.pi/agent/auth.json` cursor auth nor `CURSOR_API_KEY` is available, stop and report the live smoke as blocked.
|
|
@@ -123,7 +123,7 @@ Observe with `tmux capture-pane -pt "$SESSION"` or attach manually.
|
|
|
123
123
|
Pass criteria:
|
|
124
124
|
|
|
125
125
|
- Footer shows `(cursor) composer-2.5`. With `--cursor-no-fast`, Cursor fast mode is off and the Cursor extension status should not show `cursor fast`; ignore unrelated status text from other extensions.
|
|
126
|
-
- The run uses pi 0.
|
|
126
|
+
- The run uses pi 0.78.0 `--session-id` successfully.
|
|
127
127
|
- Assistant answer appears correctly.
|
|
128
128
|
- `/session` shows one user and one assistant message for the simple run.
|
|
129
129
|
- Persisted JSONL has one assistant message. If the screen appears duplicated, inspect JSONL before deciding whether it is a rendering bug.
|
|
@@ -131,7 +131,7 @@ Pass criteria:
|
|
|
131
131
|
|
|
132
132
|
## 4. Mandatory visual card/color rendering check
|
|
133
133
|
|
|
134
|
-
This is the canonical visual release path for Cursor provider/runtime changes. It requires offscreen TUI visual inspection, not only JSONL or code review. Use pi 0.
|
|
134
|
+
This is the canonical visual release path for Cursor provider/runtime changes. It requires offscreen TUI visual inspection, not only JSONL or code review. Use pi 0.78.0, `@cursor/sdk@1.0.16`, a fresh temporary session dir, Cursor SDK `plan` mode, native replay enabled, and the checked-in visual runner. The runner resolves `pi` by directly walking the parent `PATH`, uses `process.execPath` for Node, and prepends that Node directory for both prereq checks and tmux launches so `#!/usr/bin/env node` shims use the validated Node. The default matrix is native replay only: native replay registration is forced on, settings sources are `none`, the pi bridge is off, overlapping built-in pi tools are not exposed, and inherited Cursor SDK event-debug artifact env is cleared. With `--event-debug`, debug capture writes to a deterministic directory under `VISUAL_DIR`.
|
|
135
135
|
|
|
136
136
|
```bash
|
|
137
137
|
VISUAL_DIR="$(mktemp -d /tmp/pi-cursor-sdk-1016-visual.XXXXXX)"
|
|
@@ -15,7 +15,7 @@ Current implementation notes:
|
|
|
15
15
|
- Cursor status uses one coordinated `ctx.ui.setStatus("cursor", ...)` value for fast and non-default plan mode; the default pi footer remains intact.
|
|
16
16
|
- Installed `@cursor/sdk` user messages accept images, and Cursor models are treated as image-capable; registered input metadata is `text` plus `image`.
|
|
17
17
|
- Image payload forwarding sends images only from the latest user message. If the latest user turn is plain text after an earlier image turn, the transcript keeps an `[image omitted from transcript]` placeholder but no image bytes are sent to Cursor. The prompt explicitly tells Cursor that prior image bytes are unavailable and to ask the user to reattach or describe a prior image when needed. Carrying images forward across turns remains a future product decision because it affects token cost, privacy, stale visual context, and expected multimodal follow-up behavior.
|
|
18
|
-
- Exact `@cursor/sdk@1.0.16` is a package dependency of this extension; users should not need a global SDK install. pi 0.
|
|
18
|
+
- Exact `@cursor/sdk@1.0.16` is a package dependency of this extension; users should not need a global SDK install. pi 0.78.0 is the current validation baseline, while published pi peer dependencies are minimum-only `>=0.76.0` ranges with no upper bound. Newer pi versions are allowed to attempt loading this extension before a matching extension release exists; compatibility is best-effort until validated.
|
|
19
19
|
- Cursor auth uses pi-native API-key resolution for provider `cursor`: CLI `--api-key`, stored `~/.pi/agent/auth.json` API key from `/login`, then `CURSOR_API_KEY`. The extension config file stores only non-secret Cursor-only state such as fast defaults.
|
|
20
20
|
- Local agents pass `settingSources: ["all"]` by default so Cursor MCP servers, plugin tools, project/user settings, and related Cursor-native capabilities are available. Users can narrow loading with a comma-separated list such as `PI_CURSOR_SETTING_SOURCES=project,user,plugins`, or disable ambient setting sources with `PI_CURSOR_SETTING_SOURCES=none`. The provider suppresses direct Cursor SDK bootstrap stdout/stderr/console noise (including late first-send workspace loading such as hook compatibility warnings) so it does not pollute pi's TUI.
|
|
21
21
|
- On `cursor/*` models, pi-cursor-sdk removes only pi-generated `<project_instructions>` blocks that overlap the effective Cursor `settingSources`: `user` for `~/.pi/agent/AGENTS.md`; `project` for discovered repo/parent `AGENTS.md` and `CLAUDE.md` (verified Cursor behavior: local agents load project `AGENTS.md` and `CLAUDE.md`). `~/.pi/agent/CLAUDE.md` is not removed (Cursor user layer uses `~/.claude/CLAUDE.md`). Blocks are removed by exact pi serialization match from structured `contextFiles` via the `before_agent_start` hook, not in `buildCursorPrompt` sanitization. Suppression is skipped with `-nc`, `PI_CURSOR_SETTING_SOURCES=none`, narrowed sources such as `plugins` that omit the matching layer, or `PI_CURSOR_PRESERVE_PI_AGENTS_MD=1`. Switching away from a Cursor model restores pi's full context block on the next user message.
|
|
@@ -4,16 +4,16 @@ This workflow is the canonical repo path for verifying Cursor SDK tool replay th
|
|
|
4
4
|
|
|
5
5
|
Use it before accepting replay-card commits or PRs, and for every Cursor provider/runtime release where TUI card/color behavior could regress. Text logs and JSONL are necessary, but they are not enough when the claim is visual parity: always keep PNGs for the exact prompt, and keep before/after PNGs when reviewing a rendering change.
|
|
6
6
|
|
|
7
|
-
Current validation baseline: pi 0.
|
|
7
|
+
Current validation baseline: pi 0.78.0, exact `@cursor/sdk@1.0.16`, local validation packages `@earendil-works/pi-ai`, `@earendil-works/pi-coding-agent`, and `@earendil-works/pi-tui` at 0.78.0. Published peer dependencies remain minimum-only at pi 0.76.0+ with no upper bound, so newer pi installs can try the extension before a matching validation release exists.
|
|
8
8
|
|
|
9
|
-
## Cursor SDK 1.0.16 / pi 0.
|
|
9
|
+
## Cursor SDK 1.0.16 / pi 0.78.0 cutover visual record
|
|
10
10
|
|
|
11
11
|
Record the required cutover validation here or in the final release handoff. The default matrix is native replay only: the runner forces native replay registration on, forces Cursor setting sources off, disables the pi bridge, disables overlapping built-in pi tool exposure, and clears inherited Cursor SDK event-debug artifact env. With `--event-debug`, debug capture writes to a deterministic directory under the visual output directory. Do not commit raw ANSI logs, screenshots, terminal recordings, debug artifacts, or `.debug/visual-smoke` scratch files.
|
|
12
12
|
|
|
13
13
|
| Field | Required value / evidence |
|
|
14
14
|
| --- | --- |
|
|
15
15
|
| Command/session used | `npm run smoke:visual -- --ext "$PWD" --cwd "$PWD" --mode plan --out-dir <fresh /tmp dir> --label <matrix label> --prompt <matrix prompt>` with default native-replay isolation |
|
|
16
|
-
| Baseline versions | `pi --version` = 0.
|
|
16
|
+
| Baseline versions | `pi --version` = 0.78.0; `npm ls` = `@cursor/sdk@1.0.16` and local `@earendil-works/*@0.78.0` |
|
|
17
17
|
| Card categories checked | Claim only categories proven by both PNG and JSONL. Required cutover categories are read, grep/search, find/glob, list, shell success, write, edit/diff, and true read failure. Neutral Cursor plan/todo/task/mode activity is optional/opportunistic and only counts when JSONL contains a completed Cursor workflow event. |
|
|
18
18
|
| Observed status/card colors | Confirm native-looking cards use native pi styling; neutral Cursor activity is not red; true errors are distinct; diff previews show red/green; plan status is readable |
|
|
19
19
|
| Screenshot/ANSI evidence location | External path only, for example `/tmp/pi-cursor-sdk-1016-visual.*/read-package.{ansi,txt,html,png,jsonl.path}` |
|
|
@@ -238,7 +238,7 @@ The script writes timestamped artifacts under `--out` (default `/tmp/pi-cursor-s
|
|
|
238
238
|
|
|
239
239
|
Stdout prints artifact paths and summary counts only. Raw payloads stay on disk and may contain local paths, project text, tool args/results, or secrets — do not commit or share them.
|
|
240
240
|
|
|
241
|
-
Hard repo rule: Cursor SDK behavior claims must come from the installed `@cursor/sdk` package and/or https://cursor.com/docs/sdk/typescript, not from memory or ad-hoc probes alone. Current cutover validation targets exact `@cursor/sdk@1.0.16` and pi 0.
|
|
241
|
+
Hard repo rule: Cursor SDK behavior claims must come from the installed `@cursor/sdk` package and/or https://cursor.com/docs/sdk/typescript, not from memory or ad-hoc probes alone. Current cutover validation targets exact `@cursor/sdk@1.0.16` and pi 0.78.0 local packages.
|
|
242
242
|
|
|
243
243
|
## Pi provider SDK event capture
|
|
244
244
|
|
|
@@ -394,7 +394,7 @@ npm run debug:sdk-events -- \
|
|
|
394
394
|
|
|
395
395
|
Start with whether pi stayed alive:
|
|
396
396
|
|
|
397
|
-
0. **pi process exited / shell returned with uncaught `ConnectError` (`ETIMEDOUT`,
|
|
397
|
+
0. **pi process exited / shell returned with uncaught `ConnectError` (for example `ETIMEDOUT`, `ECONNRESET`, `read ETIMEDOUT`, or `[aborted] read ECONNRESET`)** — hard network crash bypassing provider error surfacing. Current code guards observed Cursor SDK/network-reset shapes during active Cursor turns and should show scrubbed retry guidance instead; treat a fresh process exit as a process-guard regression, capture the stack/session tail, and route to **#43/#107** rather than #40 model text echo. If tools were mid-flight, note whether session JSONL ends abruptly.
|
|
398
398
|
|
|
399
399
|
Then inspect the failing assistant turn in `$SMOKE_DIR/session/*.jsonl`:
|
|
400
400
|
|
|
@@ -414,7 +414,7 @@ rg '"type": "toolCall"|Tool call \(Cursor|cursor-replay-' "$SMOKE_DIR/session"/*
|
|
|
414
414
|
|
|
415
415
|
### When to file follow-ups
|
|
416
416
|
|
|
417
|
-
- **#43** — pi exited from uncaught `ConnectError` /
|
|
417
|
+
- **#43/#107** — pi exited from uncaught Cursor SDK `ConnectError` / network reset during HTTP traffic (hard crash, not a scrubbed #55 toast). Observed `ETIMEDOUT` and `ECONNRESET` shapes should be guarded during active Cursor turns; new exits need stack/session evidence.
|
|
418
418
|
- **#55** — caught SDK run failure or abort with missing/opaque detail (already addressed on main for surfacing).
|
|
419
419
|
- **#52** — stale/inactive native replay routing after plan-strip or stale `context.tools` snapshot (`Tool * not found` in JSONL, `inactive_trace` in `display-decisions.jsonl`); or maintainer needs an explicit "started X, never completed" debug line when JSONL shows no completion and no model text echo.
|
|
420
420
|
- **New issue** — bridge dispatch failure with `[pi-cursor-sdk:bridge]` evidence, or proven provider bug with JSONL showing missing `toolCall` despite SDK `tool-call-completed` in `on-delta.jsonl` from `debug:provider-events` or `debug:sdk-events` artifacts.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-cursor-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.28",
|
|
4
4
|
"description": "pi provider extension backed by @cursor/sdk local agents",
|
|
5
5
|
"author": "Mitch Fultz (https://github.com/fitchmultz)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -92,9 +92,9 @@
|
|
|
92
92
|
"typebox": "*"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@earendil-works/pi-ai": "0.
|
|
96
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
97
|
-
"@earendil-works/pi-tui": "0.
|
|
95
|
+
"@earendil-works/pi-ai": "0.78.0",
|
|
96
|
+
"@earendil-works/pi-coding-agent": "0.78.0",
|
|
97
|
+
"@earendil-works/pi-tui": "0.78.0",
|
|
98
98
|
"@xterm/xterm": "^6.0.0",
|
|
99
99
|
"playwright": "^1.60.0",
|
|
100
100
|
"typebox": "^1.1.38",
|
|
@@ -47,9 +47,14 @@ function isUnauthenticatedConnectCode(code: unknown): boolean {
|
|
|
47
47
|
return code === 16 || (typeof code === "string" && /^(?:16|unauthenticated)$/i.test(code));
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
function isCursorExtensionConnectStack(stack: string): boolean {
|
|
51
|
+
return stack.includes("@connectrpc/connect-node") && /(?:^|[\\/])pi-cursor-sdk(?:[\\/]|$)/.test(stack);
|
|
52
|
+
}
|
|
53
|
+
|
|
50
54
|
function getCursorConnectSource(error: unknown, record: Record<string, unknown> | undefined): CursorConnectErrorSource {
|
|
51
55
|
const stack = getErrorStack(error, record);
|
|
52
56
|
if (stack.includes("@cursor/sdk")) return "cursor-sdk-stack";
|
|
57
|
+
if (isCursorExtensionConnectStack(stack)) return "cursor-extension-connect-stack";
|
|
53
58
|
const details = Array.isArray(record?.details) ? record.details : [];
|
|
54
59
|
const hasCursorBackendDetails = details.some((detail) => {
|
|
55
60
|
const type = getErrorStringField(asRecord(detail), "type");
|
|
@@ -58,11 +63,16 @@ function getCursorConnectSource(error: unknown, record: Record<string, unknown>
|
|
|
58
63
|
return hasCursorBackendDetails ? "cursor-backend-details" : "generic-connect";
|
|
59
64
|
}
|
|
60
65
|
|
|
61
|
-
export type CursorConnectErrorSource =
|
|
66
|
+
export type CursorConnectErrorSource =
|
|
67
|
+
| "cursor-sdk-stack"
|
|
68
|
+
| "cursor-extension-connect-stack"
|
|
69
|
+
| "cursor-backend-details"
|
|
70
|
+
| "generic-connect";
|
|
62
71
|
|
|
63
72
|
export type CursorConnectErrorClassification =
|
|
64
73
|
| { kind: "abort"; source: "cursor-sdk-stack" }
|
|
65
|
-
| { kind: "unauthenticated"; source: CursorConnectErrorSource }
|
|
74
|
+
| { kind: "unauthenticated"; source: CursorConnectErrorSource }
|
|
75
|
+
| { kind: "network"; source: CursorConnectErrorSource };
|
|
66
76
|
|
|
67
77
|
export function classifyCursorConnectError(error: unknown): CursorConnectErrorClassification | undefined {
|
|
68
78
|
const record = asRecord(error);
|
|
@@ -89,6 +99,12 @@ export function classifyCursorConnectError(error: unknown): CursorConnectErrorCl
|
|
|
89
99
|
return { kind: "unauthenticated", source: getCursorConnectSource(error, record) };
|
|
90
100
|
}
|
|
91
101
|
|
|
102
|
+
const causeCode = getErrorStringField(cause, "code");
|
|
103
|
+
const causeSyscall = getErrorStringField(cause, "syscall");
|
|
104
|
+
if (isLikelyNetworkTimeout(`${message}\n${rawMessage}\n${causeCode ?? ""}\n${causeSyscall ?? ""}`)) {
|
|
105
|
+
return { kind: "network", source: getCursorConnectSource(error, record) };
|
|
106
|
+
}
|
|
107
|
+
|
|
92
108
|
return undefined;
|
|
93
109
|
}
|
|
94
110
|
|
|
@@ -26,7 +26,7 @@ function hasActiveAbortSuppression(): boolean {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function isCursorProvenance(source: string): boolean {
|
|
29
|
-
return source === "cursor-sdk-stack" || source === "cursor-backend-details";
|
|
29
|
+
return source === "cursor-sdk-stack" || source === "cursor-extension-connect-stack" || source === "cursor-backend-details";
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
function shouldSuppressProcessError(event: string | symbol, args: readonly unknown[]): boolean {
|