@sideboard-ai/core 0.1.115 → 0.1.117
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 +96 -60
- package/dist/agents/cursor-runner.js +10 -9
- package/dist/{agents-3X3EFCQY.js → agents-GUEKGV7V.js} +6 -6
- package/dist/{agents-AHAFC6FR.js → agents-OCGAZCKT.js} +5 -5
- package/dist/{chunk-66XTXHR3.js → chunk-4CDCTYTM.js} +61 -11
- package/dist/{chunk-XOYQ7LNQ.js → chunk-4NAW5BAQ.js} +3 -3
- package/dist/{chunk-4OJMZ6P2.js → chunk-4WV7C7WP.js} +3 -3
- package/dist/{chunk-DCNR7NAL.js → chunk-5X7GRP5W.js} +49 -24
- package/dist/{chunk-MZ6HJ7VL.js → chunk-74YJHND6.js} +48 -23
- package/dist/{chunk-ZRCX43LS.js → chunk-BKVDZV7X.js} +2 -2
- package/dist/{chunk-A4VZXJEJ.js → chunk-HPAWHIZ3.js} +4 -1
- package/dist/{chunk-SLU5JVKD.js → chunk-NZBDVBCP.js} +23 -2
- package/dist/{chunk-KYOTBZ6S.js → chunk-RG737OWT.js} +4 -1
- package/dist/{chunk-K3TIQXOH.js → chunk-U3IVCVLH.js} +2 -2
- package/dist/{chunk-FZCIQYNQ.js → chunk-VGPLXQIH.js} +1 -1
- package/dist/chunk-VHX673DI.js +32 -0
- package/dist/{chunk-ZMROW673.js → chunk-WCU3FHEI.js} +1 -1
- package/dist/{chunk-7WC5UWEB.js → chunk-X3NIPGQT.js} +1 -1
- package/dist/{chunk-ZYEFCSZJ.js → chunk-XTZQL7OU.js} +1 -1
- package/dist/{chunk-C6OBY6IC.js → chunk-YJ2WV5TZ.js} +54 -10
- package/dist/{coordinator-prompt-4KCALEKD.js → coordinator-prompt-QMV6YEP5.js} +3 -3
- package/dist/{coordinator-prompt-FML4I5AR.js → coordinator-prompt-XCBHAOGE.js} +3 -3
- package/dist/cursor-recover-NOQYOFRF.js +76 -0
- package/dist/{cursor-recover-JBTIDARH.js → cursor-recover-QSLWEZNA.js} +12 -7
- package/dist/{global-workspace-CSWABOG5.js → global-workspace-SBKXKQFS.js} +4 -4
- package/dist/{global-workspace-H4YNASM6.js → global-workspace-Z37MNYU6.js} +4 -4
- package/dist/index.cjs +369 -240
- package/dist/index.d.cts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +14 -10
- package/dist/mcp/run-stdio.cjs +359 -237
- package/dist/mcp/run-stdio.js +9 -9
- package/dist/{orchestrator-GKLYKLRC.js → orchestrator-4PKR6AZJ.js} +7 -7
- package/dist/{orchestrator-TXASYNHT.js → orchestrator-MKTZYWTI.js} +8 -8
- package/dist/{thread-store-OEALWU7Y.js → thread-store-JR235AWK.js} +3 -1
- package/dist/{thread-store-LPTBVW5C.js → thread-store-PMH3BMB6.js} +3 -1
- package/dist/{workspaces-HJ3EVATC.js → workspaces-C3TJJFY3.js} +5 -5
- package/dist/{workspaces-QG6PGFQR.js → workspaces-M4OICPWF.js} +5 -5
- package/dist/{worktree-IW3BX26B.js → worktree-7AEKZSEX.js} +2 -2
- package/dist/{worktree-OTFQO2W7.js → worktree-MRSTQ32S.js} +2 -2
- package/package.json +1 -1
- package/dist/cursor-recover-ZUJG6XRQ.js +0 -42
|
@@ -17,13 +17,13 @@ import {
|
|
|
17
17
|
resolveQuotaFallbackAgent,
|
|
18
18
|
stripBrightsyNdjsonNoise,
|
|
19
19
|
toolDescription
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-YJ2WV5TZ.js";
|
|
21
21
|
import {
|
|
22
22
|
addWorkspace,
|
|
23
23
|
ensureWorkspace,
|
|
24
24
|
removeWorkspace,
|
|
25
25
|
syncWorkspacesFromThreads
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-U3IVCVLH.js";
|
|
27
27
|
import {
|
|
28
28
|
assertOrchestratorCapableAgent,
|
|
29
29
|
coerceOrchestratorAgent,
|
|
@@ -36,14 +36,14 @@ import {
|
|
|
36
36
|
isOrchestratorThread,
|
|
37
37
|
isSlackCoordinatorThread,
|
|
38
38
|
orchestratorSessionPoisonedByBuiltins
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-4WV7C7WP.js";
|
|
40
40
|
import {
|
|
41
41
|
SLACK_REPLY_FORMATTING,
|
|
42
42
|
coordinatorSystemPrompt,
|
|
43
43
|
coordinatorTurnReminder,
|
|
44
44
|
enrichWorkspacesWithGithub,
|
|
45
45
|
ensureGlobalCoordinatorCwd
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-X3NIPGQT.js";
|
|
47
47
|
import {
|
|
48
48
|
extractPresentedPlan,
|
|
49
49
|
readPlanFile,
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
shouldRetryFailedAgentTurn,
|
|
64
64
|
summarizeTurnStderr,
|
|
65
65
|
turnFailChatText
|
|
66
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-NZBDVBCP.js";
|
|
67
67
|
import {
|
|
68
68
|
releaseCaffeinateHoldForThread
|
|
69
69
|
} from "./chunk-DCOZABNT.js";
|
|
@@ -109,7 +109,7 @@ import {
|
|
|
109
109
|
threadDisplayLabel,
|
|
110
110
|
withRepoGitLock,
|
|
111
111
|
worktreeNameFromPath
|
|
112
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-VGPLXQIH.js";
|
|
113
113
|
import {
|
|
114
114
|
ATTACHMENTS_DIR,
|
|
115
115
|
LEGACY_ATTACHMENTS_DIR,
|
|
@@ -145,7 +145,7 @@ import {
|
|
|
145
145
|
updateThread,
|
|
146
146
|
withThreadLock,
|
|
147
147
|
writeThread
|
|
148
|
-
} from "./chunk-
|
|
148
|
+
} from "./chunk-HPAWHIZ3.js";
|
|
149
149
|
import {
|
|
150
150
|
appDataDir,
|
|
151
151
|
findConventionSetup,
|
|
@@ -755,9 +755,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
755
755
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
756
756
|
);
|
|
757
757
|
}
|
|
758
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
758
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-SBKXKQFS.js");
|
|
759
759
|
if (isGlobalThread2(thread)) {
|
|
760
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
760
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-QMV6YEP5.js");
|
|
761
761
|
ensureGlobalCoordinatorCwd2(
|
|
762
762
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
763
763
|
);
|
|
@@ -2455,7 +2455,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2455
2455
|
return readThread(thread.id) ?? thread;
|
|
2456
2456
|
}
|
|
2457
2457
|
async function listLinearIssues(agent, repoPath) {
|
|
2458
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
2458
|
+
const { getAdapter: getAdapter2 } = await import("./agents-GUEKGV7V.js");
|
|
2459
2459
|
await requireAgent(agent, { requireLinear: true });
|
|
2460
2460
|
const adapter = getAdapter2(agent);
|
|
2461
2461
|
if (!adapter.listLinearIssues) {
|
|
@@ -2551,7 +2551,7 @@ function noteTurnLiveEvent(threadId, event) {
|
|
|
2551
2551
|
buffers.delete(threadId);
|
|
2552
2552
|
return;
|
|
2553
2553
|
}
|
|
2554
|
-
const immediate = event.type === "tool_use" || event.type === "tool_result";
|
|
2554
|
+
const immediate = event.type === "tool_use" || event.type === "tool_result" && !event.partial;
|
|
2555
2555
|
if (immediate) flush(threadId);
|
|
2556
2556
|
else scheduleFlush(threadId);
|
|
2557
2557
|
}
|
|
@@ -2591,6 +2591,21 @@ function clearTurnLive(threadId) {
|
|
|
2591
2591
|
}
|
|
2592
2592
|
}
|
|
2593
2593
|
|
|
2594
|
+
// src/orchestrator/reconcile-heal.ts
|
|
2595
|
+
var RECONCILE_HEAL_MIN_MS = 2e3;
|
|
2596
|
+
var SKIP = /* @__PURE__ */ new Set([
|
|
2597
|
+
"stdout",
|
|
2598
|
+
"thinking",
|
|
2599
|
+
"usage",
|
|
2600
|
+
"stderr",
|
|
2601
|
+
"tool_result"
|
|
2602
|
+
]);
|
|
2603
|
+
function shouldReadThreadToHealReconcile(eventType, lastCheckAt, now) {
|
|
2604
|
+
if (SKIP.has(eventType)) return false;
|
|
2605
|
+
if (lastCheckAt != null && now - lastCheckAt < RECONCILE_HEAL_MIN_MS) return false;
|
|
2606
|
+
return true;
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2594
2609
|
// src/threads/fork-worktree.ts
|
|
2595
2610
|
function requireThread2(idOrRef) {
|
|
2596
2611
|
const thread = findThreadByRef(idOrRef) ?? null;
|
|
@@ -2836,7 +2851,7 @@ async function adoptThread(input) {
|
|
|
2836
2851
|
messages: input.messages ?? []
|
|
2837
2852
|
});
|
|
2838
2853
|
writeThread(thread);
|
|
2839
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
2854
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-M4OICPWF.js");
|
|
2840
2855
|
await ensureWorkspace2(repoPath);
|
|
2841
2856
|
return thread;
|
|
2842
2857
|
}
|
|
@@ -4743,14 +4758,15 @@ function formatArtifactDirective() {
|
|
|
4743
4758
|
return [
|
|
4744
4759
|
"Sideboard side column (desktop UI):",
|
|
4745
4760
|
"claude.ai\u2019s \u201CArtifact\u201D tool does NOT exist in Claude Code. That is expected.",
|
|
4761
|
+
"Do not unprompted-duplicate a payload. Chat markdown (including tables) already renders in the transcript \u2014 do not also call present_schema with those same rows just to display them. If the user asks for an editable / interactive table, call present_schema even if markdown already showed the data. Do not also call present_artifact for a document you already fenced in chat.",
|
|
4746
4762
|
"Documents (HTML/SVG/markdown):",
|
|
4747
4763
|
"1) Emit a fenced code block tagged `html` (preferred), `svg`, or `markdown` with the FULL document \u2014 Sideboard opens a side column. Example:",
|
|
4748
4764
|
"```html",
|
|
4749
4765
|
"<!DOCTYPE html><html><head><title>Demo</title></head><body><h1>Hi</h1></body></html>",
|
|
4750
4766
|
"```",
|
|
4751
|
-
"2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content.",
|
|
4767
|
+
"2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content \u2014 not both a fence and this tool for the same body.",
|
|
4752
4768
|
"CMS / JSON Schema forms & tables (Brightsy or any schema+schemaUi source):",
|
|
4753
|
-
"3) Call Sideboard MCP `present_schema`
|
|
4769
|
+
"3) Call Sideboard MCP `present_schema` when the user needs to filter, edit, publish, or persist rows \u2014 including after you already showed a markdown table, if they then ask for an editable table. If they only need to read the data, a markdown table is enough. When you do call it, pass title, mode (table|form), and either:",
|
|
4754
4770
|
" - datasource=brightsy + resource_id (record type UUID) after fetching types via Brightsy MCP, or",
|
|
4755
4771
|
" - datasource=inline + resource: { id, title, schema, schemaUi } and optional records/record.",
|
|
4756
4772
|
"Files / media browser (CMS file manager column):",
|
|
@@ -4759,11 +4775,11 @@ function formatArtifactDirective() {
|
|
|
4759
4775
|
"Multiple-choice questions:",
|
|
4760
4776
|
"5) Call Sideboard MCP `ask_user` only when work is blocked on choosing among a few concrete options (approach forks, which API, auth vs cookies). First write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it). Include a description on every option. After calling, stop and wait for their next message with answers. If you are asking a real multiple-choice, use ask_user rather than chat bullets so Sideboard shows the composer picker.",
|
|
4761
4777
|
"Do not call ask_user for greetings, check-ins, \u201Chello\u201D, open-ended how-can-I-help, or to invent a menu of possible next tasks \u2014 reply in chat. If one option is the obvious default, proceed without asking.",
|
|
4762
|
-
"Never say artifacts, CMS UI, or the Files column are unavailable.
|
|
4778
|
+
"Never say artifacts, CMS UI, or the Files column are unavailable. present_schema is for interactive list/edit/publish (use it when they ask to edit, even if chat already had a markdown table); present_files for storage UI; html fences for standalone pages; ask_user only for those blocked predefined-option questions."
|
|
4763
4779
|
].join("\n");
|
|
4764
4780
|
}
|
|
4765
4781
|
function formatUiReminder() {
|
|
4766
|
-
return "Sideboard UI: html fence or present_artifact
|
|
4782
|
+
return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. ask_user only for a real multiple-choice (not hellos or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
|
|
4767
4783
|
}
|
|
4768
4784
|
var FILES_BY_AGENT = {
|
|
4769
4785
|
claude: [
|
|
@@ -5108,7 +5124,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
5108
5124
|
${prompt}`;
|
|
5109
5125
|
}
|
|
5110
5126
|
async function defaultDeps() {
|
|
5111
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
5127
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-MKTZYWTI.js");
|
|
5112
5128
|
const orch = getOrchestrator2();
|
|
5113
5129
|
return {
|
|
5114
5130
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -5242,6 +5258,8 @@ var Orchestrator = class {
|
|
|
5242
5258
|
draining = /* @__PURE__ */ new Set();
|
|
5243
5259
|
/** Threads past setStatus(running) but not yet in activeTurns (spawn in flight). */
|
|
5244
5260
|
startingTurns = /* @__PURE__ */ new Set();
|
|
5261
|
+
/** Last sync thread-file read for false-stop heal (throttled per thread). */
|
|
5262
|
+
lastReconcileHealAt = /* @__PURE__ */ new Map();
|
|
5245
5263
|
/**
|
|
5246
5264
|
* Threads intentionally force-stopped. Prevents runTurn from re-asserting
|
|
5247
5265
|
* `running` after spawn, and from overwriting `stopped` with idle/error when
|
|
@@ -5839,7 +5857,13 @@ var Orchestrator = class {
|
|
|
5839
5857
|
if (event.type === "stderr" && typeof event.data === "string") {
|
|
5840
5858
|
pushTurnStderr(stderrTail, event.data);
|
|
5841
5859
|
}
|
|
5842
|
-
|
|
5860
|
+
const now = Date.now();
|
|
5861
|
+
if (shouldReadThreadToHealReconcile(
|
|
5862
|
+
event.type,
|
|
5863
|
+
this.lastReconcileHealAt.get(threadId),
|
|
5864
|
+
now
|
|
5865
|
+
)) {
|
|
5866
|
+
this.lastReconcileHealAt.set(threadId, now);
|
|
5843
5867
|
const live = readThread(threadId);
|
|
5844
5868
|
if (live?.lastError?.includes("reconciled on startup") && (this.activeTurns.has(threadId) || this.startingTurns.has(threadId))) {
|
|
5845
5869
|
setStatus(threadId, "running");
|
|
@@ -5879,11 +5903,12 @@ var Orchestrator = class {
|
|
|
5879
5903
|
if (this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
|
|
5880
5904
|
const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
|
|
5881
5905
|
if (sessionId) {
|
|
5882
|
-
const { recoverFinishedCursorRun } = await import("./cursor-recover-
|
|
5906
|
+
const { recoverFinishedCursorRun } = await import("./cursor-recover-QSLWEZNA.js");
|
|
5883
5907
|
for (let i = 0; i < 8; i++) {
|
|
5884
5908
|
const recovered = recoverFinishedCursorRun({
|
|
5885
5909
|
agentId: sessionId,
|
|
5886
|
-
startedAfterMs: turnStartedAt - 5e3
|
|
5910
|
+
startedAfterMs: turnStartedAt - 5e3,
|
|
5911
|
+
threadId
|
|
5887
5912
|
});
|
|
5888
5913
|
if (recovered?.result) {
|
|
5889
5914
|
assistantText = recovered.result;
|
|
@@ -6856,7 +6881,7 @@ var Orchestrator = class {
|
|
|
6856
6881
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
6857
6882
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
6858
6883
|
try {
|
|
6859
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
6884
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-M4OICPWF.js");
|
|
6860
6885
|
await ensureWorkspace2(thread.repoPath);
|
|
6861
6886
|
} catch {
|
|
6862
6887
|
}
|
|
@@ -6910,7 +6935,7 @@ var Orchestrator = class {
|
|
|
6910
6935
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
6911
6936
|
);
|
|
6912
6937
|
}
|
|
6913
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
6938
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-7AEKZSEX.js");
|
|
6914
6939
|
const slug = thread.worktreePath.split("/").pop();
|
|
6915
6940
|
const dest = thread.worktreePath;
|
|
6916
6941
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -7018,7 +7043,7 @@ async function startOrchestration(opts) {
|
|
|
7018
7043
|
sourceRef: "default",
|
|
7019
7044
|
...createOpts
|
|
7020
7045
|
}).catch(async () => {
|
|
7021
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
7046
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-7AEKZSEX.js");
|
|
7022
7047
|
const repo = await resolveRepoRoot2(repoPath);
|
|
7023
7048
|
const def = await resolveDefaultBranch2(repo);
|
|
7024
7049
|
return orch.createThread({
|
|
@@ -7028,7 +7053,7 @@ async function startOrchestration(opts) {
|
|
|
7028
7053
|
repoPath: repo
|
|
7029
7054
|
});
|
|
7030
7055
|
});
|
|
7031
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
7056
|
+
const { updateThread: upd } = await import("./thread-store-JR235AWK.js");
|
|
7032
7057
|
const updated = upd(thread.id, {
|
|
7033
7058
|
sourceType: "orchestration",
|
|
7034
7059
|
sourceRef: goal
|
|
@@ -28,13 +28,13 @@ import {
|
|
|
28
28
|
summarizeTurnStderr,
|
|
29
29
|
toolDescription,
|
|
30
30
|
turnFailChatText
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-4CDCTYTM.js";
|
|
32
32
|
import {
|
|
33
33
|
addWorkspace,
|
|
34
34
|
ensureWorkspace,
|
|
35
35
|
removeWorkspace,
|
|
36
36
|
syncWorkspacesFromThreads
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-BKVDZV7X.js";
|
|
38
38
|
import {
|
|
39
39
|
extractPresentedPlan,
|
|
40
40
|
readPlanFile,
|
|
@@ -55,14 +55,14 @@ import {
|
|
|
55
55
|
isOrchestratorThread,
|
|
56
56
|
isSlackCoordinatorThread,
|
|
57
57
|
orchestratorSessionPoisonedByBuiltins
|
|
58
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-4NAW5BAQ.js";
|
|
59
59
|
import {
|
|
60
60
|
SLACK_REPLY_FORMATTING,
|
|
61
61
|
coordinatorSystemPrompt,
|
|
62
62
|
coordinatorTurnReminder,
|
|
63
63
|
enrichWorkspacesWithGithub,
|
|
64
64
|
ensureGlobalCoordinatorCwd
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-XTZQL7OU.js";
|
|
66
66
|
import {
|
|
67
67
|
addPrStackLayer,
|
|
68
68
|
allocateTeamName,
|
|
@@ -105,7 +105,7 @@ import {
|
|
|
105
105
|
threadDisplayLabel,
|
|
106
106
|
withRepoGitLock,
|
|
107
107
|
worktreeNameFromPath
|
|
108
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-WCU3FHEI.js";
|
|
109
109
|
import {
|
|
110
110
|
ATTACHMENTS_DIR,
|
|
111
111
|
LEGACY_ATTACHMENTS_DIR,
|
|
@@ -122,7 +122,7 @@ import {
|
|
|
122
122
|
updateThread,
|
|
123
123
|
withThreadLock,
|
|
124
124
|
writeThread
|
|
125
|
-
} from "./chunk-
|
|
125
|
+
} from "./chunk-RG737OWT.js";
|
|
126
126
|
import {
|
|
127
127
|
clearStaleIndexLocks,
|
|
128
128
|
enrichPathWithNpmGlobalBin,
|
|
@@ -742,9 +742,9 @@ async function spawnAgentTurn(thread, input, onEvent) {
|
|
|
742
742
|
`Cannot spawn ${thread.agent}: thread ${thread.id} has no worktreePath`
|
|
743
743
|
);
|
|
744
744
|
}
|
|
745
|
-
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-
|
|
745
|
+
const { isGlobalThread: isGlobalThread2 } = await import("./global-workspace-Z37MNYU6.js");
|
|
746
746
|
if (isGlobalThread2(thread)) {
|
|
747
|
-
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-
|
|
747
|
+
const { ensureGlobalCoordinatorCwd: ensureGlobalCoordinatorCwd2 } = await import("./coordinator-prompt-XCBHAOGE.js");
|
|
748
748
|
ensureGlobalCoordinatorCwd2(
|
|
749
749
|
isOrchestratorThread(thread) ? { orchestratorThreadId: thread.id } : void 0
|
|
750
750
|
);
|
|
@@ -2410,7 +2410,7 @@ async function createThread(input, _onSetupLine) {
|
|
|
2410
2410
|
return readThread(thread.id) ?? thread;
|
|
2411
2411
|
}
|
|
2412
2412
|
async function listLinearIssues(agent, repoPath) {
|
|
2413
|
-
const { getAdapter: getAdapter2 } = await import("./agents-
|
|
2413
|
+
const { getAdapter: getAdapter2 } = await import("./agents-OCGAZCKT.js");
|
|
2414
2414
|
await requireAgent(agent, { requireLinear: true });
|
|
2415
2415
|
const adapter = getAdapter2(agent);
|
|
2416
2416
|
if (!adapter.listLinearIssues) {
|
|
@@ -2506,7 +2506,7 @@ function noteTurnLiveEvent(threadId, event) {
|
|
|
2506
2506
|
buffers.delete(threadId);
|
|
2507
2507
|
return;
|
|
2508
2508
|
}
|
|
2509
|
-
const immediate = event.type === "tool_use" || event.type === "tool_result";
|
|
2509
|
+
const immediate = event.type === "tool_use" || event.type === "tool_result" && !event.partial;
|
|
2510
2510
|
if (immediate) flush(threadId);
|
|
2511
2511
|
else scheduleFlush(threadId);
|
|
2512
2512
|
}
|
|
@@ -2546,6 +2546,21 @@ function clearTurnLive(threadId) {
|
|
|
2546
2546
|
}
|
|
2547
2547
|
}
|
|
2548
2548
|
|
|
2549
|
+
// src/orchestrator/reconcile-heal.ts
|
|
2550
|
+
var RECONCILE_HEAL_MIN_MS = 2e3;
|
|
2551
|
+
var SKIP = /* @__PURE__ */ new Set([
|
|
2552
|
+
"stdout",
|
|
2553
|
+
"thinking",
|
|
2554
|
+
"usage",
|
|
2555
|
+
"stderr",
|
|
2556
|
+
"tool_result"
|
|
2557
|
+
]);
|
|
2558
|
+
function shouldReadThreadToHealReconcile(eventType, lastCheckAt, now) {
|
|
2559
|
+
if (SKIP.has(eventType)) return false;
|
|
2560
|
+
if (lastCheckAt != null && now - lastCheckAt < RECONCILE_HEAL_MIN_MS) return false;
|
|
2561
|
+
return true;
|
|
2562
|
+
}
|
|
2563
|
+
|
|
2549
2564
|
// src/threads/fork-worktree.ts
|
|
2550
2565
|
function requireThread2(idOrRef) {
|
|
2551
2566
|
const thread = findThreadByRef(idOrRef) ?? null;
|
|
@@ -2791,7 +2806,7 @@ async function adoptThread(input) {
|
|
|
2791
2806
|
messages: input.messages ?? []
|
|
2792
2807
|
});
|
|
2793
2808
|
writeThread(thread);
|
|
2794
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
2809
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-C3TJJFY3.js");
|
|
2795
2810
|
await ensureWorkspace2(repoPath);
|
|
2796
2811
|
return thread;
|
|
2797
2812
|
}
|
|
@@ -4646,14 +4661,15 @@ function formatArtifactDirective() {
|
|
|
4646
4661
|
return [
|
|
4647
4662
|
"Sideboard side column (desktop UI):",
|
|
4648
4663
|
"claude.ai\u2019s \u201CArtifact\u201D tool does NOT exist in Claude Code. That is expected.",
|
|
4664
|
+
"Do not unprompted-duplicate a payload. Chat markdown (including tables) already renders in the transcript \u2014 do not also call present_schema with those same rows just to display them. If the user asks for an editable / interactive table, call present_schema even if markdown already showed the data. Do not also call present_artifact for a document you already fenced in chat.",
|
|
4649
4665
|
"Documents (HTML/SVG/markdown):",
|
|
4650
4666
|
"1) Emit a fenced code block tagged `html` (preferred), `svg`, or `markdown` with the FULL document \u2014 Sideboard opens a side column. Example:",
|
|
4651
4667
|
"```html",
|
|
4652
4668
|
"<!DOCTYPE html><html><head><title>Demo</title></head><body><h1>Hi</h1></body></html>",
|
|
4653
4669
|
"```",
|
|
4654
|
-
"2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content.",
|
|
4670
|
+
"2) Or call Sideboard MCP `present_artifact` with title, type (html|svg|markdown), and content \u2014 not both a fence and this tool for the same body.",
|
|
4655
4671
|
"CMS / JSON Schema forms & tables (Brightsy or any schema+schemaUi source):",
|
|
4656
|
-
"3) Call Sideboard MCP `present_schema`
|
|
4672
|
+
"3) Call Sideboard MCP `present_schema` when the user needs to filter, edit, publish, or persist rows \u2014 including after you already showed a markdown table, if they then ask for an editable table. If they only need to read the data, a markdown table is enough. When you do call it, pass title, mode (table|form), and either:",
|
|
4657
4673
|
" - datasource=brightsy + resource_id (record type UUID) after fetching types via Brightsy MCP, or",
|
|
4658
4674
|
" - datasource=inline + resource: { id, title, schema, schemaUi } and optional records/record.",
|
|
4659
4675
|
"Files / media browser (CMS file manager column):",
|
|
@@ -4662,11 +4678,11 @@ function formatArtifactDirective() {
|
|
|
4662
4678
|
"Multiple-choice questions:",
|
|
4663
4679
|
"5) Call Sideboard MCP `ask_user` only when work is blocked on choosing among a few concrete options (approach forks, which API, auth vs cookies). First write a short chat message that explains the decision and what each option means (tradeoffs, when to pick it). Include a description on every option. After calling, stop and wait for their next message with answers. If you are asking a real multiple-choice, use ask_user rather than chat bullets so Sideboard shows the composer picker.",
|
|
4664
4680
|
"Do not call ask_user for greetings, check-ins, \u201Chello\u201D, open-ended how-can-I-help, or to invent a menu of possible next tasks \u2014 reply in chat. If one option is the obvious default, proceed without asking.",
|
|
4665
|
-
"Never say artifacts, CMS UI, or the Files column are unavailable.
|
|
4681
|
+
"Never say artifacts, CMS UI, or the Files column are unavailable. present_schema is for interactive list/edit/publish (use it when they ask to edit, even if chat already had a markdown table); present_files for storage UI; html fences for standalone pages; ask_user only for those blocked predefined-option questions."
|
|
4666
4682
|
].join("\n");
|
|
4667
4683
|
}
|
|
4668
4684
|
function formatUiReminder() {
|
|
4669
|
-
return "Sideboard UI: html fence or present_artifact
|
|
4685
|
+
return "Sideboard UI: markdown table is enough to read data; present_schema if they ask to edit/filter (even after markdown); present_files for the file manager. html fence or present_artifact, not both for the same document. ask_user only for a real multiple-choice (not hellos or \u201Cwhat next?\u201D) \u2014 reply in chat. Do not say artifacts/CMS UI are unavailable.";
|
|
4670
4686
|
}
|
|
4671
4687
|
|
|
4672
4688
|
// src/threads/sync-branch.ts
|
|
@@ -4937,7 +4953,7 @@ function formatScheduledPrompt(name, prompt) {
|
|
|
4937
4953
|
${prompt}`;
|
|
4938
4954
|
}
|
|
4939
4955
|
async function defaultDeps() {
|
|
4940
|
-
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-
|
|
4956
|
+
const { getOrchestrator: getOrchestrator2, startOrchestration: startOrchestration2 } = await import("./orchestrator-4PKR6AZJ.js");
|
|
4941
4957
|
const orch = getOrchestrator2();
|
|
4942
4958
|
return {
|
|
4943
4959
|
findThread: (id) => findThreadByRef(id),
|
|
@@ -5071,6 +5087,8 @@ var Orchestrator = class {
|
|
|
5071
5087
|
draining = /* @__PURE__ */ new Set();
|
|
5072
5088
|
/** Threads past setStatus(running) but not yet in activeTurns (spawn in flight). */
|
|
5073
5089
|
startingTurns = /* @__PURE__ */ new Set();
|
|
5090
|
+
/** Last sync thread-file read for false-stop heal (throttled per thread). */
|
|
5091
|
+
lastReconcileHealAt = /* @__PURE__ */ new Map();
|
|
5074
5092
|
/**
|
|
5075
5093
|
* Threads intentionally force-stopped. Prevents runTurn from re-asserting
|
|
5076
5094
|
* `running` after spawn, and from overwriting `stopped` with idle/error when
|
|
@@ -5668,7 +5686,13 @@ var Orchestrator = class {
|
|
|
5668
5686
|
if (event.type === "stderr" && typeof event.data === "string") {
|
|
5669
5687
|
pushTurnStderr(stderrTail, event.data);
|
|
5670
5688
|
}
|
|
5671
|
-
|
|
5689
|
+
const now = Date.now();
|
|
5690
|
+
if (shouldReadThreadToHealReconcile(
|
|
5691
|
+
event.type,
|
|
5692
|
+
this.lastReconcileHealAt.get(threadId),
|
|
5693
|
+
now
|
|
5694
|
+
)) {
|
|
5695
|
+
this.lastReconcileHealAt.set(threadId, now);
|
|
5672
5696
|
const live = readThread(threadId);
|
|
5673
5697
|
if (live?.lastError?.includes("reconciled on startup") && (this.activeTurns.has(threadId) || this.startingTurns.has(threadId))) {
|
|
5674
5698
|
setStatus(threadId, "running");
|
|
@@ -5708,11 +5732,12 @@ var Orchestrator = class {
|
|
|
5708
5732
|
if (this.requireThread(threadId).agent === "cursor" && exitCode !== 0 && !assistantText && parts.length === 0) {
|
|
5709
5733
|
const sessionId = result.sessionId || this.requireThread(threadId).sessionId || "";
|
|
5710
5734
|
if (sessionId) {
|
|
5711
|
-
const { recoverFinishedCursorRun } = await import("./cursor-recover-
|
|
5735
|
+
const { recoverFinishedCursorRun } = await import("./cursor-recover-NOQYOFRF.js");
|
|
5712
5736
|
for (let i = 0; i < 8; i++) {
|
|
5713
5737
|
const recovered = recoverFinishedCursorRun({
|
|
5714
5738
|
agentId: sessionId,
|
|
5715
|
-
startedAfterMs: turnStartedAt - 5e3
|
|
5739
|
+
startedAfterMs: turnStartedAt - 5e3,
|
|
5740
|
+
threadId
|
|
5716
5741
|
});
|
|
5717
5742
|
if (recovered?.result) {
|
|
5718
5743
|
assistantText = recovered.result;
|
|
@@ -6685,7 +6710,7 @@ var Orchestrator = class {
|
|
|
6685
6710
|
this.emit({ type: "status_changed", threadId: archived.id, status: "archived" });
|
|
6686
6711
|
if (thread.repoPath && !isGlobalRepoPath(thread.repoPath)) {
|
|
6687
6712
|
try {
|
|
6688
|
-
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-
|
|
6713
|
+
const { ensureWorkspace: ensureWorkspace2 } = await import("./workspaces-C3TJJFY3.js");
|
|
6689
6714
|
await ensureWorkspace2(thread.repoPath);
|
|
6690
6715
|
} catch {
|
|
6691
6716
|
}
|
|
@@ -6739,7 +6764,7 @@ var Orchestrator = class {
|
|
|
6739
6764
|
`Cowboy checkout missing: ${thread.worktreePath}. Re-add the project folder, then restore.`
|
|
6740
6765
|
);
|
|
6741
6766
|
}
|
|
6742
|
-
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-
|
|
6767
|
+
const { createThreadWorktree: createThreadWorktree2 } = await import("./worktree-MRSTQ32S.js");
|
|
6743
6768
|
const slug = thread.worktreePath.split("/").pop();
|
|
6744
6769
|
const dest = thread.worktreePath;
|
|
6745
6770
|
await withRepoGitLock(thread.repoPath, async () => {
|
|
@@ -6847,7 +6872,7 @@ async function startOrchestration(opts) {
|
|
|
6847
6872
|
sourceRef: "default",
|
|
6848
6873
|
...createOpts
|
|
6849
6874
|
}).catch(async () => {
|
|
6850
|
-
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-
|
|
6875
|
+
const { resolveDefaultBranch: resolveDefaultBranch2, resolveRepoRoot: resolveRepoRoot2 } = await import("./worktree-MRSTQ32S.js");
|
|
6851
6876
|
const repo = await resolveRepoRoot2(repoPath);
|
|
6852
6877
|
const def = await resolveDefaultBranch2(repo);
|
|
6853
6878
|
return orch.createThread({
|
|
@@ -6857,7 +6882,7 @@ async function startOrchestration(opts) {
|
|
|
6857
6882
|
repoPath: repo
|
|
6858
6883
|
});
|
|
6859
6884
|
});
|
|
6860
|
-
const { updateThread: upd } = await import("./thread-store-
|
|
6885
|
+
const { updateThread: upd } = await import("./thread-store-PMH3BMB6.js");
|
|
6861
6886
|
const updated = upd(thread.id, {
|
|
6862
6887
|
sourceType: "orchestration",
|
|
6863
6888
|
sourceRef: goal
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
isGlobalRepoPath
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-4NAW5BAQ.js";
|
|
6
6
|
import {
|
|
7
7
|
ensureGhPreferOrigin,
|
|
8
8
|
resolveRepoRoot
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-WCU3FHEI.js";
|
|
10
10
|
import {
|
|
11
11
|
appDataDir
|
|
12
12
|
} from "./chunk-BD2ICC4D.js";
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
writeFileSync,
|
|
18
18
|
readdirSync
|
|
19
19
|
} from "fs";
|
|
20
|
+
import { basename } from "path";
|
|
20
21
|
import lockfile from "proper-lockfile";
|
|
21
22
|
function nowIso() {
|
|
22
23
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -119,7 +120,8 @@ function writeThread(thread) {
|
|
|
119
120
|
function idPath(id) {
|
|
120
121
|
return id;
|
|
121
122
|
}
|
|
122
|
-
function isThreadRecordFile(
|
|
123
|
+
function isThreadRecordFile(nameOrPath) {
|
|
124
|
+
const name = basename(nameOrPath);
|
|
123
125
|
return name.endsWith(".json") && !name.endsWith(".live.json");
|
|
124
126
|
}
|
|
125
127
|
function listThreads(opts) {
|
|
@@ -178,6 +180,7 @@ export {
|
|
|
178
180
|
withThreadLock,
|
|
179
181
|
readThread,
|
|
180
182
|
writeThread,
|
|
183
|
+
isThreadRecordFile,
|
|
181
184
|
listThreads,
|
|
182
185
|
deleteThreadRecord,
|
|
183
186
|
updateThread,
|
|
@@ -130,7 +130,7 @@ function summarizeTurnStderr(tail, maxChars = 500) {
|
|
|
130
130
|
function looksLikeInvalidAgentSession(text) {
|
|
131
131
|
const lower = text.trim().toLowerCase();
|
|
132
132
|
if (!lower) return false;
|
|
133
|
-
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);
|
|
133
|
+
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);
|
|
134
134
|
}
|
|
135
135
|
function looksLikeRetryableRunnerCrash(text) {
|
|
136
136
|
if (looksLikeAgentFailureMessage(text)) return false;
|
|
@@ -585,7 +585,7 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
585
585
|
if (msg.type === "tool_call" && msg.call_id && msg.name) {
|
|
586
586
|
const normalized = normalizeCursorToolCall(msg.name, msg.args);
|
|
587
587
|
if (msg.status === "running") {
|
|
588
|
-
|
|
588
|
+
const events = [
|
|
589
589
|
{
|
|
590
590
|
type: "tool_use",
|
|
591
591
|
id: msg.call_id,
|
|
@@ -593,6 +593,16 @@ function cursorSdkMessageToEvents(msg) {
|
|
|
593
593
|
input: normalized.input
|
|
594
594
|
}
|
|
595
595
|
];
|
|
596
|
+
const live = unwrapCursorToolResult(msg.result);
|
|
597
|
+
if (live) {
|
|
598
|
+
events.push({
|
|
599
|
+
type: "tool_result",
|
|
600
|
+
id: msg.call_id,
|
|
601
|
+
content: live,
|
|
602
|
+
partial: true
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
return events;
|
|
596
606
|
}
|
|
597
607
|
if (msg.status === "completed" || msg.status === "error") {
|
|
598
608
|
return [
|
|
@@ -653,6 +663,17 @@ function nestedUpdateToEvents(update, parentId) {
|
|
|
653
663
|
isError: cursorToolResultIsError(void 0, update.toolCall.result),
|
|
654
664
|
parentId
|
|
655
665
|
});
|
|
666
|
+
} else {
|
|
667
|
+
const live = unwrapCursorToolResult(update.toolCall.result);
|
|
668
|
+
if (live) {
|
|
669
|
+
events.push({
|
|
670
|
+
type: "tool_result",
|
|
671
|
+
id: update.callId,
|
|
672
|
+
content: live,
|
|
673
|
+
partial: true,
|
|
674
|
+
parentId
|
|
675
|
+
});
|
|
676
|
+
}
|
|
656
677
|
}
|
|
657
678
|
return events;
|
|
658
679
|
}
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
writeFileSync,
|
|
20
20
|
readdirSync
|
|
21
21
|
} from "fs";
|
|
22
|
+
import { basename } from "path";
|
|
22
23
|
import lockfile from "proper-lockfile";
|
|
23
24
|
function nowIso() {
|
|
24
25
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -121,7 +122,8 @@ function writeThread(thread) {
|
|
|
121
122
|
function idPath(id) {
|
|
122
123
|
return id;
|
|
123
124
|
}
|
|
124
|
-
function isThreadRecordFile(
|
|
125
|
+
function isThreadRecordFile(nameOrPath) {
|
|
126
|
+
const name = basename(nameOrPath);
|
|
125
127
|
return name.endsWith(".json") && !name.endsWith(".live.json");
|
|
126
128
|
}
|
|
127
129
|
function listThreads(opts) {
|
|
@@ -180,6 +182,7 @@ export {
|
|
|
180
182
|
withThreadLock,
|
|
181
183
|
readThread,
|
|
182
184
|
writeThread,
|
|
185
|
+
isThreadRecordFile,
|
|
183
186
|
listThreads,
|
|
184
187
|
deleteThreadRecord,
|
|
185
188
|
updateThread,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isGlobalRepoPath
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4WV7C7WP.js";
|
|
4
4
|
import {
|
|
5
5
|
ensureGhPreferOrigin,
|
|
6
6
|
resolveRepoRoot
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-VGPLXQIH.js";
|
|
8
8
|
import {
|
|
9
9
|
appDataDir
|
|
10
10
|
} from "./chunk-QZQEXME2.js";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
appDataDir
|
|
3
|
+
} from "./chunk-QZQEXME2.js";
|
|
4
|
+
|
|
5
|
+
// src/agents/cursor-store.ts
|
|
6
|
+
import { join } from "path";
|
|
7
|
+
var CURSOR_SDK_STORE_DIR = "cursor-sdk-store";
|
|
8
|
+
function cursorSdkStoreDir(threadId) {
|
|
9
|
+
const root = join(appDataDir(), CURSOR_SDK_STORE_DIR);
|
|
10
|
+
const id = sanitizeCursorStoreSegment(threadId);
|
|
11
|
+
if (!id) return root;
|
|
12
|
+
return join(root, "threads", id);
|
|
13
|
+
}
|
|
14
|
+
function cursorSdkRunsNdjsonPath(threadId) {
|
|
15
|
+
return join(cursorSdkStoreDir(threadId), "runs.ndjson");
|
|
16
|
+
}
|
|
17
|
+
function cursorSdkRunsNdjsonSearchPaths(threadId) {
|
|
18
|
+
const scoped = cursorSdkRunsNdjsonPath(threadId);
|
|
19
|
+
const shared = cursorSdkRunsNdjsonPath(null);
|
|
20
|
+
if (!threadId || !sanitizeCursorStoreSegment(threadId) || scoped === shared) {
|
|
21
|
+
return [shared];
|
|
22
|
+
}
|
|
23
|
+
return [scoped, shared];
|
|
24
|
+
}
|
|
25
|
+
function sanitizeCursorStoreSegment(threadId) {
|
|
26
|
+
return (threadId ?? "").trim().replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
cursorSdkStoreDir,
|
|
31
|
+
cursorSdkRunsNdjsonSearchPaths
|
|
32
|
+
};
|