chatroom-cli 1.53.1 → 1.53.3
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 +281 -101
- package/dist/index.js.map +26 -22
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28015,7 +28015,7 @@ ${options.prompt}` : options.prompt;
|
|
|
28015
28015
|
process.stderr.write(`${logPrefix} spawn-error] ${reason}
|
|
28016
28016
|
`);
|
|
28017
28017
|
} finally {
|
|
28018
|
-
if (!session.agentClosed && !session.preserveForResume) {
|
|
28018
|
+
if (!session.agentClosed && session.aborted && !session.preserveForResume) {
|
|
28019
28019
|
try {
|
|
28020
28020
|
agent.close();
|
|
28021
28021
|
session.agentClosed = true;
|
|
@@ -79715,9 +79715,11 @@ var init_featureFlags = __esm(() => {
|
|
|
79715
79715
|
});
|
|
79716
79716
|
|
|
79717
79717
|
// ../../services/backend/config/reliability.ts
|
|
79718
|
-
var DAEMON_HEARTBEAT_INTERVAL_MS = 30000, AGENT_REQUEST_DEADLINE_MS = 120000, OBSERVATION_TTL_MS = 60000, OBSERVED_FULL_PUSH_INTERVAL_MS, OBSERVED_SAFETY_POLL_MS = 30000;
|
|
79718
|
+
var DAEMON_HEARTBEAT_INTERVAL_MS = 30000, AGENT_REQUEST_DEADLINE_MS = 120000, OBSERVATION_TTL_MS = 60000, OBSERVED_FULL_PUSH_INTERVAL_MS, OBSERVED_SAFETY_POLL_MS = 30000, WORKSPACE_RECENCY_WINDOW_MS, WORKSPACE_LIST_RECONCILE_MS;
|
|
79719
79719
|
var init_reliability = __esm(() => {
|
|
79720
79720
|
OBSERVED_FULL_PUSH_INTERVAL_MS = 5 * 60000;
|
|
79721
|
+
WORKSPACE_RECENCY_WINDOW_MS = 7 * 24 * 60 * 60 * 1000;
|
|
79722
|
+
WORKSPACE_LIST_RECONCILE_MS = 60 * 60 * 1000;
|
|
79721
79723
|
});
|
|
79722
79724
|
|
|
79723
79725
|
// src/commands/machine/daemon-start/capabilities-snapshot.ts
|
|
@@ -79987,34 +79989,30 @@ var init_command_discovery = __esm(() => {
|
|
|
79987
79989
|
});
|
|
79988
79990
|
|
|
79989
79991
|
// src/commands/machine/daemon-start/workspace-cache.ts
|
|
79990
|
-
function invalidateWorkspacesForMachineCache(ctx) {
|
|
79991
|
-
delete ctx._workspacesCache;
|
|
79992
|
-
}
|
|
79993
79992
|
async function getWorkspacesForMachine(ctx) {
|
|
79994
|
-
const
|
|
79995
|
-
|
|
79996
|
-
|
|
79997
|
-
if (cached4 && now - cached4.fetchedAt < CACHE_TTL_MS) {
|
|
79998
|
-
return cached4.workspaces;
|
|
79993
|
+
const store = ctx.workspaceListStore;
|
|
79994
|
+
if (store && store.updatedAt > 0) {
|
|
79995
|
+
return store.workspaces;
|
|
79999
79996
|
}
|
|
80000
79997
|
try {
|
|
80001
|
-
const workspaces = await ctx.deps.backend.query(api.workspaces.
|
|
79998
|
+
const workspaces = await ctx.deps.backend.query(api.workspaces.listRecentlyObservedWorkspacesForMachine, {
|
|
80002
79999
|
sessionId: ctx.sessionId,
|
|
80003
80000
|
machineId: ctx.machineId
|
|
80004
80001
|
});
|
|
80005
|
-
|
|
80006
|
-
|
|
80002
|
+
const mapped = workspaces.map((ws) => ({ workingDir: ws.workingDir }));
|
|
80003
|
+
if (store) {
|
|
80004
|
+
store.workspaces = mapped;
|
|
80005
|
+
store.updatedAt = Date.now();
|
|
80006
|
+
}
|
|
80007
|
+
return mapped;
|
|
80007
80008
|
} catch (err) {
|
|
80008
80009
|
console.warn(`[${formatTimestamp()}] ⚠️ Failed to query workspaces: ${getErrorMessage(err)}`);
|
|
80009
80010
|
return [];
|
|
80010
80011
|
}
|
|
80011
80012
|
}
|
|
80012
|
-
var CACHE_TTL_MS;
|
|
80013
80013
|
var init_workspace_cache = __esm(() => {
|
|
80014
|
-
init_reliability();
|
|
80015
80014
|
init_api3();
|
|
80016
80015
|
init_convex_error();
|
|
80017
|
-
CACHE_TTL_MS = DAEMON_HEARTBEAT_INTERVAL_MS;
|
|
80018
80016
|
});
|
|
80019
80017
|
|
|
80020
80018
|
// src/commands/machine/daemon-start/command-sync-heartbeat.ts
|
|
@@ -83159,7 +83157,45 @@ var init_output_store = __esm(() => {
|
|
|
83159
83157
|
RUN_ID_RE = /^[a-z0-9]+$/i;
|
|
83160
83158
|
});
|
|
83161
83159
|
|
|
83162
|
-
// src/commands/machine/daemon-start/handlers/process/log-observer-
|
|
83160
|
+
// src/commands/machine/daemon-start/handlers/process/log-observer-subscription.ts
|
|
83161
|
+
function setsEqual(a, b) {
|
|
83162
|
+
if (a.size !== b.size)
|
|
83163
|
+
return false;
|
|
83164
|
+
for (const id3 of a) {
|
|
83165
|
+
if (!b.has(id3))
|
|
83166
|
+
return false;
|
|
83167
|
+
}
|
|
83168
|
+
return true;
|
|
83169
|
+
}
|
|
83170
|
+
function formatRunIdShort(runId) {
|
|
83171
|
+
return runId.length > 8 ? `${runId.slice(0, 8)}…` : runId;
|
|
83172
|
+
}
|
|
83173
|
+
function logObserverSetChangeIfNeeded(runs) {
|
|
83174
|
+
const nextObserved = new Set;
|
|
83175
|
+
const nextPending = new Set;
|
|
83176
|
+
for (const run3 of runs) {
|
|
83177
|
+
nextObserved.add(run3._id);
|
|
83178
|
+
if (run3.pendingFullOutputSync) {
|
|
83179
|
+
nextPending.add(run3._id);
|
|
83180
|
+
}
|
|
83181
|
+
}
|
|
83182
|
+
if (setsEqual(observedRunIds, nextObserved) && setsEqual(pendingFullSyncRunIds, nextPending)) {
|
|
83183
|
+
return;
|
|
83184
|
+
}
|
|
83185
|
+
const runSummaries = [...nextObserved].map(formatRunIdShort).join(", ") || "none";
|
|
83186
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCDC Log observers updated: ${nextObserved.size} run(s) [${runSummaries}] pendingFull=${nextPending.size}`);
|
|
83187
|
+
}
|
|
83188
|
+
function applyObservedRuns(runs) {
|
|
83189
|
+
logObserverSetChangeIfNeeded(runs);
|
|
83190
|
+
observedRunIds.clear();
|
|
83191
|
+
pendingFullSyncRunIds.clear();
|
|
83192
|
+
for (const run3 of runs) {
|
|
83193
|
+
observedRunIds.add(run3._id);
|
|
83194
|
+
if (run3.pendingFullOutputSync) {
|
|
83195
|
+
pendingFullSyncRunIds.add(run3._id);
|
|
83196
|
+
}
|
|
83197
|
+
}
|
|
83198
|
+
}
|
|
83163
83199
|
function isRunLogObserved(runId) {
|
|
83164
83200
|
return observedRunIds.has(runId);
|
|
83165
83201
|
}
|
|
@@ -83169,77 +83205,41 @@ function consumePendingFullSync(runId) {
|
|
|
83169
83205
|
pendingFullSyncRunIds.delete(runId);
|
|
83170
83206
|
return true;
|
|
83171
83207
|
}
|
|
83172
|
-
function
|
|
83208
|
+
function startLogObserverSubscription(ctx, wsClient2) {
|
|
83209
|
+
const queryArgs = {
|
|
83210
|
+
sessionId: ctx.sessionId,
|
|
83211
|
+
machineId: ctx.machineId
|
|
83212
|
+
};
|
|
83173
83213
|
let stopped = false;
|
|
83174
|
-
|
|
83175
|
-
let pollInFlight = false;
|
|
83176
|
-
let timeoutHandle = null;
|
|
83177
|
-
const scheduleNext = (delayMs) => {
|
|
83214
|
+
const unsubscribe = wsClient2.onUpdate(api.daemon.commands.listRunsWithLogObservers, queryArgs, (runs) => {
|
|
83178
83215
|
if (stopped)
|
|
83179
83216
|
return;
|
|
83180
|
-
|
|
83181
|
-
|
|
83182
|
-
|
|
83183
|
-
|
|
83184
|
-
|
|
83185
|
-
timeoutHandle.unref?.();
|
|
83186
|
-
};
|
|
83187
|
-
const poll4 = async () => {
|
|
83188
|
-
if (stopped || pollInFlight)
|
|
83189
|
-
return;
|
|
83190
|
-
const hasLocalObservers = observedRunIds.size > 0;
|
|
83191
|
-
if (!hasLocalObservers && consecutiveIdlePolls >= IDLE_SKIP_AFTER_CONSECUTIVE) {
|
|
83192
|
-
scheduleNext(IDLE_POLL_INTERVAL_MS);
|
|
83193
|
-
return;
|
|
83194
|
-
}
|
|
83195
|
-
pollInFlight = true;
|
|
83196
|
-
try {
|
|
83197
|
-
const runs = await ctx.deps.backend.query(api.commands.listRunsWithLogObservers, {
|
|
83198
|
-
sessionId: ctx.sessionId,
|
|
83199
|
-
machineId: ctx.machineId
|
|
83200
|
-
});
|
|
83201
|
-
observedRunIds.clear();
|
|
83202
|
-
pendingFullSyncRunIds.clear();
|
|
83203
|
-
for (const run3 of runs) {
|
|
83204
|
-
observedRunIds.add(run3._id);
|
|
83205
|
-
if (run3.pendingFullOutputSync) {
|
|
83206
|
-
pendingFullSyncRunIds.add(run3._id);
|
|
83207
|
-
}
|
|
83208
|
-
}
|
|
83209
|
-
const isActive2 = runs.length > 0 || hasLocalObservers;
|
|
83210
|
-
if (isActive2) {
|
|
83211
|
-
consecutiveIdlePolls = 0;
|
|
83212
|
-
scheduleNext(ACTIVE_POLL_INTERVAL_MS);
|
|
83213
|
-
} else {
|
|
83214
|
-
consecutiveIdlePolls++;
|
|
83215
|
-
scheduleNext(consecutiveIdlePolls >= IDLE_SKIP_AFTER_CONSECUTIVE ? IDLE_POLL_INTERVAL_MS : ACTIVE_POLL_INTERVAL_MS);
|
|
83216
|
-
}
|
|
83217
|
-
} catch (err) {
|
|
83218
|
-
console.warn(`[${formatTimestamp()}] ⚠️ Log-observer poll failed: ${getErrorMessage(err)}`);
|
|
83219
|
-
scheduleNext(ACTIVE_POLL_INTERVAL_MS);
|
|
83220
|
-
} finally {
|
|
83221
|
-
pollInFlight = false;
|
|
83222
|
-
}
|
|
83223
|
-
};
|
|
83224
|
-
poll4();
|
|
83217
|
+
applyObservedRuns(runs ?? []);
|
|
83218
|
+
}, (err) => {
|
|
83219
|
+
console.warn(`[${formatTimestamp()}] ⚠️ Log-observer subscription error: ${getErrorMessage(err)}`);
|
|
83220
|
+
});
|
|
83221
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCDC Log-observer subscription started`);
|
|
83225
83222
|
return {
|
|
83226
83223
|
stop: () => {
|
|
83227
83224
|
stopped = true;
|
|
83228
|
-
|
|
83229
|
-
clearTimeout(timeoutHandle);
|
|
83225
|
+
unsubscribe();
|
|
83230
83226
|
observedRunIds.clear();
|
|
83231
83227
|
pendingFullSyncRunIds.clear();
|
|
83228
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCDC Log-observer subscription stopped`);
|
|
83232
83229
|
}
|
|
83233
83230
|
};
|
|
83234
83231
|
}
|
|
83235
|
-
var observedRunIds, pendingFullSyncRunIds
|
|
83236
|
-
var
|
|
83232
|
+
var observedRunIds, pendingFullSyncRunIds;
|
|
83233
|
+
var init_log_observer_subscription = __esm(() => {
|
|
83237
83234
|
init_api3();
|
|
83238
83235
|
init_convex_error();
|
|
83239
|
-
init_state2();
|
|
83240
83236
|
observedRunIds = new Set;
|
|
83241
83237
|
pendingFullSyncRunIds = new Set;
|
|
83242
|
-
|
|
83238
|
+
});
|
|
83239
|
+
|
|
83240
|
+
// src/commands/machine/daemon-start/handlers/process/log-observer-sync.ts
|
|
83241
|
+
var init_log_observer_sync = __esm(() => {
|
|
83242
|
+
init_log_observer_subscription();
|
|
83243
83243
|
});
|
|
83244
83244
|
|
|
83245
83245
|
// src/commands/machine/daemon-start/handlers/process/spawner.ts
|
|
@@ -83819,7 +83819,7 @@ function isProcessAlive(kill, pid) {
|
|
|
83819
83819
|
}
|
|
83820
83820
|
}
|
|
83821
83821
|
|
|
83822
|
-
// src/
|
|
83822
|
+
// src/domain/agent-lifecycle/entities/stop-reason.ts
|
|
83823
83823
|
function resolveStopReason(code2, signal) {
|
|
83824
83824
|
if (signal !== null)
|
|
83825
83825
|
return "agent_process.signal";
|
|
@@ -83828,11 +83828,59 @@ function resolveStopReason(code2, signal) {
|
|
|
83828
83828
|
return "agent_process.crashed";
|
|
83829
83829
|
}
|
|
83830
83830
|
|
|
83831
|
+
// src/domain/agent-lifecycle/policies/preserve-session.ts
|
|
83832
|
+
function shouldRetainHarnessSessionForReconnect(reason) {
|
|
83833
|
+
switch (reason) {
|
|
83834
|
+
case "user.stop":
|
|
83835
|
+
case "agent_process.exited_clean":
|
|
83836
|
+
case "agent_process.signal":
|
|
83837
|
+
case "agent_process.crashed":
|
|
83838
|
+
return true;
|
|
83839
|
+
default:
|
|
83840
|
+
return false;
|
|
83841
|
+
}
|
|
83842
|
+
}
|
|
83843
|
+
function shouldPreserveHarnessTeardown(reason, supportsSessionResume, hasHarnessSessionId) {
|
|
83844
|
+
return hasHarnessSessionId && supportsSessionResume && shouldRetainHarnessSessionForReconnect(reason);
|
|
83845
|
+
}
|
|
83846
|
+
|
|
83847
|
+
// src/domain/agent-lifecycle/policies/decide-resume-path.ts
|
|
83848
|
+
function decideResumePathOnRestart(input) {
|
|
83849
|
+
if (!input.supportsSessionResume) {
|
|
83850
|
+
return "cold";
|
|
83851
|
+
}
|
|
83852
|
+
if (input.wantResume && input.hasStoredSnapshot) {
|
|
83853
|
+
return "daemon_memory";
|
|
83854
|
+
}
|
|
83855
|
+
return "cold";
|
|
83856
|
+
}
|
|
83857
|
+
function shouldAutoRestartAfterProcessExit(stopReason) {
|
|
83858
|
+
switch (stopReason) {
|
|
83859
|
+
case "user.stop":
|
|
83860
|
+
case "platform.team_switch":
|
|
83861
|
+
case "daemon.shutdown":
|
|
83862
|
+
case "daemon.respawn":
|
|
83863
|
+
return false;
|
|
83864
|
+
default:
|
|
83865
|
+
return true;
|
|
83866
|
+
}
|
|
83867
|
+
}
|
|
83868
|
+
|
|
83869
|
+
// src/domain/agent-lifecycle/index.ts
|
|
83870
|
+
var init_agent_lifecycle = () => {};
|
|
83871
|
+
|
|
83831
83872
|
// ../../services/backend/src/domain/entities/harness/claude.config.ts
|
|
83832
83873
|
var claudeCapabilities;
|
|
83833
83874
|
var init_claude_config = __esm(() => {
|
|
83834
83875
|
claudeCapabilities = {
|
|
83835
|
-
|
|
83876
|
+
runtimeKind: "cli",
|
|
83877
|
+
supportsSessionResume: false,
|
|
83878
|
+
lifecycle: {
|
|
83879
|
+
turnCompleted: false,
|
|
83880
|
+
outputActivity: true,
|
|
83881
|
+
processExited: true
|
|
83882
|
+
},
|
|
83883
|
+
wireEvents: []
|
|
83836
83884
|
};
|
|
83837
83885
|
});
|
|
83838
83886
|
|
|
@@ -83840,7 +83888,14 @@ var init_claude_config = __esm(() => {
|
|
|
83840
83888
|
var commandcodeCapabilities;
|
|
83841
83889
|
var init_commandcode_config = __esm(() => {
|
|
83842
83890
|
commandcodeCapabilities = {
|
|
83843
|
-
|
|
83891
|
+
runtimeKind: "cli",
|
|
83892
|
+
supportsSessionResume: false,
|
|
83893
|
+
lifecycle: {
|
|
83894
|
+
turnCompleted: true,
|
|
83895
|
+
outputActivity: true,
|
|
83896
|
+
processExited: true
|
|
83897
|
+
},
|
|
83898
|
+
wireEvents: ["wire.log.agent_end"]
|
|
83844
83899
|
};
|
|
83845
83900
|
});
|
|
83846
83901
|
|
|
@@ -83848,7 +83903,14 @@ var init_commandcode_config = __esm(() => {
|
|
|
83848
83903
|
var copilotCapabilities;
|
|
83849
83904
|
var init_copilot_config = __esm(() => {
|
|
83850
83905
|
copilotCapabilities = {
|
|
83851
|
-
|
|
83906
|
+
runtimeKind: "cli",
|
|
83907
|
+
supportsSessionResume: false,
|
|
83908
|
+
lifecycle: {
|
|
83909
|
+
turnCompleted: true,
|
|
83910
|
+
outputActivity: true,
|
|
83911
|
+
processExited: true
|
|
83912
|
+
},
|
|
83913
|
+
wireEvents: ["wire.log.agent_end"]
|
|
83852
83914
|
};
|
|
83853
83915
|
});
|
|
83854
83916
|
|
|
@@ -83856,7 +83918,14 @@ var init_copilot_config = __esm(() => {
|
|
|
83856
83918
|
var cursorCapabilities;
|
|
83857
83919
|
var init_cursor_config = __esm(() => {
|
|
83858
83920
|
cursorCapabilities = {
|
|
83859
|
-
|
|
83921
|
+
runtimeKind: "cli",
|
|
83922
|
+
supportsSessionResume: false,
|
|
83923
|
+
lifecycle: {
|
|
83924
|
+
turnCompleted: true,
|
|
83925
|
+
outputActivity: true,
|
|
83926
|
+
processExited: true
|
|
83927
|
+
},
|
|
83928
|
+
wireEvents: ["wire.log.agent_end"]
|
|
83860
83929
|
};
|
|
83861
83930
|
});
|
|
83862
83931
|
|
|
@@ -83864,7 +83933,14 @@ var init_cursor_config = __esm(() => {
|
|
|
83864
83933
|
var cursorSdkCapabilities;
|
|
83865
83934
|
var init_cursor_sdk_config = __esm(() => {
|
|
83866
83935
|
cursorSdkCapabilities = {
|
|
83867
|
-
|
|
83936
|
+
runtimeKind: "sdk",
|
|
83937
|
+
supportsSessionResume: true,
|
|
83938
|
+
lifecycle: {
|
|
83939
|
+
turnCompleted: true,
|
|
83940
|
+
outputActivity: true,
|
|
83941
|
+
processExited: true
|
|
83942
|
+
},
|
|
83943
|
+
wireEvents: ["sdk.cursor.message", "sdk.cursor.run.completed", "wire.log.agent_end"]
|
|
83868
83944
|
};
|
|
83869
83945
|
});
|
|
83870
83946
|
|
|
@@ -83872,7 +83948,14 @@ var init_cursor_sdk_config = __esm(() => {
|
|
|
83872
83948
|
var opencodeCapabilities;
|
|
83873
83949
|
var init_opencode_config = __esm(() => {
|
|
83874
83950
|
opencodeCapabilities = {
|
|
83875
|
-
|
|
83951
|
+
runtimeKind: "cli",
|
|
83952
|
+
supportsSessionResume: false,
|
|
83953
|
+
lifecycle: {
|
|
83954
|
+
turnCompleted: false,
|
|
83955
|
+
outputActivity: true,
|
|
83956
|
+
processExited: true
|
|
83957
|
+
},
|
|
83958
|
+
wireEvents: []
|
|
83876
83959
|
};
|
|
83877
83960
|
});
|
|
83878
83961
|
|
|
@@ -83880,7 +83963,14 @@ var init_opencode_config = __esm(() => {
|
|
|
83880
83963
|
var opencodeSdkCapabilities;
|
|
83881
83964
|
var init_opencode_sdk_config = __esm(() => {
|
|
83882
83965
|
opencodeSdkCapabilities = {
|
|
83883
|
-
|
|
83966
|
+
runtimeKind: "sdk",
|
|
83967
|
+
supportsSessionResume: true,
|
|
83968
|
+
lifecycle: {
|
|
83969
|
+
turnCompleted: true,
|
|
83970
|
+
outputActivity: true,
|
|
83971
|
+
processExited: true
|
|
83972
|
+
},
|
|
83973
|
+
wireEvents: ["sdk.opencode.session.idle", "sdk.opencode.session.event"]
|
|
83884
83974
|
};
|
|
83885
83975
|
});
|
|
83886
83976
|
|
|
@@ -83888,7 +83978,22 @@ var init_opencode_sdk_config = __esm(() => {
|
|
|
83888
83978
|
var piCapabilities;
|
|
83889
83979
|
var init_pi_config = __esm(() => {
|
|
83890
83980
|
piCapabilities = {
|
|
83891
|
-
|
|
83981
|
+
runtimeKind: "cli",
|
|
83982
|
+
supportsSessionResume: true,
|
|
83983
|
+
lifecycle: {
|
|
83984
|
+
turnCompleted: true,
|
|
83985
|
+
outputActivity: true,
|
|
83986
|
+
processExited: true
|
|
83987
|
+
},
|
|
83988
|
+
wireEvents: [
|
|
83989
|
+
"wire.ndjson.agent_start",
|
|
83990
|
+
"wire.ndjson.agent_end",
|
|
83991
|
+
"wire.ndjson.message_update",
|
|
83992
|
+
"wire.ndjson.tool_execution_start",
|
|
83993
|
+
"wire.ndjson.tool_execution_end",
|
|
83994
|
+
"wire.ndjson.get_state",
|
|
83995
|
+
"wire.log.agent_end"
|
|
83996
|
+
]
|
|
83892
83997
|
};
|
|
83893
83998
|
});
|
|
83894
83999
|
|
|
@@ -84010,11 +84115,11 @@ class AgentProcessManager {
|
|
|
84010
84115
|
const key = agentKey2(opts.chatroomId, opts.role);
|
|
84011
84116
|
const slot = this.slots.get(key);
|
|
84012
84117
|
if (slot?.resumeInFlight) {
|
|
84013
|
-
console.log(`[AgentProcessManager]
|
|
84118
|
+
console.log(`[AgentProcessManager] lifecycle.turn.completed: skipping duplicate resume for ${opts.role} (resume already in flight)`);
|
|
84014
84119
|
return;
|
|
84015
84120
|
}
|
|
84016
84121
|
const capabilities = getHarnessCapabilities(opts.harness);
|
|
84017
|
-
console.log(`[AgentProcessManager]
|
|
84122
|
+
console.log(`[AgentProcessManager] lifecycle.turn.completed: role=${opts.role} pid=${opts.pid} harness=${opts.harness} supportsResume=${capabilities.supportsSessionResume}`);
|
|
84018
84123
|
if (capabilities.supportsSessionResume) {
|
|
84019
84124
|
const service = this.deps.agentServices.get(opts.harness);
|
|
84020
84125
|
if (service?.resumeTurn) {
|
|
@@ -84082,6 +84187,18 @@ class AgentProcessManager {
|
|
|
84082
84187
|
const harness = slot.harness;
|
|
84083
84188
|
const model = slot.model;
|
|
84084
84189
|
const workingDir = slot.workingDir;
|
|
84190
|
+
const harnessSessionId = slot.harnessSessionId;
|
|
84191
|
+
if (harness && harnessSessionId && getHarnessCapabilities(harness).supportsSessionResume && shouldRetainHarnessSessionForReconnect(stopReason)) {
|
|
84192
|
+
const service = this.deps.agentServices.get(harness);
|
|
84193
|
+
const harnessMeta = service ? this.readHarnessReconnectMetadata(service, opts.pid) : undefined;
|
|
84194
|
+
this.recordLastHarnessSession(key, {
|
|
84195
|
+
harnessSessionId,
|
|
84196
|
+
harness,
|
|
84197
|
+
agentName: harnessMeta?.agentName ?? "",
|
|
84198
|
+
workingDir: workingDir ?? "",
|
|
84199
|
+
model: model ?? harnessMeta?.model
|
|
84200
|
+
});
|
|
84201
|
+
}
|
|
84085
84202
|
slot.state = "idle";
|
|
84086
84203
|
slot.pid = undefined;
|
|
84087
84204
|
slot.startedAt = undefined;
|
|
@@ -84108,13 +84225,10 @@ class AgentProcessManager {
|
|
|
84108
84225
|
for (const service of this.deps.agentServices.values()) {
|
|
84109
84226
|
service.untrack(opts.pid);
|
|
84110
84227
|
}
|
|
84111
|
-
|
|
84112
|
-
|
|
84113
|
-
|
|
84114
|
-
|
|
84115
|
-
return;
|
|
84116
|
-
}
|
|
84117
|
-
if (isDaemonRespawn) {
|
|
84228
|
+
if (!shouldAutoRestartAfterProcessExit(stopReason)) {
|
|
84229
|
+
if (stopReason === "user.stop" || stopReason === "platform.team_switch" || stopReason === "daemon.shutdown") {
|
|
84230
|
+
this.deps.crashLoop.clear(opts.chatroomId, opts.role);
|
|
84231
|
+
}
|
|
84118
84232
|
return;
|
|
84119
84233
|
}
|
|
84120
84234
|
if (!harness || !workingDir) {
|
|
@@ -84473,7 +84587,12 @@ class AgentProcessManager {
|
|
|
84473
84587
|
return { success: false, error: `Unknown agent harness: ${opts.agentHarness}` };
|
|
84474
84588
|
}
|
|
84475
84589
|
let spawnResult;
|
|
84476
|
-
|
|
84590
|
+
const resumePath = decideResumePathOnRestart({
|
|
84591
|
+
supportsSessionResume: getHarnessCapabilities(opts.agentHarness).supportsSessionResume,
|
|
84592
|
+
wantResume,
|
|
84593
|
+
hasStoredSnapshot: this.lastHarnessSessions.has(key)
|
|
84594
|
+
});
|
|
84595
|
+
if (resumePath === "daemon_memory") {
|
|
84477
84596
|
spawnResult = await this.tryDaemonMemoryResume({
|
|
84478
84597
|
key,
|
|
84479
84598
|
chatroomId: opts.chatroomId,
|
|
@@ -84590,7 +84709,8 @@ class AgentProcessManager {
|
|
|
84590
84709
|
try {
|
|
84591
84710
|
const harness = slot.harness;
|
|
84592
84711
|
const service = harness ? this.deps.agentServices.get(harness) : undefined;
|
|
84593
|
-
const
|
|
84712
|
+
const supportsResume = harness ? getHarnessCapabilities(harness).supportsSessionResume : false;
|
|
84713
|
+
const preserveForResume = shouldPreserveHarnessTeardown(opts.reason, supportsResume, Boolean(slot.harnessSessionId));
|
|
84594
84714
|
if (harness && slot.harnessSessionId) {
|
|
84595
84715
|
if (preserveForResume) {
|
|
84596
84716
|
const harnessMeta = service ? this.readHarnessReconnectMetadata(service, pid) : undefined;
|
|
@@ -84668,6 +84788,7 @@ var AGENT_EXIT_RETRY_INTERVAL_MS = 1e4;
|
|
|
84668
84788
|
var init_agent_process_manager = __esm(() => {
|
|
84669
84789
|
init_orphan_tracker();
|
|
84670
84790
|
init_api3();
|
|
84791
|
+
init_agent_lifecycle();
|
|
84671
84792
|
init_types();
|
|
84672
84793
|
init_generator();
|
|
84673
84794
|
});
|
|
@@ -85246,6 +85367,62 @@ var init_observed_sync = __esm(() => {
|
|
|
85246
85367
|
init_convex_error();
|
|
85247
85368
|
});
|
|
85248
85369
|
|
|
85370
|
+
// src/commands/machine/daemon-start/workspace-list-subscription.ts
|
|
85371
|
+
function toSyncWorkspaces(workspaces) {
|
|
85372
|
+
return workspaces.map((ws) => ({ workingDir: ws.workingDir }));
|
|
85373
|
+
}
|
|
85374
|
+
function applyWorkspaceList(ctx, workspaces) {
|
|
85375
|
+
if (!ctx.workspaceListStore)
|
|
85376
|
+
return;
|
|
85377
|
+
ctx.workspaceListStore.workspaces = toSyncWorkspaces(workspaces);
|
|
85378
|
+
ctx.workspaceListStore.updatedAt = Date.now();
|
|
85379
|
+
}
|
|
85380
|
+
function startWorkspaceListSubscription(ctx, wsClient2) {
|
|
85381
|
+
ctx.workspaceListStore = { workspaces: [], updatedAt: 0 };
|
|
85382
|
+
const queryArgs = {
|
|
85383
|
+
sessionId: ctx.sessionId,
|
|
85384
|
+
machineId: ctx.machineId,
|
|
85385
|
+
recencyWindowMs: WORKSPACE_RECENCY_WINDOW_MS
|
|
85386
|
+
};
|
|
85387
|
+
let stopped = false;
|
|
85388
|
+
let reconcileInFlight = false;
|
|
85389
|
+
const unsubscribe = wsClient2.onUpdate(api.workspaces.listRecentlyObservedWorkspacesForMachine, queryArgs, (workspaces) => {
|
|
85390
|
+
if (stopped)
|
|
85391
|
+
return;
|
|
85392
|
+
applyWorkspaceList(ctx, workspaces ?? []);
|
|
85393
|
+
}, (err) => {
|
|
85394
|
+
console.warn(`[${formatTimestamp()}] ⚠️ Workspace-list subscription error: ${getErrorMessage(err)}`);
|
|
85395
|
+
});
|
|
85396
|
+
const reconcileTimer = setInterval(() => {
|
|
85397
|
+
if (stopped || reconcileInFlight)
|
|
85398
|
+
return;
|
|
85399
|
+
reconcileInFlight = true;
|
|
85400
|
+
ctx.deps.backend.query(api.workspaces.listRecentlyObservedWorkspacesForMachine, queryArgs).then((workspaces) => {
|
|
85401
|
+
if (!stopped)
|
|
85402
|
+
applyWorkspaceList(ctx, workspaces ?? []);
|
|
85403
|
+
}).catch((err) => {
|
|
85404
|
+
console.warn(`[${formatTimestamp()}] ⚠️ Workspace-list reconcile failed: ${getErrorMessage(err)}`);
|
|
85405
|
+
}).finally(() => {
|
|
85406
|
+
reconcileInFlight = false;
|
|
85407
|
+
});
|
|
85408
|
+
}, WORKSPACE_LIST_RECONCILE_MS);
|
|
85409
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCC2 Workspace-list subscription started`);
|
|
85410
|
+
return {
|
|
85411
|
+
stop: () => {
|
|
85412
|
+
stopped = true;
|
|
85413
|
+
unsubscribe();
|
|
85414
|
+
clearInterval(reconcileTimer);
|
|
85415
|
+
delete ctx.workspaceListStore;
|
|
85416
|
+
console.log(`[${formatTimestamp()}] \uD83D\uDCC2 Workspace-list subscription stopped`);
|
|
85417
|
+
}
|
|
85418
|
+
};
|
|
85419
|
+
}
|
|
85420
|
+
var init_workspace_list_subscription = __esm(() => {
|
|
85421
|
+
init_reliability();
|
|
85422
|
+
init_api3();
|
|
85423
|
+
init_convex_error();
|
|
85424
|
+
});
|
|
85425
|
+
|
|
85249
85426
|
// src/infrastructure/git/git-writer.ts
|
|
85250
85427
|
import { exec as exec5 } from "node:child_process";
|
|
85251
85428
|
import { promisify as promisify5 } from "node:util";
|
|
@@ -85961,7 +86138,6 @@ async function startCommandLoop(ctx) {
|
|
|
85961
86138
|
}).then(() => {
|
|
85962
86139
|
heartbeatCount++;
|
|
85963
86140
|
console.log(`[${formatTimestamp()}] \uD83D\uDC93 Daemon heartbeat #${heartbeatCount} OK`);
|
|
85964
|
-
invalidateWorkspacesForMachineCache(ctx);
|
|
85965
86141
|
if (!ctx.observedSyncEnabled) {
|
|
85966
86142
|
pushGitState(ctx).catch((err) => {
|
|
85967
86143
|
console.warn(`[${formatTimestamp()}] ⚠️ Git state push failed: ${getErrorMessage(err)}`);
|
|
@@ -85981,8 +86157,9 @@ async function startCommandLoop(ctx) {
|
|
|
85981
86157
|
let gitSubscriptionHandle = null;
|
|
85982
86158
|
let fileContentSubscriptionHandle = null;
|
|
85983
86159
|
let fileTreeSubscriptionHandle = null;
|
|
86160
|
+
let workspaceListSubscriptionHandle = null;
|
|
85984
86161
|
let observedSyncSubscriptionHandle = null;
|
|
85985
|
-
let
|
|
86162
|
+
let logObserverSubscriptionHandle = null;
|
|
85986
86163
|
let pendingPromptSubscriptionHandle = null;
|
|
85987
86164
|
let pendingHarnessSessionSubscriptionHandle = null;
|
|
85988
86165
|
let commandSubscriptionHandle = null;
|
|
@@ -86006,10 +86183,12 @@ async function startCommandLoop(ctx) {
|
|
|
86006
86183
|
fileContentSubscriptionHandle.stop();
|
|
86007
86184
|
if (fileTreeSubscriptionHandle)
|
|
86008
86185
|
fileTreeSubscriptionHandle.stop();
|
|
86186
|
+
if (workspaceListSubscriptionHandle)
|
|
86187
|
+
workspaceListSubscriptionHandle.stop();
|
|
86009
86188
|
if (observedSyncSubscriptionHandle)
|
|
86010
86189
|
observedSyncSubscriptionHandle.stop();
|
|
86011
|
-
if (
|
|
86012
|
-
|
|
86190
|
+
if (logObserverSubscriptionHandle)
|
|
86191
|
+
logObserverSubscriptionHandle.stop();
|
|
86013
86192
|
if (pendingPromptSubscriptionHandle)
|
|
86014
86193
|
pendingPromptSubscriptionHandle.stop();
|
|
86015
86194
|
if (pendingHarnessSessionSubscriptionHandle)
|
|
@@ -86035,10 +86214,11 @@ async function startCommandLoop(ctx) {
|
|
|
86035
86214
|
gitSubscriptionHandle = startGitRequestSubscription(ctx, wsClient2);
|
|
86036
86215
|
fileContentSubscriptionHandle = startFileContentSubscription(ctx, wsClient2);
|
|
86037
86216
|
fileTreeSubscriptionHandle = startFileTreeSubscription(ctx, wsClient2);
|
|
86217
|
+
workspaceListSubscriptionHandle = startWorkspaceListSubscription(ctx, wsClient2);
|
|
86038
86218
|
if (ctx.observedSyncEnabled) {
|
|
86039
86219
|
observedSyncSubscriptionHandle = startObservedSyncSubscription(ctx, wsClient2);
|
|
86040
86220
|
}
|
|
86041
|
-
|
|
86221
|
+
logObserverSubscriptionHandle = startLogObserverSubscription(ctx, wsClient2);
|
|
86042
86222
|
if (featureFlags.directHarnessWorkers) {
|
|
86043
86223
|
const sessionRepository = new ConvexSessionRepository({
|
|
86044
86224
|
backend: ctx.deps.backend,
|
|
@@ -86128,8 +86308,8 @@ var init_command_loop = __esm(() => {
|
|
|
86128
86308
|
init_manager();
|
|
86129
86309
|
init_init2();
|
|
86130
86310
|
init_log_observer_sync();
|
|
86131
|
-
init_workspace_cache();
|
|
86132
86311
|
init_observed_sync();
|
|
86312
|
+
init_workspace_list_subscription();
|
|
86133
86313
|
init_api3();
|
|
86134
86314
|
init_client2();
|
|
86135
86315
|
init_local_actions();
|
|
@@ -87304,8 +87484,8 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
|
87304
87484
|
if (!sessionId)
|
|
87305
87485
|
return;
|
|
87306
87486
|
const client4 = await getConvexClient2();
|
|
87307
|
-
sendLifecycleHeartbeat2(client4, { sessionId, chatroomId, role
|
|
87487
|
+
sendLifecycleHeartbeat2(client4, { sessionId, chatroomId, role });
|
|
87308
87488
|
});
|
|
87309
87489
|
program2.parse();
|
|
87310
87490
|
|
|
87311
|
-
//# debugId=
|
|
87491
|
+
//# debugId=738F13B9B9408F0B64756E2164756E21
|