chatroom-cli 1.36.1 → 1.37.1
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/index.js +274 -40
- package/dist/index.js.map +10 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13426,6 +13426,10 @@ function startSessionEventForwarder(client4, options) {
|
|
|
13426
13426
|
const errorTarget = options.errorTarget ?? process.stderr;
|
|
13427
13427
|
let cancelled = false;
|
|
13428
13428
|
let doneResolve;
|
|
13429
|
+
let sessionStarted = false;
|
|
13430
|
+
const seenToolStates = new Map;
|
|
13431
|
+
let lastStatus;
|
|
13432
|
+
const agentEndCallbacks = [];
|
|
13429
13433
|
const donePromise = new Promise((resolve) => {
|
|
13430
13434
|
doneResolve = resolve;
|
|
13431
13435
|
});
|
|
@@ -13445,31 +13449,76 @@ function startSessionEventForwarder(client4, options) {
|
|
|
13445
13449
|
const eventSession = eventSessionId(event);
|
|
13446
13450
|
if (eventSession && eventSession !== options.sessionId)
|
|
13447
13451
|
continue;
|
|
13448
|
-
if (eventSession === undefined && event.type !== "session.idle" && event.type !== "session.compacted" && event.type !== "session.error" && event.type !== "session.status" && event.type !== "file.edited")
|
|
13452
|
+
if (eventSession === undefined && event.type !== "message.part.updated" && event.type !== "session.idle" && event.type !== "session.compacted" && event.type !== "session.error" && event.type !== "session.status" && event.type !== "file.edited")
|
|
13449
13453
|
continue;
|
|
13454
|
+
if (!sessionStarted) {
|
|
13455
|
+
sessionStarted = true;
|
|
13456
|
+
target.write(formatLogLine(options, "session] Started", `role: ${options.role}`) + `
|
|
13457
|
+
`);
|
|
13458
|
+
}
|
|
13450
13459
|
switch (event.type) {
|
|
13451
13460
|
case "message.part.updated": {
|
|
13452
13461
|
const props = event.properties;
|
|
13453
13462
|
const part = props?.part;
|
|
13454
|
-
if (part?.type === "text"
|
|
13455
|
-
|
|
13463
|
+
if (part?.type === "text") {
|
|
13464
|
+
const chunk = props?.delta !== undefined && props.delta !== "" ? props.delta : part.text;
|
|
13465
|
+
if (chunk) {
|
|
13466
|
+
target.write(formatLogLine(options, "text", chunk) + `
|
|
13467
|
+
`);
|
|
13468
|
+
}
|
|
13469
|
+
} else if (part?.type === "reasoning") {
|
|
13470
|
+
const chunk = props?.delta !== undefined && props.delta !== "" ? props.delta : part.text;
|
|
13471
|
+
if (chunk) {
|
|
13472
|
+
target.write(formatLogLine(options, "thinking", chunk) + `
|
|
13456
13473
|
`);
|
|
13474
|
+
}
|
|
13457
13475
|
} else if (part?.type === "tool" && part.tool) {
|
|
13458
|
-
|
|
13459
|
-
|
|
13476
|
+
let appendInput = function(base, input, tool) {
|
|
13477
|
+
if (!input || typeof input === "object" && Object.keys(input).length === 0) {
|
|
13478
|
+
return base;
|
|
13479
|
+
}
|
|
13480
|
+
const inp = input;
|
|
13481
|
+
if (tool === "bash" && typeof inp.command === "string") {
|
|
13482
|
+
return `${base}: ${inp.command}`;
|
|
13483
|
+
}
|
|
13484
|
+
const inputStr = typeof inp === "string" ? inp : JSON.stringify(inp);
|
|
13485
|
+
return `${base}: ${inputStr}`;
|
|
13486
|
+
};
|
|
13487
|
+
const state = typeof props?.state === "string" ? props.state : typeof part.state?.status === "string" ? part.state.status : "started";
|
|
13488
|
+
let payload = state;
|
|
13489
|
+
if (part.state?.input) {
|
|
13490
|
+
payload = appendInput(payload, part.state.input, part.tool);
|
|
13491
|
+
}
|
|
13492
|
+
if (state === "completed" && part.state?.time?.start !== undefined && part.state?.time?.end !== undefined) {
|
|
13493
|
+
const duration = ((part.state.time.end - part.state.time.start) / 1000).toFixed(1);
|
|
13494
|
+
payload = appendInput(`${state} (${duration}s)`, part.state.input, part.tool);
|
|
13495
|
+
}
|
|
13496
|
+
const callID = part.callID ?? "unknown";
|
|
13497
|
+
const seenKey = `${callID}:${state}`;
|
|
13498
|
+
if (!seenToolStates.has(seenKey)) {
|
|
13499
|
+
seenToolStates.set(seenKey, payload);
|
|
13500
|
+
target.write(formatLogLine(options, "tool: " + part.tool, payload) + `
|
|
13460
13501
|
`);
|
|
13502
|
+
}
|
|
13503
|
+
if (state === "completed" || state === "error") {
|
|
13504
|
+
seenToolStates.delete(seenKey);
|
|
13505
|
+
}
|
|
13461
13506
|
}
|
|
13462
13507
|
break;
|
|
13463
13508
|
}
|
|
13464
13509
|
case "file.edited": {
|
|
13465
13510
|
const props = event.properties;
|
|
13466
|
-
|
|
13511
|
+
const kind = props?.action ?? props?.kind;
|
|
13512
|
+
const filePayload = kind ? `${props?.file} (${kind})` : props?.file;
|
|
13513
|
+
target.write(formatLogLine(options, "file", filePayload) + `
|
|
13467
13514
|
`);
|
|
13468
13515
|
break;
|
|
13469
13516
|
}
|
|
13470
13517
|
case "session.idle": {
|
|
13471
13518
|
target.write(formatLogLine(options, "agent_end") + `
|
|
13472
13519
|
`);
|
|
13520
|
+
for (const cb of agentEndCallbacks)
|
|
13521
|
+
cb();
|
|
13473
13522
|
break;
|
|
13474
13523
|
}
|
|
13475
13524
|
case "session.compacted": {
|
|
@@ -13479,15 +13528,25 @@ function startSessionEventForwarder(client4, options) {
|
|
|
13479
13528
|
}
|
|
13480
13529
|
case "session.status": {
|
|
13481
13530
|
const props = event.properties;
|
|
13482
|
-
|
|
13531
|
+
const currentStatus = props?.status?.type;
|
|
13532
|
+
if (currentStatus !== lastStatus) {
|
|
13533
|
+
lastStatus = currentStatus;
|
|
13534
|
+
target.write(formatLogLine(options, "status", currentStatus) + `
|
|
13483
13535
|
`);
|
|
13536
|
+
}
|
|
13484
13537
|
break;
|
|
13485
13538
|
}
|
|
13486
13539
|
case "session.error": {
|
|
13487
13540
|
const props = event.properties;
|
|
13488
13541
|
const err = props?.error;
|
|
13489
13542
|
const errMsg = err?.name ? `${err.name}${err?.data?.message ? ": " + err.data.message : ""}` : String(err ?? "unknown");
|
|
13490
|
-
|
|
13543
|
+
let payload = errMsg;
|
|
13544
|
+
if (props?.tool) {
|
|
13545
|
+
payload += ` [tool: ${props.tool}]`;
|
|
13546
|
+
} else if (props?.command) {
|
|
13547
|
+
payload += ` [command: ${props.command}]`;
|
|
13548
|
+
}
|
|
13549
|
+
errorTarget.write(formatLogLine(options, "error", payload) + `
|
|
13491
13550
|
`);
|
|
13492
13551
|
break;
|
|
13493
13552
|
}
|
|
@@ -13508,7 +13567,10 @@ function startSessionEventForwarder(client4, options) {
|
|
|
13508
13567
|
stop: () => {
|
|
13509
13568
|
cancelled = true;
|
|
13510
13569
|
},
|
|
13511
|
-
done: donePromise
|
|
13570
|
+
done: donePromise,
|
|
13571
|
+
onAgentEnd: (cb) => {
|
|
13572
|
+
agentEndCallbacks.push(cb);
|
|
13573
|
+
}
|
|
13512
13574
|
};
|
|
13513
13575
|
}
|
|
13514
13576
|
|
|
@@ -13629,7 +13691,12 @@ var init_opencode_sdk_agent_service = __esm(() => {
|
|
|
13629
13691
|
agent: selected.name,
|
|
13630
13692
|
...composedSystem ? { system: composedSystem } : {},
|
|
13631
13693
|
parts: [{ type: "text", text: prompt }],
|
|
13632
|
-
...modelParts ? { model: modelParts } : {}
|
|
13694
|
+
...modelParts ? { model: modelParts } : {},
|
|
13695
|
+
tools: {
|
|
13696
|
+
task: false,
|
|
13697
|
+
question: false,
|
|
13698
|
+
external_directory: false
|
|
13699
|
+
}
|
|
13633
13700
|
}
|
|
13634
13701
|
}), PROMPT_ASYNC_TIMEOUT_MS, "session.promptAsync");
|
|
13635
13702
|
} catch (err) {
|
|
@@ -13688,6 +13755,9 @@ var init_opencode_sdk_agent_service = __esm(() => {
|
|
|
13688
13755
|
},
|
|
13689
13756
|
onOutput: (cb) => {
|
|
13690
13757
|
outputCallbacks.push(cb);
|
|
13758
|
+
},
|
|
13759
|
+
onAgentEnd: (cb) => {
|
|
13760
|
+
forwarder?.onAgentEnd(cb);
|
|
13691
13761
|
}
|
|
13692
13762
|
};
|
|
13693
13763
|
}
|
|
@@ -58879,6 +58949,13 @@ function handlePing() {
|
|
|
58879
58949
|
// src/commands/machine/daemon-start/handlers/command-runner.ts
|
|
58880
58950
|
import { spawn as spawn3 } from "node:child_process";
|
|
58881
58951
|
import { access as access3 } from "node:fs/promises";
|
|
58952
|
+
function evictStalePendingStops() {
|
|
58953
|
+
const evictBefore = Date.now() - PENDING_STOP_TTL_MS;
|
|
58954
|
+
for (const [runId, ts] of pendingStops) {
|
|
58955
|
+
if (ts < evictBefore)
|
|
58956
|
+
pendingStops.delete(runId);
|
|
58957
|
+
}
|
|
58958
|
+
}
|
|
58882
58959
|
async function reportRunFailed(ctx, runId, reason) {
|
|
58883
58960
|
try {
|
|
58884
58961
|
await ctx.deps.backend.mutation(api.commands.updateRunStatus, {
|
|
@@ -58923,6 +59000,21 @@ async function onCommandRun(ctx, event) {
|
|
|
58923
59000
|
console.log(`[${formatTimestamp()}] ⚠️ Command already running: ${runIdStr}`);
|
|
58924
59001
|
return;
|
|
58925
59002
|
}
|
|
59003
|
+
if (pendingStops.has(runIdStr)) {
|
|
59004
|
+
pendingStops.delete(runIdStr);
|
|
59005
|
+
console.log(`[${formatTimestamp()}] ⏭️ Skipping command run due to pending stop: ${commandName} (${runIdStr})`);
|
|
59006
|
+
try {
|
|
59007
|
+
await ctx.deps.backend.mutation(api.commands.updateRunStatus, {
|
|
59008
|
+
sessionId: ctx.sessionId,
|
|
59009
|
+
machineId: ctx.machineId,
|
|
59010
|
+
runId,
|
|
59011
|
+
status: "stopped"
|
|
59012
|
+
});
|
|
59013
|
+
} catch (err) {
|
|
59014
|
+
console.warn(`[${formatTimestamp()}] ⚠️ Failed to update status to stopped for pending-stop skip: ${getErrorMessage(err)}`);
|
|
59015
|
+
}
|
|
59016
|
+
return;
|
|
59017
|
+
}
|
|
58926
59018
|
console.log(`[${formatTimestamp()}] \uD83D\uDE80 Running command: ${commandName} → ${script}`);
|
|
58927
59019
|
if (!workingDir.startsWith("/")) {
|
|
58928
59020
|
console.error(`[${formatTimestamp()}] ❌ Rejected command: workingDir is not absolute: ${workingDir}`);
|
|
@@ -58942,6 +59034,34 @@ async function onCommandRun(ctx, event) {
|
|
|
58942
59034
|
stdio: ["ignore", "pipe", "pipe"],
|
|
58943
59035
|
detached: true
|
|
58944
59036
|
});
|
|
59037
|
+
const timeoutTimer = setTimeout(() => {
|
|
59038
|
+
console.log(`[${formatTimestamp()}] ⏰ Command timed out after ${DEFAULT_COMMAND_TIMEOUT_MS / 60000} minutes: ${commandName} (runId: ${runIdStr})`);
|
|
59039
|
+
const pid = child.pid;
|
|
59040
|
+
if (pid) {
|
|
59041
|
+
try {
|
|
59042
|
+
process.kill(-pid, "SIGTERM");
|
|
59043
|
+
} catch {
|
|
59044
|
+
child.kill("SIGTERM");
|
|
59045
|
+
}
|
|
59046
|
+
} else {
|
|
59047
|
+
child.kill("SIGTERM");
|
|
59048
|
+
}
|
|
59049
|
+
setTimeout(() => {
|
|
59050
|
+
if (!runningProcesses.has(runIdStr))
|
|
59051
|
+
return;
|
|
59052
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDD2A Force-killing timed-out process: ${runIdStr}`);
|
|
59053
|
+
if (pid) {
|
|
59054
|
+
try {
|
|
59055
|
+
process.kill(-pid, "SIGKILL");
|
|
59056
|
+
} catch {
|
|
59057
|
+
child.kill("SIGKILL");
|
|
59058
|
+
}
|
|
59059
|
+
} else {
|
|
59060
|
+
child.kill("SIGKILL");
|
|
59061
|
+
}
|
|
59062
|
+
}, FORCE_KILL_DELAY_MS);
|
|
59063
|
+
}, DEFAULT_COMMAND_TIMEOUT_MS);
|
|
59064
|
+
timeoutTimer.unref?.();
|
|
58945
59065
|
const tracked = {
|
|
58946
59066
|
process: child,
|
|
58947
59067
|
runId: runIdStr,
|
|
@@ -58949,7 +59069,8 @@ async function onCommandRun(ctx, event) {
|
|
|
58949
59069
|
chunkIndex: 0,
|
|
58950
59070
|
flushTimer: setInterval(() => {
|
|
58951
59071
|
flushOutput(ctx, tracked).catch(() => {});
|
|
58952
|
-
}, OUTPUT_FLUSH_INTERVAL_MS)
|
|
59072
|
+
}, OUTPUT_FLUSH_INTERVAL_MS),
|
|
59073
|
+
timeoutTimer
|
|
58953
59074
|
};
|
|
58954
59075
|
tracked.flushTimer.unref?.();
|
|
58955
59076
|
runningProcesses.set(runIdStr, tracked);
|
|
@@ -58974,6 +59095,8 @@ async function onCommandRun(ctx, event) {
|
|
|
58974
59095
|
console.log(`[${formatTimestamp()}] \uD83C\uDFC1 Command exited: ${commandName} (code=${code2}, signal=${signal})`);
|
|
58975
59096
|
await flushOutput(ctx, tracked).catch(() => {});
|
|
58976
59097
|
clearInterval(tracked.flushTimer);
|
|
59098
|
+
if (tracked.timeoutTimer)
|
|
59099
|
+
clearTimeout(tracked.timeoutTimer);
|
|
58977
59100
|
runningProcesses.delete(runIdStr);
|
|
58978
59101
|
const status = code2 === 0 ? "completed" : signal ? "stopped" : "failed";
|
|
58979
59102
|
try {
|
|
@@ -58991,6 +59114,8 @@ async function onCommandRun(ctx, event) {
|
|
|
58991
59114
|
child.on("error", async (err) => {
|
|
58992
59115
|
console.error(`[${formatTimestamp()}] ❌ Command spawn failed: ${commandName}: ${err.message}`);
|
|
58993
59116
|
clearInterval(tracked.flushTimer);
|
|
59117
|
+
if (tracked.timeoutTimer)
|
|
59118
|
+
clearTimeout(tracked.timeoutTimer);
|
|
58994
59119
|
runningProcesses.delete(runIdStr);
|
|
58995
59120
|
try {
|
|
58996
59121
|
await ctx.deps.backend.mutation(api.commands.updateRunStatus, {
|
|
@@ -59009,6 +59134,8 @@ async function onCommandStop(ctx, event) {
|
|
|
59009
59134
|
const tracked = runningProcesses.get(runIdStr);
|
|
59010
59135
|
if (!tracked) {
|
|
59011
59136
|
console.log(`[${formatTimestamp()}] ⚠️ No running process found for run: ${runIdStr}`);
|
|
59137
|
+
pendingStops.set(runIdStr, Date.now());
|
|
59138
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCDD Registered pending stop for run: ${runIdStr}`);
|
|
59012
59139
|
try {
|
|
59013
59140
|
await ctx.deps.backend.mutation(api.commands.updateRunStatus, {
|
|
59014
59141
|
sessionId: ctx.sessionId,
|
|
@@ -59018,11 +59145,16 @@ async function onCommandStop(ctx, event) {
|
|
|
59018
59145
|
});
|
|
59019
59146
|
console.log(`[${formatTimestamp()}] \uD83D\uDCDD Marked orphaned run as stopped: ${runIdStr}`);
|
|
59020
59147
|
} catch (err) {
|
|
59021
|
-
console.warn(`[${formatTimestamp()}] ⚠️ Failed to mark orphaned run as stopped: ${getErrorMessage(err)}`);
|
|
59148
|
+
console.warn(`[${formatTimestamp()}] ⚠️ Failed to mark orphaned run as stopped (will retry): ${getErrorMessage(err)}`);
|
|
59149
|
+
throw err;
|
|
59022
59150
|
}
|
|
59023
59151
|
return;
|
|
59024
59152
|
}
|
|
59025
59153
|
console.log(`[${formatTimestamp()}] \uD83D\uDED1 Stopping command run: ${runIdStr}`);
|
|
59154
|
+
if (tracked.timeoutTimer) {
|
|
59155
|
+
clearTimeout(tracked.timeoutTimer);
|
|
59156
|
+
tracked.timeoutTimer = null;
|
|
59157
|
+
}
|
|
59026
59158
|
const pid = tracked.process.pid;
|
|
59027
59159
|
if (pid) {
|
|
59028
59160
|
try {
|
|
@@ -59034,7 +59166,7 @@ async function onCommandStop(ctx, event) {
|
|
|
59034
59166
|
tracked.process.kill("SIGTERM");
|
|
59035
59167
|
}
|
|
59036
59168
|
setTimeout(() => {
|
|
59037
|
-
if (
|
|
59169
|
+
if (!runningProcesses.has(runIdStr))
|
|
59038
59170
|
return;
|
|
59039
59171
|
console.log(`[${formatTimestamp()}] \uD83D\uDD2A Force-killing process: ${runIdStr}`);
|
|
59040
59172
|
if (pid) {
|
|
@@ -59046,14 +59178,55 @@ async function onCommandStop(ctx, event) {
|
|
|
59046
59178
|
} else {
|
|
59047
59179
|
tracked.process.kill("SIGKILL");
|
|
59048
59180
|
}
|
|
59049
|
-
},
|
|
59181
|
+
}, FORCE_KILL_DELAY_MS);
|
|
59050
59182
|
}
|
|
59051
|
-
|
|
59183
|
+
async function shutdownAllCommands(ctx) {
|
|
59184
|
+
if (runningProcesses.size === 0)
|
|
59185
|
+
return;
|
|
59186
|
+
console.log(`[${formatTimestamp()}] Shutting down ${runningProcesses.size} running command(s)...`);
|
|
59187
|
+
for (const [, tracked] of runningProcesses) {
|
|
59188
|
+
clearInterval(tracked.flushTimer);
|
|
59189
|
+
if (tracked.timeoutTimer)
|
|
59190
|
+
clearTimeout(tracked.timeoutTimer);
|
|
59191
|
+
await flushOutput(ctx, tracked).catch(() => {});
|
|
59192
|
+
const pid = tracked.process.pid;
|
|
59193
|
+
if (pid) {
|
|
59194
|
+
try {
|
|
59195
|
+
process.kill(-pid, "SIGTERM");
|
|
59196
|
+
} catch {
|
|
59197
|
+
tracked.process.kill("SIGTERM");
|
|
59198
|
+
}
|
|
59199
|
+
} else {
|
|
59200
|
+
tracked.process.kill("SIGTERM");
|
|
59201
|
+
}
|
|
59202
|
+
}
|
|
59203
|
+
await new Promise((resolve5) => {
|
|
59204
|
+
const t = setTimeout(resolve5, 3000);
|
|
59205
|
+
t.unref?.();
|
|
59206
|
+
});
|
|
59207
|
+
for (const [, tracked] of runningProcesses) {
|
|
59208
|
+
const pid = tracked.process.pid;
|
|
59209
|
+
if (pid) {
|
|
59210
|
+
try {
|
|
59211
|
+
process.kill(-pid, "SIGKILL");
|
|
59212
|
+
} catch {}
|
|
59213
|
+
} else {
|
|
59214
|
+
try {
|
|
59215
|
+
tracked.process.kill("SIGKILL");
|
|
59216
|
+
} catch {}
|
|
59217
|
+
}
|
|
59218
|
+
}
|
|
59219
|
+
runningProcesses.clear();
|
|
59220
|
+
console.log(`[${formatTimestamp()}] All commands stopped`);
|
|
59221
|
+
}
|
|
59222
|
+
var runningProcesses, pendingStops, PENDING_STOP_TTL_MS = 60000, OUTPUT_FLUSH_INTERVAL_MS = 3000, MAX_BUFFER_SIZE, DEFAULT_COMMAND_TIMEOUT_MS, FORCE_KILL_DELAY_MS = 5000;
|
|
59052
59223
|
var init_command_runner = __esm(() => {
|
|
59053
59224
|
init_api3();
|
|
59054
59225
|
init_convex_error();
|
|
59055
59226
|
runningProcesses = new Map;
|
|
59227
|
+
pendingStops = new Map;
|
|
59056
59228
|
MAX_BUFFER_SIZE = 100 * 1024;
|
|
59229
|
+
DEFAULT_COMMAND_TIMEOUT_MS = 30 * 60 * 1000;
|
|
59057
59230
|
});
|
|
59058
59231
|
|
|
59059
59232
|
// src/commands/machine/daemon-start/handlers/state-recovery.ts
|
|
@@ -59097,6 +59270,14 @@ var init_state_recovery = __esm(() => {
|
|
|
59097
59270
|
init_api3();
|
|
59098
59271
|
});
|
|
59099
59272
|
|
|
59273
|
+
// src/commands/machine/daemon-start/capabilities-snapshot.ts
|
|
59274
|
+
function harnessCapabilitiesFingerprint(harnesses, versions) {
|
|
59275
|
+
const h = [...harnesses].sort().join("\x01");
|
|
59276
|
+
const keys = Object.keys(versions).sort();
|
|
59277
|
+
const v3 = keys.map((k) => `${k}:${JSON.stringify(versions[k] ?? null)}`).join("\x02");
|
|
59278
|
+
return `${h}::${v3}`;
|
|
59279
|
+
}
|
|
59280
|
+
|
|
59100
59281
|
// src/infrastructure/local-api/routes/identity.ts
|
|
59101
59282
|
async function handleIdentity(_req, ctx) {
|
|
59102
59283
|
const identity = {
|
|
@@ -60294,6 +60475,17 @@ async function recoverState(ctx) {
|
|
|
60294
60475
|
} catch (e) {
|
|
60295
60476
|
console.log(` ⚠️ Failed to clear stale PIDs: ${getErrorMessage(e)}`);
|
|
60296
60477
|
}
|
|
60478
|
+
try {
|
|
60479
|
+
const runResult = await ctx.deps.backend.mutation(api.commands.clearStaleCommandRuns, {
|
|
60480
|
+
sessionId: ctx.sessionId,
|
|
60481
|
+
machineId: ctx.machineId
|
|
60482
|
+
});
|
|
60483
|
+
if (runResult.clearedCount > 0) {
|
|
60484
|
+
console.log(` \uD83E\uDDF9 Cleared ${runResult.clearedCount} stale command run(s) from backend`);
|
|
60485
|
+
}
|
|
60486
|
+
} catch (e) {
|
|
60487
|
+
console.log(` ⚠️ Failed to clear stale command runs: ${getErrorMessage(e)}`);
|
|
60488
|
+
}
|
|
60297
60489
|
}
|
|
60298
60490
|
async function initDaemon() {
|
|
60299
60491
|
if (!acquireLock()) {
|
|
@@ -60344,6 +60536,7 @@ async function initDaemon() {
|
|
|
60344
60536
|
agentServices,
|
|
60345
60537
|
lastPushedGitState: new Map,
|
|
60346
60538
|
lastPushedModels: availableModels,
|
|
60539
|
+
lastPushedHarnessFingerprint: harnessCapabilitiesFingerprint(config3.availableHarnesses, config3.harnessVersions),
|
|
60347
60540
|
observedSyncEnabled: featureFlags.observedSyncEnabled ?? false
|
|
60348
60541
|
};
|
|
60349
60542
|
registerEventListeners(ctx);
|
|
@@ -60392,6 +60585,7 @@ var init_init2 = __esm(() => {
|
|
|
60392
60585
|
|
|
60393
60586
|
// src/events/lifecycle/on-daemon-shutdown.ts
|
|
60394
60587
|
async function onDaemonShutdown(ctx) {
|
|
60588
|
+
await shutdownAllCommands(ctx);
|
|
60395
60589
|
const activeAgents = ctx.deps.agentProcessManager.listActive();
|
|
60396
60590
|
if (activeAgents.length > 0) {
|
|
60397
60591
|
console.log(`[${formatTimestamp()}] Stopping ${activeAgents.length} agent(s)...`);
|
|
@@ -60420,6 +60614,7 @@ async function onDaemonShutdown(ctx) {
|
|
|
60420
60614
|
}
|
|
60421
60615
|
var init_on_daemon_shutdown = __esm(() => {
|
|
60422
60616
|
init_api3();
|
|
60617
|
+
init_command_runner();
|
|
60423
60618
|
});
|
|
60424
60619
|
|
|
60425
60620
|
// src/infrastructure/git/git-writer.ts
|
|
@@ -60611,15 +60806,18 @@ function formatModelMap(map) {
|
|
|
60611
60806
|
return Object.entries(map).map(([harness, models]) => `${harness}: ${models.join(", ")}`).join("; ");
|
|
60612
60807
|
}
|
|
60613
60808
|
async function refreshModels(ctx) {
|
|
60614
|
-
if (!ctx.config)
|
|
60615
|
-
return;
|
|
60809
|
+
if (!ctx.config) {
|
|
60810
|
+
return { kind: "noop" };
|
|
60811
|
+
}
|
|
60616
60812
|
const models = await discoverModels(ctx.agentServices);
|
|
60617
60813
|
const freshConfig = ensureMachineRegistered();
|
|
60618
60814
|
ctx.config.availableHarnesses = freshConfig.availableHarnesses;
|
|
60619
60815
|
ctx.config.harnessVersions = freshConfig.harnessVersions;
|
|
60620
|
-
const
|
|
60621
|
-
|
|
60622
|
-
|
|
60816
|
+
const modelDiff = diffModels(ctx.lastPushedModels, models);
|
|
60817
|
+
const nextHarnessFingerprint = harnessCapabilitiesFingerprint(ctx.config.availableHarnesses, ctx.config.harnessVersions);
|
|
60818
|
+
const harnessFingerprintChanged = ctx.lastPushedHarnessFingerprint !== null && nextHarnessFingerprint !== ctx.lastPushedHarnessFingerprint;
|
|
60819
|
+
if (!modelDiff.hasChanges && !harnessFingerprintChanged) {
|
|
60820
|
+
return { kind: "skipped_no_changes" };
|
|
60623
60821
|
}
|
|
60624
60822
|
const totalCount = Object.values(models).flat().length;
|
|
60625
60823
|
try {
|
|
@@ -60631,15 +60829,19 @@ async function refreshModels(ctx) {
|
|
|
60631
60829
|
availableModels: models
|
|
60632
60830
|
});
|
|
60633
60831
|
ctx.lastPushedModels = models;
|
|
60634
|
-
|
|
60635
|
-
|
|
60832
|
+
ctx.lastPushedHarnessFingerprint = nextHarnessFingerprint;
|
|
60833
|
+
if (Object.keys(modelDiff.added).length > 0) {
|
|
60834
|
+
console.log(`[${formatTimestamp()}] ➕ New models detected — ${formatModelMap(modelDiff.added)}`);
|
|
60636
60835
|
}
|
|
60637
|
-
if (Object.keys(
|
|
60638
|
-
console.log(`[${formatTimestamp()}] ➖ Models no longer available — ${formatModelMap(
|
|
60836
|
+
if (Object.keys(modelDiff.removed).length > 0) {
|
|
60837
|
+
console.log(`[${formatTimestamp()}] ➖ Models no longer available — ${formatModelMap(modelDiff.removed)}`);
|
|
60639
60838
|
}
|
|
60640
60839
|
console.log(`[${formatTimestamp()}] \uD83D\uDD04 Model refresh pushed: ${totalCount > 0 ? `${totalCount} models` : "none discovered"}`);
|
|
60840
|
+
return { kind: "pushed" };
|
|
60641
60841
|
} catch (error) {
|
|
60642
|
-
|
|
60842
|
+
const message = getErrorMessage(error);
|
|
60843
|
+
console.warn(`[${formatTimestamp()}] ⚠️ Model refresh failed: ${message}`);
|
|
60844
|
+
return { kind: "failed", message };
|
|
60643
60845
|
}
|
|
60644
60846
|
}
|
|
60645
60847
|
function evictStaleDedupEntries(tracker) {
|
|
@@ -60656,6 +60858,10 @@ function evictStaleDedupEntries(tracker) {
|
|
|
60656
60858
|
if (ts2 < evictBefore)
|
|
60657
60859
|
tracker.gitRefreshIds.delete(id);
|
|
60658
60860
|
}
|
|
60861
|
+
for (const [id, ts2] of tracker.capabilitiesRefreshIds) {
|
|
60862
|
+
if (ts2 < evictBefore)
|
|
60863
|
+
tracker.capabilitiesRefreshIds.delete(id);
|
|
60864
|
+
}
|
|
60659
60865
|
for (const [id, ts2] of tracker.localActionIds) {
|
|
60660
60866
|
if (ts2 < evictBefore)
|
|
60661
60867
|
tracker.localActionIds.delete(id);
|
|
@@ -60668,6 +60874,7 @@ function evictStaleDedupEntries(tracker) {
|
|
|
60668
60874
|
if (ts2 < evictBefore)
|
|
60669
60875
|
tracker.commandStopIds.delete(id);
|
|
60670
60876
|
}
|
|
60877
|
+
evictStalePendingStops();
|
|
60671
60878
|
}
|
|
60672
60879
|
async function dispatchCommandEvent(ctx, event, tracker) {
|
|
60673
60880
|
const eventId = event._id.toString();
|
|
@@ -60675,40 +60882,40 @@ async function dispatchCommandEvent(ctx, event, tracker) {
|
|
|
60675
60882
|
if (event.type === "agent.requestStart") {
|
|
60676
60883
|
if (tracker.commandIds.has(eventId))
|
|
60677
60884
|
return;
|
|
60678
|
-
tracker.commandIds.set(eventId, Date.now());
|
|
60679
60885
|
await onRequestStartAgent(ctx, event);
|
|
60886
|
+
tracker.commandIds.set(eventId, Date.now());
|
|
60680
60887
|
} else if (event.type === "agent.requestStop") {
|
|
60681
60888
|
if (tracker.commandIds.has(eventId))
|
|
60682
60889
|
return;
|
|
60683
|
-
tracker.commandIds.set(eventId, Date.now());
|
|
60684
60890
|
await onRequestStopAgent(ctx, event);
|
|
60891
|
+
tracker.commandIds.set(eventId, Date.now());
|
|
60685
60892
|
} else if (event.type === "daemon.ping") {
|
|
60686
60893
|
if (tracker.pingIds.has(eventId))
|
|
60687
60894
|
return;
|
|
60688
|
-
tracker.pingIds.set(eventId, Date.now());
|
|
60689
60895
|
handlePing();
|
|
60690
60896
|
await ctx.deps.backend.mutation(api.machines.ackPing, {
|
|
60691
60897
|
sessionId: ctx.sessionId,
|
|
60692
60898
|
machineId: ctx.machineId,
|
|
60693
60899
|
pingEventId: event._id
|
|
60694
60900
|
});
|
|
60901
|
+
tracker.pingIds.set(eventId, Date.now());
|
|
60695
60902
|
} else if (event.type === "daemon.gitRefresh") {
|
|
60696
60903
|
if (tracker.gitRefreshIds.has(eventId))
|
|
60697
60904
|
return;
|
|
60698
|
-
tracker.gitRefreshIds.set(eventId, Date.now());
|
|
60699
60905
|
const stateKey = makeGitStateKey(ctx.machineId, event.workingDir);
|
|
60700
60906
|
ctx.lastPushedGitState.delete(stateKey);
|
|
60701
60907
|
console.log(`[${formatTimestamp()}] \uD83D\uDD04 Git refresh requested for ${event.workingDir}`);
|
|
60702
60908
|
await pushGitState(ctx);
|
|
60909
|
+
tracker.gitRefreshIds.set(eventId, Date.now());
|
|
60703
60910
|
} else if (event.type === "daemon.localAction") {
|
|
60704
60911
|
if (tracker.localActionIds.has(eventId))
|
|
60705
60912
|
return;
|
|
60706
|
-
tracker.localActionIds.set(eventId, Date.now());
|
|
60707
60913
|
console.log(`[${formatTimestamp()}] \uD83D\uDDA5️ Local action: ${event.action} → ${event.workingDir}`);
|
|
60708
60914
|
const result = await executeLocalAction(event.action, event.workingDir);
|
|
60709
60915
|
if (!result.success) {
|
|
60710
60916
|
console.warn(`[${formatTimestamp()}] ⚠️ Local action failed: ${result.error}`);
|
|
60711
60917
|
}
|
|
60918
|
+
tracker.localActionIds.set(eventId, Date.now());
|
|
60712
60919
|
} else if (eventType === "command.run") {
|
|
60713
60920
|
if (tracker.commandRunIds.has(eventId))
|
|
60714
60921
|
return;
|
|
@@ -60717,8 +60924,42 @@ async function dispatchCommandEvent(ctx, event, tracker) {
|
|
|
60717
60924
|
} else if (eventType === "command.stop") {
|
|
60718
60925
|
if (tracker.commandStopIds.has(eventId))
|
|
60719
60926
|
return;
|
|
60720
|
-
tracker.commandStopIds.set(eventId, Date.now());
|
|
60721
60927
|
await onCommandStop(ctx, event);
|
|
60928
|
+
tracker.commandStopIds.set(eventId, Date.now());
|
|
60929
|
+
} else if (event.type === "daemon.refreshCapabilities") {
|
|
60930
|
+
if (tracker.capabilitiesRefreshIds.has(eventId))
|
|
60931
|
+
return;
|
|
60932
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDD04 Manual capabilities refresh requested`);
|
|
60933
|
+
const outcome = await refreshModels(ctx);
|
|
60934
|
+
tracker.capabilitiesRefreshIds.set(eventId, Date.now());
|
|
60935
|
+
const batchId = "batchId" in event && event.batchId !== undefined ? event.batchId : undefined;
|
|
60936
|
+
if (!batchId) {
|
|
60937
|
+
return;
|
|
60938
|
+
}
|
|
60939
|
+
let status;
|
|
60940
|
+
let errorMessage;
|
|
60941
|
+
if (outcome.kind === "pushed") {
|
|
60942
|
+
status = "completed";
|
|
60943
|
+
} else if (outcome.kind === "skipped_no_changes") {
|
|
60944
|
+
status = "skipped_no_changes";
|
|
60945
|
+
} else if (outcome.kind === "failed") {
|
|
60946
|
+
status = "failed";
|
|
60947
|
+
errorMessage = outcome.message;
|
|
60948
|
+
} else {
|
|
60949
|
+
status = "failed";
|
|
60950
|
+
errorMessage = "Daemon configuration unavailable";
|
|
60951
|
+
}
|
|
60952
|
+
try {
|
|
60953
|
+
await ctx.deps.backend.mutation(api.machines.reportCapabilitiesRefreshResult, {
|
|
60954
|
+
sessionId: ctx.sessionId,
|
|
60955
|
+
batchId,
|
|
60956
|
+
machineId: ctx.machineId,
|
|
60957
|
+
status,
|
|
60958
|
+
errorMessage
|
|
60959
|
+
});
|
|
60960
|
+
} catch (error) {
|
|
60961
|
+
console.warn(`[${formatTimestamp()}] ⚠️ Capabilities refresh report failed: ${getErrorMessage(error)}`);
|
|
60962
|
+
}
|
|
60722
60963
|
}
|
|
60723
60964
|
}
|
|
60724
60965
|
async function startCommandLoop(ctx) {
|
|
@@ -60790,6 +61031,7 @@ Listening for commands...`);
|
|
|
60790
61031
|
commandIds: new Map,
|
|
60791
61032
|
pingIds: new Map,
|
|
60792
61033
|
gitRefreshIds: new Map,
|
|
61034
|
+
capabilitiesRefreshIds: new Map,
|
|
60793
61035
|
localActionIds: new Map,
|
|
60794
61036
|
commandRunIds: new Map,
|
|
60795
61037
|
commandStopIds: new Map
|
|
@@ -60810,15 +61052,8 @@ Listening for commands...`);
|
|
|
60810
61052
|
}
|
|
60811
61053
|
}
|
|
60812
61054
|
});
|
|
60813
|
-
const modelRefreshTimer = setInterval(() => {
|
|
60814
|
-
refreshModels(ctx).catch((err) => {
|
|
60815
|
-
console.warn(`[${formatTimestamp()}] ⚠️ Model refresh error: ${getErrorMessage(err)}`);
|
|
60816
|
-
});
|
|
60817
|
-
}, MODEL_REFRESH_INTERVAL_MS);
|
|
60818
|
-
modelRefreshTimer.unref();
|
|
60819
61055
|
return await new Promise(() => {});
|
|
60820
61056
|
}
|
|
60821
|
-
var MODEL_REFRESH_INTERVAL_MS;
|
|
60822
61057
|
var init_command_loop = __esm(() => {
|
|
60823
61058
|
init_on_request_start_agent();
|
|
60824
61059
|
init_on_request_stop_agent();
|
|
@@ -60837,7 +61072,6 @@ var init_command_loop = __esm(() => {
|
|
|
60837
61072
|
init_local_actions();
|
|
60838
61073
|
init_machine();
|
|
60839
61074
|
init_convex_error();
|
|
60840
|
-
MODEL_REFRESH_INTERVAL_MS = 10 * 1000;
|
|
60841
61075
|
});
|
|
60842
61076
|
|
|
60843
61077
|
// src/commands/machine/daemon-start/index.ts
|
|
@@ -61934,5 +62168,5 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
61934
62168
|
});
|
|
61935
62169
|
program2.parse();
|
|
61936
62170
|
|
|
61937
|
-
//# debugId=
|
|
62171
|
+
//# debugId=1C43E3169710F16B64756E2164756E21
|
|
61938
62172
|
//# sourceMappingURL=index.js.map
|