lody 0.89.4 → 0.90.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.
|
@@ -63,7 +63,7 @@ const DEEPSEEK_HARNESS_AGENT_PRESETS = [
|
|
|
63
63
|
}
|
|
64
64
|
];
|
|
65
65
|
const ACP_EXTENSION_DSH_VERSION = "0.1.0";
|
|
66
|
-
const DEEPSEEK_HARNESS_VERSION = "0.1.1-rc.
|
|
66
|
+
const DEEPSEEK_HARNESS_VERSION = "0.1.1-rc.2";
|
|
67
67
|
const ACP_EXTENSION_DSH_PROFILE_REVISION = "v5";
|
|
68
68
|
const ACP_EXTENSION_DSH_SESSION_ROOT_ENV = "ACP_EXTENSION_DSH_SESSION_ROOT";
|
|
69
69
|
const ACP_EXTENSION_DSH_QUERY_PATH_ENV = "ACP_EXTENSION_DSH_QUERY_PATH";
|
|
@@ -32,7 +32,7 @@ import "perf_hooks";
|
|
|
32
32
|
import "net";
|
|
33
33
|
import "tls";
|
|
34
34
|
import "url";
|
|
35
|
-
import "./profile-
|
|
35
|
+
import "./profile-CPDWaQXE.js";
|
|
36
36
|
import "assert";
|
|
37
37
|
import "fs/promises";
|
|
38
38
|
import "better-sqlite3";
|
|
@@ -80,7 +80,7 @@ let __tla = Promise.all([
|
|
|
80
80
|
}
|
|
81
81
|
})()
|
|
82
82
|
]).then(async () => {
|
|
83
|
-
const reviewViewerVersion = "0.
|
|
83
|
+
const reviewViewerVersion = "0.90.0";
|
|
84
84
|
const reviewViewerSha256 = "dc9c7fc1dde49bb39c5fe86392d69219b469c0cab4fd492d8b562045e7f676e4";
|
|
85
85
|
const reviewViewerFileName = "standalone.html";
|
|
86
86
|
const DEFAULT_CDN_BASES = [
|
package/dist/deepseek-acp.js
CHANGED
|
@@ -2,7 +2,7 @@ import { randomUUID, createHash } from "node:crypto";
|
|
|
2
2
|
import { isAbsolute } from "node:path";
|
|
3
3
|
import { Readable, Writable } from "node:stream";
|
|
4
4
|
import { n as ndJsonStream, A as AgentSideConnection, R as RequestError, P as PROTOCOL_VERSION } from "./chunks/acp-DBqkNziA.js";
|
|
5
|
-
import { D as DEEPSEEK_HARNESS_PERMISSION_MODES, c as DEEPSEEK_HARNESS_REASONING_OPTIONS, e as ACP_EXTENSION_DSH_VERSION, a as DEEPSEEK_HARNESS_AGENT_PRESETS } from "./chunks/profile-
|
|
5
|
+
import { D as DEEPSEEK_HARNESS_PERMISSION_MODES, c as DEEPSEEK_HARNESS_REASONING_OPTIONS, e as ACP_EXTENSION_DSH_VERSION, a as DEEPSEEK_HARNESS_AGENT_PRESETS } from "./chunks/profile-CPDWaQXE.js";
|
|
6
6
|
import "./chunks/schemas-Du3qLZPS.js";
|
|
7
7
|
const name = "acp-extension-dsh";
|
|
8
8
|
const inject = [
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import * as os$1 from "node:os";
|
|
|
14
14
|
import os__default, { userInfo, homedir, cpus } from "node:os";
|
|
15
15
|
import * as path from "node:path";
|
|
16
16
|
import path__default, { posix as posix$1, basename, win32, join as join$2, resolve as resolve$1, dirname as dirname$1, relative as relative$1, isAbsolute as isAbsolute$2, sep as sep$1, delimiter, normalize } from "node:path";
|
|
17
|
-
import { _ as _coercedNumber, Z as ZodNumber$1, o as object$1, s as string$1, l as literal$1, n as number$4, b as boolean, a as _enum$1, c as array$2,
|
|
17
|
+
import { _ as _coercedNumber, Z as ZodNumber$1, o as object$1, s as string$1, l as literal$1, n as number$4, b as boolean, a as _enum$1, c as array$2, r as record$1, d as discriminatedUnion, e as _instanceof, u as unknown, f as union$7, p as preprocess, g as ZodError$1, h as _null, i as normalizeParams, $ as $constructor, j as $ZodObject, k as defineLazy, m as $ZodType, q as parse$5, t as safeParse$1, v as parseAsync, w as safeParseAsync$1, x as clone$2, y as looseObject, z as intersection, A as optional$1, B as datetime, C as custom$1, D as toJSONSchema, E as ZodOptional$1, F as never$1, G as xor } from "./chunks/schemas-Du3qLZPS.js";
|
|
18
18
|
import require$$0$4, { once as once$1, EventEmitter as EventEmitter$1 } from "node:events";
|
|
19
19
|
import Tw__default, { execFile, spawn as spawn$1, execFileSync } from "node:child_process";
|
|
20
20
|
import process$2 from "node:process";
|
|
@@ -42,7 +42,7 @@ import { performance as performance$1 } from "perf_hooks";
|
|
|
42
42
|
import require$$0$9 from "net";
|
|
43
43
|
import require$$4$2 from "tls";
|
|
44
44
|
import require$$7$2, { fileURLToPath as fileURLToPath$1, pathToFileURL as pathToFileURL$1 } from "url";
|
|
45
|
-
import { D as DEEPSEEK_HARNESS_PERMISSION_MODES, a as DEEPSEEK_HARNESS_AGENT_PRESETS, b as DEEPSEEK_HARNESS_MODELS, c as DEEPSEEK_HARNESS_REASONING_OPTIONS, A as ACP_EXTENSION_DSH_CAPABILITY_SOURCE_VERSION, d as createDeepSeekHarnessCordisConfig, e as ACP_EXTENSION_DSH_VERSION, f as ACP_EXTENSION_DSH_PROFILE_REVISION, g as ACP_EXTENSION_DSH_QUERY_PATH_ENV, h as ACP_EXTENSION_DSH_SESSION_ROOT_ENV, i as DEEPSEEK_HARNESS_NPX_PACKAGES, j as DEEPSEEK_HARNESS_VERSION, k as DEEPSEEK_HARNESS_DEFAULT_SESSION_COMPRESSION } from "./chunks/profile-
|
|
45
|
+
import { D as DEEPSEEK_HARNESS_PERMISSION_MODES, a as DEEPSEEK_HARNESS_AGENT_PRESETS, b as DEEPSEEK_HARNESS_MODELS, c as DEEPSEEK_HARNESS_REASONING_OPTIONS, A as ACP_EXTENSION_DSH_CAPABILITY_SOURCE_VERSION, d as createDeepSeekHarnessCordisConfig, e as ACP_EXTENSION_DSH_VERSION, f as ACP_EXTENSION_DSH_PROFILE_REVISION, g as ACP_EXTENSION_DSH_QUERY_PATH_ENV, h as ACP_EXTENSION_DSH_SESSION_ROOT_ENV, i as DEEPSEEK_HARNESS_NPX_PACKAGES, j as DEEPSEEK_HARNESS_VERSION, k as DEEPSEEK_HARNESS_DEFAULT_SESSION_COMPRESSION } from "./chunks/profile-CPDWaQXE.js";
|
|
46
46
|
import assert from "assert";
|
|
47
47
|
import * as fs$2 from "fs/promises";
|
|
48
48
|
import fs__default$2 from "fs/promises";
|
|
@@ -4325,7 +4325,7 @@ Upgrade Node, then re-run: npx lody@latest`;
|
|
|
4325
4325
|
}
|
|
4326
4326
|
const name$2 = "lody";
|
|
4327
4327
|
const name$1 = "@lody/cli-cloud";
|
|
4328
|
-
const version$9 = "0.
|
|
4328
|
+
const version$9 = "0.90.0";
|
|
4329
4329
|
const type$2 = "module";
|
|
4330
4330
|
const scripts = {
|
|
4331
4331
|
"dev": "node dev.mjs",
|
|
@@ -11506,6 +11506,10 @@ Requirements:
|
|
|
11506
11506
|
connection: CliBackendConnectionSchema
|
|
11507
11507
|
}).strict().optional(),
|
|
11508
11508
|
connectedWorkspaces: array$2(CliRuntimeWorkspaceSchema).optional(),
|
|
11509
|
+
connectionAges: object$1({
|
|
11510
|
+
backendNotConnectedSinceMs: number$4().int().nonnegative().optional(),
|
|
11511
|
+
workspaceNotConnectedSinceMs: record$1(string$1().min(1), number$4().int().nonnegative()).optional()
|
|
11512
|
+
}).strict().optional(),
|
|
11509
11513
|
machineId: string$1().min(1).optional(),
|
|
11510
11514
|
pid: number$4().int(),
|
|
11511
11515
|
updatedAtMs: number$4(),
|
|
@@ -23342,28 +23346,35 @@ ${context2.authorReply.trim()}
|
|
|
23342
23346
|
...right2
|
|
23343
23347
|
];
|
|
23344
23348
|
};
|
|
23345
|
-
const
|
|
23349
|
+
const isBenchmarkingIpv4 = ([first2, second]) => first2 === 198 && (second === 18 || second === 19);
|
|
23350
|
+
const classifyIpv4 = (octets) => {
|
|
23351
|
+
const [first2, second, third, fourth] = octets;
|
|
23346
23352
|
if (first2 === 127) return "loopback";
|
|
23347
23353
|
if (first2 === 10 || first2 === 172 && second >= 16 && second <= 31) return "private-lan";
|
|
23348
23354
|
if (first2 === 192 && second === 168) return "private-lan";
|
|
23349
|
-
const prohibited = first2 === 0 || first2 >= 224 || first2 === 100 && second >= 64 && second <= 127 || first2 === 169 && second === 254 || first2 === 192 && second === 0 && third === 0 || first2 === 192 && second === 0 && third === 2 ||
|
|
23355
|
+
const prohibited = first2 === 0 || first2 >= 224 || first2 === 100 && second >= 64 && second <= 127 || first2 === 169 && second === 254 || first2 === 192 && second === 0 && third === 0 || first2 === 192 && second === 0 && third === 2 || isBenchmarkingIpv4(octets) || first2 === 198 && second === 51 && third === 100 || first2 === 203 && second === 0 && third === 113 || first2 === 255 && second === 255 && third === 255 && fourth === 255;
|
|
23350
23356
|
return prohibited ? "prohibited" : "public";
|
|
23351
23357
|
};
|
|
23358
|
+
const mappedIpv4 = (segments) => {
|
|
23359
|
+
if (!segments.slice(0, 5).every((segment) => segment === 0) || segments[5] !== 65535) {
|
|
23360
|
+
return null;
|
|
23361
|
+
}
|
|
23362
|
+
const high = segments[6] ?? 0;
|
|
23363
|
+
const low = segments[7] ?? 0;
|
|
23364
|
+
return [
|
|
23365
|
+
high >> 8,
|
|
23366
|
+
high & 255,
|
|
23367
|
+
low >> 8,
|
|
23368
|
+
low & 255
|
|
23369
|
+
];
|
|
23370
|
+
};
|
|
23352
23371
|
const classifyIpv6 = (segments) => {
|
|
23353
23372
|
if (segments.every((segment) => segment === 0)) return "prohibited";
|
|
23354
23373
|
if (segments.slice(0, 7).every((segment) => segment === 0) && segments[7] === 1) {
|
|
23355
23374
|
return "loopback";
|
|
23356
23375
|
}
|
|
23357
|
-
|
|
23358
|
-
|
|
23359
|
-
const low = segments[7] ?? 0;
|
|
23360
|
-
return classifyIpv4([
|
|
23361
|
-
high >> 8,
|
|
23362
|
-
high & 255,
|
|
23363
|
-
low >> 8,
|
|
23364
|
-
low & 255
|
|
23365
|
-
]);
|
|
23366
|
-
}
|
|
23376
|
+
const mapped = mappedIpv4(segments);
|
|
23377
|
+
if (mapped) return classifyIpv4(mapped);
|
|
23367
23378
|
const first2 = segments[0] ?? 0;
|
|
23368
23379
|
if ((first2 & 65024) === 64512) return "private-lan";
|
|
23369
23380
|
if ((first2 & 65472) === 65152 || (first2 & 65280) === 65280) return "prohibited";
|
|
@@ -127598,7 +127609,6 @@ ${error2.message}` : execaMessage;
|
|
|
127598
127609
|
return {
|
|
127599
127610
|
command: "npx",
|
|
127600
127611
|
args: [
|
|
127601
|
-
"--force",
|
|
127602
127612
|
"--prefer-offline",
|
|
127603
127613
|
"-y",
|
|
127604
127614
|
...DEEPSEEK_HARNESS_NPX_PACKAGES.flatMap((packageName) => [
|
|
@@ -129075,7 +129085,7 @@ ${fallbackStderrTail}` : errorMessage2;
|
|
|
129075
129085
|
sessionResponse
|
|
129076
129086
|
};
|
|
129077
129087
|
};
|
|
129078
|
-
function waitForChildProcessExit$
|
|
129088
|
+
function waitForChildProcessExit$2(child, timeoutMs) {
|
|
129079
129089
|
if (child.exitCode !== null) {
|
|
129080
129090
|
return Promise.resolve(true);
|
|
129081
129091
|
}
|
|
@@ -129112,7 +129122,7 @@ ${fallbackStderrTail}` : errorMessage2;
|
|
|
129112
129122
|
} catch {
|
|
129113
129123
|
return;
|
|
129114
129124
|
}
|
|
129115
|
-
if (await waitForChildProcessExit$
|
|
129125
|
+
if (await waitForChildProcessExit$2(child, exitTimeoutMs)) {
|
|
129116
129126
|
return;
|
|
129117
129127
|
}
|
|
129118
129128
|
logger2.debug(`[${sessionLabel}] ACP agent process did not exit within ${exitTimeoutMs}ms of SIGTERM; escalating to SIGKILL`);
|
|
@@ -129121,7 +129131,7 @@ ${fallbackStderrTail}` : errorMessage2;
|
|
|
129121
129131
|
} catch {
|
|
129122
129132
|
return;
|
|
129123
129133
|
}
|
|
129124
|
-
await waitForChildProcessExit$
|
|
129134
|
+
await waitForChildProcessExit$2(child, exitTimeoutMs);
|
|
129125
129135
|
}
|
|
129126
129136
|
const spawnAcpProcess = (options) => {
|
|
129127
129137
|
let command2 = options.command;
|
|
@@ -166472,7 +166482,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
166472
166482
|
const ACP_OPERATION_TIMEOUT_MS = 12e4;
|
|
166473
166483
|
const ACP_PROCESS_EXIT_TIMEOUT_MS = 3e3;
|
|
166474
166484
|
const MAX_LOCAL_PROJECT_HISTORY_CATALOG_SESSIONS = 100;
|
|
166475
|
-
function waitForChildProcessExit(child, timeoutMs) {
|
|
166485
|
+
function waitForChildProcessExit$1(child, timeoutMs) {
|
|
166476
166486
|
if (child.exitCode !== null) {
|
|
166477
166487
|
return Promise.resolve(true);
|
|
166478
166488
|
}
|
|
@@ -166504,7 +166514,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
166504
166514
|
} catch {
|
|
166505
166515
|
return;
|
|
166506
166516
|
}
|
|
166507
|
-
if (await waitForChildProcessExit(child, ACP_PROCESS_EXIT_TIMEOUT_MS)) {
|
|
166517
|
+
if (await waitForChildProcessExit$1(child, ACP_PROCESS_EXIT_TIMEOUT_MS)) {
|
|
166508
166518
|
return;
|
|
166509
166519
|
}
|
|
166510
166520
|
try {
|
|
@@ -166512,7 +166522,7 @@ ${escapeHtmlScriptContent(VISUAL_ANNOTATION_INSPECTOR_BROWSER_SCRIPT)}
|
|
|
166512
166522
|
} catch {
|
|
166513
166523
|
return;
|
|
166514
166524
|
}
|
|
166515
|
-
await waitForChildProcessExit(child, ACP_PROCESS_EXIT_TIMEOUT_MS);
|
|
166525
|
+
await waitForChildProcessExit$1(child, ACP_PROCESS_EXIT_TIMEOUT_MS);
|
|
166516
166526
|
}
|
|
166517
166527
|
async function withTimeout(promise2, label2) {
|
|
166518
166528
|
let timeout2 = null;
|
|
@@ -193456,20 +193466,29 @@ ${trimmed2}${closing}`;
|
|
|
193456
193466
|
phase = "starting";
|
|
193457
193467
|
startupStage = "bootstrap";
|
|
193458
193468
|
connectivity;
|
|
193459
|
-
backend
|
|
193460
|
-
|
|
193461
|
-
connection: "connecting"
|
|
193462
|
-
};
|
|
193469
|
+
backend;
|
|
193470
|
+
backendNotConnectedSinceMs;
|
|
193463
193471
|
connectedWorkspaces = [];
|
|
193472
|
+
workspaceNotConnectedSinceMs = /* @__PURE__ */ new Map();
|
|
193464
193473
|
machineId;
|
|
193465
193474
|
activeSessionCount = 0;
|
|
193466
193475
|
connectedRoomCount = 0;
|
|
193467
|
-
updatedAtMs
|
|
193476
|
+
updatedAtMs;
|
|
193468
193477
|
issuesByCode = /* @__PURE__ */ new Map();
|
|
193478
|
+
trackBackendConnectionAge;
|
|
193479
|
+
now;
|
|
193469
193480
|
constructor(options = {}) {
|
|
193470
193481
|
this.pid = options.pid ?? process.pid;
|
|
193471
193482
|
this.machineId = options.machineId;
|
|
193472
193483
|
this.supervisor = options.supervisor;
|
|
193484
|
+
this.trackBackendConnectionAge = options.trackBackendConnectionAge ?? true;
|
|
193485
|
+
this.now = options.now ?? Date.now;
|
|
193486
|
+
this.updatedAtMs = this.now();
|
|
193487
|
+
this.backend = {
|
|
193488
|
+
authorization: "pending",
|
|
193489
|
+
connection: "connecting"
|
|
193490
|
+
};
|
|
193491
|
+
this.backendNotConnectedSinceMs = this.trackBackendConnectionAge ? this.updatedAtMs : void 0;
|
|
193473
193492
|
}
|
|
193474
193493
|
setMachineId(machineId) {
|
|
193475
193494
|
if (this.machineId === machineId) {
|
|
@@ -193517,24 +193536,52 @@ ${trimmed2}${closing}`;
|
|
|
193517
193536
|
this.touch();
|
|
193518
193537
|
}
|
|
193519
193538
|
setBackendConnection(connection2) {
|
|
193520
|
-
|
|
193539
|
+
const nowMs2 = this.now();
|
|
193540
|
+
const notConnectedSinceMs = !this.trackBackendConnectionAge || connection2 === "connected" ? void 0 : this.backend.connection === "connected" ? nowMs2 : this.backendNotConnectedSinceMs ?? nowMs2;
|
|
193541
|
+
if (this.backend.connection === connection2 && this.backendNotConnectedSinceMs === notConnectedSinceMs) {
|
|
193521
193542
|
return;
|
|
193522
193543
|
}
|
|
193523
193544
|
this.backend = {
|
|
193524
193545
|
...this.backend,
|
|
193525
193546
|
connection: connection2
|
|
193526
193547
|
};
|
|
193548
|
+
this.backendNotConnectedSinceMs = notConnectedSinceMs;
|
|
193527
193549
|
this.touch();
|
|
193528
193550
|
}
|
|
193529
193551
|
setConnectedWorkspaces(workspaces) {
|
|
193530
|
-
|
|
193552
|
+
const nowMs2 = this.now();
|
|
193553
|
+
const previousById = new Map(this.connectedWorkspaces.map((workspace) => [
|
|
193554
|
+
workspace.id,
|
|
193555
|
+
workspace
|
|
193556
|
+
]));
|
|
193557
|
+
const nextWorkspaceNotConnectedSinceMs = /* @__PURE__ */ new Map();
|
|
193558
|
+
const nextWorkspaces = workspaces.map((workspace) => {
|
|
193559
|
+
const previous = previousById.get(workspace.id);
|
|
193560
|
+
const notConnectedSinceMs = !this.trackBackendConnectionAge || workspace.backendConnection === "connected" ? void 0 : previous?.backendConnection === "connected" ? nowMs2 : this.workspaceNotConnectedSinceMs.get(workspace.id) ?? nowMs2;
|
|
193561
|
+
if (notConnectedSinceMs !== void 0) {
|
|
193562
|
+
nextWorkspaceNotConnectedSinceMs.set(workspace.id, notConnectedSinceMs);
|
|
193563
|
+
}
|
|
193564
|
+
return {
|
|
193565
|
+
id: workspace.id,
|
|
193566
|
+
name: workspace.name,
|
|
193567
|
+
slug: workspace.slug,
|
|
193568
|
+
role: workspace.role,
|
|
193569
|
+
backendConnection: workspace.backendConnection
|
|
193570
|
+
};
|
|
193571
|
+
});
|
|
193572
|
+
if (JSON.stringify(this.connectedWorkspaces) === JSON.stringify(nextWorkspaces) && JSON.stringify([
|
|
193573
|
+
...this.workspaceNotConnectedSinceMs
|
|
193574
|
+
]) === JSON.stringify([
|
|
193575
|
+
...nextWorkspaceNotConnectedSinceMs
|
|
193576
|
+
])) {
|
|
193531
193577
|
return;
|
|
193532
193578
|
}
|
|
193533
|
-
this.connectedWorkspaces =
|
|
193579
|
+
this.connectedWorkspaces = nextWorkspaces;
|
|
193580
|
+
this.workspaceNotConnectedSinceMs = nextWorkspaceNotConnectedSinceMs;
|
|
193534
193581
|
this.touch();
|
|
193535
193582
|
}
|
|
193536
193583
|
upsertIssue(input2) {
|
|
193537
|
-
const nowMs2 =
|
|
193584
|
+
const nowMs2 = this.now();
|
|
193538
193585
|
const existing = this.issuesByCode.get(input2.code);
|
|
193539
193586
|
if (existing) {
|
|
193540
193587
|
const next2 = {
|
|
@@ -193599,6 +193646,14 @@ ${trimmed2}${closing}`;
|
|
|
193599
193646
|
connectivity: this.connectivity,
|
|
193600
193647
|
backend: this.backend,
|
|
193601
193648
|
connectedWorkspaces: this.connectedWorkspaces,
|
|
193649
|
+
connectionAges: this.trackBackendConnectionAge ? {
|
|
193650
|
+
...this.backendNotConnectedSinceMs === void 0 ? {} : {
|
|
193651
|
+
backendNotConnectedSinceMs: this.backendNotConnectedSinceMs
|
|
193652
|
+
},
|
|
193653
|
+
...this.workspaceNotConnectedSinceMs.size === 0 ? {} : {
|
|
193654
|
+
workspaceNotConnectedSinceMs: Object.fromEntries(this.workspaceNotConnectedSinceMs)
|
|
193655
|
+
}
|
|
193656
|
+
} : void 0,
|
|
193602
193657
|
machineId: this.machineId,
|
|
193603
193658
|
pid: this.pid,
|
|
193604
193659
|
updatedAtMs: this.updatedAtMs,
|
|
@@ -193625,7 +193680,7 @@ ${trimmed2}${closing}`;
|
|
|
193625
193680
|
}
|
|
193626
193681
|
}
|
|
193627
193682
|
touch() {
|
|
193628
|
-
this.updatedAtMs =
|
|
193683
|
+
this.updatedAtMs = this.now();
|
|
193629
193684
|
this.phase = this.computePhase();
|
|
193630
193685
|
}
|
|
193631
193686
|
computePhase() {
|
|
@@ -194171,7 +194226,7 @@ Shutting down gracefully${reason}...`);
|
|
|
194171
194226
|
}
|
|
194172
194227
|
if (!hostRecord) {
|
|
194173
194228
|
hostRecord = parseRecord(value);
|
|
194174
|
-
if (!hostRecord || hostRecord.instanceId !== options.instanceId || options.expectedPid !== void 0 && hostRecord.pid !== options.expectedPid || hostRecord.mode !== options.expectedMode) {
|
|
194229
|
+
if (!hostRecord || hostRecord.instanceId !== options.instanceId || options.expectedPid !== void 0 && hostRecord.pid !== options.expectedPid || options.expectedMode !== void 0 && hostRecord.mode !== options.expectedMode) {
|
|
194175
194230
|
finish({
|
|
194176
194231
|
ok: false,
|
|
194177
194232
|
error: "owner_mismatch"
|
|
@@ -194337,7 +194392,8 @@ Shutting down gracefully${reason}...`);
|
|
|
194337
194392
|
};
|
|
194338
194393
|
const authFailureExitCode = supervisorIdentity ? EXIT_CODE_AUTH_FAILURE : 1;
|
|
194339
194394
|
const runtimeStateReporter = new CliRuntimeStateReporter({
|
|
194340
|
-
supervisor: toRuntimeSupervisorIdentity(supervisorIdentity)
|
|
194395
|
+
supervisor: toRuntimeSupervisorIdentity(supervisorIdentity),
|
|
194396
|
+
trackBackendConnectionAge: platformKind === "cloud"
|
|
194341
194397
|
});
|
|
194342
194398
|
runtimeStateReporter.setStartupStage("bootstrap");
|
|
194343
194399
|
const electronManaged = supervisorIdentity?.launchMode === "electron";
|
|
@@ -222170,7 +222226,7 @@ ${page}${helpTipBottom}${choiceDescription}${ansiEscapes.cursorHide}`;
|
|
|
222170
222226
|
data = createReviewBundleSnapshot(bundle);
|
|
222171
222227
|
}
|
|
222172
222228
|
const { injectReviewSnapshot } = await import("./chunks/index-VoI6Ds2-.js");
|
|
222173
|
-
const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-
|
|
222229
|
+
const { resolveReviewViewerTemplate } = await import("./chunks/review-viewer-CGdWKpLa.js").then(async (m) => {
|
|
222174
222230
|
await m.__tla;
|
|
222175
222231
|
return m;
|
|
222176
222232
|
});
|
|
@@ -222340,7 +222396,7 @@ ${result.stderr}`;
|
|
|
222340
222396
|
const DEFAULT_HEALTHY_RUN_MS = 6e4;
|
|
222341
222397
|
const DEFAULT_TERMINATION_GRACE_MS = 3e4;
|
|
222342
222398
|
const DEFAULT_FORCE_KILL_WAIT_MS = 5e3;
|
|
222343
|
-
function isChildProcessRunning(child) {
|
|
222399
|
+
function isChildProcessRunning$1(child) {
|
|
222344
222400
|
return child !== null && child.exitCode === null && child.signalCode === null;
|
|
222345
222401
|
}
|
|
222346
222402
|
function runtimeMatchesHost(runtime, host) {
|
|
@@ -222760,7 +222816,7 @@ ${result.stderr}`;
|
|
|
222760
222816
|
startHealthyRunTimer(run2) {
|
|
222761
222817
|
this.clearHealthyRunTimer();
|
|
222762
222818
|
const timer2 = setTimeout(() => {
|
|
222763
|
-
if (this.healthyRunTimer !== timer2 || this.activeRun !== run2 || !this.isCurrent(run2.generation) || !isChildProcessRunning(run2.handle.child)) {
|
|
222819
|
+
if (this.healthyRunTimer !== timer2 || this.activeRun !== run2 || !this.isCurrent(run2.generation) || !isChildProcessRunning$1(run2.handle.child)) {
|
|
222764
222820
|
return;
|
|
222765
222821
|
}
|
|
222766
222822
|
this.healthyRunTimer = null;
|
|
@@ -222810,7 +222866,7 @@ ${result.stderr}`;
|
|
|
222810
222866
|
this.signalChild(run2.handle.child, "SIGTERM");
|
|
222811
222867
|
}
|
|
222812
222868
|
signalChild(child, signal) {
|
|
222813
|
-
if (!isChildProcessRunning(child)) return;
|
|
222869
|
+
if (!isChildProcessRunning$1(child)) return;
|
|
222814
222870
|
try {
|
|
222815
222871
|
child.kill(signal);
|
|
222816
222872
|
} catch {
|
|
@@ -222831,7 +222887,7 @@ ${result.stderr}`;
|
|
|
222831
222887
|
}
|
|
222832
222888
|
}
|
|
222833
222889
|
async waitForChildExit(child) {
|
|
222834
|
-
if (!isChildProcessRunning(child)) return;
|
|
222890
|
+
if (!isChildProcessRunning$1(child)) return;
|
|
222835
222891
|
await new Promise((resolve2) => {
|
|
222836
222892
|
let settled = false;
|
|
222837
222893
|
const finish = () => {
|
|
@@ -222843,7 +222899,7 @@ ${result.stderr}`;
|
|
|
222843
222899
|
};
|
|
222844
222900
|
child.once("exit", finish);
|
|
222845
222901
|
child.once("close", finish);
|
|
222846
|
-
if (!isChildProcessRunning(child)) finish();
|
|
222902
|
+
if (!isChildProcessRunning$1(child)) finish();
|
|
222847
222903
|
});
|
|
222848
222904
|
}
|
|
222849
222905
|
async abortable(operation, signal, message) {
|
|
@@ -223033,7 +223089,7 @@ ${result.stderr}`;
|
|
|
223033
223089
|
}
|
|
223034
223090
|
buildState() {
|
|
223035
223091
|
const runtime = this.latestRuntimeState;
|
|
223036
|
-
const childRunning = isChildProcessRunning(this.activeRun?.handle.child ?? null);
|
|
223092
|
+
const childRunning = isChildProcessRunning$1(this.activeRun?.handle.child ?? null);
|
|
223037
223093
|
let phase;
|
|
223038
223094
|
if (this.desiredState === "stopped") {
|
|
223039
223095
|
phase = childRunning ? "stopping" : runtime ? phaseFromRuntime(runtime) : "stopped";
|
|
@@ -223197,6 +223253,8 @@ ${result.stdout ?? ""}`;
|
|
|
223197
223253
|
const DAEMON_RUNNER_READY_FD = 3;
|
|
223198
223254
|
const DAEMON_RUNNER_READY_TIMEOUT_MS = 3e4;
|
|
223199
223255
|
const DAEMON_RUNNER_READY_MAX_BUFFER = 8 * 1024;
|
|
223256
|
+
const DAEMON_RUNNER_SHUTDOWN_GRACE_MS = 4e4;
|
|
223257
|
+
const DAEMON_RUNNER_FORCE_KILL_WAIT_MS = 5e3;
|
|
223200
223258
|
const DaemonRunnerLaunchOutcomeSchema = discriminatedUnion("status", [
|
|
223201
223259
|
object$1({
|
|
223202
223260
|
status: literal$1("ready"),
|
|
@@ -223229,6 +223287,94 @@ ${result.stdout ?? ""}`;
|
|
|
223229
223287
|
} catch {
|
|
223230
223288
|
}
|
|
223231
223289
|
}
|
|
223290
|
+
function interpretDaemonRunnerLaunchOutcome(outcome, runnerPid) {
|
|
223291
|
+
switch (outcome.status) {
|
|
223292
|
+
case "ready":
|
|
223293
|
+
return {
|
|
223294
|
+
outcome: {
|
|
223295
|
+
status: "ready",
|
|
223296
|
+
pid: runnerPid,
|
|
223297
|
+
instanceId: outcome.instanceId
|
|
223298
|
+
},
|
|
223299
|
+
cancelRunner: false
|
|
223300
|
+
};
|
|
223301
|
+
case "occupied":
|
|
223302
|
+
return {
|
|
223303
|
+
outcome: {
|
|
223304
|
+
status: "occupied",
|
|
223305
|
+
runnerPid,
|
|
223306
|
+
ownerMode: outcome.ownerMode,
|
|
223307
|
+
ownerPid: outcome.ownerPid
|
|
223308
|
+
},
|
|
223309
|
+
cancelRunner: false
|
|
223310
|
+
};
|
|
223311
|
+
case "error":
|
|
223312
|
+
return {
|
|
223313
|
+
outcome: {
|
|
223314
|
+
status: "error",
|
|
223315
|
+
runnerPid,
|
|
223316
|
+
message: outcome.message
|
|
223317
|
+
},
|
|
223318
|
+
cancelRunner: true
|
|
223319
|
+
};
|
|
223320
|
+
default: {
|
|
223321
|
+
const unreachable = outcome;
|
|
223322
|
+
return unreachable;
|
|
223323
|
+
}
|
|
223324
|
+
}
|
|
223325
|
+
}
|
|
223326
|
+
function isChildProcessRunning(child) {
|
|
223327
|
+
return child.exitCode === null && child.signalCode === null;
|
|
223328
|
+
}
|
|
223329
|
+
async function waitForChildProcessExit(child, timeoutMs) {
|
|
223330
|
+
if (!isChildProcessRunning(child)) return true;
|
|
223331
|
+
return await new Promise((resolve2) => {
|
|
223332
|
+
let settled = false;
|
|
223333
|
+
let timeout2;
|
|
223334
|
+
let onExit2;
|
|
223335
|
+
const finish = (exited) => {
|
|
223336
|
+
if (settled) return;
|
|
223337
|
+
settled = true;
|
|
223338
|
+
if (timeout2 !== void 0) clearTimeout(timeout2);
|
|
223339
|
+
child.off("exit", onExit2);
|
|
223340
|
+
child.off("close", onExit2);
|
|
223341
|
+
resolve2(exited);
|
|
223342
|
+
};
|
|
223343
|
+
onExit2 = () => finish(true);
|
|
223344
|
+
timeout2 = setTimeout(() => finish(!isChildProcessRunning(child)), timeoutMs);
|
|
223345
|
+
child.once("exit", onExit2);
|
|
223346
|
+
child.once("close", onExit2);
|
|
223347
|
+
if (!isChildProcessRunning(child)) finish(true);
|
|
223348
|
+
});
|
|
223349
|
+
}
|
|
223350
|
+
async function terminateSpawnedDaemonRunner(child, runnerPid, options = {}) {
|
|
223351
|
+
if (!isChildProcessRunning(child)) return true;
|
|
223352
|
+
const pidRecord = readPidFileRecord();
|
|
223353
|
+
let gracefulShutdownRequested = false;
|
|
223354
|
+
if (pidRecord?.pid === runnerPid) {
|
|
223355
|
+
const requested = await requestLocalCliHostShutdown({
|
|
223356
|
+
instanceId: pidRecord.instanceId,
|
|
223357
|
+
token: pidRecord.controlToken,
|
|
223358
|
+
expectedPid: runnerPid,
|
|
223359
|
+
expectedMode: "daemon"
|
|
223360
|
+
});
|
|
223361
|
+
gracefulShutdownRequested = requested.ok;
|
|
223362
|
+
}
|
|
223363
|
+
if (!gracefulShutdownRequested) {
|
|
223364
|
+
try {
|
|
223365
|
+
child.kill("SIGTERM");
|
|
223366
|
+
} catch {
|
|
223367
|
+
}
|
|
223368
|
+
}
|
|
223369
|
+
if (await waitForChildProcessExit(child, options.shutdownGraceMs ?? DAEMON_RUNNER_SHUTDOWN_GRACE_MS)) {
|
|
223370
|
+
return true;
|
|
223371
|
+
}
|
|
223372
|
+
try {
|
|
223373
|
+
child.kill("SIGKILL");
|
|
223374
|
+
} catch {
|
|
223375
|
+
}
|
|
223376
|
+
return await waitForChildProcessExit(child, options.forceKillWaitMs ?? DAEMON_RUNNER_FORCE_KILL_WAIT_MS);
|
|
223377
|
+
}
|
|
223232
223378
|
async function spawnDaemonRunnerAndAwaitReady(passthroughArgs, options = {}) {
|
|
223233
223379
|
const bin = resolveLodyBin();
|
|
223234
223380
|
const env2 = {
|
|
@@ -223266,26 +223412,30 @@ ${result.stdout ?? ""}`;
|
|
|
223266
223412
|
};
|
|
223267
223413
|
}
|
|
223268
223414
|
const readyPipe = child.stdio[DAEMON_RUNNER_READY_FD] ?? null;
|
|
223269
|
-
const
|
|
223415
|
+
const waitResult = await new Promise((resolve2) => {
|
|
223270
223416
|
let settled = false;
|
|
223271
223417
|
let buffer2 = "";
|
|
223272
|
-
|
|
223418
|
+
let timeout2;
|
|
223419
|
+
const finish = (outcome, cancelRunner = false) => {
|
|
223273
223420
|
if (settled) return;
|
|
223274
223421
|
settled = true;
|
|
223275
|
-
clearTimeout(timeout2);
|
|
223276
|
-
resolve2(
|
|
223422
|
+
if (timeout2 !== void 0) clearTimeout(timeout2);
|
|
223423
|
+
resolve2({
|
|
223424
|
+
outcome,
|
|
223425
|
+
cancelRunner
|
|
223426
|
+
});
|
|
223277
223427
|
};
|
|
223278
|
-
|
|
223428
|
+
timeout2 = setTimeout(() => finish({
|
|
223279
223429
|
status: "timeout",
|
|
223280
223430
|
runnerPid
|
|
223281
|
-
}), options.timeoutMs ?? DAEMON_RUNNER_READY_TIMEOUT_MS);
|
|
223431
|
+
}, true), options.timeoutMs ?? DAEMON_RUNNER_READY_TIMEOUT_MS);
|
|
223282
223432
|
timeout2.unref?.();
|
|
223283
223433
|
if (!readyPipe) {
|
|
223284
223434
|
finish({
|
|
223285
223435
|
status: "error",
|
|
223286
223436
|
runnerPid,
|
|
223287
223437
|
message: "readiness channel unavailable"
|
|
223288
|
-
});
|
|
223438
|
+
}, true);
|
|
223289
223439
|
return;
|
|
223290
223440
|
}
|
|
223291
223441
|
readyPipe.on("data", (chunk) => {
|
|
@@ -223297,7 +223447,7 @@ ${result.stdout ?? ""}`;
|
|
|
223297
223447
|
status: "error",
|
|
223298
223448
|
runnerPid,
|
|
223299
223449
|
message: "invalid readiness report"
|
|
223300
|
-
});
|
|
223450
|
+
}, true);
|
|
223301
223451
|
}
|
|
223302
223452
|
return;
|
|
223303
223453
|
}
|
|
@@ -223309,7 +223459,7 @@ ${result.stdout ?? ""}`;
|
|
|
223309
223459
|
status: "error",
|
|
223310
223460
|
runnerPid,
|
|
223311
223461
|
message: "invalid readiness report"
|
|
223312
|
-
});
|
|
223462
|
+
}, true);
|
|
223313
223463
|
return;
|
|
223314
223464
|
}
|
|
223315
223465
|
const outcome = DaemonRunnerLaunchOutcomeSchema.safeParse(parsed);
|
|
@@ -223318,41 +223468,31 @@ ${result.stdout ?? ""}`;
|
|
|
223318
223468
|
status: "error",
|
|
223319
223469
|
runnerPid,
|
|
223320
223470
|
message: "invalid readiness report"
|
|
223321
|
-
});
|
|
223471
|
+
}, true);
|
|
223322
223472
|
return;
|
|
223323
223473
|
}
|
|
223324
|
-
|
|
223325
|
-
|
|
223326
|
-
status: "ready",
|
|
223327
|
-
pid: runnerPid,
|
|
223328
|
-
instanceId: outcome.data.instanceId
|
|
223329
|
-
});
|
|
223330
|
-
} else if (outcome.data.status === "occupied") {
|
|
223331
|
-
finish({
|
|
223332
|
-
status: "occupied",
|
|
223333
|
-
runnerPid,
|
|
223334
|
-
ownerMode: outcome.data.ownerMode,
|
|
223335
|
-
ownerPid: outcome.data.ownerPid
|
|
223336
|
-
});
|
|
223337
|
-
} else {
|
|
223338
|
-
finish({
|
|
223339
|
-
status: "error",
|
|
223340
|
-
runnerPid,
|
|
223341
|
-
message: outcome.data.message
|
|
223342
|
-
});
|
|
223343
|
-
}
|
|
223474
|
+
const interpreted = interpretDaemonRunnerLaunchOutcome(outcome.data, runnerPid);
|
|
223475
|
+
finish(interpreted.outcome, interpreted.cancelRunner);
|
|
223344
223476
|
});
|
|
223345
223477
|
readyPipe.once("end", () => finish({
|
|
223346
223478
|
status: "runner_exited",
|
|
223347
223479
|
runnerPid
|
|
223348
|
-
}));
|
|
223480
|
+
}, true));
|
|
223349
223481
|
readyPipe.once("error", () => finish({
|
|
223350
223482
|
status: "runner_exited",
|
|
223351
223483
|
runnerPid
|
|
223352
|
-
}));
|
|
223484
|
+
}, true));
|
|
223353
223485
|
});
|
|
223354
223486
|
readyPipe?.removeAllListeners();
|
|
223355
223487
|
readyPipe?.destroy();
|
|
223488
|
+
let result = waitResult.outcome;
|
|
223489
|
+
if (waitResult.cancelRunner && !await terminateSpawnedDaemonRunner(child, runnerPid)) {
|
|
223490
|
+
result = {
|
|
223491
|
+
status: "error",
|
|
223492
|
+
runnerPid,
|
|
223493
|
+
message: `Daemon launch failed (${result.status}) and runner ${runnerPid} did not exit`
|
|
223494
|
+
};
|
|
223495
|
+
}
|
|
223356
223496
|
child.unref();
|
|
223357
223497
|
return result;
|
|
223358
223498
|
}
|
|
@@ -223457,21 +223597,115 @@ ${result.stdout ?? ""}`;
|
|
|
223457
223597
|
...sanitized
|
|
223458
223598
|
];
|
|
223459
223599
|
}
|
|
223460
|
-
|
|
223600
|
+
const DAEMON_CONNECTION_ERROR_AFTER_MS = 6e4;
|
|
223601
|
+
const defaultPalette = {
|
|
223602
|
+
success: chalk.green,
|
|
223603
|
+
warning: chalk.yellow,
|
|
223604
|
+
error: chalk.red,
|
|
223605
|
+
muted: chalk.gray
|
|
223606
|
+
};
|
|
223607
|
+
function formatElapsed(elapsedMs) {
|
|
223608
|
+
const totalSeconds = Math.max(0, Math.floor(elapsedMs / 1e3));
|
|
223609
|
+
if (totalSeconds < 60) return `${totalSeconds}s`;
|
|
223610
|
+
const totalMinutes = Math.floor(totalSeconds / 60);
|
|
223611
|
+
const seconds2 = totalSeconds % 60;
|
|
223612
|
+
if (totalMinutes < 60) {
|
|
223613
|
+
return seconds2 === 0 ? `${totalMinutes}m` : `${totalMinutes}m ${seconds2}s`;
|
|
223614
|
+
}
|
|
223615
|
+
const totalHours = Math.floor(totalMinutes / 60);
|
|
223616
|
+
const minutes2 = totalMinutes % 60;
|
|
223617
|
+
if (totalHours < 24) {
|
|
223618
|
+
return minutes2 === 0 ? `${totalHours}h` : `${totalHours}h ${minutes2}m`;
|
|
223619
|
+
}
|
|
223620
|
+
const days2 = Math.floor(totalHours / 24);
|
|
223621
|
+
const hours2 = totalHours % 24;
|
|
223622
|
+
return hours2 === 0 ? `${days2}d` : `${days2}d ${hours2}h`;
|
|
223623
|
+
}
|
|
223624
|
+
function formatAuthorization(authorization, palette) {
|
|
223625
|
+
switch (authorization) {
|
|
223626
|
+
case "authorized":
|
|
223627
|
+
return palette.success(authorization);
|
|
223628
|
+
case "pending":
|
|
223629
|
+
return palette.warning(authorization);
|
|
223630
|
+
case "rejected":
|
|
223631
|
+
return palette.error(authorization);
|
|
223632
|
+
case "unknown":
|
|
223633
|
+
return palette.muted(authorization);
|
|
223634
|
+
default: {
|
|
223635
|
+
const unreachable = authorization;
|
|
223636
|
+
return unreachable;
|
|
223637
|
+
}
|
|
223638
|
+
}
|
|
223639
|
+
}
|
|
223640
|
+
function formatConnection(connection2, notConnectedSinceMs, options) {
|
|
223641
|
+
if (connection2 === "connected") {
|
|
223642
|
+
return {
|
|
223643
|
+
formatted: options.palette.success(connection2),
|
|
223644
|
+
unavailableFor: null,
|
|
223645
|
+
stale: false
|
|
223646
|
+
};
|
|
223647
|
+
}
|
|
223648
|
+
if (connection2 === "unknown") {
|
|
223649
|
+
return {
|
|
223650
|
+
formatted: options.palette.muted(connection2),
|
|
223651
|
+
unavailableFor: null,
|
|
223652
|
+
stale: false
|
|
223653
|
+
};
|
|
223654
|
+
}
|
|
223655
|
+
const elapsedMs = notConnectedSinceMs === void 0 ? null : Math.max(0, options.nowMs - notConnectedSinceMs);
|
|
223656
|
+
const unavailableFor = elapsedMs === null ? null : formatElapsed(elapsedMs);
|
|
223657
|
+
const label2 = unavailableFor === null ? connection2 : `${connection2} (${unavailableFor})`;
|
|
223658
|
+
const stale = elapsedMs !== null && elapsedMs >= options.connectionErrorAfterMs;
|
|
223659
|
+
const tone = stale || connection2 === "disconnected" ? options.palette.error : options.palette.warning;
|
|
223660
|
+
return {
|
|
223661
|
+
formatted: tone(label2),
|
|
223662
|
+
unavailableFor,
|
|
223663
|
+
stale
|
|
223664
|
+
};
|
|
223665
|
+
}
|
|
223666
|
+
function formatDaemonConnectivityStatus(connectivity, palette = defaultPalette) {
|
|
223667
|
+
switch (connectivity) {
|
|
223668
|
+
case "online":
|
|
223669
|
+
return palette.success(connectivity);
|
|
223670
|
+
case "reconnecting":
|
|
223671
|
+
return palette.warning(connectivity);
|
|
223672
|
+
case "offline":
|
|
223673
|
+
return palette.error(connectivity);
|
|
223674
|
+
default: {
|
|
223675
|
+
const unreachable = connectivity;
|
|
223676
|
+
return unreachable;
|
|
223677
|
+
}
|
|
223678
|
+
}
|
|
223679
|
+
}
|
|
223680
|
+
function formatDaemonBackendStatus(runtimeState, options = {}) {
|
|
223681
|
+
const resolvedOptions = {
|
|
223682
|
+
nowMs: options.nowMs ?? Date.now(),
|
|
223683
|
+
connectionErrorAfterMs: options.connectionErrorAfterMs ?? DAEMON_CONNECTION_ERROR_AFTER_MS,
|
|
223684
|
+
palette: options.palette ?? defaultPalette
|
|
223685
|
+
};
|
|
223686
|
+
const authorization = runtimeState.backend?.authorization ?? "unknown";
|
|
223687
|
+
const backendConnection = formatConnection(runtimeState.backend?.connection ?? "unknown", runtimeState.connectionAges?.backendNotConnectedSinceMs, resolvedOptions);
|
|
223461
223688
|
const lines2 = [
|
|
223462
|
-
` Backend Auth: ${
|
|
223463
|
-
` Backend Link: ${
|
|
223689
|
+
` Backend Auth: ${formatAuthorization(authorization, resolvedOptions.palette)}`,
|
|
223690
|
+
` Backend Link: ${backendConnection.formatted}`
|
|
223464
223691
|
];
|
|
223692
|
+
if (backendConnection.stale && backendConnection.unavailableFor) {
|
|
223693
|
+
lines2.push(resolvedOptions.palette.error(` Backend Error: not connected for ${backendConnection.unavailableFor}`));
|
|
223694
|
+
}
|
|
223465
223695
|
if (!runtimeState.connectedWorkspaces) {
|
|
223466
|
-
lines2.push(
|
|
223696
|
+
lines2.push(` Workspaces: ${resolvedOptions.palette.muted("unavailable")}`);
|
|
223467
223697
|
return lines2;
|
|
223468
223698
|
}
|
|
223469
223699
|
lines2.push(` Workspaces: ${runtimeState.connectedWorkspaces.length}`);
|
|
223470
223700
|
for (const workspace of runtimeState.connectedWorkspaces) {
|
|
223471
223701
|
const label2 = workspace.slug ? `${workspace.name} (${workspace.slug})` : workspace.name;
|
|
223702
|
+
const connection2 = formatConnection(workspace.backendConnection, runtimeState.connectionAges?.workspaceNotConnectedSinceMs?.[workspace.id], resolvedOptions);
|
|
223472
223703
|
lines2.push(` - ${label2} [${workspace.role}]`);
|
|
223473
223704
|
lines2.push(` ID: ${workspace.id}`);
|
|
223474
|
-
lines2.push(` Backend: ${
|
|
223705
|
+
lines2.push(` Backend: ${connection2.formatted}`);
|
|
223706
|
+
if (connection2.stale && connection2.unavailableFor) {
|
|
223707
|
+
lines2.push(resolvedOptions.palette.error(` Error: not connected for ${connection2.unavailableFor}`));
|
|
223708
|
+
}
|
|
223475
223709
|
}
|
|
223476
223710
|
return lines2;
|
|
223477
223711
|
}
|
|
@@ -223567,7 +223801,7 @@ ${result.stdout ?? ""}`;
|
|
|
223567
223801
|
};
|
|
223568
223802
|
case "error":
|
|
223569
223803
|
return {
|
|
223570
|
-
status: "
|
|
223804
|
+
status: "startup_error",
|
|
223571
223805
|
pid: result.runnerPid,
|
|
223572
223806
|
message: result.message
|
|
223573
223807
|
};
|
|
@@ -223582,7 +223816,7 @@ ${result.stdout ?? ""}`;
|
|
|
223582
223816
|
};
|
|
223583
223817
|
case "timeout":
|
|
223584
223818
|
return {
|
|
223585
|
-
status: "
|
|
223819
|
+
status: "startup_timeout",
|
|
223586
223820
|
pid: result.runnerPid
|
|
223587
223821
|
};
|
|
223588
223822
|
default: {
|
|
@@ -223693,11 +223927,11 @@ ${result.stdout ?? ""}`;
|
|
|
223693
223927
|
await exitDaemonCommand(1);
|
|
223694
223928
|
return;
|
|
223695
223929
|
}
|
|
223696
|
-
if (result.status === "
|
|
223930
|
+
if (result.status === "startup_error") {
|
|
223697
223931
|
captureDaemonEvent("daemon_start_failed", {
|
|
223698
|
-
reason_code: "
|
|
223932
|
+
reason_code: "startup_error"
|
|
223699
223933
|
});
|
|
223700
|
-
console.error(`Daemon runner
|
|
223934
|
+
console.error(`Daemon startup (runner PID ${result.pid}) failed: ${result.message}`);
|
|
223701
223935
|
await exitDaemonCommand(1);
|
|
223702
223936
|
return;
|
|
223703
223937
|
}
|
|
@@ -223705,15 +223939,15 @@ ${result.stdout ?? ""}`;
|
|
|
223705
223939
|
captureDaemonEvent("daemon_start_failed", {
|
|
223706
223940
|
reason_code: "runner_exited"
|
|
223707
223941
|
});
|
|
223708
|
-
console.error(`Daemon runner (PID ${result.pid}) exited before
|
|
223942
|
+
console.error(`Daemon runner (PID ${result.pid}) exited before its worker became ready.`);
|
|
223709
223943
|
await exitDaemonCommand(1);
|
|
223710
223944
|
return;
|
|
223711
223945
|
}
|
|
223712
|
-
if (result.status === "
|
|
223946
|
+
if (result.status === "startup_timeout") {
|
|
223713
223947
|
captureDaemonEvent("daemon_start_failed", {
|
|
223714
|
-
reason_code: "
|
|
223948
|
+
reason_code: "startup_timeout"
|
|
223715
223949
|
});
|
|
223716
|
-
console.error(`Daemon
|
|
223950
|
+
console.error(`Daemon worker (PID ${result.pid}) did not become ready in time.`);
|
|
223717
223951
|
await exitDaemonCommand(1);
|
|
223718
223952
|
return;
|
|
223719
223953
|
}
|
|
@@ -223775,9 +224009,9 @@ ${result.stdout ?? ""}`;
|
|
|
223775
224009
|
console.log(` Stage: ${runtimeState.startupStage}`);
|
|
223776
224010
|
}
|
|
223777
224011
|
if (runtimeBelongsToDaemon && runtimeState.connectivity) {
|
|
223778
|
-
console.log(` Connectivity: ${runtimeState.connectivity}`);
|
|
224012
|
+
console.log(` Connectivity: ${formatDaemonConnectivityStatus(runtimeState.connectivity)}`);
|
|
223779
224013
|
}
|
|
223780
|
-
if (runtimeBelongsToDaemon) {
|
|
224014
|
+
if (runtimeBelongsToDaemon && getCliPlatformKind() === "cloud") {
|
|
223781
224015
|
for (const line3 of formatDaemonBackendStatus(runtimeState)) {
|
|
223782
224016
|
console.log(line3);
|
|
223783
224017
|
}
|
|
@@ -223910,18 +224144,18 @@ ${result.stdout ?? ""}`;
|
|
|
223910
224144
|
await exitDaemonCommand(1);
|
|
223911
224145
|
return;
|
|
223912
224146
|
}
|
|
223913
|
-
if (startResult.status === "
|
|
223914
|
-
console.error(`Daemon runner
|
|
224147
|
+
if (startResult.status === "startup_error") {
|
|
224148
|
+
console.error(`Daemon startup (runner PID ${startResult.pid}) failed: ${startResult.message}`);
|
|
223915
224149
|
await exitDaemonCommand(1);
|
|
223916
224150
|
return;
|
|
223917
224151
|
}
|
|
223918
224152
|
if (startResult.status === "runner_exited") {
|
|
223919
|
-
console.error(`Daemon runner (PID ${startResult.pid}) exited before
|
|
224153
|
+
console.error(`Daemon runner (PID ${startResult.pid}) exited before its worker became ready.`);
|
|
223920
224154
|
await exitDaemonCommand(1);
|
|
223921
224155
|
return;
|
|
223922
224156
|
}
|
|
223923
|
-
if (startResult.status === "
|
|
223924
|
-
console.error(`Daemon
|
|
224157
|
+
if (startResult.status === "startup_timeout") {
|
|
224158
|
+
console.error(`Daemon worker (PID ${startResult.pid}) did not become ready in time.`);
|
|
223925
224159
|
await exitDaemonCommand(1);
|
|
223926
224160
|
return;
|
|
223927
224161
|
}
|
|
@@ -223933,6 +224167,23 @@ ${result.stdout ?? ""}`;
|
|
|
223933
224167
|
await exitDaemonCommand(0);
|
|
223934
224168
|
return;
|
|
223935
224169
|
}));
|
|
224170
|
+
const MAX_STARTUP_ERROR_CHARS = 2e3;
|
|
224171
|
+
function isDaemonWorkerReady(state2) {
|
|
224172
|
+
return state2.runtime?.startupStage === "ready" && state2.runtime.phase !== "fatal";
|
|
224173
|
+
}
|
|
224174
|
+
function isRetryableDaemonWorkerStartupExit(result) {
|
|
224175
|
+
return result.code === EXIT_CODE_RETRYABLE_STARTUP;
|
|
224176
|
+
}
|
|
224177
|
+
function describeDaemonWorkerStartupFailure(result) {
|
|
224178
|
+
const output = (result.stderr.trim() || result.stdout.trim()).split("\0").join("");
|
|
224179
|
+
if (output) {
|
|
224180
|
+
return output.length <= MAX_STARTUP_ERROR_CHARS ? output : `\u2026${output.slice(-MAX_STARTUP_ERROR_CHARS)}`;
|
|
224181
|
+
}
|
|
224182
|
+
if (result.signal) {
|
|
224183
|
+
return `CLI worker exited from signal ${result.signal} before becoming ready`;
|
|
224184
|
+
}
|
|
224185
|
+
return `CLI worker exited with code ${result.code ?? "unknown"} before becoming ready`;
|
|
224186
|
+
}
|
|
223936
224187
|
function launchLodyStart(passthroughArgs, identity2) {
|
|
223937
224188
|
const bin = resolveLodyBin();
|
|
223938
224189
|
const args2 = [
|
|
@@ -224014,6 +224265,12 @@ ${result.stdout ?? ""}`;
|
|
|
224014
224265
|
instanceId: randomUUID(),
|
|
224015
224266
|
token: `${randomUUID()}${randomUUID()}`
|
|
224016
224267
|
};
|
|
224268
|
+
let launchOutcomePending = process.env[DAEMON_RUNNER_READY_FD_ENV] !== void 0;
|
|
224269
|
+
const reportLaunchOutcome = (outcome) => {
|
|
224270
|
+
if (!launchOutcomePending) return;
|
|
224271
|
+
launchOutcomePending = false;
|
|
224272
|
+
reportDaemonRunnerLaunchOutcome(outcome);
|
|
224273
|
+
};
|
|
224017
224274
|
let hostShutdownRequested = false;
|
|
224018
224275
|
let hostShutdownHandler = null;
|
|
224019
224276
|
const requestHostShutdown = () => {
|
|
@@ -224032,7 +224289,7 @@ ${result.stdout ?? ""}`;
|
|
|
224032
224289
|
if (initialLease.status === "occupied") {
|
|
224033
224290
|
const owner = initialLease.record ? `${initialLease.record.mode} process ${initialLease.record.pid}` : "another local CLI host";
|
|
224034
224291
|
logger2.error(`Cannot start daemon: ${owner} already owns the local agent runtime.`);
|
|
224035
|
-
|
|
224292
|
+
reportLaunchOutcome({
|
|
224036
224293
|
status: "occupied",
|
|
224037
224294
|
...initialLease.record ? {
|
|
224038
224295
|
ownerMode: initialLease.record.mode,
|
|
@@ -224051,18 +224308,13 @@ ${result.stdout ?? ""}`;
|
|
|
224051
224308
|
hostLease = null;
|
|
224052
224309
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
224053
224310
|
logger2.error(`Failed to claim daemon ownership: ${message}`);
|
|
224054
|
-
|
|
224311
|
+
reportLaunchOutcome({
|
|
224055
224312
|
status: "error",
|
|
224056
224313
|
message
|
|
224057
224314
|
});
|
|
224058
224315
|
await flushTelemetry();
|
|
224059
224316
|
process.exit(1);
|
|
224060
224317
|
}
|
|
224061
|
-
reportDaemonRunnerLaunchOutcome({
|
|
224062
|
-
status: "ready",
|
|
224063
|
-
pid: process.pid,
|
|
224064
|
-
instanceId: supervisorIdentity.instanceId
|
|
224065
|
-
});
|
|
224066
224318
|
logger2.info(`Daemon watchdog started (PID ${process.pid})`);
|
|
224067
224319
|
await normalizeCurrentProcessResourceProfile(logger2);
|
|
224068
224320
|
for (const diagnostic of getRuntimeDiagnostics(version$9)) {
|
|
@@ -224189,6 +224441,17 @@ ${result.stdout ?? ""}`;
|
|
|
224189
224441
|
}
|
|
224190
224442
|
},
|
|
224191
224443
|
decideExit: async (result, signal) => {
|
|
224444
|
+
if (launchOutcomePending && !isRetryableDaemonWorkerStartupExit(result)) {
|
|
224445
|
+
const message = describeDaemonWorkerStartupFailure(result);
|
|
224446
|
+
reportLaunchOutcome({
|
|
224447
|
+
status: "error",
|
|
224448
|
+
message
|
|
224449
|
+
});
|
|
224450
|
+
return {
|
|
224451
|
+
action: "fatal",
|
|
224452
|
+
message: `Initial daemon worker startup failed: ${message}`
|
|
224453
|
+
};
|
|
224454
|
+
}
|
|
224192
224455
|
if (result.code === 0) {
|
|
224193
224456
|
return {
|
|
224194
224457
|
action: "stop",
|
|
@@ -224256,6 +224519,13 @@ ${result.stdout ?? ""}`;
|
|
|
224256
224519
|
},
|
|
224257
224520
|
onStateChange: (state2) => {
|
|
224258
224521
|
reportSupervisorAnalytics(state2);
|
|
224522
|
+
if (launchOutcomePending && isDaemonWorkerReady(state2)) {
|
|
224523
|
+
reportLaunchOutcome({
|
|
224524
|
+
status: "ready",
|
|
224525
|
+
pid: process.pid,
|
|
224526
|
+
instanceId: supervisorIdentity.instanceId
|
|
224527
|
+
});
|
|
224528
|
+
}
|
|
224259
224529
|
if (state2.phase === "fatal") {
|
|
224260
224530
|
logger2.error(`Fatal: ${state2.message ?? "unknown"}`);
|
|
224261
224531
|
} else if (state2.message) {
|
|
@@ -240485,6 +240755,8 @@ ${result.stdout ?? ""}`;
|
|
|
240485
240755
|
const SESSION_CREATE_MANY_TOOL_NAME = "lody_session_create_many";
|
|
240486
240756
|
const SESSION_CHAT_MANY_TOOL_NAME = "lody_session_chat_many";
|
|
240487
240757
|
const SESSION_ARCHIVE_TOOL_NAME = "lody_session_archive";
|
|
240758
|
+
const SESSION_RENAME_TOOL_NAME = "lody_session_rename";
|
|
240759
|
+
const SESSION_RENAME_MANY_TOOL_NAME = "lody_session_rename_many";
|
|
240488
240760
|
const OPERATION_GET_TOOL_NAME = "lody_operation_get";
|
|
240489
240761
|
const OPERATION_CANCEL_TOOL_NAME = "lody_operation_cancel";
|
|
240490
240762
|
const TASK_LIST_TOOL_NAME = "lody_task_list";
|
|
@@ -240509,6 +240781,7 @@ ${result.stdout ?? ""}`;
|
|
|
240509
240781
|
const DEFAULT_MCP_SESSION_HISTORY_LIMIT = 10;
|
|
240510
240782
|
const MAX_MCP_SESSION_HISTORY_LIMIT = 50;
|
|
240511
240783
|
const MAX_MCP_SESSION_HISTORY_BYTES = 128 * 1024;
|
|
240784
|
+
const MAX_MCP_SESSION_TITLE_CHARS = 200;
|
|
240512
240785
|
const MAX_MCP_TASK_BODY_BYTES = 64 * 1024;
|
|
240513
240786
|
const MAX_MCP_TASK_LINKS = 50;
|
|
240514
240787
|
const MAX_MCP_TASK_EDIT_CHARS = 64e3;
|
|
@@ -240639,7 +240912,7 @@ ${result.stdout ?? ""}`;
|
|
|
240639
240912
|
resume: boolean().optional().describe("Set to true to resume an accepted Operation without resending its input."),
|
|
240640
240913
|
wait: literal$1(true).optional().describe("Wait for the assistant reply using the temporary legacy adapter."),
|
|
240641
240914
|
timeoutSeconds: number$4().int().positive().max(MAX_MCP_SESSION_WAIT_TIMEOUT_SECONDS).optional().describe("Legacy wait timeout in seconds, up to one hour."),
|
|
240642
|
-
useCurrentSessionAsParent: boolean().optional().describe("Create a child of the current Session; cannot be combined with workContext."),
|
|
240915
|
+
useCurrentSessionAsParent: boolean().optional().describe("Create a child of the current Session that reuses the exact same workspace directory; cannot be combined with workContext."),
|
|
240643
240916
|
workContext: SessionWorkContextInputSchema.optional().describe("Execution context for an independent Session; cannot be combined with useCurrentSessionAsParent=true.")
|
|
240644
240917
|
}).strict().superRefine((value, ctx) => {
|
|
240645
240918
|
const result = SessionCreateRuntimeInputSchema.safeParse(value);
|
|
@@ -240761,7 +241034,7 @@ ${result.stdout ?? ""}`;
|
|
|
240761
241034
|
]);
|
|
240762
241035
|
const SessionCreateBatchPublishedItemSchema = object$1({
|
|
240763
241036
|
...SessionCreateBatchItemShape,
|
|
240764
|
-
useCurrentSessionAsParent: boolean().optional().describe("Create a child of the current Session; cannot be combined with workContext."),
|
|
241037
|
+
useCurrentSessionAsParent: boolean().optional().describe("Create a child of the current Session that reuses the exact same workspace directory; cannot be combined with workContext."),
|
|
240765
241038
|
workContext: SessionWorkContextInputSchema.optional().describe("Execution context for an independent Session; cannot be combined with useCurrentSessionAsParent=true.")
|
|
240766
241039
|
}).strict();
|
|
240767
241040
|
const SessionCreateManyToolInputSchema = object$1({
|
|
@@ -240793,6 +241066,18 @@ ${result.stdout ?? ""}`;
|
|
|
240793
241066
|
const SessionArchiveToolInputSchema = object$1({
|
|
240794
241067
|
sessionId: string$1().trim().min(1)
|
|
240795
241068
|
}).strict();
|
|
241069
|
+
const SessionTitleToolInputSchema = string$1().trim().min(1).max(MAX_MCP_SESSION_TITLE_CHARS).describe(`New session title, up to ${MAX_MCP_SESSION_TITLE_CHARS} characters.`);
|
|
241070
|
+
const SessionRenameToolInputSchema = object$1({
|
|
241071
|
+
sessionId: string$1().trim().min(1).optional().describe("Target session id, or current. Defaults to current."),
|
|
241072
|
+
title: SessionTitleToolInputSchema
|
|
241073
|
+
}).strict();
|
|
241074
|
+
const SessionRenameManyItemSchema = object$1({
|
|
241075
|
+
sessionId: string$1().trim().min(1).describe("Target session id, or current."),
|
|
241076
|
+
title: SessionTitleToolInputSchema
|
|
241077
|
+
}).strict();
|
|
241078
|
+
const SessionRenameManyToolInputSchema = object$1({
|
|
241079
|
+
items: array$2(SessionRenameManyItemSchema).min(1).max(MAX_MCP_COMMAND_BATCH_SIZE).refine((items2) => new Set(items2.map((item) => item.sessionId)).size === items2.length, "sessionId values must be unique")
|
|
241080
|
+
}).strict();
|
|
240796
241081
|
const SessionStatusManyToolInputSchema = object$1({
|
|
240797
241082
|
sessionIds: array$2(string$1().trim().min(1)).max(1e3).refine((items2) => new Set(items2).size === items2.length, "sessionIds must be unique")
|
|
240798
241083
|
}).strict();
|
|
@@ -240907,30 +241192,22 @@ ${result.stdout ?? ""}`;
|
|
|
240907
241192
|
} : {}
|
|
240908
241193
|
});
|
|
240909
241194
|
const jsonTextResult = (value, isError2 = false) => textResult(JSON.stringify(value, null, 2), isError2);
|
|
240910
|
-
const
|
|
241195
|
+
const normalizeMcpError = (error2) => {
|
|
240911
241196
|
if (error2 instanceof LodyOperationStoreError) {
|
|
240912
|
-
return
|
|
240913
|
-
ok: false,
|
|
240914
|
-
error: error2.toLodyError()
|
|
240915
|
-
}, true);
|
|
241197
|
+
return error2.toLodyError();
|
|
240916
241198
|
}
|
|
240917
241199
|
if (error2 instanceof LocalDaemonAvailabilityError) {
|
|
240918
|
-
return
|
|
240919
|
-
ok: false,
|
|
240920
|
-
error: error2.toLodyError()
|
|
240921
|
-
}, true);
|
|
241200
|
+
return error2.toLodyError();
|
|
240922
241201
|
}
|
|
240923
241202
|
if (error2 instanceof WorkspaceSyncUnavailableError) {
|
|
240924
|
-
return
|
|
240925
|
-
ok: false,
|
|
240926
|
-
error: error2.toLodyError()
|
|
240927
|
-
}, true);
|
|
241203
|
+
return error2.toLodyError();
|
|
240928
241204
|
}
|
|
240929
|
-
return
|
|
240930
|
-
ok: false,
|
|
240931
|
-
error: makeLodyError("INTERNAL_ERROR", formatMcpErrorMessage(error2), false)
|
|
240932
|
-
}, true);
|
|
241205
|
+
return makeLodyError("INTERNAL_ERROR", formatMcpErrorMessage(error2), false);
|
|
240933
241206
|
};
|
|
241207
|
+
const mcpErrorResult = (error2) => jsonTextResult({
|
|
241208
|
+
ok: false,
|
|
241209
|
+
error: normalizeMcpError(error2)
|
|
241210
|
+
}, true);
|
|
240934
241211
|
const postSessionControl = async (request2, localControlSocketPath, timeoutMs = SESSION_CONTROL_TIMEOUT_MS) => {
|
|
240935
241212
|
const responses = await runPromise(makeLocalControlClientAuto({
|
|
240936
241213
|
socketPath: localControlSocketPath
|
|
@@ -242264,6 +242541,60 @@ ${prompt2}` : prompt2;
|
|
|
242264
242541
|
}, worker));
|
|
242265
242542
|
return output;
|
|
242266
242543
|
};
|
|
242544
|
+
const resolveSessionRenameItems = (items2, ctx) => {
|
|
242545
|
+
assertBatchSize(items2.length, MAX_MCP_COMMAND_BATCH_SIZE);
|
|
242546
|
+
const resolved = items2.map((item) => ({
|
|
242547
|
+
sessionId: resolveMcpSessionId(item.sessionId, ctx),
|
|
242548
|
+
title: item.title
|
|
242549
|
+
}));
|
|
242550
|
+
if (new Set(resolved.map((item) => item.sessionId)).size !== resolved.length) {
|
|
242551
|
+
throw new LodyOperationStoreError("DUPLICATE_SESSION", "A session may appear only once in a rename batch.", false);
|
|
242552
|
+
}
|
|
242553
|
+
return resolved;
|
|
242554
|
+
};
|
|
242555
|
+
const applySessionRenameItems = async (items2, rename2) => await mapWithConcurrency(items2, 5, async (item) => {
|
|
242556
|
+
try {
|
|
242557
|
+
await rename2(item);
|
|
242558
|
+
return {
|
|
242559
|
+
sessionId: item.sessionId,
|
|
242560
|
+
ok: true,
|
|
242561
|
+
title: item.title
|
|
242562
|
+
};
|
|
242563
|
+
} catch (error2) {
|
|
242564
|
+
return {
|
|
242565
|
+
sessionId: item.sessionId,
|
|
242566
|
+
ok: false,
|
|
242567
|
+
error: normalizeMcpError(error2)
|
|
242568
|
+
};
|
|
242569
|
+
}
|
|
242570
|
+
});
|
|
242571
|
+
const persistSessionRenameItems = async (manager, items2, syncReason) => {
|
|
242572
|
+
const results = await applySessionRenameItems(items2, async (item) => {
|
|
242573
|
+
const session2 = await readCurrentSessionMeta(manager, item.sessionId);
|
|
242574
|
+
if (!session2) {
|
|
242575
|
+
throw new LodyOperationStoreError("SESSION_NOT_FOUND", `Session not found: ${item.sessionId}`, false);
|
|
242576
|
+
}
|
|
242577
|
+
await manager.repo.upsertDocMeta(getSessionRoomId(item.sessionId), {
|
|
242578
|
+
title: item.title,
|
|
242579
|
+
titleSource: "user"
|
|
242580
|
+
});
|
|
242581
|
+
});
|
|
242582
|
+
if (results.some((item) => item.ok)) {
|
|
242583
|
+
await ensureWorkspaceMetaSynced(manager, syncReason);
|
|
242584
|
+
}
|
|
242585
|
+
return results;
|
|
242586
|
+
};
|
|
242587
|
+
const renameSessionItems = async (input2) => {
|
|
242588
|
+
const ctx = getSessionContext();
|
|
242589
|
+
const resolved = resolveSessionRenameItems(input2.items, ctx);
|
|
242590
|
+
const auth = getAuthContextOrThrow$1("mcp");
|
|
242591
|
+
const workspace = await resolveWorkspaceOrThrow$1(auth, getMcpWorkspaceId(ctx));
|
|
242592
|
+
return await withWorkspaceManager$1(auth, workspace, "mcp", async (manager) => {
|
|
242593
|
+
const reason = `mcp.session_rename_many:${ctx.sessionId}`;
|
|
242594
|
+
await syncWorkspaceMetaForRead(manager, reason);
|
|
242595
|
+
return await persistSessionRenameItems(manager, resolved, reason);
|
|
242596
|
+
});
|
|
242597
|
+
};
|
|
242267
242598
|
const buildOperationTargetCancelArgs = (workspaceId, item) => [
|
|
242268
242599
|
"session",
|
|
242269
242600
|
"cancel",
|
|
@@ -243244,6 +243575,41 @@ ${lines2.join("\n")}` : ""}${suffix}`);
|
|
|
243244
243575
|
return mcpErrorResult(error2);
|
|
243245
243576
|
}
|
|
243246
243577
|
});
|
|
243578
|
+
server.registerTool(SESSION_RENAME_TOOL_NAME, {
|
|
243579
|
+
title: "Rename a Lody session",
|
|
243580
|
+
description: "Set the title of one Session. Omit sessionId (or pass current) to rename the current Session. The durable rename is treated as a user-directed title and is not replaced by later automatic title generation.",
|
|
243581
|
+
inputSchema: SessionRenameToolInputSchema
|
|
243582
|
+
}, async (args2) => {
|
|
243583
|
+
try {
|
|
243584
|
+
const [item] = await renameSessionItems({
|
|
243585
|
+
items: [
|
|
243586
|
+
{
|
|
243587
|
+
sessionId: args2.sessionId ?? "current",
|
|
243588
|
+
title: args2.title
|
|
243589
|
+
}
|
|
243590
|
+
]
|
|
243591
|
+
});
|
|
243592
|
+
if (!item) {
|
|
243593
|
+
throw new Error("Session rename returned no result.");
|
|
243594
|
+
}
|
|
243595
|
+
return jsonTextResult(item, item.ok === false);
|
|
243596
|
+
} catch (error2) {
|
|
243597
|
+
return mcpErrorResult(error2);
|
|
243598
|
+
}
|
|
243599
|
+
});
|
|
243600
|
+
server.registerTool(SESSION_RENAME_MANY_TOOL_NAME, {
|
|
243601
|
+
title: "Rename multiple Lody sessions",
|
|
243602
|
+
description: "Set titles for 1-20 Sessions. Session ids must be unique. Results preserve input order and failures are isolated per item; successful renames remain applied when another item fails.",
|
|
243603
|
+
inputSchema: SessionRenameManyToolInputSchema
|
|
243604
|
+
}, async (args2) => {
|
|
243605
|
+
try {
|
|
243606
|
+
return jsonTextResult({
|
|
243607
|
+
items: await renameSessionItems(args2)
|
|
243608
|
+
});
|
|
243609
|
+
} catch (error2) {
|
|
243610
|
+
return mcpErrorResult(error2);
|
|
243611
|
+
}
|
|
243612
|
+
});
|
|
243247
243613
|
server.registerTool(SESSION_ARCHIVE_TOOL_NAME, {
|
|
243248
243614
|
title: "Archive a Lody session",
|
|
243249
243615
|
description: "Idempotently archive a Session. Archiving a parent cascades to child Sessions; pending Operation Deliveries remain pending until a human restores the Session.",
|