@sideboard-ai/core 0.1.52 → 0.1.56
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/dist/agents/cursor-runner.cjs +126 -11
- package/dist/agents/cursor-runner.js +45 -6
- package/dist/{agents-YKSS6VBO.js → agents-2YYWW723.js} +3 -3
- package/dist/{agents-ON6RKKND.js → agents-AQFEFKBL.js} +2 -2
- package/dist/{app-settings-LZP632KI.js → app-settings-2LQNRTBE.js} +3 -1
- package/dist/{app-settings-7XVDQJ7F.js → app-settings-73DI4B6T.js} +3 -1
- package/dist/{chunk-J5JTEJ5O.js → chunk-3WJAUKIL.js} +89 -7
- package/dist/{chunk-GNML24AW.js → chunk-5DMYULLC.js} +1 -1
- package/dist/{chunk-D3METLRW.js → chunk-7F454EE2.js} +96 -14
- package/dist/{chunk-6QTZVJ7A.js → chunk-C3J4GDW4.js} +188 -24
- package/dist/{chunk-HBJSHRY2.js → chunk-C4BCC5X5.js} +17 -1
- package/dist/{chunk-T5QQVXK3.js → chunk-DIOF73S2.js} +17 -1
- package/dist/{chunk-UEAHMGHW.js → chunk-DQJ5D42H.js} +16 -2
- package/dist/{chunk-YOWIYAVA.js → chunk-EBWEKG52.js} +36 -11
- package/dist/{chunk-XX5BB7NV.js → chunk-S42XDFKF.js} +36 -11
- package/dist/{chunk-LRLKJM3O.js → chunk-UA5NDAHL.js} +16 -2
- package/dist/{chunk-YDXQ72MD.js → chunk-V2DUTUNC.js} +1 -1
- package/dist/{coordinator-prompt-S6JZD5EF.js → coordinator-prompt-ICF36NUQ.js} +2 -1
- package/dist/{coordinator-prompt-6FXVTSFN.js → coordinator-prompt-RBKUNRPR.js} +2 -1
- package/dist/{global-workspace-EV4G2WMQ.js → global-workspace-667XLBW6.js} +3 -2
- package/dist/{global-workspace-MSX2K27Y.js → global-workspace-S7VLWPWG.js} +3 -2
- package/dist/index.cjs +395 -61
- package/dist/index.d.cts +25 -2
- package/dist/index.d.ts +25 -2
- package/dist/index.js +164 -43
- package/dist/mcp/run-stdio.cjs +389 -57
- package/dist/mcp/run-stdio.js +164 -44
- package/dist/{workspaces-AYTBR6KQ.js → workspaces-FPJJXXAE.js} +4 -3
- package/dist/{workspaces-3RQQZQRO.js → workspaces-LYIDE2VR.js} +4 -3
- package/package.json +1 -1
|
@@ -84,6 +84,75 @@ function usageFromCursor(usage) {
|
|
|
84
84
|
cacheWriteTokens: usage.cacheWriteTokens ? Number(usage.cacheWriteTokens) : void 0
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
|
+
function asRecord(value) {
|
|
88
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
return void 0;
|
|
92
|
+
}
|
|
93
|
+
function normalizeCursorToolCall(name, args) {
|
|
94
|
+
const raw = asRecord(args);
|
|
95
|
+
const toolName = typeof raw?.toolName === "string" && raw.toolName.trim() ? raw.toolName.trim() : null;
|
|
96
|
+
const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord(raw?.args) != null);
|
|
97
|
+
if (looksLikeMcp && toolName) {
|
|
98
|
+
const providerRaw = typeof raw.providerIdentifier === "string" && raw.providerIdentifier.trim() ? raw.providerIdentifier.trim() : "sideboard";
|
|
99
|
+
const provider = providerRaw.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
100
|
+
const nested = asRecord(raw.args);
|
|
101
|
+
return {
|
|
102
|
+
name: `mcp__${provider}__${toolName}`,
|
|
103
|
+
input: nested ?? { toolName }
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return { name, input: raw };
|
|
107
|
+
}
|
|
108
|
+
function unwrapCursorToolResult(result) {
|
|
109
|
+
if (result == null) return void 0;
|
|
110
|
+
if (typeof result === "string") return result;
|
|
111
|
+
const rec = asRecord(result);
|
|
112
|
+
if (!rec) {
|
|
113
|
+
try {
|
|
114
|
+
return JSON.stringify(result);
|
|
115
|
+
} catch {
|
|
116
|
+
return String(result);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const collectTexts = (items) => {
|
|
120
|
+
const texts = [];
|
|
121
|
+
for (const item of items) {
|
|
122
|
+
const row = asRecord(item);
|
|
123
|
+
if (!row) continue;
|
|
124
|
+
if (typeof row.text === "string") {
|
|
125
|
+
texts.push(row.text);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
const nested = asRecord(row.text);
|
|
129
|
+
if (typeof nested?.text === "string") texts.push(nested.text);
|
|
130
|
+
}
|
|
131
|
+
return texts;
|
|
132
|
+
};
|
|
133
|
+
const value = asRecord(rec.value);
|
|
134
|
+
if (value && Array.isArray(value.content)) {
|
|
135
|
+
const texts = collectTexts(value.content);
|
|
136
|
+
if (texts.length) return texts.join("\n");
|
|
137
|
+
}
|
|
138
|
+
if (Array.isArray(rec.content)) {
|
|
139
|
+
const texts = collectTexts(rec.content);
|
|
140
|
+
if (texts.length) return texts.join("\n");
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
return JSON.stringify(result);
|
|
144
|
+
} catch {
|
|
145
|
+
return String(result);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function cursorToolResultIsError(status, result) {
|
|
149
|
+
if (status === "error") return true;
|
|
150
|
+
const rec = asRecord(result);
|
|
151
|
+
if (!rec) return false;
|
|
152
|
+
if (rec.status === "error") return true;
|
|
153
|
+
const value = asRecord(rec.value);
|
|
154
|
+
return value?.isError === true;
|
|
155
|
+
}
|
|
87
156
|
function cursorSdkMessageToEvents(msg) {
|
|
88
157
|
if (!msg?.type) return [];
|
|
89
158
|
if (msg.type === "system" && msg.agent_id) {
|
|
@@ -98,35 +167,42 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
98
167
|
if (block?.type === "text" && block.text) {
|
|
99
168
|
out.push({ type: "stdout", data: block.text });
|
|
100
169
|
} else if (block?.type === "tool_use" && block.id && block.name) {
|
|
170
|
+
const normalized = normalizeCursorToolCall(block.name, block.input);
|
|
101
171
|
out.push({
|
|
102
172
|
type: "tool_use",
|
|
103
173
|
id: block.id,
|
|
104
|
-
name:
|
|
105
|
-
input:
|
|
174
|
+
name: normalized.name,
|
|
175
|
+
input: normalized.input
|
|
106
176
|
});
|
|
107
177
|
}
|
|
108
178
|
}
|
|
109
179
|
return out;
|
|
110
180
|
}
|
|
111
181
|
if (msg.type === "tool_call" && msg.call_id && msg.name) {
|
|
182
|
+
const normalized = normalizeCursorToolCall(msg.name, msg.args);
|
|
112
183
|
if (msg.status === "running") {
|
|
113
184
|
return [
|
|
114
185
|
{
|
|
115
186
|
type: "tool_use",
|
|
116
187
|
id: msg.call_id,
|
|
117
|
-
name:
|
|
118
|
-
input:
|
|
188
|
+
name: normalized.name,
|
|
189
|
+
input: normalized.input
|
|
119
190
|
}
|
|
120
191
|
];
|
|
121
192
|
}
|
|
122
193
|
if (msg.status === "completed" || msg.status === "error") {
|
|
123
|
-
const content = typeof msg.result === "string" ? msg.result : msg.result != null ? JSON.stringify(msg.result) : void 0;
|
|
124
194
|
return [
|
|
195
|
+
{
|
|
196
|
+
type: "tool_use",
|
|
197
|
+
id: msg.call_id,
|
|
198
|
+
name: normalized.name,
|
|
199
|
+
input: normalized.input
|
|
200
|
+
},
|
|
125
201
|
{
|
|
126
202
|
type: "tool_result",
|
|
127
203
|
id: msg.call_id,
|
|
128
|
-
content,
|
|
129
|
-
isError: msg.status
|
|
204
|
+
content: unwrapCursorToolResult(msg.result),
|
|
205
|
+
isError: cursorToolResultIsError(msg.status, msg.result)
|
|
130
206
|
}
|
|
131
207
|
];
|
|
132
208
|
}
|
|
@@ -171,6 +247,33 @@ function localAgentStore() {
|
|
|
171
247
|
(0, import_node_fs3.mkdirSync)(root, { recursive: true });
|
|
172
248
|
return new import_sdk.JsonlLocalAgentStore(root);
|
|
173
249
|
}
|
|
250
|
+
function isAgentBusyError(err) {
|
|
251
|
+
if (err instanceof import_sdk.AgentBusyError) return true;
|
|
252
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
253
|
+
return /already has active run/i.test(message);
|
|
254
|
+
}
|
|
255
|
+
async function cancelStaleLocalRuns(agentId, opts) {
|
|
256
|
+
const listed = await import_sdk.Agent.listRuns(agentId, {
|
|
257
|
+
runtime: "local",
|
|
258
|
+
cwd: opts.cwd,
|
|
259
|
+
store: opts.store,
|
|
260
|
+
limit: 20
|
|
261
|
+
});
|
|
262
|
+
let cancelled = 0;
|
|
263
|
+
for (const run of listed.items) {
|
|
264
|
+
if (run.status !== "running") continue;
|
|
265
|
+
try {
|
|
266
|
+
await import_sdk.Agent.cancelRun(run.id, {
|
|
267
|
+
runtime: "local",
|
|
268
|
+
cwd: opts.cwd,
|
|
269
|
+
store: opts.store
|
|
270
|
+
});
|
|
271
|
+
cancelled += 1;
|
|
272
|
+
} catch {
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return cancelled;
|
|
276
|
+
}
|
|
174
277
|
async function readStdinJson() {
|
|
175
278
|
const rl = (0, import_node_readline.createInterface)({ input: process.stdin, crlfDelay: Infinity });
|
|
176
279
|
const chunks = [];
|
|
@@ -242,10 +345,22 @@ async function main() {
|
|
|
242
345
|
}
|
|
243
346
|
try {
|
|
244
347
|
emit({ type: "session_id", data: agent.agentId });
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
348
|
+
const sendOpts = mcpServers ? { mcpServers } : void 0;
|
|
349
|
+
let run;
|
|
350
|
+
try {
|
|
351
|
+
run = await agent.send(req.prompt, sendOpts);
|
|
352
|
+
} catch (err) {
|
|
353
|
+
if (!isAgentBusyError(err)) throw err;
|
|
354
|
+
const n = await cancelStaleLocalRuns(agent.agentId, {
|
|
355
|
+
cwd: req.cwd,
|
|
356
|
+
store
|
|
357
|
+
});
|
|
358
|
+
emit({
|
|
359
|
+
type: "stderr",
|
|
360
|
+
data: n > 0 ? `Cursor agent had ${n} stale active run(s) \u2014 cancelled and retrying` : "Cursor agent busy \u2014 retrying send"
|
|
361
|
+
});
|
|
362
|
+
run = await agent.send(req.prompt, sendOpts);
|
|
363
|
+
}
|
|
249
364
|
for await (const msg of run.stream()) {
|
|
250
365
|
for (const event of cursorSdkMessageToEvents(msg)) {
|
|
251
366
|
emit(event);
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import {
|
|
3
3
|
cursorSdkMessageToEvents,
|
|
4
4
|
formatUnknownDetail
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-3WJAUKIL.js";
|
|
6
6
|
import {
|
|
7
7
|
appDataDir
|
|
8
8
|
} from "../chunk-M37RITA6.js";
|
|
9
9
|
|
|
10
10
|
// src/agents/cursor-runner.ts
|
|
11
|
-
import { Agent, CursorAgentError, JsonlLocalAgentStore } from "@cursor/sdk";
|
|
11
|
+
import { Agent, AgentBusyError, CursorAgentError, JsonlLocalAgentStore } from "@cursor/sdk";
|
|
12
12
|
import { mkdirSync } from "fs";
|
|
13
13
|
import { join } from "path";
|
|
14
14
|
import { createInterface } from "readline";
|
|
@@ -35,6 +35,33 @@ function localAgentStore() {
|
|
|
35
35
|
mkdirSync(root, { recursive: true });
|
|
36
36
|
return new JsonlLocalAgentStore(root);
|
|
37
37
|
}
|
|
38
|
+
function isAgentBusyError(err) {
|
|
39
|
+
if (err instanceof AgentBusyError) return true;
|
|
40
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
41
|
+
return /already has active run/i.test(message);
|
|
42
|
+
}
|
|
43
|
+
async function cancelStaleLocalRuns(agentId, opts) {
|
|
44
|
+
const listed = await Agent.listRuns(agentId, {
|
|
45
|
+
runtime: "local",
|
|
46
|
+
cwd: opts.cwd,
|
|
47
|
+
store: opts.store,
|
|
48
|
+
limit: 20
|
|
49
|
+
});
|
|
50
|
+
let cancelled = 0;
|
|
51
|
+
for (const run of listed.items) {
|
|
52
|
+
if (run.status !== "running") continue;
|
|
53
|
+
try {
|
|
54
|
+
await Agent.cancelRun(run.id, {
|
|
55
|
+
runtime: "local",
|
|
56
|
+
cwd: opts.cwd,
|
|
57
|
+
store: opts.store
|
|
58
|
+
});
|
|
59
|
+
cancelled += 1;
|
|
60
|
+
} catch {
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return cancelled;
|
|
64
|
+
}
|
|
38
65
|
async function readStdinJson() {
|
|
39
66
|
const rl = createInterface({ input: process.stdin, crlfDelay: Infinity });
|
|
40
67
|
const chunks = [];
|
|
@@ -106,10 +133,22 @@ async function main() {
|
|
|
106
133
|
}
|
|
107
134
|
try {
|
|
108
135
|
emit({ type: "session_id", data: agent.agentId });
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
136
|
+
const sendOpts = mcpServers ? { mcpServers } : void 0;
|
|
137
|
+
let run;
|
|
138
|
+
try {
|
|
139
|
+
run = await agent.send(req.prompt, sendOpts);
|
|
140
|
+
} catch (err) {
|
|
141
|
+
if (!isAgentBusyError(err)) throw err;
|
|
142
|
+
const n = await cancelStaleLocalRuns(agent.agentId, {
|
|
143
|
+
cwd: req.cwd,
|
|
144
|
+
store
|
|
145
|
+
});
|
|
146
|
+
emit({
|
|
147
|
+
type: "stderr",
|
|
148
|
+
data: n > 0 ? `Cursor agent had ${n} stale active run(s) \u2014 cancelled and retrying` : "Cursor agent busy \u2014 retrying send"
|
|
149
|
+
});
|
|
150
|
+
run = await agent.send(req.prompt, sendOpts);
|
|
151
|
+
}
|
|
113
152
|
for await (const msg of run.stream()) {
|
|
114
153
|
for (const event of cursorSdkMessageToEvents(msg)) {
|
|
115
154
|
emit(event);
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
permissionMode,
|
|
27
27
|
resolveCursorModelId,
|
|
28
28
|
resolveQuotaFallbackAgent
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-7F454EE2.js";
|
|
30
30
|
import {
|
|
31
31
|
ORCHESTRATOR_AGENT_KINDS,
|
|
32
32
|
assertOrchestratorCapableAgent,
|
|
@@ -37,8 +37,8 @@ import "./chunk-BXJ76RHF.js";
|
|
|
37
37
|
import {
|
|
38
38
|
cursorSdkMessageToEvents,
|
|
39
39
|
parseCursorRunnerLine
|
|
40
|
-
} from "./chunk-
|
|
41
|
-
import "./chunk-
|
|
40
|
+
} from "./chunk-3WJAUKIL.js";
|
|
41
|
+
import "./chunk-DIOF73S2.js";
|
|
42
42
|
import "./chunk-77WWLBCI.js";
|
|
43
43
|
import "./chunk-M37RITA6.js";
|
|
44
44
|
import {
|
|
@@ -30,9 +30,8 @@ import {
|
|
|
30
30
|
permissionMode,
|
|
31
31
|
resolveCursorModelId,
|
|
32
32
|
resolveQuotaFallbackAgent
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-C3J4GDW4.js";
|
|
34
34
|
import "./chunk-H6GGDLYS.js";
|
|
35
|
-
import "./chunk-HBJSHRY2.js";
|
|
36
35
|
import {
|
|
37
36
|
ORCHESTRATOR_AGENT_KINDS,
|
|
38
37
|
assertOrchestratorCapableAgent,
|
|
@@ -42,6 +41,7 @@ import {
|
|
|
42
41
|
import {
|
|
43
42
|
ensureAgentPath
|
|
44
43
|
} from "./chunk-ZNM4MAN4.js";
|
|
44
|
+
import "./chunk-C4BCC5X5.js";
|
|
45
45
|
import "./chunk-KGZBYWZ3.js";
|
|
46
46
|
import "./chunk-7MV3RXSC.js";
|
|
47
47
|
export {
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
orchestrationQuotaOnLimit,
|
|
28
28
|
resolveClaudeExecutable,
|
|
29
29
|
resolveEffectiveIssueSource,
|
|
30
|
+
resolveNewThreadOptions,
|
|
30
31
|
resolveThreadDefaults,
|
|
31
32
|
saveAppSettings,
|
|
32
33
|
updateAdvancedSettings,
|
|
@@ -35,7 +36,7 @@ import {
|
|
|
35
36
|
updateClaudeSettings,
|
|
36
37
|
updateDefaultsSettings,
|
|
37
38
|
updateIntegrationsSettings
|
|
38
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-DIOF73S2.js";
|
|
39
40
|
import "./chunk-77WWLBCI.js";
|
|
40
41
|
import "./chunk-M37RITA6.js";
|
|
41
42
|
export {
|
|
@@ -67,6 +68,7 @@ export {
|
|
|
67
68
|
orchestrationQuotaOnLimit,
|
|
68
69
|
resolveClaudeExecutable,
|
|
69
70
|
resolveEffectiveIssueSource,
|
|
71
|
+
resolveNewThreadOptions,
|
|
70
72
|
resolveThreadDefaults,
|
|
71
73
|
saveAppSettings,
|
|
72
74
|
updateAdvancedSettings,
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
orchestrationQuotaOnLimit,
|
|
30
30
|
resolveClaudeExecutable,
|
|
31
31
|
resolveEffectiveIssueSource,
|
|
32
|
+
resolveNewThreadOptions,
|
|
32
33
|
resolveThreadDefaults,
|
|
33
34
|
saveAppSettings,
|
|
34
35
|
updateAdvancedSettings,
|
|
@@ -37,7 +38,7 @@ import {
|
|
|
37
38
|
updateClaudeSettings,
|
|
38
39
|
updateDefaultsSettings,
|
|
39
40
|
updateIntegrationsSettings
|
|
40
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-C4BCC5X5.js";
|
|
41
42
|
import "./chunk-KGZBYWZ3.js";
|
|
42
43
|
import "./chunk-7MV3RXSC.js";
|
|
43
44
|
export {
|
|
@@ -69,6 +70,7 @@ export {
|
|
|
69
70
|
orchestrationQuotaOnLimit,
|
|
70
71
|
resolveClaudeExecutable,
|
|
71
72
|
resolveEffectiveIssueSource,
|
|
73
|
+
resolveNewThreadOptions,
|
|
72
74
|
resolveThreadDefaults,
|
|
73
75
|
saveAppSettings,
|
|
74
76
|
updateAdvancedSettings,
|
|
@@ -60,6 +60,11 @@ function summarizeTurnStderr(tail, maxChars = 500) {
|
|
|
60
60
|
if (joined.length <= maxChars) return joined;
|
|
61
61
|
return joined.slice(joined.length - maxChars);
|
|
62
62
|
}
|
|
63
|
+
function looksLikeInvalidAgentSession(text) {
|
|
64
|
+
const lower = text.trim().toLowerCase();
|
|
65
|
+
if (!lower) return false;
|
|
66
|
+
return /session not found/.test(lower) || /no conversation found/.test(lower) || /conversation .+ not found/.test(lower) || /thread .+ not found/.test(lower) || /unknown session/.test(lower) || /invalid session/.test(lower) || /session .+ (missing|expired|deleted|gone)/.test(lower) || /cannot resume/.test(lower) || /failed to (load|resume|open) session/.test(lower);
|
|
67
|
+
}
|
|
63
68
|
function looksLikeAgentFailureMessage(text) {
|
|
64
69
|
const lower = text.trim().toLowerCase();
|
|
65
70
|
if (!lower) return false;
|
|
@@ -127,6 +132,75 @@ function usageFromCursor(usage) {
|
|
|
127
132
|
cacheWriteTokens: usage.cacheWriteTokens ? Number(usage.cacheWriteTokens) : void 0
|
|
128
133
|
};
|
|
129
134
|
}
|
|
135
|
+
function asRecord(value) {
|
|
136
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
139
|
+
return void 0;
|
|
140
|
+
}
|
|
141
|
+
function normalizeCursorToolCall(name, args) {
|
|
142
|
+
const raw = asRecord(args);
|
|
143
|
+
const toolName = typeof raw?.toolName === "string" && raw.toolName.trim() ? raw.toolName.trim() : null;
|
|
144
|
+
const looksLikeMcp = name === "mcp" || toolName != null && (typeof raw?.providerIdentifier === "string" || asRecord(raw?.args) != null);
|
|
145
|
+
if (looksLikeMcp && toolName) {
|
|
146
|
+
const providerRaw = typeof raw.providerIdentifier === "string" && raw.providerIdentifier.trim() ? raw.providerIdentifier.trim() : "sideboard";
|
|
147
|
+
const provider = providerRaw.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
148
|
+
const nested = asRecord(raw.args);
|
|
149
|
+
return {
|
|
150
|
+
name: `mcp__${provider}__${toolName}`,
|
|
151
|
+
input: nested ?? { toolName }
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return { name, input: raw };
|
|
155
|
+
}
|
|
156
|
+
function unwrapCursorToolResult(result) {
|
|
157
|
+
if (result == null) return void 0;
|
|
158
|
+
if (typeof result === "string") return result;
|
|
159
|
+
const rec = asRecord(result);
|
|
160
|
+
if (!rec) {
|
|
161
|
+
try {
|
|
162
|
+
return JSON.stringify(result);
|
|
163
|
+
} catch {
|
|
164
|
+
return String(result);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const collectTexts = (items) => {
|
|
168
|
+
const texts = [];
|
|
169
|
+
for (const item of items) {
|
|
170
|
+
const row = asRecord(item);
|
|
171
|
+
if (!row) continue;
|
|
172
|
+
if (typeof row.text === "string") {
|
|
173
|
+
texts.push(row.text);
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
const nested = asRecord(row.text);
|
|
177
|
+
if (typeof nested?.text === "string") texts.push(nested.text);
|
|
178
|
+
}
|
|
179
|
+
return texts;
|
|
180
|
+
};
|
|
181
|
+
const value = asRecord(rec.value);
|
|
182
|
+
if (value && Array.isArray(value.content)) {
|
|
183
|
+
const texts = collectTexts(value.content);
|
|
184
|
+
if (texts.length) return texts.join("\n");
|
|
185
|
+
}
|
|
186
|
+
if (Array.isArray(rec.content)) {
|
|
187
|
+
const texts = collectTexts(rec.content);
|
|
188
|
+
if (texts.length) return texts.join("\n");
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
return JSON.stringify(result);
|
|
192
|
+
} catch {
|
|
193
|
+
return String(result);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function cursorToolResultIsError(status, result) {
|
|
197
|
+
if (status === "error") return true;
|
|
198
|
+
const rec = asRecord(result);
|
|
199
|
+
if (!rec) return false;
|
|
200
|
+
if (rec.status === "error") return true;
|
|
201
|
+
const value = asRecord(rec.value);
|
|
202
|
+
return value?.isError === true;
|
|
203
|
+
}
|
|
130
204
|
function cursorSdkMessageToEvents(msg) {
|
|
131
205
|
if (!msg?.type) return [];
|
|
132
206
|
if (msg.type === "system" && msg.agent_id) {
|
|
@@ -141,35 +215,42 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
141
215
|
if (block?.type === "text" && block.text) {
|
|
142
216
|
out.push({ type: "stdout", data: block.text });
|
|
143
217
|
} else if (block?.type === "tool_use" && block.id && block.name) {
|
|
218
|
+
const normalized = normalizeCursorToolCall(block.name, block.input);
|
|
144
219
|
out.push({
|
|
145
220
|
type: "tool_use",
|
|
146
221
|
id: block.id,
|
|
147
|
-
name:
|
|
148
|
-
input:
|
|
222
|
+
name: normalized.name,
|
|
223
|
+
input: normalized.input
|
|
149
224
|
});
|
|
150
225
|
}
|
|
151
226
|
}
|
|
152
227
|
return out;
|
|
153
228
|
}
|
|
154
229
|
if (msg.type === "tool_call" && msg.call_id && msg.name) {
|
|
230
|
+
const normalized = normalizeCursorToolCall(msg.name, msg.args);
|
|
155
231
|
if (msg.status === "running") {
|
|
156
232
|
return [
|
|
157
233
|
{
|
|
158
234
|
type: "tool_use",
|
|
159
235
|
id: msg.call_id,
|
|
160
|
-
name:
|
|
161
|
-
input:
|
|
236
|
+
name: normalized.name,
|
|
237
|
+
input: normalized.input
|
|
162
238
|
}
|
|
163
239
|
];
|
|
164
240
|
}
|
|
165
241
|
if (msg.status === "completed" || msg.status === "error") {
|
|
166
|
-
const content = typeof msg.result === "string" ? msg.result : msg.result != null ? JSON.stringify(msg.result) : void 0;
|
|
167
242
|
return [
|
|
243
|
+
{
|
|
244
|
+
type: "tool_use",
|
|
245
|
+
id: msg.call_id,
|
|
246
|
+
name: normalized.name,
|
|
247
|
+
input: normalized.input
|
|
248
|
+
},
|
|
168
249
|
{
|
|
169
250
|
type: "tool_result",
|
|
170
251
|
id: msg.call_id,
|
|
171
|
-
content,
|
|
172
|
-
isError: msg.status
|
|
252
|
+
content: unwrapCursorToolResult(msg.result),
|
|
253
|
+
isError: cursorToolResultIsError(msg.status, msg.result)
|
|
173
254
|
}
|
|
174
255
|
];
|
|
175
256
|
}
|
|
@@ -212,6 +293,7 @@ export {
|
|
|
212
293
|
extractJsonErrorMessage,
|
|
213
294
|
pushTurnStderr,
|
|
214
295
|
summarizeTurnStderr,
|
|
296
|
+
looksLikeInvalidAgentSession,
|
|
215
297
|
looksLikeAgentFailureMessage,
|
|
216
298
|
fallbackTurnFailDetail,
|
|
217
299
|
humanizeAgentFailDetail,
|