@schoolai/shipyard 3.1.1 → 3.2.0-rc.20260415.0
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/{chunk-ERKQ6CBC.js → chunk-7WMHXVZ5.js} +2 -2
- package/dist/{chunk-ERKQ6CBC.js.map → chunk-7WMHXVZ5.js.map} +1 -1
- package/dist/{chunk-WHHNOYQE.js → chunk-JAR2IPWI.js} +2 -2
- package/dist/index.js +3 -3
- package/dist/{login-VMDYGKB7.js → login-R24HAB3T.js} +3 -3
- package/dist/{serve-HDRZ2CU6.js → serve-ROGOK56J.js} +467 -219
- package/dist/serve-ROGOK56J.js.map +1 -0
- package/dist/{start-63XQAT6J.js → start-Z5LEWLLS.js} +4 -4
- package/package.json +1 -1
- package/dist/serve-HDRZ2CU6.js.map +0 -1
- /package/dist/{chunk-WHHNOYQE.js.map → chunk-JAR2IPWI.js.map} +0 -0
- /package/dist/{login-VMDYGKB7.js.map → login-R24HAB3T.js.map} +0 -0
- /package/dist/{start-63XQAT6J.js.map → start-Z5LEWLLS.js.map} +0 -0
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
VaultKeyPutRequestSchema,
|
|
38
38
|
VaultKeyPutResponseSchema,
|
|
39
39
|
classifyClaudeCodeCompatibility
|
|
40
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-7WMHXVZ5.js";
|
|
41
41
|
import {
|
|
42
42
|
loadAuthToken
|
|
43
43
|
} from "./chunk-IHSXN66C.js";
|
|
@@ -24345,7 +24345,8 @@ var DiffHunkAnnotationSchema = BaseCommentZodSchema.extend({
|
|
|
24345
24345
|
lineNumber: external_exports.number(),
|
|
24346
24346
|
lineContent: external_exports.string(),
|
|
24347
24347
|
lineContentHash: external_exports.string(),
|
|
24348
|
-
side: external_exports.enum(["original", "modified"])
|
|
24348
|
+
side: external_exports.enum(["original", "modified"]),
|
|
24349
|
+
diffScope: external_exports.enum(["working-tree", "branch", "last-turn", "pr"]).optional()
|
|
24349
24350
|
});
|
|
24350
24351
|
var PreviewElementAnnotationSchema = BaseCommentZodSchema.extend({
|
|
24351
24352
|
annotationType: external_exports.literal("preview-element"),
|
|
@@ -26709,6 +26710,17 @@ var BrowserToFileIOMessageSchema = external_exports.discriminatedUnion("type", [
|
|
|
26709
26710
|
external_exports.object({
|
|
26710
26711
|
type: external_exports.literal("git_ls_files"),
|
|
26711
26712
|
requestId: external_exports.string()
|
|
26713
|
+
}),
|
|
26714
|
+
external_exports.object({
|
|
26715
|
+
type: external_exports.literal("git_branch_diff_files"),
|
|
26716
|
+
requestId: external_exports.string(),
|
|
26717
|
+
baseRef: external_exports.string().optional()
|
|
26718
|
+
}),
|
|
26719
|
+
external_exports.object({
|
|
26720
|
+
type: external_exports.literal("git_branch_diff_file"),
|
|
26721
|
+
requestId: external_exports.string(),
|
|
26722
|
+
path: external_exports.string(),
|
|
26723
|
+
mergeBase: external_exports.string()
|
|
26712
26724
|
})
|
|
26713
26725
|
]);
|
|
26714
26726
|
var FileChangeSchema = external_exports.object({
|
|
@@ -26770,6 +26782,19 @@ var DaemonToFileIOMessageSchema = external_exports.discriminatedUnion("type", [
|
|
|
26770
26782
|
requestId: external_exports.string(),
|
|
26771
26783
|
files: external_exports.array(external_exports.string())
|
|
26772
26784
|
}),
|
|
26785
|
+
external_exports.object({
|
|
26786
|
+
type: external_exports.literal("git_branch_diff_files_result"),
|
|
26787
|
+
requestId: external_exports.string(),
|
|
26788
|
+
files: external_exports.array(CheckpointFileEntrySchema),
|
|
26789
|
+
mergeBase: external_exports.string(),
|
|
26790
|
+
baseRef: external_exports.string()
|
|
26791
|
+
}),
|
|
26792
|
+
external_exports.object({
|
|
26793
|
+
type: external_exports.literal("git_branch_diff_file_result"),
|
|
26794
|
+
requestId: external_exports.string(),
|
|
26795
|
+
originalContent: external_exports.string(),
|
|
26796
|
+
modifiedContent: external_exports.string()
|
|
26797
|
+
}),
|
|
26773
26798
|
external_exports.object({ type: external_exports.literal("error"), requestId: external_exports.string(), error: external_exports.string() }),
|
|
26774
26799
|
external_exports.object({
|
|
26775
26800
|
type: external_exports.literal("checkpoint_ready"),
|
|
@@ -28754,6 +28779,35 @@ async function rerunChecks(cwd, prNumber) {
|
|
|
28754
28779
|
}
|
|
28755
28780
|
}
|
|
28756
28781
|
|
|
28782
|
+
// src/shared/capabilities/git-diff.ts
|
|
28783
|
+
async function getDefaultBranch(cwd) {
|
|
28784
|
+
try {
|
|
28785
|
+
const ref = await runWithTimeout(
|
|
28786
|
+
"git",
|
|
28787
|
+
["symbolic-ref", "refs/remotes/origin/HEAD", "--short"],
|
|
28788
|
+
cwd,
|
|
28789
|
+
TIMEOUT_MS
|
|
28790
|
+
);
|
|
28791
|
+
return ref || null;
|
|
28792
|
+
} catch {
|
|
28793
|
+
}
|
|
28794
|
+
for (const candidate of ["origin/main", "origin/master"]) {
|
|
28795
|
+
try {
|
|
28796
|
+
await runWithTimeout("git", ["rev-parse", "--verify", candidate], cwd, TIMEOUT_MS);
|
|
28797
|
+
return candidate;
|
|
28798
|
+
} catch {
|
|
28799
|
+
}
|
|
28800
|
+
}
|
|
28801
|
+
return null;
|
|
28802
|
+
}
|
|
28803
|
+
async function getMergeBase(cwd, baseBranch) {
|
|
28804
|
+
try {
|
|
28805
|
+
return await runWithTimeout("git", ["merge-base", baseBranch, "HEAD"], cwd, TIMEOUT_MS);
|
|
28806
|
+
} catch {
|
|
28807
|
+
return null;
|
|
28808
|
+
}
|
|
28809
|
+
}
|
|
28810
|
+
|
|
28757
28811
|
// src/shared/capabilities/index.ts
|
|
28758
28812
|
var AutoModeConfigSchema = external_exports.object({
|
|
28759
28813
|
cachedGrowthBookFeatures: external_exports.object({ tengu_auto_mode_config: external_exports.object({ enabled: external_exports.string() }) }).passthrough()
|
|
@@ -29215,6 +29269,28 @@ function narrow(value) {
|
|
|
29215
29269
|
import { unlinkSync } from "fs";
|
|
29216
29270
|
import { readFile as readFile5, unlink as unlink2, writeFile as writeFile3 } from "fs/promises";
|
|
29217
29271
|
import { join as join8 } from "path";
|
|
29272
|
+
|
|
29273
|
+
// src/services/bootstrap/classify-uncaught-error.ts
|
|
29274
|
+
function classifyUncaughtError(error2) {
|
|
29275
|
+
if (!(error2 instanceof Error)) return "fatal";
|
|
29276
|
+
const code2 = "code" in error2 && typeof error2.code === "string" ? error2.code : void 0;
|
|
29277
|
+
const msg = error2.message;
|
|
29278
|
+
if (code2 === "EPIPE" || code2 === "ECONNRESET" || code2 === "ECONNABORTED" || code2 === "ECONNREFUSED" || code2 === "ERR_STREAM_DESTROYED") {
|
|
29279
|
+
return "recoverable";
|
|
29280
|
+
}
|
|
29281
|
+
if (msg.includes("can't add channel") && msg.includes("stopped")) {
|
|
29282
|
+
return "recoverable";
|
|
29283
|
+
}
|
|
29284
|
+
if (msg.includes("RTCDataChannel.readyState is not")) {
|
|
29285
|
+
return "recoverable";
|
|
29286
|
+
}
|
|
29287
|
+
if (msg.includes("ProcessTransport is not ready")) {
|
|
29288
|
+
return "recoverable";
|
|
29289
|
+
}
|
|
29290
|
+
return "fatal";
|
|
29291
|
+
}
|
|
29292
|
+
|
|
29293
|
+
// src/services/bootstrap/lifecycle.ts
|
|
29218
29294
|
function isProcessAlive(pid) {
|
|
29219
29295
|
try {
|
|
29220
29296
|
process.kill(pid, 0);
|
|
@@ -29244,7 +29320,12 @@ var LifecycleManager = class {
|
|
|
29244
29320
|
process.on("SIGTERM", termHandler);
|
|
29245
29321
|
process.on("SIGINT", intHandler);
|
|
29246
29322
|
const exceptionHandler = (error2) => {
|
|
29247
|
-
|
|
29323
|
+
const severity = classifyUncaughtError(error2);
|
|
29324
|
+
if (severity === "recoverable") {
|
|
29325
|
+
this.#log.warn({ err: error2 }, "Recoverable uncaught exception \u2014 absorbed");
|
|
29326
|
+
return;
|
|
29327
|
+
}
|
|
29328
|
+
this.#log.error({ err: error2 }, "Fatal uncaught exception \u2014 initiating shutdown");
|
|
29248
29329
|
void this.#shutdown("uncaughtException");
|
|
29249
29330
|
};
|
|
29250
29331
|
const rejectionHandler = (reason) => {
|
|
@@ -29588,7 +29669,7 @@ function nanoid(size2 = 21) {
|
|
|
29588
29669
|
}
|
|
29589
29670
|
|
|
29590
29671
|
// src/services/bootstrap/signaling.ts
|
|
29591
|
-
var DAEMON_NPM_VERSION = true ? "3.
|
|
29672
|
+
var DAEMON_NPM_VERSION = true ? "3.2.0" : "unknown";
|
|
29592
29673
|
function createDaemonSignaling(config2) {
|
|
29593
29674
|
const agentId = config2.agentId ?? nanoid();
|
|
29594
29675
|
function send(msg) {
|
|
@@ -29743,6 +29824,7 @@ function handleBrowserPreviewChannel(port, send, sendBinary, log, options) {
|
|
|
29743
29824
|
const requestTimeoutMs = options?.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
29744
29825
|
const activeRequests = /* @__PURE__ */ new Map();
|
|
29745
29826
|
const cookieJar = /* @__PURE__ */ new Map();
|
|
29827
|
+
const previewPrefix = `/__preview/url/${encodeURIComponent(`http://localhost:${port}`)}/`;
|
|
29746
29828
|
function respond(msg) {
|
|
29747
29829
|
send(JSON.stringify(msg));
|
|
29748
29830
|
}
|
|
@@ -29896,7 +29978,7 @@ function handleBrowserPreviewChannel(port, send, sendBinary, log, options) {
|
|
|
29896
29978
|
res.on("data", (chunk) => chunks.push(chunk));
|
|
29897
29979
|
res.on("end", () => {
|
|
29898
29980
|
const rawJs = Buffer.concat(chunks).toString("utf-8");
|
|
29899
|
-
const rewritten = rewriteJsImportPaths(rawJs);
|
|
29981
|
+
const rewritten = rewriteJsImportPaths(rawJs, previewPrefix);
|
|
29900
29982
|
const body = new TextEncoder().encode(rewritten);
|
|
29901
29983
|
headers["content-length"] = String(body.byteLength);
|
|
29902
29984
|
respond({
|
|
@@ -30019,8 +30101,9 @@ function injectBaseHref(html, origin) {
|
|
|
30019
30101
|
function rewriteRootRelativePaths(html) {
|
|
30020
30102
|
return html.replace(/((?:src|href|action)\s*=\s*["'])\/(?!\/)/gi, "$1./");
|
|
30021
30103
|
}
|
|
30022
|
-
function rewriteJsImportPaths(js) {
|
|
30023
|
-
|
|
30104
|
+
function rewriteJsImportPaths(js, previewPrefix) {
|
|
30105
|
+
const replacement = previewPrefix ?? "./";
|
|
30106
|
+
return js.replace(/((?:from|import)\s*\(\s*["'])\/(?!\/)/g, `$1${replacement}`).replace(/(from\s+["'])\/(?!\/)/g, `$1${replacement}`);
|
|
30024
30107
|
}
|
|
30025
30108
|
function handleBrowserPreviewUrlChannel(send, sendBinary, log, options) {
|
|
30026
30109
|
const requestTimeoutMs = options?.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
@@ -30113,7 +30196,10 @@ function handleBrowserPreviewUrlChannel(send, sendBinary, log, options) {
|
|
|
30113
30196
|
injectBaseHref(new TextDecoder().decode(rawBody), targetUrl.origin)
|
|
30114
30197
|
);
|
|
30115
30198
|
} else if (isJs) {
|
|
30116
|
-
|
|
30199
|
+
const urlPrefix = `/__preview/url/${encodeURIComponent(targetUrl.origin)}/`;
|
|
30200
|
+
body = new TextEncoder().encode(
|
|
30201
|
+
rewriteJsImportPaths(new TextDecoder().decode(rawBody), urlPrefix)
|
|
30202
|
+
);
|
|
30117
30203
|
} else {
|
|
30118
30204
|
body = rawBody;
|
|
30119
30205
|
}
|
|
@@ -32301,8 +32387,7 @@ async function sweepStaleTasks(taskStateStore, taskManager, log) {
|
|
|
32301
32387
|
const noBroadcast = { broadcast: false };
|
|
32302
32388
|
for (const action of actions) {
|
|
32303
32389
|
if (action.kind === "mark_input_required") {
|
|
32304
|
-
await taskStateStore.
|
|
32305
|
-
await taskStateStore.acknowledge(action.taskId, noBroadcast);
|
|
32390
|
+
await taskStateStore.sweepToInputRequired(action.taskId, noBroadcast);
|
|
32306
32391
|
log({
|
|
32307
32392
|
event: "stale_task_swept",
|
|
32308
32393
|
taskId: action.taskId,
|
|
@@ -43227,6 +43312,11 @@ Use \`add_comment\` to annotate your work and respond to reviewer feedback. Use
|
|
|
43227
43312
|
|
|
43228
43313
|
You can **create** comments on diff and plan surfaces only (\`mode: "diff"\` and \`mode: "plan"\`). You can **reply** to comments on all 5 surfaces. Preview and canvas comments are user-originated feedback on your running app or visualizations \u2014 respond by replying to acknowledge and acting on the feedback.
|
|
43229
43314
|
|
|
43315
|
+
**Diff scope** \u2014 \`diff\` surface comments may include a \`diff-scope\` attribute indicating which view the comment was made on:
|
|
43316
|
+
- \`working-tree\` \u2014 uncommitted changes (your latest edits, like \`git diff\`)
|
|
43317
|
+
- \`branch\` \u2014 full branch diff vs base branch (all commits + uncommitted, like \`git diff main...HEAD\`)
|
|
43318
|
+
- \`last-turn\` \u2014 changes from a specific agent turn
|
|
43319
|
+
|
|
43230
43320
|
**When publishing plans** \u2014 \`mode: "plan"\` for non-obvious design decisions, anchored to specific plan text.
|
|
43231
43321
|
|
|
43232
43322
|
**Periodically during long tasks** \u2014 \`list_comments\` to catch missed feedback, especially after context loss.
|
|
@@ -75126,8 +75216,10 @@ function deriveArtifact(annotation, taskId) {
|
|
|
75126
75216
|
}
|
|
75127
75217
|
function surfaceAttrs(annotation) {
|
|
75128
75218
|
switch (annotation.annotationType) {
|
|
75129
|
-
case "diff-hunk":
|
|
75130
|
-
|
|
75219
|
+
case "diff-hunk": {
|
|
75220
|
+
const scopeAttr = annotation.diffScope ? ` diff-scope="${escapeXmlAttr(annotation.diffScope)}"` : "";
|
|
75221
|
+
return ` file="${escapeXmlAttr(annotation.filePath)}" line="${annotation.lineNumber}"${scopeAttr}`;
|
|
75222
|
+
}
|
|
75131
75223
|
case "plan-text":
|
|
75132
75224
|
return annotation.anchorText ? ` anchor="${escapeXmlAttr(annotation.anchorText)}"` : "";
|
|
75133
75225
|
case "preview-element":
|
|
@@ -76776,8 +76868,6 @@ ${conversationReplay}` : conversationReplay;
|
|
|
76776
76868
|
});
|
|
76777
76869
|
this.#ownSessionId = null;
|
|
76778
76870
|
this.#effectiveSpawnMode = { kind: "fresh" };
|
|
76779
|
-
this.#config.sessionPersistence.clear(this.#config.channelId).catch(() => {
|
|
76780
|
-
});
|
|
76781
76871
|
}
|
|
76782
76872
|
if (this.#tryForkFailedRetry(error2)) return;
|
|
76783
76873
|
if (this.#tryStaleResumeRetry(error2)) return;
|
|
@@ -80354,7 +80444,7 @@ var StructuredTaskTracker = class {
|
|
|
80354
80444
|
* Attach a file watcher for CC task files. Called after init_received
|
|
80355
80445
|
* when we know the CC session ID, or immediately for resumed sessions.
|
|
80356
80446
|
*/
|
|
80357
|
-
attachFileWatcher(sessionId) {
|
|
80447
|
+
attachFileWatcher(sessionId, options) {
|
|
80358
80448
|
if (this.#ccTaskWatcherDispose) {
|
|
80359
80449
|
this.#deps.log({
|
|
80360
80450
|
event: "file_watcher_already_attached",
|
|
@@ -80365,17 +80455,17 @@ var StructuredTaskTracker = class {
|
|
|
80365
80455
|
}
|
|
80366
80456
|
const watcher = createCCTaskFileWatcher(sessionId, this.#deps.log);
|
|
80367
80457
|
this.#ccTaskFileWriter = createCCTaskFileWriter(watcher.dir, this.#deps.log);
|
|
80368
|
-
this.#initFileWatcher(watcher);
|
|
80458
|
+
this.#initFileWatcher(watcher, options);
|
|
80369
80459
|
if (this.#currentOverlay) {
|
|
80370
|
-
this.#flushStructuredTasks();
|
|
80460
|
+
this.#flushStructuredTasks(options);
|
|
80371
80461
|
}
|
|
80372
80462
|
}
|
|
80373
80463
|
/**
|
|
80374
80464
|
* Apply an overlay on top of CC tasks. Stores the overlay and re-flushes.
|
|
80375
80465
|
*/
|
|
80376
|
-
applyOverlay(overlay) {
|
|
80466
|
+
applyOverlay(overlay, options) {
|
|
80377
80467
|
this.#currentOverlay = overlay;
|
|
80378
|
-
this.#flushStructuredTasks();
|
|
80468
|
+
this.#flushStructuredTasks(options);
|
|
80379
80469
|
}
|
|
80380
80470
|
processStructuredTaskEvents(content) {
|
|
80381
80471
|
const events = extractStructuredTaskEvents(content);
|
|
@@ -80500,11 +80590,11 @@ var StructuredTaskTracker = class {
|
|
|
80500
80590
|
applyDepEdgeAdditions(merged, overlay.depEdges);
|
|
80501
80591
|
return merged;
|
|
80502
80592
|
}
|
|
80503
|
-
#flushStructuredTasks() {
|
|
80593
|
+
#flushStructuredTasks(options) {
|
|
80504
80594
|
const overlay = this.#currentOverlay ?? DEFAULT_TASK_OVERLAY;
|
|
80505
80595
|
const merged = this.#applyOverlayToMap(this.#structuredTasks, overlay);
|
|
80506
80596
|
const todoProgress = this.#computeTodoProgress(merged);
|
|
80507
|
-
this.#deps.updateStructuredTasks(Object.fromEntries(merged), todoProgress);
|
|
80597
|
+
this.#deps.updateStructuredTasks(Object.fromEntries(merged), todoProgress, options);
|
|
80508
80598
|
if (!this.#suppressWriteThrough) {
|
|
80509
80599
|
this.#ccTaskFileWriter?.writeMergedTasks(merged);
|
|
80510
80600
|
}
|
|
@@ -80525,9 +80615,12 @@ var StructuredTaskTracker = class {
|
|
|
80525
80615
|
currentActivity
|
|
80526
80616
|
};
|
|
80527
80617
|
}
|
|
80528
|
-
#initFileWatcher(watcher) {
|
|
80618
|
+
#initFileWatcher(watcher, initOptions) {
|
|
80619
|
+
let isFirstRead = !!initOptions?.preserveUpdatedAt;
|
|
80529
80620
|
this.#ccTaskWatcherDispose = watcher.watch((tasks) => {
|
|
80530
|
-
|
|
80621
|
+
const opts = isFirstRead ? initOptions : void 0;
|
|
80622
|
+
isFirstRead = false;
|
|
80623
|
+
this.#reconcileFromDisk(tasks, opts);
|
|
80531
80624
|
});
|
|
80532
80625
|
}
|
|
80533
80626
|
/**
|
|
@@ -80537,7 +80630,7 @@ var StructuredTaskTracker = class {
|
|
|
80537
80630
|
* - Remove tasks that were previously from disk but are now gone
|
|
80538
80631
|
* - Re-flush with overlay applied
|
|
80539
80632
|
*/
|
|
80540
|
-
#reconcileFromDisk(ccTasks) {
|
|
80633
|
+
#reconcileFromDisk(ccTasks, options) {
|
|
80541
80634
|
const currentDiskIds = /* @__PURE__ */ new Set();
|
|
80542
80635
|
for (const file of ccTasks) {
|
|
80543
80636
|
currentDiskIds.add(file.id);
|
|
@@ -80558,7 +80651,7 @@ var StructuredTaskTracker = class {
|
|
|
80558
80651
|
}
|
|
80559
80652
|
this.#suppressWriteThrough = true;
|
|
80560
80653
|
try {
|
|
80561
|
-
this.#flushStructuredTasks();
|
|
80654
|
+
this.#flushStructuredTasks(options);
|
|
80562
80655
|
} finally {
|
|
80563
80656
|
this.#suppressWriteThrough = false;
|
|
80564
80657
|
}
|
|
@@ -81296,7 +81389,9 @@ var Task = class _Task {
|
|
|
81296
81389
|
log: deps.log
|
|
81297
81390
|
});
|
|
81298
81391
|
if (deps.existingSessionId) {
|
|
81299
|
-
this.#structuredTaskTracker.attachFileWatcher(deps.existingSessionId
|
|
81392
|
+
this.#structuredTaskTracker.attachFileWatcher(deps.existingSessionId, {
|
|
81393
|
+
preserveUpdatedAt: true
|
|
81394
|
+
});
|
|
81300
81395
|
}
|
|
81301
81396
|
this.#subagentManager = new SubagentManager({
|
|
81302
81397
|
taskId: deps.taskId,
|
|
@@ -82524,8 +82619,8 @@ Use this context to maintain continuity. You have already done this work \u2014
|
|
|
82524
82619
|
}
|
|
82525
82620
|
}
|
|
82526
82621
|
}
|
|
82527
|
-
applyOverlay(overlay) {
|
|
82528
|
-
this.#structuredTaskTracker.applyOverlay(overlay);
|
|
82622
|
+
applyOverlay(overlay, options) {
|
|
82623
|
+
this.#structuredTaskTracker.applyOverlay(overlay, options);
|
|
82529
82624
|
}
|
|
82530
82625
|
/** ---------------------------------------------------------------- */
|
|
82531
82626
|
/** Resource resolution */
|
|
@@ -83202,7 +83297,8 @@ var TaskManager = class {
|
|
|
83202
83297
|
this.#tasks.set(taskId, { taskId, channelId, cwd, mode, orchestrator });
|
|
83203
83298
|
this.#flushPendingStreamSubs(taskId, orchestrator);
|
|
83204
83299
|
this.#deps.taskStateStore.getTask(taskId).then((record) => {
|
|
83205
|
-
if (record?.taskOverlay)
|
|
83300
|
+
if (record?.taskOverlay)
|
|
83301
|
+
orchestrator.applyOverlay(record.taskOverlay, { preserveUpdatedAt: true });
|
|
83206
83302
|
}).catch((err) => {
|
|
83207
83303
|
this.#deps.log({
|
|
83208
83304
|
event: "overlay_restore_failed",
|
|
@@ -83244,10 +83340,27 @@ var TaskManager = class {
|
|
|
83244
83340
|
getTaskMode(taskId) {
|
|
83245
83341
|
return this.#tasks.get(taskId)?.mode ?? "task";
|
|
83246
83342
|
}
|
|
83247
|
-
handleUserMessage(taskId, content, settings, cwd, participantId, senderDisplayName) {
|
|
83248
|
-
|
|
83343
|
+
async handleUserMessage(taskId, content, settings, cwd, participantId, senderDisplayName) {
|
|
83344
|
+
let task = this.#tasks.get(taskId);
|
|
83249
83345
|
if (!task) {
|
|
83250
|
-
|
|
83346
|
+
const record = await this.#deps.taskStateStore.getTask(taskId);
|
|
83347
|
+
if (!record) {
|
|
83348
|
+
throw new Error(`No orchestrator for task ${taskId}`);
|
|
83349
|
+
}
|
|
83350
|
+
this.restoreOrchestrator(taskId, record.channelId, {
|
|
83351
|
+
initialState: "cold_idle",
|
|
83352
|
+
cwd: record.cwd,
|
|
83353
|
+
mode: record.mode,
|
|
83354
|
+
costBaseline: {
|
|
83355
|
+
totalCostUsd: record.totalCostUsd,
|
|
83356
|
+
totalOutputTokens: record.totalOutputTokens
|
|
83357
|
+
}
|
|
83358
|
+
});
|
|
83359
|
+
task = this.#tasks.get(taskId);
|
|
83360
|
+
if (!task) {
|
|
83361
|
+
throw new Error(`Failed to restore orchestrator for task ${taskId}`);
|
|
83362
|
+
}
|
|
83363
|
+
this.#deps.log({ event: "task_lazy_restored", taskId, channelId: record.channelId });
|
|
83251
83364
|
}
|
|
83252
83365
|
if (cwd && cwd !== task.cwd) {
|
|
83253
83366
|
task.cwd = cwd;
|
|
@@ -83567,8 +83680,13 @@ var TaskManager = class {
|
|
|
83567
83680
|
});
|
|
83568
83681
|
});
|
|
83569
83682
|
},
|
|
83570
|
-
updateStructuredTasks: (tasks, todoProgress) => {
|
|
83571
|
-
this.#deps.taskStateStore.updateStructuredTasks(
|
|
83683
|
+
updateStructuredTasks: (tasks, todoProgress, options) => {
|
|
83684
|
+
this.#deps.taskStateStore.updateStructuredTasks(
|
|
83685
|
+
taskId,
|
|
83686
|
+
tasks,
|
|
83687
|
+
todoProgress,
|
|
83688
|
+
options ? { preserveUpdatedAt: options.preserveUpdatedAt } : void 0
|
|
83689
|
+
).catch((err) => {
|
|
83572
83690
|
this.#deps.log({
|
|
83573
83691
|
event: "task_state_store_structured_tasks_failed",
|
|
83574
83692
|
taskId,
|
|
@@ -83715,52 +83833,29 @@ function buildTaskStateStore(dataDir) {
|
|
|
83715
83833
|
});
|
|
83716
83834
|
},
|
|
83717
83835
|
async updateTaskStatus(taskId, status, options) {
|
|
83718
|
-
|
|
83719
|
-
if (!task) return;
|
|
83720
|
-
pushBroadcast(options);
|
|
83721
|
-
await store.set(taskId, applyStatusTransition(task, status, Date.now()));
|
|
83836
|
+
await safeUpdate(taskId, (task) => applyStatusTransition(task, status, Date.now()), options);
|
|
83722
83837
|
},
|
|
83723
83838
|
async updateTitle(taskId, title, options) {
|
|
83724
|
-
|
|
83725
|
-
if (!task) return;
|
|
83726
|
-
pushBroadcast(options);
|
|
83727
|
-
await store.set(taskId, {
|
|
83728
|
-
...task,
|
|
83729
|
-
title,
|
|
83730
|
-
updatedAt: Date.now()
|
|
83731
|
-
});
|
|
83839
|
+
await safeUpdate(taskId, (task) => ({ ...task, title, updatedAt: Date.now() }), options);
|
|
83732
83840
|
},
|
|
83733
83841
|
async updateCwd(taskId, cwd, options) {
|
|
83734
|
-
|
|
83735
|
-
if (!task) return;
|
|
83736
|
-
pushBroadcast(options);
|
|
83737
|
-
await store.set(taskId, {
|
|
83738
|
-
...task,
|
|
83739
|
-
cwd,
|
|
83740
|
-
updatedAt: Date.now()
|
|
83741
|
-
});
|
|
83842
|
+
await safeUpdate(taskId, (task) => ({ ...task, cwd, updatedAt: Date.now() }), options);
|
|
83742
83843
|
},
|
|
83743
83844
|
async updateMode(taskId, mode, options) {
|
|
83744
|
-
|
|
83745
|
-
if (!task) return;
|
|
83746
|
-
pushBroadcast(options);
|
|
83747
|
-
await store.set(taskId, {
|
|
83748
|
-
...task,
|
|
83749
|
-
mode,
|
|
83750
|
-
updatedAt: Date.now()
|
|
83751
|
-
});
|
|
83845
|
+
await safeUpdate(taskId, (task) => ({ ...task, mode, updatedAt: Date.now() }), options);
|
|
83752
83846
|
},
|
|
83753
83847
|
async updateTodoProgress(taskId, progress, options) {
|
|
83754
|
-
|
|
83755
|
-
|
|
83756
|
-
|
|
83757
|
-
|
|
83758
|
-
|
|
83759
|
-
|
|
83760
|
-
|
|
83761
|
-
|
|
83762
|
-
|
|
83763
|
-
|
|
83848
|
+
await safeUpdate(
|
|
83849
|
+
taskId,
|
|
83850
|
+
(task) => ({
|
|
83851
|
+
...task,
|
|
83852
|
+
todoCompleted: progress.todoCompleted,
|
|
83853
|
+
todoTotal: progress.todoTotal,
|
|
83854
|
+
currentActivity: progress.currentActivity,
|
|
83855
|
+
updatedAt: Date.now()
|
|
83856
|
+
}),
|
|
83857
|
+
options
|
|
83858
|
+
);
|
|
83764
83859
|
},
|
|
83765
83860
|
async acknowledge(taskId, options) {
|
|
83766
83861
|
await safeUpdate(taskId, (task) => ({ ...task, acknowledgedAt: Date.now() }), options);
|
|
@@ -83769,39 +83864,42 @@ function buildTaskStateStore(dataDir) {
|
|
|
83769
83864
|
await safeUpdate(taskId, (task) => ({ ...task, pinned: !task.pinned }), options);
|
|
83770
83865
|
},
|
|
83771
83866
|
async updateStructuredTasks(taskId, tasks, todoProgress, options) {
|
|
83772
|
-
|
|
83773
|
-
|
|
83774
|
-
|
|
83775
|
-
|
|
83776
|
-
|
|
83777
|
-
|
|
83778
|
-
|
|
83779
|
-
|
|
83780
|
-
|
|
83781
|
-
|
|
83782
|
-
|
|
83783
|
-
|
|
83784
|
-
|
|
83867
|
+
await safeUpdate(
|
|
83868
|
+
taskId,
|
|
83869
|
+
(task) => ({
|
|
83870
|
+
...task,
|
|
83871
|
+
structuredTasks: tasks,
|
|
83872
|
+
...todoProgress && {
|
|
83873
|
+
todoCompleted: todoProgress.todoCompleted,
|
|
83874
|
+
todoTotal: todoProgress.todoTotal,
|
|
83875
|
+
currentActivity: todoProgress.currentActivity
|
|
83876
|
+
},
|
|
83877
|
+
updatedAt: options?.preserveUpdatedAt ? task.updatedAt : Date.now()
|
|
83878
|
+
}),
|
|
83879
|
+
options
|
|
83880
|
+
);
|
|
83785
83881
|
},
|
|
83786
83882
|
async updateTaskOverlay(taskId, overlay, options) {
|
|
83787
|
-
|
|
83788
|
-
|
|
83789
|
-
|
|
83790
|
-
|
|
83791
|
-
|
|
83792
|
-
|
|
83793
|
-
|
|
83794
|
-
|
|
83883
|
+
await safeUpdate(
|
|
83884
|
+
taskId,
|
|
83885
|
+
(task) => ({
|
|
83886
|
+
...task,
|
|
83887
|
+
taskOverlay: overlay,
|
|
83888
|
+
updatedAt: options?.preserveUpdatedAt ? task.updatedAt : Date.now()
|
|
83889
|
+
}),
|
|
83890
|
+
options
|
|
83891
|
+
);
|
|
83795
83892
|
},
|
|
83796
83893
|
async updateComposerSettings(taskId, settings, options) {
|
|
83797
|
-
|
|
83798
|
-
|
|
83799
|
-
|
|
83800
|
-
|
|
83801
|
-
|
|
83802
|
-
|
|
83803
|
-
|
|
83804
|
-
|
|
83894
|
+
await safeUpdate(
|
|
83895
|
+
taskId,
|
|
83896
|
+
(task) => ({
|
|
83897
|
+
...task,
|
|
83898
|
+
composerSettings: { ...task.composerSettings, ...settings },
|
|
83899
|
+
updatedAt: Date.now()
|
|
83900
|
+
}),
|
|
83901
|
+
options
|
|
83902
|
+
);
|
|
83805
83903
|
},
|
|
83806
83904
|
async updateCostStats(taskId, stats, options) {
|
|
83807
83905
|
await safeUpdate(
|
|
@@ -83827,12 +83925,27 @@ function buildTaskStateStore(dataDir) {
|
|
|
83827
83925
|
options
|
|
83828
83926
|
);
|
|
83829
83927
|
},
|
|
83928
|
+
async sweepToInputRequired(taskId, options) {
|
|
83929
|
+
await safeUpdate(
|
|
83930
|
+
taskId,
|
|
83931
|
+
(task) => ({
|
|
83932
|
+
...task,
|
|
83933
|
+
status: "input_required",
|
|
83934
|
+
taskStartedAt: null
|
|
83935
|
+
}),
|
|
83936
|
+
options
|
|
83937
|
+
);
|
|
83938
|
+
},
|
|
83830
83939
|
async getTask(taskId) {
|
|
83831
83940
|
return store.get(taskId);
|
|
83832
83941
|
},
|
|
83833
83942
|
async listTasks() {
|
|
83834
83943
|
return store.list();
|
|
83835
83944
|
},
|
|
83945
|
+
async listTasksWithVersion() {
|
|
83946
|
+
const tasks = await store.list();
|
|
83947
|
+
return { tasks, version: _version };
|
|
83948
|
+
},
|
|
83836
83949
|
subscribe(listener) {
|
|
83837
83950
|
taskListeners.add(listener);
|
|
83838
83951
|
return () => {
|
|
@@ -84145,13 +84258,15 @@ ${additionalSystemPrompt}` : basePrompt;
|
|
|
84145
84258
|
async function detectInitialCapabilities(tokenStore, settings) {
|
|
84146
84259
|
return detectCapabilities(tokenStore, settings.preferredAnthropicAuth ?? void 0);
|
|
84147
84260
|
}
|
|
84148
|
-
function applyProxyFiltering(merged, proxyRef,
|
|
84149
|
-
|
|
84261
|
+
function applyProxyFiltering(merged, proxyRef, disabledNames) {
|
|
84262
|
+
const proxy = proxyRef.current;
|
|
84263
|
+
if (!proxy) return;
|
|
84264
|
+
for (const name of proxy.getAllManagedNames()) {
|
|
84150
84265
|
if (name in merged) {
|
|
84151
84266
|
delete merged[name];
|
|
84152
84267
|
}
|
|
84153
84268
|
}
|
|
84154
|
-
const freshConfigs =
|
|
84269
|
+
const freshConfigs = proxy.getServerConfigs();
|
|
84155
84270
|
for (const [name, config2] of freshConfigs) {
|
|
84156
84271
|
if (!disabledNames.has(name)) {
|
|
84157
84272
|
merged[name] = config2;
|
|
@@ -84180,7 +84295,7 @@ function collectProxyEndpoints(capabilitiesRef, claudeAiToken) {
|
|
|
84180
84295
|
}
|
|
84181
84296
|
return endpoints;
|
|
84182
84297
|
}
|
|
84183
|
-
async function initializeProxyServer(deps, capabilitiesRef,
|
|
84298
|
+
async function initializeProxyServer(deps, capabilitiesRef, onReauthComplete) {
|
|
84184
84299
|
const claudeAiToken = await readAnthropicOAuthToken();
|
|
84185
84300
|
const proxyEndpoints = collectProxyEndpoints(capabilitiesRef, claudeAiToken ?? void 0);
|
|
84186
84301
|
if (proxyEndpoints.size === 0) return { proxyServer: null };
|
|
@@ -84192,11 +84307,14 @@ async function initializeProxyServer(deps, capabilitiesRef, proxyManagedNames, o
|
|
|
84192
84307
|
});
|
|
84193
84308
|
try {
|
|
84194
84309
|
await proxy.initialize(proxyEndpoints);
|
|
84195
|
-
|
|
84310
|
+
const connectedNames = proxy.getServerNames();
|
|
84311
|
+
const allNames = [...proxyEndpoints.keys()];
|
|
84196
84312
|
deps.log({
|
|
84197
84313
|
event: "mcp_proxy_initialized",
|
|
84198
84314
|
serverCount: proxyEndpoints.size,
|
|
84199
|
-
|
|
84315
|
+
connectedCount: connectedNames.length,
|
|
84316
|
+
connectedNames,
|
|
84317
|
+
failedNames: allNames.filter((n) => !connectedNames.includes(n))
|
|
84200
84318
|
});
|
|
84201
84319
|
return { proxyServer: proxy };
|
|
84202
84320
|
} catch (err) {
|
|
@@ -84409,7 +84527,6 @@ async function createDaemon(deps) {
|
|
|
84409
84527
|
initialContent
|
|
84410
84528
|
);
|
|
84411
84529
|
}
|
|
84412
|
-
const proxyManagedNames = /* @__PURE__ */ new Set();
|
|
84413
84530
|
const resolveMcpServers = () => {
|
|
84414
84531
|
if (isVanillaAgentMode()) return void 0;
|
|
84415
84532
|
const userServers = resolveUserMcpServers(capabilitiesRef.current, deps.tokenStore);
|
|
@@ -84417,9 +84534,11 @@ async function createDaemon(deps) {
|
|
|
84417
84534
|
capabilitiesRef.current?.mcpServers?.filter((s2) => !s2.enabled).map((s2) => s2.name) ?? []
|
|
84418
84535
|
);
|
|
84419
84536
|
const pluginServers = resolvePluginMcpServersMap(deps.tokenStore, deps.log, disabledNames);
|
|
84420
|
-
|
|
84537
|
+
const proxyManagedNames = proxyRef.current?.getAllManagedNames() ?? [];
|
|
84538
|
+
if (!userServers && pluginServers.size === 0 && proxyManagedNames.length === 0)
|
|
84539
|
+
return void 0;
|
|
84421
84540
|
const merged = mergePluginAndUserServers(pluginServers, userServers, deps.log);
|
|
84422
|
-
applyProxyFiltering(merged, proxyRef,
|
|
84541
|
+
applyProxyFiltering(merged, proxyRef, disabledNames);
|
|
84423
84542
|
deps.log({
|
|
84424
84543
|
event: "resolve_mcp_servers",
|
|
84425
84544
|
capabilityServerCount: capabilitiesRef.current?.mcpServers?.length ?? 0,
|
|
@@ -84427,7 +84546,7 @@ async function createDaemon(deps) {
|
|
|
84427
84546
|
userServerCount: userServers ? Object.keys(userServers).length : 0,
|
|
84428
84547
|
userServerNames: userServers ? Object.keys(userServers) : [],
|
|
84429
84548
|
pluginServerCount: pluginServers.size,
|
|
84430
|
-
proxyManaged:
|
|
84549
|
+
proxyManaged: proxyManagedNames,
|
|
84431
84550
|
mergedCount: Object.keys(merged).length,
|
|
84432
84551
|
mergedNames: Object.keys(merged)
|
|
84433
84552
|
});
|
|
@@ -84493,7 +84612,13 @@ async function createDaemon(deps) {
|
|
|
84493
84612
|
taskManager.createTask(params);
|
|
84494
84613
|
},
|
|
84495
84614
|
sendMessage: (taskId, content, settings, cwd) => {
|
|
84496
|
-
taskManager.handleUserMessage(taskId, content, settings, cwd)
|
|
84615
|
+
taskManager.handleUserMessage(taskId, content, settings, cwd).catch((err) => {
|
|
84616
|
+
deps.log({
|
|
84617
|
+
event: "schedule_send_message_error",
|
|
84618
|
+
taskId,
|
|
84619
|
+
error: err instanceof Error ? err.message : String(err)
|
|
84620
|
+
});
|
|
84621
|
+
});
|
|
84497
84622
|
},
|
|
84498
84623
|
getRunningScheduleIds: async () => {
|
|
84499
84624
|
const running = /* @__PURE__ */ new Set();
|
|
@@ -84652,7 +84777,6 @@ async function createDaemon(deps) {
|
|
|
84652
84777
|
const { proxyServer } = await initializeProxyServer(
|
|
84653
84778
|
deps,
|
|
84654
84779
|
capabilitiesRef,
|
|
84655
|
-
proxyManagedNames,
|
|
84656
84780
|
() => oauthStateStore.invalidate()
|
|
84657
84781
|
);
|
|
84658
84782
|
proxyRef.current = proxyServer;
|
|
@@ -87109,7 +87233,10 @@ function wireControlChannel(rawChannel, daemon, logAdapter, deps) {
|
|
|
87109
87233
|
if (resolved) {
|
|
87110
87234
|
const without = { ...resolved };
|
|
87111
87235
|
delete without[serverName];
|
|
87112
|
-
daemon.preWarmManager.updateMcpServers(without).then(() => daemon.preWarmManager.updateMcpServers(resolved)).then(() =>
|
|
87236
|
+
daemon.preWarmManager.updateMcpServers(without).then(() => daemon.preWarmManager.updateMcpServers(resolved)).then(() => {
|
|
87237
|
+
daemon.taskManager.reconnectMcpServer(serverName);
|
|
87238
|
+
daemon.taskManager.triggerFastMcpPolling();
|
|
87239
|
+
}).catch((err) => {
|
|
87113
87240
|
logAdapter({
|
|
87114
87241
|
event: `${eventName}_reconnect_failed`,
|
|
87115
87242
|
serverName,
|
|
@@ -87328,12 +87455,11 @@ function wireControlChannel(rawChannel, daemon, logAdapter, deps) {
|
|
|
87328
87455
|
});
|
|
87329
87456
|
},
|
|
87330
87457
|
onRequestTaskIndex: () => {
|
|
87331
|
-
|
|
87332
|
-
daemon.taskStateStore.listTasks().then((tasks) => {
|
|
87458
|
+
daemon.taskStateStore.listTasksWithVersion().then(({ tasks, version }) => {
|
|
87333
87459
|
controlHandler.sendControl({
|
|
87334
87460
|
type: "task_index_snapshot",
|
|
87335
87461
|
tasks,
|
|
87336
|
-
version
|
|
87462
|
+
version
|
|
87337
87463
|
});
|
|
87338
87464
|
}).catch((err) => {
|
|
87339
87465
|
logAdapter({
|
|
@@ -87547,19 +87673,6 @@ function wireControlChannel(rawChannel, daemon, logAdapter, deps) {
|
|
|
87547
87673
|
}
|
|
87548
87674
|
};
|
|
87549
87675
|
pushMcpStatus(5);
|
|
87550
|
-
const initialSnapshotVersion = daemon.taskStateStore.version;
|
|
87551
|
-
daemon.taskStateStore.listTasks().then((tasks) => {
|
|
87552
|
-
controlHandler.sendControl({
|
|
87553
|
-
type: "task_index_snapshot",
|
|
87554
|
-
tasks,
|
|
87555
|
-
version: initialSnapshotVersion
|
|
87556
|
-
});
|
|
87557
|
-
}).catch((err) => {
|
|
87558
|
-
logAdapter({
|
|
87559
|
-
event: "task_index_initial_push_failed",
|
|
87560
|
-
error: err instanceof Error ? err.message : String(err)
|
|
87561
|
-
});
|
|
87562
|
-
});
|
|
87563
87676
|
daemon.userSettingsStore.getSettings().then((settings) => {
|
|
87564
87677
|
controlHandler.sendControl({ type: "user_settings_snapshot", settings });
|
|
87565
87678
|
}).catch((err) => {
|
|
@@ -87661,7 +87774,7 @@ function handleMessageChannel(opts) {
|
|
|
87661
87774
|
}
|
|
87662
87775
|
return result.data;
|
|
87663
87776
|
}
|
|
87664
|
-
function handleSendMessage2(msg) {
|
|
87777
|
+
async function handleSendMessage2(msg) {
|
|
87665
87778
|
try {
|
|
87666
87779
|
const settings = {
|
|
87667
87780
|
model: msg.model,
|
|
@@ -87672,7 +87785,7 @@ function handleMessageChannel(opts) {
|
|
|
87672
87785
|
if (opts.onUserMessage) {
|
|
87673
87786
|
opts.onUserMessage(msg.content, settings, msg.cwd, participantId, senderDisplayName);
|
|
87674
87787
|
} else {
|
|
87675
|
-
taskManager.handleUserMessage(
|
|
87788
|
+
await taskManager.handleUserMessage(
|
|
87676
87789
|
taskId,
|
|
87677
87790
|
msg.content,
|
|
87678
87791
|
settings,
|
|
@@ -87755,7 +87868,7 @@ function handleMessageChannel(opts) {
|
|
|
87755
87868
|
}
|
|
87756
87869
|
switch (msg.type) {
|
|
87757
87870
|
case "send_message":
|
|
87758
|
-
handleSendMessage2(msg);
|
|
87871
|
+
void handleSendMessage2(msg);
|
|
87759
87872
|
break;
|
|
87760
87873
|
case "stop":
|
|
87761
87874
|
if (opts.onStop) opts.onStop();
|
|
@@ -88445,6 +88558,12 @@ function handleFileIOChannel(initialCwd, send, log, deps) {
|
|
|
88445
88558
|
case "git_ls_files":
|
|
88446
88559
|
handleGitLsFiles(msg.requestId);
|
|
88447
88560
|
break;
|
|
88561
|
+
case "git_branch_diff_files":
|
|
88562
|
+
handleGitBranchDiffFiles(msg.requestId, msg.baseRef);
|
|
88563
|
+
break;
|
|
88564
|
+
case "git_branch_diff_file":
|
|
88565
|
+
handleGitBranchDiffFile(msg.requestId, msg.path, msg.mergeBase);
|
|
88566
|
+
break;
|
|
88448
88567
|
default:
|
|
88449
88568
|
assertNever(msg);
|
|
88450
88569
|
}
|
|
@@ -88546,6 +88665,79 @@ function handleFileIOChannel(initialCwd, send, log, deps) {
|
|
|
88546
88665
|
respondError(requestId, formatError(err));
|
|
88547
88666
|
}
|
|
88548
88667
|
}
|
|
88668
|
+
async function handleGitBranchDiffFiles(requestId, baseRefOverride) {
|
|
88669
|
+
try {
|
|
88670
|
+
const baseRef = baseRefOverride ?? await getDefaultBranch(cwd);
|
|
88671
|
+
if (!baseRef) {
|
|
88672
|
+
respond({
|
|
88673
|
+
type: "git_branch_diff_files_result",
|
|
88674
|
+
requestId,
|
|
88675
|
+
files: [],
|
|
88676
|
+
mergeBase: "",
|
|
88677
|
+
baseRef: ""
|
|
88678
|
+
});
|
|
88679
|
+
return;
|
|
88680
|
+
}
|
|
88681
|
+
const mergeBase = await getMergeBase(cwd, baseRef);
|
|
88682
|
+
if (!mergeBase) {
|
|
88683
|
+
respond({
|
|
88684
|
+
type: "git_branch_diff_files_result",
|
|
88685
|
+
requestId,
|
|
88686
|
+
files: [],
|
|
88687
|
+
mergeBase: "",
|
|
88688
|
+
baseRef
|
|
88689
|
+
});
|
|
88690
|
+
return;
|
|
88691
|
+
}
|
|
88692
|
+
const { stdout } = await execFileAsync3(
|
|
88693
|
+
"git",
|
|
88694
|
+
["diff", "--name-status", `${mergeBase}..HEAD`],
|
|
88695
|
+
{ cwd, maxBuffer: 10 * 1024 * 1024 }
|
|
88696
|
+
);
|
|
88697
|
+
const files = stdout.split("\n").filter(Boolean).map((line) => {
|
|
88698
|
+
const parts = line.split(" ");
|
|
88699
|
+
const statusCode = parts[0] ?? "";
|
|
88700
|
+
const filePath = parts[1] ?? "";
|
|
88701
|
+
let status;
|
|
88702
|
+
if (statusCode === "A") {
|
|
88703
|
+
status = "added";
|
|
88704
|
+
} else if (statusCode === "D") {
|
|
88705
|
+
status = "deleted";
|
|
88706
|
+
} else {
|
|
88707
|
+
status = "modified";
|
|
88708
|
+
}
|
|
88709
|
+
return { path: filePath, status, insertions: 0, deletions: 0 };
|
|
88710
|
+
});
|
|
88711
|
+
respond({
|
|
88712
|
+
type: "git_branch_diff_files_result",
|
|
88713
|
+
requestId,
|
|
88714
|
+
files,
|
|
88715
|
+
mergeBase,
|
|
88716
|
+
baseRef
|
|
88717
|
+
});
|
|
88718
|
+
} catch (err) {
|
|
88719
|
+
respondError(requestId, formatError(err));
|
|
88720
|
+
}
|
|
88721
|
+
}
|
|
88722
|
+
async function handleGitBranchDiffFile(requestId, filePath, mergeBase) {
|
|
88723
|
+
try {
|
|
88724
|
+
const originalContent = await readGitObject(`${mergeBase}:${filePath}`) ?? "";
|
|
88725
|
+
let modifiedContent;
|
|
88726
|
+
try {
|
|
88727
|
+
modifiedContent = await readFile25(resolve(cwd, filePath), "utf-8");
|
|
88728
|
+
} catch {
|
|
88729
|
+
modifiedContent = "";
|
|
88730
|
+
}
|
|
88731
|
+
respond({
|
|
88732
|
+
type: "git_branch_diff_file_result",
|
|
88733
|
+
requestId,
|
|
88734
|
+
originalContent,
|
|
88735
|
+
modifiedContent
|
|
88736
|
+
});
|
|
88737
|
+
} catch (err) {
|
|
88738
|
+
respondError(requestId, formatError(err));
|
|
88739
|
+
}
|
|
88740
|
+
}
|
|
88549
88741
|
async function handleGitDiffFile(requestId, safeRelPath, absPath, cached) {
|
|
88550
88742
|
try {
|
|
88551
88743
|
let originalContent = "";
|
|
@@ -89030,6 +89222,9 @@ function handleLSPChannel(cwd, send, log) {
|
|
|
89030
89222
|
exited = true;
|
|
89031
89223
|
child = null;
|
|
89032
89224
|
});
|
|
89225
|
+
proc.stdin?.on("error", (err) => {
|
|
89226
|
+
log({ event: "lsp_stdin_error", error: err.message });
|
|
89227
|
+
});
|
|
89033
89228
|
log({ event: "lsp_spawned", pid: proc.pid });
|
|
89034
89229
|
return proc;
|
|
89035
89230
|
}
|
|
@@ -89066,8 +89261,13 @@ function handleLSPChannel(cwd, send, log) {
|
|
|
89066
89261
|
const header = `Content-Length: ${Buffer.byteLength(data)}\r
|
|
89067
89262
|
\r
|
|
89068
89263
|
`;
|
|
89069
|
-
|
|
89070
|
-
|
|
89264
|
+
try {
|
|
89265
|
+
child.stdin?.write(header);
|
|
89266
|
+
child.stdin?.write(data);
|
|
89267
|
+
} catch {
|
|
89268
|
+
log({ event: "lsp_write_failed", exited });
|
|
89269
|
+
child = null;
|
|
89270
|
+
}
|
|
89071
89271
|
}
|
|
89072
89272
|
function dispose() {
|
|
89073
89273
|
disposed = true;
|
|
@@ -89248,84 +89448,94 @@ function createPeerManager(config2) {
|
|
|
89248
89448
|
return factoryPromise;
|
|
89249
89449
|
}
|
|
89250
89450
|
function handleDataChannel(machineId, event) {
|
|
89251
|
-
|
|
89252
|
-
|
|
89253
|
-
|
|
89254
|
-
|
|
89255
|
-
|
|
89256
|
-
|
|
89257
|
-
|
|
89258
|
-
|
|
89259
|
-
|
|
89260
|
-
|
|
89261
|
-
|
|
89262
|
-
|
|
89263
|
-
|
|
89264
|
-
|
|
89265
|
-
|
|
89266
|
-
|
|
89267
|
-
|
|
89268
|
-
|
|
89269
|
-
|
|
89270
|
-
|
|
89271
|
-
|
|
89272
|
-
|
|
89273
|
-
|
|
89274
|
-
|
|
89275
|
-
|
|
89276
|
-
|
|
89277
|
-
|
|
89278
|
-
|
|
89279
|
-
|
|
89280
|
-
|
|
89281
|
-
|
|
89282
|
-
|
|
89283
|
-
|
|
89284
|
-
|
|
89285
|
-
|
|
89286
|
-
|
|
89287
|
-
|
|
89288
|
-
|
|
89289
|
-
|
|
89290
|
-
|
|
89291
|
-
|
|
89292
|
-
|
|
89293
|
-
|
|
89294
|
-
|
|
89295
|
-
|
|
89296
|
-
|
|
89297
|
-
|
|
89298
|
-
|
|
89299
|
-
|
|
89300
|
-
|
|
89301
|
-
|
|
89302
|
-
|
|
89303
|
-
|
|
89304
|
-
|
|
89305
|
-
|
|
89306
|
-
|
|
89307
|
-
|
|
89308
|
-
|
|
89309
|
-
|
|
89310
|
-
|
|
89311
|
-
|
|
89312
|
-
|
|
89313
|
-
|
|
89314
|
-
|
|
89315
|
-
|
|
89316
|
-
|
|
89317
|
-
|
|
89318
|
-
|
|
89319
|
-
|
|
89320
|
-
|
|
89321
|
-
|
|
89322
|
-
|
|
89323
|
-
|
|
89324
|
-
|
|
89325
|
-
|
|
89451
|
+
try {
|
|
89452
|
+
config2.onPeerDataChannel?.(machineId);
|
|
89453
|
+
const channel = event.channel;
|
|
89454
|
+
const label = channel.label ?? "";
|
|
89455
|
+
const route = routeDataChannel(label);
|
|
89456
|
+
switch (route.kind) {
|
|
89457
|
+
case "thread_messages": {
|
|
89458
|
+
config2.log.debug(
|
|
89459
|
+
{ machineId, taskId: route.taskId, threadId: route.threadId },
|
|
89460
|
+
"Thread messages data channel received"
|
|
89461
|
+
);
|
|
89462
|
+
config2.onThreadMessageChannel?.(machineId, event.channel, route.taskId, route.threadId);
|
|
89463
|
+
return;
|
|
89464
|
+
}
|
|
89465
|
+
case "task_messages": {
|
|
89466
|
+
config2.log.debug(
|
|
89467
|
+
{ machineId, taskId: route.taskId },
|
|
89468
|
+
"Task messages data channel received"
|
|
89469
|
+
);
|
|
89470
|
+
config2.onTaskMessageChannel?.(machineId, event.channel, route.taskId);
|
|
89471
|
+
return;
|
|
89472
|
+
}
|
|
89473
|
+
case "daemon_control": {
|
|
89474
|
+
config2.log.info({ machineId }, "Daemon control data channel received");
|
|
89475
|
+
config2.onControlChannel?.(machineId, event.channel);
|
|
89476
|
+
return;
|
|
89477
|
+
}
|
|
89478
|
+
case "loro_sync": {
|
|
89479
|
+
config2.log.info({ machineId }, "Loro sync data channel received");
|
|
89480
|
+
const rawChannel = event.channel;
|
|
89481
|
+
guardLoroChannelSend(rawChannel, config2.log);
|
|
89482
|
+
config2.webrtcAdapter.attachDataChannel(
|
|
89483
|
+
machineIdToPeerId(machineId),
|
|
89484
|
+
event.channel
|
|
89485
|
+
);
|
|
89486
|
+
return;
|
|
89487
|
+
}
|
|
89488
|
+
case "file_io": {
|
|
89489
|
+
config2.log.debug({ machineId, id: route.id }, "File I/O data channel received");
|
|
89490
|
+
config2.onFileIOChannel?.(machineId, event.channel, route.id);
|
|
89491
|
+
return;
|
|
89492
|
+
}
|
|
89493
|
+
case "lsp": {
|
|
89494
|
+
config2.log.debug({ machineId, id: route.id }, "LSP data channel received");
|
|
89495
|
+
config2.onLSPChannel?.(machineId, event.channel, route.id);
|
|
89496
|
+
return;
|
|
89497
|
+
}
|
|
89498
|
+
case "browser_preview": {
|
|
89499
|
+
config2.log.debug(
|
|
89500
|
+
{ machineId, port: route.port },
|
|
89501
|
+
"Browser preview data channel received"
|
|
89502
|
+
);
|
|
89503
|
+
config2.onBrowserPreviewChannel?.(machineId, event.channel, route.port);
|
|
89504
|
+
return;
|
|
89505
|
+
}
|
|
89506
|
+
case "browser_preview_url": {
|
|
89507
|
+
config2.log.debug({ machineId }, "Browser preview URL data channel received");
|
|
89508
|
+
config2.onBrowserPreviewUrlChannel?.(machineId, event.channel);
|
|
89509
|
+
return;
|
|
89510
|
+
}
|
|
89511
|
+
case "terminal": {
|
|
89512
|
+
config2.log.debug(
|
|
89513
|
+
{ machineId, taskId: route.taskId, terminalId: route.terminalId },
|
|
89514
|
+
"Terminal data channel received"
|
|
89515
|
+
);
|
|
89516
|
+
config2.onTerminalChannel?.(machineId, event.channel, route.taskId, route.terminalId);
|
|
89517
|
+
return;
|
|
89518
|
+
}
|
|
89519
|
+
case "asset_transfer": {
|
|
89520
|
+
config2.log.debug({ machineId }, "Asset transfer data channel received");
|
|
89521
|
+
config2.onAssetTransferChannel?.(machineId, event.channel);
|
|
89522
|
+
return;
|
|
89523
|
+
}
|
|
89524
|
+
case "unknown": {
|
|
89525
|
+
config2.log.warn(
|
|
89526
|
+
{ machineId, label: route.label },
|
|
89527
|
+
"Ignoring unrecognized data channel label"
|
|
89528
|
+
);
|
|
89529
|
+
return;
|
|
89530
|
+
}
|
|
89531
|
+
default:
|
|
89532
|
+
assertNever3(route);
|
|
89326
89533
|
}
|
|
89327
|
-
|
|
89328
|
-
|
|
89534
|
+
} catch (err) {
|
|
89535
|
+
config2.log.warn(
|
|
89536
|
+
{ machineId, err: err instanceof Error ? err.message : String(err) },
|
|
89537
|
+
"Data channel routing failed (peer connection likely closing)"
|
|
89538
|
+
);
|
|
89329
89539
|
}
|
|
89330
89540
|
}
|
|
89331
89541
|
function setupPeerHandlers(machineId, pc) {
|
|
@@ -89347,6 +89557,7 @@ function createPeerManager(config2) {
|
|
|
89347
89557
|
if (state === "failed" || state === "closed") {
|
|
89348
89558
|
config2.webrtcAdapter.detachDataChannel(machineIdToPeerId(machineId));
|
|
89349
89559
|
peers.delete(machineId);
|
|
89560
|
+
pc.onconnectionstatechange = null;
|
|
89350
89561
|
pc.close();
|
|
89351
89562
|
}
|
|
89352
89563
|
};
|
|
@@ -89402,7 +89613,20 @@ function createPeerManager(config2) {
|
|
|
89402
89613
|
if (!pc.createOffer) {
|
|
89403
89614
|
throw new Error("PeerConnection does not support createOffer");
|
|
89404
89615
|
}
|
|
89405
|
-
|
|
89616
|
+
let channel;
|
|
89617
|
+
try {
|
|
89618
|
+
channel = pc.createDataChannel(LORO_SYNC_LABEL, { ordered: true });
|
|
89619
|
+
} catch (err) {
|
|
89620
|
+
config2.log.warn(
|
|
89621
|
+
{ targetMachineId, err: String(err) },
|
|
89622
|
+
"createDataChannel failed (connection likely closing)"
|
|
89623
|
+
);
|
|
89624
|
+
pendingCreates.delete(targetMachineId);
|
|
89625
|
+
peers.delete(targetMachineId);
|
|
89626
|
+
pc.onconnectionstatechange = null;
|
|
89627
|
+
pc.close();
|
|
89628
|
+
throw err;
|
|
89629
|
+
}
|
|
89406
89630
|
const rawChannel = channel;
|
|
89407
89631
|
guardLoroChannelSend(rawChannel, config2.log);
|
|
89408
89632
|
rawChannel.onopen = () => {
|
|
@@ -89461,6 +89685,7 @@ function createPeerManager(config2) {
|
|
|
89461
89685
|
const pc = peers.get(targetId);
|
|
89462
89686
|
if (pc) {
|
|
89463
89687
|
config2.webrtcAdapter.detachDataChannel(machineIdToPeerId(targetId));
|
|
89688
|
+
pc.onconnectionstatechange = null;
|
|
89464
89689
|
pc.close();
|
|
89465
89690
|
peers.delete(targetId);
|
|
89466
89691
|
}
|
|
@@ -89468,6 +89693,7 @@ function createPeerManager(config2) {
|
|
|
89468
89693
|
destroy() {
|
|
89469
89694
|
for (const [machineId, pc] of peers) {
|
|
89470
89695
|
config2.webrtcAdapter.detachDataChannel(machineIdToPeerId(machineId));
|
|
89696
|
+
pc.onconnectionstatechange = null;
|
|
89471
89697
|
pc.close();
|
|
89472
89698
|
}
|
|
89473
89699
|
peers.clear();
|
|
@@ -91478,7 +91704,16 @@ function attachConversationHandler(daemon, dc, channelId, params, log, attempts)
|
|
|
91478
91704
|
const handlerOpts = {
|
|
91479
91705
|
taskId,
|
|
91480
91706
|
channelId,
|
|
91481
|
-
send: (data) =>
|
|
91707
|
+
send: (data) => {
|
|
91708
|
+
try {
|
|
91709
|
+
dc.send(data);
|
|
91710
|
+
} catch (err) {
|
|
91711
|
+
log({
|
|
91712
|
+
event: "message_channel_send_failed",
|
|
91713
|
+
error: err instanceof Error ? err.message : String(err)
|
|
91714
|
+
});
|
|
91715
|
+
}
|
|
91716
|
+
},
|
|
91482
91717
|
taskManager: daemon.taskManager,
|
|
91483
91718
|
store: daemon.store,
|
|
91484
91719
|
log,
|
|
@@ -91602,7 +91837,16 @@ function wireThreadErrorFallback(daemon, dc, taskId, threadId, channelId, log) {
|
|
|
91602
91837
|
const handler = handleMessageChannel({
|
|
91603
91838
|
taskId,
|
|
91604
91839
|
channelId,
|
|
91605
|
-
send: (data) =>
|
|
91840
|
+
send: (data) => {
|
|
91841
|
+
try {
|
|
91842
|
+
dc.send(data);
|
|
91843
|
+
} catch (err) {
|
|
91844
|
+
log({
|
|
91845
|
+
event: "message_channel_send_failed",
|
|
91846
|
+
error: err instanceof Error ? err.message : String(err)
|
|
91847
|
+
});
|
|
91848
|
+
}
|
|
91849
|
+
},
|
|
91606
91850
|
taskManager: daemon.taskManager,
|
|
91607
91851
|
store: daemon.store,
|
|
91608
91852
|
log,
|
|
@@ -91647,15 +91891,19 @@ function routeSignalingMessage(peerManager, signalingHandle, log) {
|
|
|
91647
91891
|
switch (msg.type) {
|
|
91648
91892
|
case "webrtc-offer":
|
|
91649
91893
|
if (msg.fromMachineId)
|
|
91650
|
-
peerManager?.handleOffer(msg.fromMachineId, toSDPDescription(msg.offer))
|
|
91894
|
+
peerManager?.handleOffer(msg.fromMachineId, toSDPDescription(msg.offer)).catch(
|
|
91895
|
+
(err) => log.error({ event: "webrtc_offer_failed", error: String(err) })
|
|
91896
|
+
);
|
|
91651
91897
|
break;
|
|
91652
91898
|
case "webrtc-answer":
|
|
91653
91899
|
if (msg.fromMachineId)
|
|
91654
|
-
peerManager?.handleAnswer(msg.fromMachineId, toSDPDescription(msg.answer))
|
|
91900
|
+
peerManager?.handleAnswer(msg.fromMachineId, toSDPDescription(msg.answer)).catch(
|
|
91901
|
+
(err) => log.error({ event: "webrtc_answer_failed", error: String(err) })
|
|
91902
|
+
);
|
|
91655
91903
|
break;
|
|
91656
91904
|
case "webrtc-ice":
|
|
91657
91905
|
if (msg.fromMachineId)
|
|
91658
|
-
peerManager?.handleIce(msg.fromMachineId, toICECandidate(msg.candidate));
|
|
91906
|
+
peerManager?.handleIce(msg.fromMachineId, toICECandidate(msg.candidate)).catch((err) => log.error({ event: "webrtc_ice_failed", error: String(err) }));
|
|
91659
91907
|
break;
|
|
91660
91908
|
case "ice-servers":
|
|
91661
91909
|
peerManager?.updateIceServers(msg.iceServers);
|
|
@@ -91696,4 +91944,4 @@ export {
|
|
|
91696
91944
|
classifyLogLevel,
|
|
91697
91945
|
serve
|
|
91698
91946
|
};
|
|
91699
|
-
//# sourceMappingURL=serve-
|
|
91947
|
+
//# sourceMappingURL=serve-ROGOK56J.js.map
|