@sideboard-ai/core 0.1.283 → 0.1.285
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/{abletime-WLDBJJUI.js → abletime-4CH2IOX5.js} +4 -4
- package/dist/{abletime-X64E3GUJ.js → abletime-I4RODUKT.js} +4 -4
- package/dist/{abletime-oauth-AXR676W5.js → abletime-oauth-7OZZ3ABX.js} +3 -3
- package/dist/{abletime-oauth-UWOCEICP.js → abletime-oauth-C2HN2Q6F.js} +3 -3
- package/dist/{abletime-rest-S4XWEXV2.js → abletime-rest-E4LBRFLM.js} +3 -3
- package/dist/{abletime-rest-LPUDJUEP.js → abletime-rest-WFI2HWBU.js} +3 -3
- package/dist/agents/cursor-runner.cjs +54 -14
- package/dist/agents/cursor-runner.js +51 -14
- package/dist/{agents-XA2E64AW.js → agents-FKMYAKFD.js} +5 -5
- package/dist/{agents-2IE4HKHA.js → agents-ITNCZ6CA.js} +7 -7
- package/dist/chunk-2GPQZZLY.js +59 -0
- package/dist/{chunk-BYZ7F2BQ.js → chunk-2K723QZH.js} +12 -10
- package/dist/{chunk-ROPGQRPU.js → chunk-33KDPEK4.js} +1 -1
- package/dist/{chunk-W7HIK2A6.js → chunk-5QOLFOAX.js} +19 -3
- package/dist/{chunk-I6HSGKMZ.js → chunk-5T4YWFLD.js} +2 -2
- package/dist/{chunk-U7HAVAGJ.js → chunk-6CVVNAIU.js} +2 -2
- package/dist/{chunk-TQRSVE7D.js → chunk-7IAMHN2N.js} +1 -1
- package/dist/{chunk-DQZPF6WL.js → chunk-BMUVNTT4.js} +3 -3
- package/dist/{chunk-2KNO2GJQ.js → chunk-C6NVTLZK.js} +16 -14
- package/dist/{chunk-VA55JG2I.js → chunk-DEJALWKM.js} +5 -5
- package/dist/{chunk-XTPQEZZA.js → chunk-IJMUYHPT.js} +3 -3
- package/dist/chunk-JAT3JFOS.js +61 -0
- package/dist/{chunk-EIEAR62M.js → chunk-LMWPVC5L.js} +2 -2
- package/dist/{chunk-DGPROCE5.js → chunk-LS4FFCPL.js} +3 -3
- package/dist/{chunk-P2BSMNHB.js → chunk-PXMLMBMI.js} +1 -1
- package/dist/{chunk-UZUXWBXK.js → chunk-S2OOM7AU.js} +1 -1
- package/dist/{chunk-BS3QLVPL.js → chunk-TMM4FEZ5.js} +3 -3
- package/dist/{chunk-ADXVTKLC.js → chunk-TXHZJESB.js} +4 -4
- package/dist/{chunk-K2S33ZCB.js → chunk-U6QDXT4K.js} +20 -4
- package/dist/{chunk-GWFVCCJZ.js → chunk-VGNLMGBK.js} +6 -6
- package/dist/{chunk-IFURHRAR.js → chunk-VOIWX5HA.js} +1 -1
- package/dist/{chunk-PY4UCMRI.js → chunk-VQEARG5H.js} +5 -5
- package/dist/{chunk-BDAUPNHL.js → chunk-XSDCLM3F.js} +1 -1
- package/dist/{chunk-OCUIZD4Y.js → chunk-XSPOJFTV.js} +6 -6
- package/dist/{conductor-U776JSXQ.js → conductor-GBX6LSP2.js} +3 -3
- package/dist/{conductor-CNSCOC54.js → conductor-MU3TYVCD.js} +2 -2
- package/dist/{connected-teams-JIUOSZ6C.js → connected-teams-AB7ZHJVO.js} +3 -3
- package/dist/{connected-teams-RU6VATCM.js → connected-teams-BJ6PMIST.js} +3 -3
- package/dist/index.cjs +241 -120
- package/dist/index.d.cts +11 -4
- package/dist/index.d.ts +11 -4
- package/dist/index.js +176 -101
- package/dist/mcp/run-stdio.cjs +68 -25
- package/dist/mcp/run-stdio.js +10 -10
- package/dist/{oauth-S3M7B475.js → oauth-DP4ZV2M2.js} +2 -2
- package/dist/{oauth-K6CWZEQO.js → oauth-WCUZ6Z5G.js} +2 -2
- package/dist/{orchestrator-FPGVKEID.js → orchestrator-F7KXYDQW.js} +9 -9
- package/dist/{orchestrator-HWJHK5NL.js → orchestrator-VUIRO6NC.js} +7 -7
- package/package.json +1 -1
- package/dist/chunk-N7WZ6NIN.js +0 -41
- package/dist/chunk-VKQGAWHY.js +0 -40
package/dist/index.js
CHANGED
|
@@ -198,7 +198,7 @@ import {
|
|
|
198
198
|
worktreeBoardStatus,
|
|
199
199
|
worktreeCleanupSettings,
|
|
200
200
|
writeWorktreeFile
|
|
201
|
-
} from "./chunk-
|
|
201
|
+
} from "./chunk-C6NVTLZK.js";
|
|
202
202
|
import {
|
|
203
203
|
BASE_ALLOWED_TOOLS,
|
|
204
204
|
BRIGHTSY_MCP_ALLOWED_TOOLS,
|
|
@@ -288,7 +288,7 @@ import {
|
|
|
288
288
|
whichOnPath,
|
|
289
289
|
worktreeMcpToolNames,
|
|
290
290
|
writeInjectedMcpConfig
|
|
291
|
-
} from "./chunk-
|
|
291
|
+
} from "./chunk-XSPOJFTV.js";
|
|
292
292
|
import {
|
|
293
293
|
brightsyMcpServerName,
|
|
294
294
|
connectBrightsyTeam,
|
|
@@ -298,7 +298,7 @@ import {
|
|
|
298
298
|
listBrightsyAccounts,
|
|
299
299
|
listConnectedBrightsyTeams,
|
|
300
300
|
switchBrightsyAccount
|
|
301
|
-
} from "./chunk-
|
|
301
|
+
} from "./chunk-VGNLMGBK.js";
|
|
302
302
|
import {
|
|
303
303
|
BRIGHTSY_SUMMARIZE_CONTEXT_TOOL,
|
|
304
304
|
CHARS_PER_CONTEXT_TOKEN,
|
|
@@ -415,7 +415,7 @@ import {
|
|
|
415
415
|
workspaceAgentChatSummaries,
|
|
416
416
|
worktreeRunPortsPath,
|
|
417
417
|
wrapReviewSkillMarkdown
|
|
418
|
-
} from "./chunk-
|
|
418
|
+
} from "./chunk-BMUVNTT4.js";
|
|
419
419
|
import {
|
|
420
420
|
STDERR_EVENT_MAX_CHARS,
|
|
421
421
|
STDOUT_EVENT_MAX_CHARS,
|
|
@@ -457,7 +457,7 @@ import {
|
|
|
457
457
|
visibleToolRowDetail,
|
|
458
458
|
withEventParentId,
|
|
459
459
|
withEventsParentId
|
|
460
|
-
} from "./chunk-
|
|
460
|
+
} from "./chunk-XSDCLM3F.js";
|
|
461
461
|
import "./chunk-7H655NEW.js";
|
|
462
462
|
import {
|
|
463
463
|
ABLETIME_OAUTH_CALLBACK_PATH,
|
|
@@ -481,7 +481,7 @@ import {
|
|
|
481
481
|
parseAbleTimeOAuthCallbackUrl,
|
|
482
482
|
resolveAbleTimeOAuthHost,
|
|
483
483
|
startAbleTimeOAuth
|
|
484
|
-
} from "./chunk-
|
|
484
|
+
} from "./chunk-IJMUYHPT.js";
|
|
485
485
|
import {
|
|
486
486
|
ableTimeDependencyTarget,
|
|
487
487
|
commentAbleTimeTask,
|
|
@@ -506,8 +506,8 @@ import {
|
|
|
506
506
|
toAbleTimeIssueInfo,
|
|
507
507
|
updateAbleTimeTask,
|
|
508
508
|
verifyAbleTimeConnection
|
|
509
|
-
} from "./chunk-
|
|
510
|
-
import "./chunk-
|
|
509
|
+
} from "./chunk-LS4FFCPL.js";
|
|
510
|
+
import "./chunk-6CVVNAIU.js";
|
|
511
511
|
import {
|
|
512
512
|
ABLETIME_MCP_PATH,
|
|
513
513
|
ABLETIME_MCP_PM_PATH,
|
|
@@ -528,7 +528,7 @@ import {
|
|
|
528
528
|
normalizeAbleTimeCredential,
|
|
529
529
|
normalizeAbleTimeHost,
|
|
530
530
|
rewriteAbleTimeError
|
|
531
|
-
} from "./chunk-
|
|
531
|
+
} from "./chunk-DEJALWKM.js";
|
|
532
532
|
import {
|
|
533
533
|
LEGACY_PLAN_FILE_REL,
|
|
534
534
|
PLAN_FILE_NAME,
|
|
@@ -728,15 +728,16 @@ import {
|
|
|
728
728
|
refreshBrightsyAccessToken,
|
|
729
729
|
registerBrightsyOAuthClient,
|
|
730
730
|
saveBrightsyConfig
|
|
731
|
-
} from "./chunk-
|
|
731
|
+
} from "./chunk-33KDPEK4.js";
|
|
732
732
|
import {
|
|
733
|
+
currentHttpFetch,
|
|
733
734
|
formatFetchError,
|
|
734
735
|
httpFetch,
|
|
735
736
|
setHttpFetchImpl
|
|
736
|
-
} from "./chunk-
|
|
737
|
+
} from "./chunk-JAT3JFOS.js";
|
|
737
738
|
import {
|
|
738
739
|
clipMcpToolResult
|
|
739
|
-
} from "./chunk-
|
|
740
|
+
} from "./chunk-S2OOM7AU.js";
|
|
740
741
|
import "./chunk-AXQ4ZWHK.js";
|
|
741
742
|
import {
|
|
742
743
|
AGENT_RUNNER_MAX_OLD_SPACE_MB,
|
|
@@ -752,8 +753,8 @@ import {
|
|
|
752
753
|
trustSystemCertificates,
|
|
753
754
|
turnCostUsdFromCursorUsage,
|
|
754
755
|
withMaxOldSpaceSize
|
|
755
|
-
} from "./chunk-
|
|
756
|
-
import "./chunk-
|
|
756
|
+
} from "./chunk-VOIWX5HA.js";
|
|
757
|
+
import "./chunk-U6QDXT4K.js";
|
|
757
758
|
import {
|
|
758
759
|
ATTACHMENTS_DIR,
|
|
759
760
|
CLI_DIR,
|
|
@@ -5015,7 +5016,7 @@ async function handleJobStop(params, _ctx) {
|
|
|
5015
5016
|
return stopDetachedJob(jobCwd(rec), id, reason ? { reason } : void 0);
|
|
5016
5017
|
}
|
|
5017
5018
|
async function defaultTurnWait(ref, timeoutMs) {
|
|
5018
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
5019
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-F7KXYDQW.js");
|
|
5019
5020
|
const orch = getOrchestrator2();
|
|
5020
5021
|
const thread = await orch.waitForTurn(ref, timeoutMs, {
|
|
5021
5022
|
resolveIfStillRunning: true
|
|
@@ -10113,7 +10114,7 @@ function deliverPhoneTurn(opts, chatId) {
|
|
|
10113
10114
|
});
|
|
10114
10115
|
}
|
|
10115
10116
|
|
|
10116
|
-
// src/remote/
|
|
10117
|
+
// src/remote/phone-turn.ts
|
|
10117
10118
|
function formatRemotePrompt(text5) {
|
|
10118
10119
|
return `Phone
|
|
10119
10120
|
|
|
@@ -10122,6 +10123,29 @@ ${text5.trim()}`;
|
|
|
10122
10123
|
function isRemoteStopCommand(text5) {
|
|
10123
10124
|
return text5.trim().toLowerCase() === "stop";
|
|
10124
10125
|
}
|
|
10126
|
+
function phoneFollowUpQueues(status) {
|
|
10127
|
+
return followUpBehavior() === "queue" && (status === "running" || status === "queued");
|
|
10128
|
+
}
|
|
10129
|
+
var PHONE_TURN_MS = 14 * 60 * 1e3;
|
|
10130
|
+
function delay(ms) {
|
|
10131
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
10132
|
+
}
|
|
10133
|
+
async function waitForPhoneTurn(threadId, stillCurrent) {
|
|
10134
|
+
const deadline = Date.now() + PHONE_TURN_MS;
|
|
10135
|
+
while (stillCurrent() && Date.now() < deadline) {
|
|
10136
|
+
const thread2 = readPhoneThread(threadId) ?? readThread(threadId);
|
|
10137
|
+
if (!thread2) return;
|
|
10138
|
+
if (thread2.status === "stopped" && thread2.queue.length > 0) {
|
|
10139
|
+
await delay(40);
|
|
10140
|
+
continue;
|
|
10141
|
+
}
|
|
10142
|
+
break;
|
|
10143
|
+
}
|
|
10144
|
+
if (!stillCurrent()) return;
|
|
10145
|
+
const thread = readPhoneThread(threadId) ?? readThread(threadId);
|
|
10146
|
+
if (!thread || thread.status !== "running" && thread.status !== "queued") return;
|
|
10147
|
+
await getOrchestrator().waitForTurn(threadId, Math.max(1, deadline - Date.now()));
|
|
10148
|
+
}
|
|
10125
10149
|
var handleChain2 = Promise.resolve();
|
|
10126
10150
|
var inboundGeneration = 0;
|
|
10127
10151
|
function enqueue(fn) {
|
|
@@ -10145,6 +10169,77 @@ function interruptRemoteCoordinator(deviceId, log = () => void 0) {
|
|
|
10145
10169
|
return false;
|
|
10146
10170
|
}
|
|
10147
10171
|
}
|
|
10172
|
+
function runCoordinatorPrompt(opts, body, generation) {
|
|
10173
|
+
const current = () => generation === inboundGeneration;
|
|
10174
|
+
return (async () => {
|
|
10175
|
+
if (!current()) return;
|
|
10176
|
+
const agent = coerceOrchestratorAgent(opts.agent ?? resolveOrchestratorDefaults().agent);
|
|
10177
|
+
if (!body) return;
|
|
10178
|
+
if (isRemoteStopCommand(body)) {
|
|
10179
|
+
if (!current()) return;
|
|
10180
|
+
opts.onOutbound({ type: "assistant", text: REMOTE_STOPPED_REPLY });
|
|
10181
|
+
return;
|
|
10182
|
+
}
|
|
10183
|
+
let thread = ensureRemoteCoordinator(opts.deviceId, agent);
|
|
10184
|
+
thread = readThread(thread.id) ?? thread;
|
|
10185
|
+
const followUp = followUpBehavior();
|
|
10186
|
+
const orch = getOrchestrator();
|
|
10187
|
+
try {
|
|
10188
|
+
await orch.send(thread.id, formatRemotePrompt(body), { followUp });
|
|
10189
|
+
if (!current()) return;
|
|
10190
|
+
await waitForPhoneTurn(thread.id, current);
|
|
10191
|
+
} catch (err) {
|
|
10192
|
+
if (!current()) return;
|
|
10193
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
10194
|
+
opts.onOutbound({ type: "assistant", text: `Sideboard failed: ${message}` });
|
|
10195
|
+
return;
|
|
10196
|
+
}
|
|
10197
|
+
if (!current()) return;
|
|
10198
|
+
thread = readThread(thread.id) ?? thread;
|
|
10199
|
+
if (thread.status === "stopped") return;
|
|
10200
|
+
const result = orch.getTurnResult(thread.id);
|
|
10201
|
+
const pending = extractPendingPlanQuestions(
|
|
10202
|
+
[...thread.messages].reverse().find((m) => m.role === "agent")?.parts
|
|
10203
|
+
);
|
|
10204
|
+
if (result.taskState === "input-required" && pending) {
|
|
10205
|
+
opts.onOutbound({
|
|
10206
|
+
type: "ask_user",
|
|
10207
|
+
text: result.text.trim(),
|
|
10208
|
+
questions: pending.questions.map((q) => ({
|
|
10209
|
+
question: q.question,
|
|
10210
|
+
options: q.options.map(
|
|
10211
|
+
(o) => o.description ? { label: o.label, description: o.description } : { label: o.label }
|
|
10212
|
+
)
|
|
10213
|
+
}))
|
|
10214
|
+
});
|
|
10215
|
+
return;
|
|
10216
|
+
}
|
|
10217
|
+
const reply = outboundReplyFromTurn(result, {
|
|
10218
|
+
inputRequired: "Sideboard is waiting for an answer.",
|
|
10219
|
+
canceled: REMOTE_STOPPED_REPLY,
|
|
10220
|
+
completedEmpty: () => "",
|
|
10221
|
+
failed: (detail) => detail ? `Sideboard failed: ${detail}` : "Sideboard failed before producing a result."
|
|
10222
|
+
});
|
|
10223
|
+
if (reply.trim()) opts.onOutbound({ type: "assistant", text: reply.trim() });
|
|
10224
|
+
})();
|
|
10225
|
+
}
|
|
10226
|
+
function beginCoordinatorPrompt(body, opts) {
|
|
10227
|
+
const live = body ? findRemoteCoordinator(opts.deviceId) : null;
|
|
10228
|
+
const fresh = live ? readThread(live.id) ?? live : null;
|
|
10229
|
+
if (body && !isRemoteStopCommand(body) && phoneFollowUpQueues(fresh?.status)) {
|
|
10230
|
+
const generation2 = inboundGeneration;
|
|
10231
|
+
enqueue(() => runCoordinatorPrompt(opts, body, generation2));
|
|
10232
|
+
return;
|
|
10233
|
+
}
|
|
10234
|
+
const generation = ++inboundGeneration;
|
|
10235
|
+
if (body && isRemoteStopCommand(body)) {
|
|
10236
|
+
interruptRemoteCoordinator(opts.deviceId, opts.onLog ?? (() => void 0));
|
|
10237
|
+
}
|
|
10238
|
+
const task = runCoordinatorPrompt(opts, body, generation);
|
|
10239
|
+
enqueue(() => task);
|
|
10240
|
+
}
|
|
10241
|
+
|
|
10242
|
+
// src/remote/listen.ts
|
|
10148
10243
|
function emitOpened(opts, opened) {
|
|
10149
10244
|
setPhoneOpenChat(opened.chat.id);
|
|
10150
10245
|
emitControl(opts, { op: "opened", ...opened });
|
|
@@ -10414,23 +10509,27 @@ function handlePhoneControl(cmd, opts) {
|
|
|
10414
10509
|
return;
|
|
10415
10510
|
}
|
|
10416
10511
|
const chatId = cmd.chatId;
|
|
10512
|
+
const existing = readPhoneThread(chatId);
|
|
10513
|
+
if (phoneFollowUpQueues(existing?.status)) {
|
|
10514
|
+
deliverPhoneTurn(opts, chatId);
|
|
10515
|
+
const generation2 = chatGeneration.get(chatId) ?? bumpChat(chatId);
|
|
10516
|
+
enqueueChat(chatId, () => runPhonePrompt(opts, cmd, chatId, generation2));
|
|
10517
|
+
return;
|
|
10518
|
+
}
|
|
10417
10519
|
const generation = bumpChat(chatId);
|
|
10418
10520
|
phoneTurnGen.set(chatId, generation);
|
|
10419
|
-
|
|
10420
|
-
enqueueChat(chatId,
|
|
10421
|
-
|
|
10521
|
+
const task = runPhonePrompt(opts, cmd, chatId, generation);
|
|
10522
|
+
enqueueChat(chatId, () => task);
|
|
10523
|
+
}
|
|
10524
|
+
function runPhonePrompt(opts, cmd, chatId, generation) {
|
|
10525
|
+
const current = () => chatGeneration.get(chatId) === generation;
|
|
10526
|
+
return (async () => {
|
|
10527
|
+
if (!current()) return;
|
|
10422
10528
|
const thread = readPhoneThread(chatId);
|
|
10423
10529
|
if (!thread) {
|
|
10424
10530
|
emitControl(opts, { op: "error", chatId, message: "That agent is not on this Mac." });
|
|
10425
10531
|
return;
|
|
10426
10532
|
}
|
|
10427
|
-
if (thread.status === "running" || thread.status === "queued") {
|
|
10428
|
-
try {
|
|
10429
|
-
getOrchestrator().stop(thread.id, { clearQueue: true });
|
|
10430
|
-
} catch {
|
|
10431
|
-
}
|
|
10432
|
-
}
|
|
10433
|
-
if (chatGeneration.get(chatId) !== generation) return;
|
|
10434
10533
|
const stopStream = watchPhoneStream(opts, chatId, thread.id, generation);
|
|
10435
10534
|
try {
|
|
10436
10535
|
try {
|
|
@@ -10438,14 +10537,19 @@ function handlePhoneControl(cmd, opts) {
|
|
|
10438
10537
|
} catch (err) {
|
|
10439
10538
|
emitControl(opts, { op: "error", chatId, message: phoneError(err) });
|
|
10440
10539
|
}
|
|
10540
|
+
if (!current()) return;
|
|
10441
10541
|
const live = readPhoneThread(thread.id) ?? thread;
|
|
10542
|
+
const followUp = followUpBehavior();
|
|
10442
10543
|
const staged = stagePhoneTurnFiles(live.worktreePath, cmd);
|
|
10443
10544
|
const text5 = cmd.text.trim() || (staged.length ? "See the attached files." : "");
|
|
10444
|
-
|
|
10445
|
-
|
|
10446
|
-
|
|
10545
|
+
await getOrchestrator().send(thread.id, formatRemotePrompt(text5), {
|
|
10546
|
+
attachments: staged,
|
|
10547
|
+
followUp
|
|
10548
|
+
});
|
|
10549
|
+
if (!current()) return;
|
|
10550
|
+
await waitForPhoneTurn(thread.id, current);
|
|
10447
10551
|
} catch (err) {
|
|
10448
|
-
if (
|
|
10552
|
+
if (!current()) return;
|
|
10449
10553
|
const message = err instanceof Error ? err.message : String(err);
|
|
10450
10554
|
emitControl(opts, { op: "error", chatId, message: `Sideboard failed: ${message}` });
|
|
10451
10555
|
return;
|
|
@@ -10453,12 +10557,11 @@ function handlePhoneControl(cmd, opts) {
|
|
|
10453
10557
|
stopStream();
|
|
10454
10558
|
finishPhoneTurn(chatId, generation);
|
|
10455
10559
|
}
|
|
10456
|
-
if (
|
|
10560
|
+
if (!current()) return;
|
|
10457
10561
|
emitChatTurn(opts, chatId, thread.id);
|
|
10458
|
-
});
|
|
10562
|
+
})();
|
|
10459
10563
|
}
|
|
10460
10564
|
function handleRemoteInbound(text5, opts) {
|
|
10461
|
-
const log = opts.onLog ?? (() => void 0);
|
|
10462
10565
|
const body = text5.trim();
|
|
10463
10566
|
const control = takePhoneControl(body);
|
|
10464
10567
|
if (control) {
|
|
@@ -10469,64 +10572,7 @@ function handleRemoteInbound(text5, opts) {
|
|
|
10469
10572
|
handlePhoneControl(control, opts);
|
|
10470
10573
|
return;
|
|
10471
10574
|
}
|
|
10472
|
-
|
|
10473
|
-
if (body) interruptRemoteCoordinator(opts.deviceId, log);
|
|
10474
|
-
enqueue(async () => {
|
|
10475
|
-
if (generation !== inboundGeneration) return;
|
|
10476
|
-
const agent = coerceOrchestratorAgent(opts.agent ?? resolveOrchestratorDefaults().agent);
|
|
10477
|
-
if (!body) return;
|
|
10478
|
-
if (isRemoteStopCommand(body)) {
|
|
10479
|
-
if (generation !== inboundGeneration) return;
|
|
10480
|
-
opts.onOutbound({ type: "assistant", text: REMOTE_STOPPED_REPLY });
|
|
10481
|
-
return;
|
|
10482
|
-
}
|
|
10483
|
-
let thread = ensureRemoteCoordinator(opts.deviceId, agent);
|
|
10484
|
-
const fresh = readThread(thread.id) ?? thread;
|
|
10485
|
-
if (fresh.status === "running" || fresh.status === "queued") {
|
|
10486
|
-
try {
|
|
10487
|
-
getOrchestrator().stop(fresh.id, { clearQueue: true });
|
|
10488
|
-
} catch {
|
|
10489
|
-
}
|
|
10490
|
-
}
|
|
10491
|
-
if (generation !== inboundGeneration) return;
|
|
10492
|
-
const orch = getOrchestrator();
|
|
10493
|
-
try {
|
|
10494
|
-
await orch.send(thread.id, formatRemotePrompt(body));
|
|
10495
|
-
await orch.waitForTurn(thread.id, 14 * 60 * 1e3);
|
|
10496
|
-
} catch (err) {
|
|
10497
|
-
if (generation !== inboundGeneration) return;
|
|
10498
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
10499
|
-
opts.onOutbound({ type: "assistant", text: `Sideboard failed: ${message}` });
|
|
10500
|
-
return;
|
|
10501
|
-
}
|
|
10502
|
-
if (generation !== inboundGeneration) return;
|
|
10503
|
-
thread = readThread(thread.id) ?? thread;
|
|
10504
|
-
if (thread.status === "stopped") return;
|
|
10505
|
-
const result = orch.getTurnResult(thread.id);
|
|
10506
|
-
const pending = extractPendingPlanQuestions(
|
|
10507
|
-
[...thread.messages].reverse().find((m) => m.role === "agent")?.parts
|
|
10508
|
-
);
|
|
10509
|
-
if (result.taskState === "input-required" && pending) {
|
|
10510
|
-
opts.onOutbound({
|
|
10511
|
-
type: "ask_user",
|
|
10512
|
-
text: result.text.trim(),
|
|
10513
|
-
questions: pending.questions.map((q) => ({
|
|
10514
|
-
question: q.question,
|
|
10515
|
-
options: q.options.map(
|
|
10516
|
-
(o) => o.description ? { label: o.label, description: o.description } : { label: o.label }
|
|
10517
|
-
)
|
|
10518
|
-
}))
|
|
10519
|
-
});
|
|
10520
|
-
return;
|
|
10521
|
-
}
|
|
10522
|
-
const reply = outboundReplyFromTurn(result, {
|
|
10523
|
-
inputRequired: "Sideboard is waiting for an answer.",
|
|
10524
|
-
canceled: REMOTE_STOPPED_REPLY,
|
|
10525
|
-
completedEmpty: () => "",
|
|
10526
|
-
failed: (detail) => detail ? `Sideboard failed: ${detail}` : "Sideboard failed before producing a result."
|
|
10527
|
-
});
|
|
10528
|
-
if (reply.trim()) opts.onOutbound({ type: "assistant", text: reply.trim() });
|
|
10529
|
-
});
|
|
10575
|
+
beginCoordinatorPrompt(body, opts);
|
|
10530
10576
|
}
|
|
10531
10577
|
|
|
10532
10578
|
// src/remote/phone-board-sync.ts
|
|
@@ -11463,15 +11509,43 @@ function sleep2(ms, signal) {
|
|
|
11463
11509
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
11464
11510
|
});
|
|
11465
11511
|
}
|
|
11512
|
+
var RELAY_TLS_HINT = " \u2014 the TLS certificate was rejected. A work proxy often does this when Sideboard is not allowlisted, or when the app does not trust the corporate CA.";
|
|
11513
|
+
var RELAY_NETWORK_HINT = " Sideboard could not reach the relay. On a work computer this is often a VPN, a proxy, or an allowlist that does not include Sideboard.";
|
|
11514
|
+
var RELAY_NETWORK_RE = /fetch failed|Failed to fetch|ENOTFOUND|ECONNREFUSED|ECONNRESET|ETIMEDOUT|EHOSTUNREACH|ENETUNREACH|EAI_AGAIN|EPERM|UND_ERR_|ERR_CONNECTION|ERR_NETWORK|ERR_PROXY|ERR_TUNNEL|ERR_INTERNET|ERR_BLOCKED|ERR_NAME_NOT_RESOLVED|ERR_ADDRESS_UNREACHABLE|ERR_CERT|CERT_|UNABLE_TO_GET_ISSUER|SELF_SIGNED/i;
|
|
11515
|
+
function relayFetchError(err, url) {
|
|
11516
|
+
const formatted = formatFetchError(err, url, { tlsHint: RELAY_TLS_HINT });
|
|
11517
|
+
if (formatted.includes(RELAY_TLS_HINT) || !RELAY_NETWORK_RE.test(formatted)) {
|
|
11518
|
+
return new Error(formatted);
|
|
11519
|
+
}
|
|
11520
|
+
return new Error(`${formatted}${RELAY_NETWORK_HINT}`);
|
|
11521
|
+
}
|
|
11522
|
+
async function relayFetch(fetchImpl, url, init) {
|
|
11523
|
+
const fn = fetchImpl ?? currentHttpFetch();
|
|
11524
|
+
try {
|
|
11525
|
+
return await fn(url, init);
|
|
11526
|
+
} catch (err) {
|
|
11527
|
+
throw relayFetchError(err, url);
|
|
11528
|
+
}
|
|
11529
|
+
}
|
|
11530
|
+
async function readJson2(res, url) {
|
|
11531
|
+
try {
|
|
11532
|
+
return await res.json();
|
|
11533
|
+
} catch {
|
|
11534
|
+
const kind = (res.headers.get("content-type") ?? "").includes("html") ? "an HTML page" : "a non-JSON body";
|
|
11535
|
+
throw new Error(
|
|
11536
|
+
`Relay sign-in returned HTTP ${res.status} with ${kind} (${url}). A work proxy or allowlist often answers with a block page instead of the relay.`
|
|
11537
|
+
);
|
|
11538
|
+
}
|
|
11539
|
+
}
|
|
11466
11540
|
async function startRemoteAccountLogin(opts) {
|
|
11467
11541
|
if (opts.signal?.aborted) throw new RemoteAccountLoginCancelled();
|
|
11468
11542
|
const origin = (opts.origin ?? remoteAccountHttpOrigin()).replace(/\/+$/, "");
|
|
11469
|
-
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
11470
11543
|
const state = randomBytes7(16).toString("hex");
|
|
11471
11544
|
const timeoutMs = opts.timeoutMs ?? 5 * 6e4;
|
|
11472
11545
|
const pollIntervalMs = opts.pollIntervalMs ?? 400;
|
|
11473
11546
|
const linkToken = opts.linkToken?.trim() ?? "";
|
|
11474
|
-
const
|
|
11547
|
+
const startUrl = `${origin}${REMOTE_LOGIN_PATH}`;
|
|
11548
|
+
const started = await relayFetch(opts.fetchImpl, startUrl, {
|
|
11475
11549
|
method: "POST",
|
|
11476
11550
|
headers: { "Content-Type": "application/json" },
|
|
11477
11551
|
body: JSON.stringify({
|
|
@@ -11480,9 +11554,9 @@ async function startRemoteAccountLogin(opts) {
|
|
|
11480
11554
|
...linkToken ? { accountToken: linkToken } : {}
|
|
11481
11555
|
})
|
|
11482
11556
|
});
|
|
11483
|
-
const startBody = await started
|
|
11557
|
+
const startBody = await readJson2(started, startUrl);
|
|
11484
11558
|
if (!started.ok || !startBody.url) {
|
|
11485
|
-
throw new Error(startBody.error ||
|
|
11559
|
+
throw new Error(startBody.error || `Could not start sign-in (HTTP ${started.status}).`);
|
|
11486
11560
|
}
|
|
11487
11561
|
await Promise.resolve(opts.openUrl?.(startBody.url));
|
|
11488
11562
|
const deadline = Date.now() + timeoutMs;
|
|
@@ -11491,9 +11565,11 @@ async function startRemoteAccountLogin(opts) {
|
|
|
11491
11565
|
if (opts.signal?.aborted) throw new RemoteAccountLoginCancelled();
|
|
11492
11566
|
let res;
|
|
11493
11567
|
try {
|
|
11494
|
-
res = await fetchImpl
|
|
11495
|
-
} catch {
|
|
11496
|
-
if (opts.signal?.aborted
|
|
11568
|
+
res = await relayFetch(opts.fetchImpl, resultUrl);
|
|
11569
|
+
} catch (err) {
|
|
11570
|
+
if (opts.signal?.aborted || isRemoteAccountLoginCancelled(err)) {
|
|
11571
|
+
throw new RemoteAccountLoginCancelled();
|
|
11572
|
+
}
|
|
11497
11573
|
await sleep2(pollIntervalMs, opts.signal);
|
|
11498
11574
|
continue;
|
|
11499
11575
|
}
|
|
@@ -11518,8 +11594,7 @@ async function startRemoteAccountLogin(opts) {
|
|
|
11518
11594
|
}
|
|
11519
11595
|
async function disconnectRemoteAccount(opts) {
|
|
11520
11596
|
const origin = (opts.origin ?? remoteAccountHttpOrigin()).replace(/\/+$/, "");
|
|
11521
|
-
|
|
11522
|
-
await fetchImpl(`${origin}${REMOTE_LOGOUT_PATH}`, {
|
|
11597
|
+
await relayFetch(opts.fetchImpl, `${origin}${REMOTE_LOGOUT_PATH}`, {
|
|
11523
11598
|
method: "POST",
|
|
11524
11599
|
headers: { "Content-Type": "application/json" },
|
|
11525
11600
|
body: JSON.stringify({ accountToken: opts.accountToken })
|
|
@@ -12411,7 +12486,7 @@ async function continueSourceThread(threadId, prompt) {
|
|
|
12411
12486
|
await continueOnReply(threadId, prompt);
|
|
12412
12487
|
return;
|
|
12413
12488
|
}
|
|
12414
|
-
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-
|
|
12489
|
+
const { getOrchestrator: getOrchestrator2 } = await import("./orchestrator-F7KXYDQW.js");
|
|
12415
12490
|
await getOrchestrator2().send(threadId, prompt);
|
|
12416
12491
|
} catch {
|
|
12417
12492
|
}
|
package/dist/mcp/run-stdio.cjs
CHANGED
|
@@ -800,6 +800,30 @@ var init_workspace_scratch = __esm({
|
|
|
800
800
|
}
|
|
801
801
|
});
|
|
802
802
|
|
|
803
|
+
// src/agents/cursor-stream-cutoff.ts
|
|
804
|
+
function looksLikeCursorStreamCutOff(text7) {
|
|
805
|
+
return CURSOR_STREAM_CUTOFF.test(text7.trim());
|
|
806
|
+
}
|
|
807
|
+
function cursorStreamCutOffContinueLimit(detail) {
|
|
808
|
+
if (looksLikeCursorStreamCutOff(detail) || /connection stalled/i.test(detail)) {
|
|
809
|
+
return CURSOR_STREAM_CUTOFF_CONTINUE_LIMIT;
|
|
810
|
+
}
|
|
811
|
+
return null;
|
|
812
|
+
}
|
|
813
|
+
function nextCrashContinueCount(detail, used) {
|
|
814
|
+
const limit = cursorStreamCutOffContinueLimit(detail) ?? 1;
|
|
815
|
+
if (used >= limit) return null;
|
|
816
|
+
return used + 1;
|
|
817
|
+
}
|
|
818
|
+
var CURSOR_STREAM_CUTOFF, CURSOR_STREAM_CUTOFF_CONTINUE_LIMIT;
|
|
819
|
+
var init_cursor_stream_cutoff = __esm({
|
|
820
|
+
"src/agents/cursor-stream-cutoff.ts"() {
|
|
821
|
+
"use strict";
|
|
822
|
+
CURSOR_STREAM_CUTOFF = /nghttp2|premature close|\[unavailable\]\s+error\b|http\/2 stream closed|\bcancel \(0x8\)|error code cancel\b/i;
|
|
823
|
+
CURSOR_STREAM_CUTOFF_CONTINUE_LIMIT = 3;
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
|
|
803
827
|
// src/agents/error-detail.ts
|
|
804
828
|
function formatUnknownDetail(err) {
|
|
805
829
|
if (err == null) return "";
|
|
@@ -990,9 +1014,6 @@ function looksLikeInvalidAgentSession(text7) {
|
|
|
990
1014
|
if (!lower) return false;
|
|
991
1015
|
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) || /corrupt local agent checkpoint/.test(lower) || /missing root blob/.test(lower) || /\bagent\b.{0,120}\bnot found\b/.test(lower) || /\brun\b.{0,80}\bnot found for agent\b/.test(lower);
|
|
992
1016
|
}
|
|
993
|
-
function looksLikeCursorStreamCutOff(text7) {
|
|
994
|
-
return /nghttp2|premature close|\[unavailable\]\s+error\b/i.test(text7.trim());
|
|
995
|
-
}
|
|
996
1017
|
function looksLikeBrightsyEmptyCompletion(text7) {
|
|
997
1018
|
const core = text7.trim().replace(/^exit\s*\d+:\s*/i, "").replace(/^error:\s*/i, "").trim();
|
|
998
1019
|
return /^i did not receive a valid model response\. please try again\.$/i.test(core);
|
|
@@ -1166,6 +1187,8 @@ var NODE_VERSION_FOOTER, NESTED_ELECTRON_SUMMARY, HOMEBREW_LIBUV_SUMMARY, BUNDLE
|
|
|
1166
1187
|
var init_error_detail = __esm({
|
|
1167
1188
|
"src/agents/error-detail.ts"() {
|
|
1168
1189
|
"use strict";
|
|
1190
|
+
init_cursor_stream_cutoff();
|
|
1191
|
+
init_cursor_stream_cutoff();
|
|
1169
1192
|
NODE_VERSION_FOOTER = /^Node\.js v\d+/i;
|
|
1170
1193
|
NESTED_ELECTRON_SUMMARY = "Cursor local agent crashed at Electron startup (nested Chromium / HasCustomHostObject)";
|
|
1171
1194
|
HOMEBREW_LIBUV_SUMMARY = "Cursor runner crashed in Node (Homebrew Node + shared libuv). Install Node 24 LTS (`brew install node@24`) and retry.";
|
|
@@ -10231,30 +10254,49 @@ var init_accounts = __esm({
|
|
|
10231
10254
|
});
|
|
10232
10255
|
|
|
10233
10256
|
// src/http/fetch.ts
|
|
10234
|
-
function
|
|
10235
|
-
|
|
10236
|
-
return TLS_ISSUER_RE.test(text7) ? TLS_ISSUER_HINT : "";
|
|
10257
|
+
function isTlsIssuerFailure(code, message) {
|
|
10258
|
+
return TLS_ISSUER_RE.test(`${code ?? ""} ${message}`);
|
|
10237
10259
|
}
|
|
10238
|
-
function
|
|
10239
|
-
if (
|
|
10240
|
-
|
|
10241
|
-
|
|
10242
|
-
|
|
10260
|
+
function describeCause(cause, depth = 0) {
|
|
10261
|
+
if (depth > 5 || cause == null) return null;
|
|
10262
|
+
if (cause instanceof AggregateError) {
|
|
10263
|
+
for (const item of cause.errors) {
|
|
10264
|
+
const found = describeCause(item, depth + 1);
|
|
10265
|
+
if (found && (found.code || found.message)) return found;
|
|
10266
|
+
}
|
|
10267
|
+
return cause.message ? { message: cause.message } : null;
|
|
10268
|
+
}
|
|
10243
10269
|
if (cause instanceof Error) {
|
|
10244
10270
|
const code = typeof cause.code === "string" ? cause.code : void 0;
|
|
10245
|
-
|
|
10246
|
-
|
|
10247
|
-
|
|
10248
|
-
|
|
10249
|
-
|
|
10250
|
-
}
|
|
10251
|
-
|
|
10271
|
+
const nested = describeCause(cause.cause, depth + 1);
|
|
10272
|
+
if ((!cause.message || cause.message === "fetch failed") && nested) return nested;
|
|
10273
|
+
if (cause.message || code) return { code, message: cause.message };
|
|
10274
|
+
return nested;
|
|
10275
|
+
}
|
|
10276
|
+
return { message: String(cause) };
|
|
10277
|
+
}
|
|
10278
|
+
function causeSuffix(detail) {
|
|
10279
|
+
if (!detail) return "";
|
|
10280
|
+
if (detail.code && detail.message) return ` [${detail.code}: ${detail.message}]`;
|
|
10281
|
+
if (detail.code) return ` [${detail.code}]`;
|
|
10282
|
+
if (detail.message) return ` [${detail.message}]`;
|
|
10283
|
+
return "";
|
|
10284
|
+
}
|
|
10285
|
+
function formatFetchError(err, url, opts) {
|
|
10286
|
+
if (!(err instanceof Error)) return `${String(err)} (${url})`;
|
|
10287
|
+
const detail = describeCause(err.cause);
|
|
10288
|
+
const hintSource = `${err.message} ${detail?.code ?? ""} ${detail?.message ?? ""}`;
|
|
10289
|
+
const tls2 = isTlsIssuerFailure(detail?.code, hintSource);
|
|
10290
|
+
const hint = tls2 ? opts?.tlsHint ?? TLS_ISSUER_HINT : "";
|
|
10291
|
+
return `${err.message}${causeSuffix(detail)} (${url})${hint}`;
|
|
10292
|
+
}
|
|
10293
|
+
function currentHttpFetch() {
|
|
10294
|
+
return injected ?? globalThis.fetch.bind(globalThis);
|
|
10252
10295
|
}
|
|
10253
10296
|
async function httpFetch(input, init) {
|
|
10254
10297
|
const url = typeof input === "string" ? input : input.href;
|
|
10255
|
-
const fn = injected ?? globalThis.fetch.bind(globalThis);
|
|
10256
10298
|
try {
|
|
10257
|
-
return await
|
|
10299
|
+
return await currentHttpFetch()(url, init);
|
|
10258
10300
|
} catch (err) {
|
|
10259
10301
|
throw new Error(formatFetchError(err, url));
|
|
10260
10302
|
}
|
|
@@ -25408,10 +25450,10 @@ var init_orchestrator = __esm({
|
|
|
25408
25450
|
/** Timers for orchestration session-quota auto-resume. */
|
|
25409
25451
|
quotaResumeTimers = /* @__PURE__ */ new Map();
|
|
25410
25452
|
/**
|
|
25411
|
-
*
|
|
25412
|
-
*
|
|
25453
|
+
* Crash-continue count per thread. Cleared on a successful finish or a user
|
|
25454
|
+
* send. Stream cutoffs may resume more than once; other crashes once.
|
|
25413
25455
|
*/
|
|
25414
|
-
crashContinued = /* @__PURE__ */ new
|
|
25456
|
+
crashContinued = /* @__PURE__ */ new Map();
|
|
25415
25457
|
/** Auto-continues after a worktree turn ended while a detached job still runs. */
|
|
25416
25458
|
jobContinueCount = /* @__PURE__ */ new Map();
|
|
25417
25459
|
jobContinueNudged = /* @__PURE__ */ new Set();
|
|
@@ -25850,7 +25892,6 @@ var init_orchestrator = __esm({
|
|
|
25850
25892
|
* next prompt so the same agent can continue instead of sitting on lastError.
|
|
25851
25893
|
*/
|
|
25852
25894
|
maybeEnqueueCrashContinue(threadId, opts) {
|
|
25853
|
-
if (this.crashContinued.has(threadId)) return;
|
|
25854
25895
|
if (this.haltDrain.has(threadId)) return;
|
|
25855
25896
|
if (!shouldFeedErrorBackToAgent({
|
|
25856
25897
|
detail: opts.detail,
|
|
@@ -25859,9 +25900,11 @@ var init_orchestrator = __esm({
|
|
|
25859
25900
|
})) {
|
|
25860
25901
|
return;
|
|
25861
25902
|
}
|
|
25903
|
+
const resumeCount = nextCrashContinueCount(opts.detail, this.crashContinued.get(threadId) ?? 0);
|
|
25904
|
+
if (resumeCount == null) return;
|
|
25862
25905
|
const thread = readThread(threadId);
|
|
25863
25906
|
if (!thread || thread.status === "archived") return;
|
|
25864
|
-
this.crashContinued.
|
|
25907
|
+
this.crashContinued.set(threadId, resumeCount);
|
|
25865
25908
|
const prompt = formatAgentErrorContinuePrompt(opts.detail);
|
|
25866
25909
|
const next = prependQueuedItem(thread.queue, thread.queueAttachments, prompt);
|
|
25867
25910
|
updateThread(threadId, next);
|
package/dist/mcp/run-stdio.js
CHANGED
|
@@ -18,9 +18,9 @@ import {
|
|
|
18
18
|
searchAbleTimeTasks,
|
|
19
19
|
toAbleTimeIssueInfo,
|
|
20
20
|
updateAbleTimeTask
|
|
21
|
-
} from "../chunk-
|
|
22
|
-
import "../chunk-
|
|
23
|
-
import "../chunk-
|
|
21
|
+
} from "../chunk-TMM4FEZ5.js";
|
|
22
|
+
import "../chunk-5T4YWFLD.js";
|
|
23
|
+
import "../chunk-VQEARG5H.js";
|
|
24
24
|
import {
|
|
25
25
|
AGENT_GIT_ACTIONS,
|
|
26
26
|
BOARD_COLUMN_DEFS,
|
|
@@ -71,7 +71,7 @@ import {
|
|
|
71
71
|
syncBoardPins,
|
|
72
72
|
updateSchedule,
|
|
73
73
|
workspaceTagTargetRef
|
|
74
|
-
} from "../chunk-
|
|
74
|
+
} from "../chunk-2K723QZH.js";
|
|
75
75
|
import "../chunk-LX5R5JOR.js";
|
|
76
76
|
import {
|
|
77
77
|
PRESENT_PLAN_REQUIRES_PLAN_MODE,
|
|
@@ -90,12 +90,12 @@ import {
|
|
|
90
90
|
sideboardMcpProfile,
|
|
91
91
|
trustSystemCertificates,
|
|
92
92
|
worktreeMcpToolNames
|
|
93
|
-
} from "../chunk-
|
|
94
|
-
import "../chunk-
|
|
95
|
-
import "../chunk-
|
|
93
|
+
} from "../chunk-TXHZJESB.js";
|
|
94
|
+
import "../chunk-7IAMHN2N.js";
|
|
95
|
+
import "../chunk-PXMLMBMI.js";
|
|
96
96
|
import {
|
|
97
97
|
httpFetch
|
|
98
|
-
} from "../chunk-
|
|
98
|
+
} from "../chunk-2GPQZZLY.js";
|
|
99
99
|
import {
|
|
100
100
|
mcpWaitForJobTimeoutMs,
|
|
101
101
|
mcpWaitForTurnTimeoutMs,
|
|
@@ -106,12 +106,12 @@ import {
|
|
|
106
106
|
waitForDetachedJob,
|
|
107
107
|
waitForTurnToolResult,
|
|
108
108
|
workspaceAgentChatSummaries
|
|
109
|
-
} from "../chunk-
|
|
109
|
+
} from "../chunk-LMWPVC5L.js";
|
|
110
110
|
import {
|
|
111
111
|
clipToolResultForStore,
|
|
112
112
|
isInternalAgentStatusText,
|
|
113
113
|
looksLikeHugeToolResultDump
|
|
114
|
-
} from "../chunk-
|
|
114
|
+
} from "../chunk-5QOLFOAX.js";
|
|
115
115
|
import {
|
|
116
116
|
GLOBAL_WORKSPACE_ID,
|
|
117
117
|
isCloudCoordinatorThread
|
|
@@ -7,8 +7,8 @@ import {
|
|
|
7
7
|
normalizeBrightsyEndpoint,
|
|
8
8
|
refreshBrightsyAccessToken,
|
|
9
9
|
registerBrightsyOAuthClient
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-33KDPEK4.js";
|
|
11
|
+
import "./chunk-JAT3JFOS.js";
|
|
12
12
|
export {
|
|
13
13
|
BRIGHTSY_OAUTH_CLIENT_ID,
|
|
14
14
|
BRIGHTSY_OAUTH_REDIRECT,
|