@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.
Files changed (30) hide show
  1. package/dist/agents/cursor-runner.cjs +126 -11
  2. package/dist/agents/cursor-runner.js +45 -6
  3. package/dist/{agents-YKSS6VBO.js → agents-2YYWW723.js} +3 -3
  4. package/dist/{agents-ON6RKKND.js → agents-AQFEFKBL.js} +2 -2
  5. package/dist/{app-settings-LZP632KI.js → app-settings-2LQNRTBE.js} +3 -1
  6. package/dist/{app-settings-7XVDQJ7F.js → app-settings-73DI4B6T.js} +3 -1
  7. package/dist/{chunk-J5JTEJ5O.js → chunk-3WJAUKIL.js} +89 -7
  8. package/dist/{chunk-GNML24AW.js → chunk-5DMYULLC.js} +1 -1
  9. package/dist/{chunk-D3METLRW.js → chunk-7F454EE2.js} +96 -14
  10. package/dist/{chunk-6QTZVJ7A.js → chunk-C3J4GDW4.js} +188 -24
  11. package/dist/{chunk-HBJSHRY2.js → chunk-C4BCC5X5.js} +17 -1
  12. package/dist/{chunk-T5QQVXK3.js → chunk-DIOF73S2.js} +17 -1
  13. package/dist/{chunk-UEAHMGHW.js → chunk-DQJ5D42H.js} +16 -2
  14. package/dist/{chunk-YOWIYAVA.js → chunk-EBWEKG52.js} +36 -11
  15. package/dist/{chunk-XX5BB7NV.js → chunk-S42XDFKF.js} +36 -11
  16. package/dist/{chunk-LRLKJM3O.js → chunk-UA5NDAHL.js} +16 -2
  17. package/dist/{chunk-YDXQ72MD.js → chunk-V2DUTUNC.js} +1 -1
  18. package/dist/{coordinator-prompt-S6JZD5EF.js → coordinator-prompt-ICF36NUQ.js} +2 -1
  19. package/dist/{coordinator-prompt-6FXVTSFN.js → coordinator-prompt-RBKUNRPR.js} +2 -1
  20. package/dist/{global-workspace-EV4G2WMQ.js → global-workspace-667XLBW6.js} +3 -2
  21. package/dist/{global-workspace-MSX2K27Y.js → global-workspace-S7VLWPWG.js} +3 -2
  22. package/dist/index.cjs +395 -61
  23. package/dist/index.d.cts +25 -2
  24. package/dist/index.d.ts +25 -2
  25. package/dist/index.js +164 -43
  26. package/dist/mcp/run-stdio.cjs +389 -57
  27. package/dist/mcp/run-stdio.js +164 -44
  28. package/dist/{workspaces-AYTBR6KQ.js → workspaces-FPJJXXAE.js} +4 -3
  29. package/dist/{workspaces-3RQQZQRO.js → workspaces-LYIDE2VR.js} +4 -3
  30. 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: block.name,
105
- input: block.input && typeof block.input === "object" ? block.input : void 0
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: msg.name,
118
- input: msg.args && typeof msg.args === "object" ? msg.args : void 0
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 === "error"
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 run = await agent.send(
246
- req.prompt,
247
- mcpServers ? { mcpServers } : void 0
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-J5JTEJ5O.js";
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 run = await agent.send(
110
- req.prompt,
111
- mcpServers ? { mcpServers } : void 0
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-D3METLRW.js";
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-J5JTEJ5O.js";
41
- import "./chunk-T5QQVXK3.js";
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-6QTZVJ7A.js";
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-T5QQVXK3.js";
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-HBJSHRY2.js";
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: block.name,
148
- input: block.input && typeof block.input === "object" ? block.input : void 0
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: msg.name,
161
- input: msg.args && typeof msg.args === "object" ? msg.args : void 0
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 === "error"
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,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isGlobalRepoPath
3
- } from "./chunk-XX5BB7NV.js";
3
+ } from "./chunk-S42XDFKF.js";
4
4
  import {
5
5
  ensureGhPreferOrigin,
6
6
  resolveRepoRoot