@adhdev/daemon-core 0.8.25 → 0.8.27
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/agent-stream/provider-adapter.d.ts +1 -0
- package/dist/boot/daemon-lifecycle.d.ts +2 -0
- package/dist/cli-adapters/pty-transport.d.ts +3 -0
- package/dist/commands/router.d.ts +24 -0
- package/dist/index.js +221 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +221 -14
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +1 -0
- package/dist/providers/extension-provider-instance.d.ts +7 -0
- package/dist/status/normalize.js +14 -2
- package/dist/status/normalize.js.map +1 -1
- package/dist/status/normalize.mjs +14 -2
- package/dist/status/normalize.mjs.map +1 -1
- package/dist/status/snapshot.d.ts +0 -2
- package/node_modules/@adhdev/session-host-core/dist/index.d.mts +72 -1
- package/node_modules/@adhdev/session-host-core/dist/index.d.ts +72 -1
- package/node_modules/@adhdev/session-host-core/dist/index.js.map +1 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/agent-stream/provider-adapter.ts +30 -1
- package/src/boot/daemon-lifecycle.ts +3 -0
- package/src/cli-adapters/pty-transport.ts +3 -0
- package/src/cli-adapters/session-host-transport.ts +8 -0
- package/src/commands/chat-commands.ts +2 -2
- package/src/commands/handler.ts +25 -3
- package/src/commands/router.ts +132 -0
- package/src/providers/cli-provider-instance.ts +29 -1
- package/src/providers/extension-provider-instance.ts +24 -1
- package/src/status/normalize.ts +19 -2
- package/src/status/snapshot.ts +6 -13
|
@@ -16,6 +16,7 @@ export declare class ProviderStreamAdapter implements IAgentStreamAdapter {
|
|
|
16
16
|
constructor(provider: ProviderModule);
|
|
17
17
|
private callScript;
|
|
18
18
|
private hasScript;
|
|
19
|
+
private parseMaybeJson;
|
|
19
20
|
private summarizeRaw;
|
|
20
21
|
private isTransportError;
|
|
21
22
|
readChat(evaluate: AgentEvaluateFn): Promise<AgentStreamState>;
|
|
@@ -10,6 +10,7 @@ import { DaemonCdpManager } from '../cdp/manager.js';
|
|
|
10
10
|
import { DaemonCdpInitializer } from '../cdp/initializer.js';
|
|
11
11
|
import { DaemonCommandHandler } from '../commands/handler.js';
|
|
12
12
|
import { DaemonCommandRouter } from '../commands/router.js';
|
|
13
|
+
import type { SessionHostControlPlane } from '../commands/router.js';
|
|
13
14
|
import { DaemonCliManager, type CliTransportFactoryParams, type HostedCliRuntimeDescriptor } from '../commands/cli-manager.js';
|
|
14
15
|
import { DaemonAgentStreamManager } from '../agent-stream/manager.js';
|
|
15
16
|
import { AgentStreamPoller } from '../agent-stream/poller.js';
|
|
@@ -35,6 +36,7 @@ export interface DaemonInitConfig {
|
|
|
35
36
|
/** Router transport-specific callbacks */
|
|
36
37
|
onStatusChange?: () => void;
|
|
37
38
|
onPostChatCommand?: () => void;
|
|
39
|
+
sessionHostControl?: SessionHostControlPlane | null;
|
|
38
40
|
getCdpLogFn?: (ideType: string) => (msg: string) => void;
|
|
39
41
|
/** Additional callback after CDP manager created (transport-specific extras) */
|
|
40
42
|
onCdpManagerSetup?: (ideType: string, manager: DaemonCdpManager, managerKey: string) => void | Promise<void>;
|
|
@@ -20,6 +20,9 @@ export interface PtyRuntimeMetadata {
|
|
|
20
20
|
workspaceLabel?: string;
|
|
21
21
|
writeOwner?: PtyRuntimeWriteOwner | null;
|
|
22
22
|
attachedClients?: PtyRuntimeClientInfo[];
|
|
23
|
+
restoredFromStorage?: boolean;
|
|
24
|
+
recoveryState?: string | null;
|
|
25
|
+
recoveryError?: string | null;
|
|
23
26
|
}
|
|
24
27
|
export interface PtyRuntimeTransport {
|
|
25
28
|
readonly pid: number;
|
|
@@ -14,6 +14,28 @@ import { DaemonCliManager } from './cli-manager.js';
|
|
|
14
14
|
import type { ProviderLoader } from '../providers/provider-loader.js';
|
|
15
15
|
import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
|
|
16
16
|
import { SessionRegistry } from '../sessions/registry.js';
|
|
17
|
+
export interface SessionHostControlPlane {
|
|
18
|
+
getDiagnostics(payload?: {
|
|
19
|
+
includeSessions?: boolean;
|
|
20
|
+
limit?: number;
|
|
21
|
+
}): Promise<any>;
|
|
22
|
+
listSessions(): Promise<any[]>;
|
|
23
|
+
stopSession(sessionId: string): Promise<any>;
|
|
24
|
+
resumeSession(sessionId: string): Promise<any>;
|
|
25
|
+
restartSession(sessionId: string): Promise<any>;
|
|
26
|
+
sendSignal(sessionId: string, signal: string): Promise<any>;
|
|
27
|
+
forceDetachClient(sessionId: string, clientId: string): Promise<any>;
|
|
28
|
+
acquireWrite(payload: {
|
|
29
|
+
sessionId: string;
|
|
30
|
+
clientId: string;
|
|
31
|
+
ownerType: 'agent' | 'user';
|
|
32
|
+
force?: boolean;
|
|
33
|
+
}): Promise<any>;
|
|
34
|
+
releaseWrite(payload: {
|
|
35
|
+
sessionId: string;
|
|
36
|
+
clientId: string;
|
|
37
|
+
}): Promise<any>;
|
|
38
|
+
}
|
|
17
39
|
export interface CommandRouterDeps {
|
|
18
40
|
commandHandler: DaemonCommandHandler;
|
|
19
41
|
cliManager: DaemonCliManager;
|
|
@@ -37,6 +59,8 @@ export interface CommandRouterDeps {
|
|
|
37
59
|
getCdpLogFn?: (ideType: string) => (msg: string) => void;
|
|
38
60
|
/** Package name for upgrade detection ('adhdev' or '@adhdev/daemon-standalone') */
|
|
39
61
|
packageName?: string;
|
|
62
|
+
/** Session host control plane */
|
|
63
|
+
sessionHostControl?: SessionHostControlPlane | null;
|
|
40
64
|
}
|
|
41
65
|
export interface CommandRouterResult {
|
|
42
66
|
success: boolean;
|
package/dist/index.js
CHANGED
|
@@ -5201,6 +5201,7 @@ var ExtensionProviderInstance = class {
|
|
|
5201
5201
|
currentStatus = "idle";
|
|
5202
5202
|
agentStreams = [];
|
|
5203
5203
|
messages = [];
|
|
5204
|
+
prevMessageHashes = /* @__PURE__ */ new Map();
|
|
5204
5205
|
activeModal = null;
|
|
5205
5206
|
currentModel = "";
|
|
5206
5207
|
currentMode = "";
|
|
@@ -5266,7 +5267,7 @@ var ExtensionProviderInstance = class {
|
|
|
5266
5267
|
onEvent(event, data) {
|
|
5267
5268
|
if (event === "stream_update") {
|
|
5268
5269
|
if (data?.streams) this.agentStreams = data.streams;
|
|
5269
|
-
if (data?.messages) this.messages = data.messages;
|
|
5270
|
+
if (data?.messages) this.messages = this.assignReceivedAt(data.messages);
|
|
5270
5271
|
if (data?.activeModal !== void 0) this.activeModal = data.activeModal;
|
|
5271
5272
|
if (data?.model) this.currentModel = data.model;
|
|
5272
5273
|
if (data?.mode) this.currentMode = data.mode;
|
|
@@ -5292,6 +5293,7 @@ var ExtensionProviderInstance = class {
|
|
|
5292
5293
|
dispose() {
|
|
5293
5294
|
this.agentStreams = [];
|
|
5294
5295
|
this.messages = [];
|
|
5296
|
+
this.prevMessageHashes.clear();
|
|
5295
5297
|
this.monitor.reset();
|
|
5296
5298
|
this.appliedEffectKeys.clear();
|
|
5297
5299
|
this.runtimeMessages = [];
|
|
@@ -5447,6 +5449,23 @@ var ExtensionProviderInstance = class {
|
|
|
5447
5449
|
this.chatId || this.instanceId
|
|
5448
5450
|
);
|
|
5449
5451
|
}
|
|
5452
|
+
/**
|
|
5453
|
+
* Assign stable receivedAt to extension messages.
|
|
5454
|
+
* Same pattern as IdeProviderInstance.readChat() prevByHash —
|
|
5455
|
+
* preserves first-seen timestamp across polling cycles.
|
|
5456
|
+
*/
|
|
5457
|
+
assignReceivedAt(messages) {
|
|
5458
|
+
const now = Date.now();
|
|
5459
|
+
const nextHashes = /* @__PURE__ */ new Map();
|
|
5460
|
+
for (const msg of messages) {
|
|
5461
|
+
const hash = `${msg.role}:${(msg.content || "").slice(0, 100)}`;
|
|
5462
|
+
const prevTime = this.prevMessageHashes.get(hash);
|
|
5463
|
+
msg.receivedAt = prevTime || now;
|
|
5464
|
+
nextHashes.set(hash, msg.receivedAt);
|
|
5465
|
+
}
|
|
5466
|
+
this.prevMessageHashes = nextHashes;
|
|
5467
|
+
return messages;
|
|
5468
|
+
}
|
|
5450
5469
|
mergeConversationMessages(messages) {
|
|
5451
5470
|
if (this.runtimeMessages.length === 0) return messages;
|
|
5452
5471
|
return [...messages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b) => {
|
|
@@ -5503,6 +5522,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
5503
5522
|
}
|
|
5504
5523
|
this.agentStreams = [];
|
|
5505
5524
|
this.messages = [];
|
|
5525
|
+
this.prevMessageHashes.clear();
|
|
5506
5526
|
this.activeModal = null;
|
|
5507
5527
|
this.currentModel = "";
|
|
5508
5528
|
this.currentMode = "";
|
|
@@ -6488,16 +6508,28 @@ function trimMessageForStatus(message, stringLimit) {
|
|
|
6488
6508
|
if (!message || typeof message !== "object") return message;
|
|
6489
6509
|
return trimStructuredStrings(message, stringLimit);
|
|
6490
6510
|
}
|
|
6511
|
+
function normalizeMessageTime(message) {
|
|
6512
|
+
if (!message || typeof message !== "object") return message;
|
|
6513
|
+
const msg = message;
|
|
6514
|
+
if (msg.receivedAt == null) {
|
|
6515
|
+
const fallback = msg.timestamp ?? msg.createdAt;
|
|
6516
|
+
if (fallback != null) {
|
|
6517
|
+
const ts2 = typeof fallback === "string" ? Date.parse(fallback) : Number(fallback);
|
|
6518
|
+
if (Number.isFinite(ts2) && ts2 > 0) msg.receivedAt = ts2;
|
|
6519
|
+
}
|
|
6520
|
+
}
|
|
6521
|
+
return msg;
|
|
6522
|
+
}
|
|
6491
6523
|
function trimMessagesForStatus(messages) {
|
|
6492
6524
|
if (!Array.isArray(messages) || messages.length === 0) return [];
|
|
6493
6525
|
const recent = messages.slice(-STATUS_ACTIVE_CHAT_MESSAGE_LIMIT);
|
|
6494
6526
|
const kept = [];
|
|
6495
6527
|
let totalBytes = 0;
|
|
6496
6528
|
for (let i = recent.length - 1; i >= 0; i -= 1) {
|
|
6497
|
-
let normalized = trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_STRING_LIMIT);
|
|
6529
|
+
let normalized = normalizeMessageTime(trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_STRING_LIMIT));
|
|
6498
6530
|
let size = estimateBytes(normalized);
|
|
6499
6531
|
if (size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {
|
|
6500
|
-
normalized = trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT);
|
|
6532
|
+
normalized = normalizeMessageTime(trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT));
|
|
6501
6533
|
size = estimateBytes(normalized);
|
|
6502
6534
|
}
|
|
6503
6535
|
if (kept.length > 0 && totalBytes + size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {
|
|
@@ -7120,7 +7152,7 @@ async function handleSendChat(h, args) {
|
|
|
7120
7152
|
if (isExtensionTransport(transport)) {
|
|
7121
7153
|
_log(`Extension: ${provider?.type || "unknown_extension"}`);
|
|
7122
7154
|
try {
|
|
7123
|
-
const evalResult = await h.evaluateProviderScript("sendMessage", {
|
|
7155
|
+
const evalResult = await h.evaluateProviderScript("sendMessage", { message: text }, 3e4);
|
|
7124
7156
|
if (evalResult?.result) {
|
|
7125
7157
|
const parsed = parseMaybeJson(evalResult.result);
|
|
7126
7158
|
if (didProviderConfirmSend(parsed)) {
|
|
@@ -7151,7 +7183,7 @@ async function handleSendChat(h, args) {
|
|
|
7151
7183
|
return { success: false, error: `CDP for ${managerKey || "unknown"} not connected` };
|
|
7152
7184
|
}
|
|
7153
7185
|
_log(`Targeting IDE: ${getCurrentManagerKey(h)}`);
|
|
7154
|
-
const sendScript = h.getProviderScript("sendMessage", {
|
|
7186
|
+
const sendScript = h.getProviderScript("sendMessage", { message: text });
|
|
7155
7187
|
if (sendScript) {
|
|
7156
7188
|
try {
|
|
7157
7189
|
const result = await targetCdp.evaluate(sendScript, 3e4);
|
|
@@ -8553,9 +8585,26 @@ var DaemonCommandHandler = class {
|
|
|
8553
8585
|
if (provider?.scripts) {
|
|
8554
8586
|
const fn = provider.scripts[scriptName];
|
|
8555
8587
|
if (typeof fn === "function") {
|
|
8556
|
-
|
|
8557
|
-
|
|
8558
|
-
|
|
8588
|
+
if (params && Object.keys(params).length > 0) {
|
|
8589
|
+
const firstVal = Object.values(params)[0];
|
|
8590
|
+
if (scriptName === "sendMessage" && typeof firstVal === "string") {
|
|
8591
|
+
const legacyScript = fn(firstVal);
|
|
8592
|
+
if (legacyScript) return legacyScript;
|
|
8593
|
+
}
|
|
8594
|
+
const script = fn(params);
|
|
8595
|
+
if (script) {
|
|
8596
|
+
const likelyLegacyObjectLeak = typeof script === "string" && script.includes("[object Object]") && typeof firstVal === "string";
|
|
8597
|
+
if (!likelyLegacyObjectLeak) return script;
|
|
8598
|
+
}
|
|
8599
|
+
if (firstVal !== void 0) {
|
|
8600
|
+
const legacyScript = fn(firstVal);
|
|
8601
|
+
if (legacyScript) return legacyScript;
|
|
8602
|
+
}
|
|
8603
|
+
if (script) return script;
|
|
8604
|
+
} else {
|
|
8605
|
+
const script = fn();
|
|
8606
|
+
if (script) return script;
|
|
8607
|
+
}
|
|
8559
8608
|
}
|
|
8560
8609
|
}
|
|
8561
8610
|
return null;
|
|
@@ -9016,6 +9065,7 @@ var CliProviderInstance = class {
|
|
|
9016
9065
|
this.detectStatusTransition();
|
|
9017
9066
|
});
|
|
9018
9067
|
await this.adapter.spawn();
|
|
9068
|
+
this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
|
|
9019
9069
|
if (this.providerSessionId) {
|
|
9020
9070
|
const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
|
|
9021
9071
|
if (restoredHistory.messages.length > 0) {
|
|
@@ -9110,6 +9160,7 @@ var CliProviderInstance = class {
|
|
|
9110
9160
|
this.promoteProviderSessionId(parsedProviderSessionId);
|
|
9111
9161
|
}
|
|
9112
9162
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
9163
|
+
this.maybeAppendRuntimeRecoveryMessage(runtime);
|
|
9113
9164
|
const parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
|
|
9114
9165
|
const controlValues = extractProviderControlValues(this.provider.controls, parsedStatus);
|
|
9115
9166
|
if (controlValues) {
|
|
@@ -9436,6 +9487,28 @@ ${effect.notification.body || ""}`.trim();
|
|
|
9436
9487
|
const pad = (value) => String(value).padStart(2, "0");
|
|
9437
9488
|
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
|
|
9438
9489
|
}
|
|
9490
|
+
maybeAppendRuntimeRecoveryMessage(runtime) {
|
|
9491
|
+
if (!runtime?.restoredFromStorage || !runtime.runtimeId) return;
|
|
9492
|
+
const recoveryState = String(runtime.recoveryState || "").trim();
|
|
9493
|
+
if (!recoveryState) return;
|
|
9494
|
+
let content = "";
|
|
9495
|
+
if (recoveryState === "auto_resumed") {
|
|
9496
|
+
content = "Session host restored this CLI after restart and reattached it from a saved snapshot.";
|
|
9497
|
+
} else if (recoveryState === "resume_failed") {
|
|
9498
|
+
const errorSuffix = runtime.recoveryError ? ` Resume failed: ${runtime.recoveryError}` : "";
|
|
9499
|
+
content = `Session host found this CLI after restart, but automatic resume failed.${errorSuffix}`;
|
|
9500
|
+
} else if (recoveryState === "host_restart_interrupted") {
|
|
9501
|
+
content = "Session host found this CLI in interrupted state after restart and is attempting to resume it.";
|
|
9502
|
+
} else if (recoveryState === "orphan_snapshot") {
|
|
9503
|
+
content = "Session host restored the last snapshot for this CLI, but the original runtime was not resumed automatically.";
|
|
9504
|
+
} else {
|
|
9505
|
+
content = `Session host restored this CLI after restart (${recoveryState}).`;
|
|
9506
|
+
}
|
|
9507
|
+
this.appendRuntimeSystemMessage(
|
|
9508
|
+
content,
|
|
9509
|
+
`runtime_recovery:${runtime.runtimeId}:${recoveryState}`
|
|
9510
|
+
);
|
|
9511
|
+
}
|
|
9439
9512
|
appendRuntimeSystemMessage(content, dedupKey, receivedAt = Date.now()) {
|
|
9440
9513
|
const normalizedContent = String(content || "").trim();
|
|
9441
9514
|
if (!normalizedContent) return;
|
|
@@ -12724,17 +12797,17 @@ function parseMessageTime(value) {
|
|
|
12724
12797
|
function getSessionMessageUpdatedAt(session) {
|
|
12725
12798
|
const lastMessage = session.activeChat?.messages?.at?.(-1);
|
|
12726
12799
|
if (!lastMessage) return 0;
|
|
12727
|
-
return parseMessageTime(lastMessage.
|
|
12800
|
+
return parseMessageTime(lastMessage.receivedAt) || 0;
|
|
12728
12801
|
}
|
|
12729
12802
|
function getSessionCompletionMarker(session) {
|
|
12730
12803
|
const lastMessage = session.activeChat?.messages?.at?.(-1);
|
|
12731
12804
|
if (!lastMessage) return "";
|
|
12732
12805
|
const role = typeof lastMessage.role === "string" ? lastMessage.role : "";
|
|
12733
|
-
if (role === "user" || role === "human") return "";
|
|
12806
|
+
if (role === "user" || role === "human" || role === "system") return "";
|
|
12734
12807
|
if (typeof lastMessage._turnKey === "string" && lastMessage._turnKey) return `turn:${lastMessage._turnKey}`;
|
|
12735
12808
|
if (typeof lastMessage.id === "string" && lastMessage.id) return `id:${lastMessage.id}`;
|
|
12736
12809
|
if (typeof lastMessage.index === "number" && Number.isFinite(lastMessage.index)) return `idx:${lastMessage.index}`;
|
|
12737
|
-
const timestamp = parseMessageTime(lastMessage.
|
|
12810
|
+
const timestamp = parseMessageTime(lastMessage.receivedAt);
|
|
12738
12811
|
return timestamp > 0 ? `ts:${timestamp}` : "";
|
|
12739
12812
|
}
|
|
12740
12813
|
function getSessionLastUsedAt(session) {
|
|
@@ -12751,7 +12824,7 @@ function getUnreadState(hasContentChange, status, lastUsedAt, lastSeenAt, lastRo
|
|
|
12751
12824
|
if (status === "generating" || status === "starting") {
|
|
12752
12825
|
return { unread: false, inboxBucket: "working" };
|
|
12753
12826
|
}
|
|
12754
|
-
const unread = completionMarker ? completionMarker !== seenCompletionMarker : hasContentChange && lastUsedAt > lastSeenAt && lastRole !== "user" && lastRole !== "human";
|
|
12827
|
+
const unread = completionMarker ? completionMarker !== seenCompletionMarker : hasContentChange && lastUsedAt > lastSeenAt && lastRole !== "user" && lastRole !== "human" && lastRole !== "system";
|
|
12755
12828
|
return { unread, inboxBucket: unread ? "task_complete" : "idle" };
|
|
12756
12829
|
}
|
|
12757
12830
|
function buildRecentLaunches(recentActivity) {
|
|
@@ -13036,6 +13109,25 @@ var CHAT_COMMANDS = [
|
|
|
13036
13109
|
"change_model"
|
|
13037
13110
|
];
|
|
13038
13111
|
var READ_DEBUG_ENABLED2 = process.argv.includes("--dev") || process.env.ADHDEV_READ_DEBUG === "1";
|
|
13112
|
+
function toHostedCliRuntimeDescriptor(record) {
|
|
13113
|
+
if (!record || typeof record !== "object") return null;
|
|
13114
|
+
const runtimeId = typeof record.sessionId === "string" ? record.sessionId : "";
|
|
13115
|
+
const cliType = typeof record.providerType === "string" ? record.providerType : "";
|
|
13116
|
+
const workspace = typeof record.workspace === "string" ? record.workspace : "";
|
|
13117
|
+
if (!runtimeId || !cliType || !workspace) return null;
|
|
13118
|
+
return {
|
|
13119
|
+
runtimeId,
|
|
13120
|
+
runtimeKey: typeof record.runtimeKey === "string" ? record.runtimeKey : void 0,
|
|
13121
|
+
displayName: typeof record.displayName === "string" ? record.displayName : void 0,
|
|
13122
|
+
workspaceLabel: typeof record.workspaceLabel === "string" ? record.workspaceLabel : void 0,
|
|
13123
|
+
lifecycle: typeof record.lifecycle === "string" ? record.lifecycle : void 0,
|
|
13124
|
+
recoveryState: typeof record.meta?.runtimeRecoveryState === "string" ? String(record.meta.runtimeRecoveryState) : null,
|
|
13125
|
+
cliType,
|
|
13126
|
+
workspace,
|
|
13127
|
+
cliArgs: Array.isArray(record.meta?.cliArgs) ? record.meta.cliArgs : [],
|
|
13128
|
+
providerSessionId: typeof record.meta?.providerSessionId === "string" ? String(record.meta.providerSessionId) : void 0
|
|
13129
|
+
};
|
|
13130
|
+
}
|
|
13039
13131
|
var DaemonCommandRouter = class {
|
|
13040
13132
|
deps;
|
|
13041
13133
|
constructor(deps) {
|
|
@@ -13109,6 +13201,90 @@ var DaemonCommandRouter = class {
|
|
|
13109
13201
|
return { success: false, error: e.message };
|
|
13110
13202
|
}
|
|
13111
13203
|
}
|
|
13204
|
+
case "session_host_get_diagnostics": {
|
|
13205
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
13206
|
+
const diagnostics = await this.deps.sessionHostControl.getDiagnostics({
|
|
13207
|
+
includeSessions: args?.includeSessions !== false,
|
|
13208
|
+
limit: Number(args?.limit) || void 0
|
|
13209
|
+
});
|
|
13210
|
+
return { success: true, diagnostics };
|
|
13211
|
+
}
|
|
13212
|
+
case "session_host_list_sessions": {
|
|
13213
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
13214
|
+
const sessions = await this.deps.sessionHostControl.listSessions();
|
|
13215
|
+
return { success: true, sessions };
|
|
13216
|
+
}
|
|
13217
|
+
case "session_host_stop_session": {
|
|
13218
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
13219
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
13220
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
13221
|
+
const record = await this.deps.sessionHostControl.stopSession(sessionId);
|
|
13222
|
+
return { success: true, record };
|
|
13223
|
+
}
|
|
13224
|
+
case "session_host_resume_session": {
|
|
13225
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
13226
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
13227
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
13228
|
+
const record = await this.deps.sessionHostControl.resumeSession(sessionId);
|
|
13229
|
+
const hosted = toHostedCliRuntimeDescriptor(record);
|
|
13230
|
+
if (hosted) {
|
|
13231
|
+
await this.deps.cliManager.restoreHostedSessions([hosted]);
|
|
13232
|
+
}
|
|
13233
|
+
return { success: true, record };
|
|
13234
|
+
}
|
|
13235
|
+
case "session_host_restart_session": {
|
|
13236
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
13237
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
13238
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
13239
|
+
const record = await this.deps.sessionHostControl.restartSession(sessionId);
|
|
13240
|
+
const hosted = toHostedCliRuntimeDescriptor(record);
|
|
13241
|
+
if (hosted) {
|
|
13242
|
+
await this.deps.cliManager.restoreHostedSessions([hosted]);
|
|
13243
|
+
}
|
|
13244
|
+
return { success: true, record };
|
|
13245
|
+
}
|
|
13246
|
+
case "session_host_send_signal": {
|
|
13247
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
13248
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
13249
|
+
const signal = typeof args?.signal === "string" ? args.signal : "";
|
|
13250
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
13251
|
+
if (!signal) return { success: false, error: "signal required" };
|
|
13252
|
+
const record = await this.deps.sessionHostControl.sendSignal(sessionId, signal);
|
|
13253
|
+
return { success: true, record };
|
|
13254
|
+
}
|
|
13255
|
+
case "session_host_force_detach_client": {
|
|
13256
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
13257
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
13258
|
+
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
13259
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
13260
|
+
if (!clientId) return { success: false, error: "clientId required" };
|
|
13261
|
+
const record = await this.deps.sessionHostControl.forceDetachClient(sessionId, clientId);
|
|
13262
|
+
return { success: true, record };
|
|
13263
|
+
}
|
|
13264
|
+
case "session_host_acquire_write": {
|
|
13265
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
13266
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
13267
|
+
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
13268
|
+
const ownerType = args?.ownerType === "agent" ? "agent" : "user";
|
|
13269
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
13270
|
+
if (!clientId) return { success: false, error: "clientId required" };
|
|
13271
|
+
const record = await this.deps.sessionHostControl.acquireWrite({
|
|
13272
|
+
sessionId,
|
|
13273
|
+
clientId,
|
|
13274
|
+
ownerType,
|
|
13275
|
+
force: args?.force !== false
|
|
13276
|
+
});
|
|
13277
|
+
return { success: true, record };
|
|
13278
|
+
}
|
|
13279
|
+
case "session_host_release_write": {
|
|
13280
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
13281
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
13282
|
+
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
13283
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
13284
|
+
if (!clientId) return { success: false, error: "clientId required" };
|
|
13285
|
+
const record = await this.deps.sessionHostControl.releaseWrite({ sessionId, clientId });
|
|
13286
|
+
return { success: true, record };
|
|
13287
|
+
}
|
|
13112
13288
|
case "list_saved_sessions": {
|
|
13113
13289
|
const providerType = typeof args?.providerType === "string" ? args.providerType.trim() : typeof args?.agentType === "string" ? args.agentType.trim() : "";
|
|
13114
13290
|
const kind = args?.kind === "acp" ? "acp" : "cli";
|
|
@@ -13637,6 +13813,14 @@ var ProviderStreamAdapter = class {
|
|
|
13637
13813
|
hasScript(name) {
|
|
13638
13814
|
return typeof this.provider.scripts?.[name] === "function";
|
|
13639
13815
|
}
|
|
13816
|
+
parseMaybeJson(raw) {
|
|
13817
|
+
if (typeof raw !== "string") return raw;
|
|
13818
|
+
try {
|
|
13819
|
+
return JSON.parse(raw);
|
|
13820
|
+
} catch {
|
|
13821
|
+
return raw;
|
|
13822
|
+
}
|
|
13823
|
+
}
|
|
13640
13824
|
summarizeRaw(raw) {
|
|
13641
13825
|
try {
|
|
13642
13826
|
if (typeof raw === "string") return raw.replace(/\s+/g, " ").trim().slice(0, 240);
|
|
@@ -13697,12 +13881,30 @@ var ProviderStreamAdapter = class {
|
|
|
13697
13881
|
}
|
|
13698
13882
|
}
|
|
13699
13883
|
async sendMessage(evaluate, text) {
|
|
13700
|
-
const
|
|
13884
|
+
const params = { message: text };
|
|
13885
|
+
const script = this.callScript("sendMessage", params) || this.callScript("sendMessage", text);
|
|
13701
13886
|
if (!script) throw new Error(`[${this.agentName}] sendMessage script not available`);
|
|
13702
13887
|
const result = await evaluate(script);
|
|
13703
13888
|
if (result && typeof result === "string" && result.startsWith("error:")) {
|
|
13704
13889
|
throw new Error(`[${this.agentName}] sendMessage failed: ${result}`);
|
|
13705
13890
|
}
|
|
13891
|
+
const parsed = this.parseMaybeJson(result);
|
|
13892
|
+
if (parsed === true) return;
|
|
13893
|
+
if (typeof parsed === "string") {
|
|
13894
|
+
const normalized = parsed.trim().toLowerCase();
|
|
13895
|
+
if (normalized === "ok" || normalized === "sent" || normalized === "success" || normalized === "true") {
|
|
13896
|
+
return;
|
|
13897
|
+
}
|
|
13898
|
+
}
|
|
13899
|
+
if (parsed && typeof parsed === "object") {
|
|
13900
|
+
if (parsed.sent === true || parsed.success === true || parsed.ok === true || parsed.submitted === true || parsed.dispatched === true) {
|
|
13901
|
+
return;
|
|
13902
|
+
}
|
|
13903
|
+
if (typeof parsed.error === "string" && parsed.error.trim()) {
|
|
13904
|
+
throw new Error(`[${this.agentName}] sendMessage failed: ${parsed.error}`);
|
|
13905
|
+
}
|
|
13906
|
+
}
|
|
13907
|
+
throw new Error(`[${this.agentName}] sendMessage was not confirmed`);
|
|
13706
13908
|
}
|
|
13707
13909
|
async resolveAction(evaluate, action, button) {
|
|
13708
13910
|
const script = this.callScript("resolveAction", { action, button });
|
|
@@ -19953,6 +20155,7 @@ var SessionHostRuntimeTransport = class {
|
|
|
19953
20155
|
}
|
|
19954
20156
|
}
|
|
19955
20157
|
handleEvent(event) {
|
|
20158
|
+
if (!("sessionId" in event)) return;
|
|
19956
20159
|
if (event.sessionId !== this.options.runtimeId) return;
|
|
19957
20160
|
if ((event.type === "session_started" || event.type === "session_resumed") && typeof event.pid === "number") {
|
|
19958
20161
|
this.currentPid = event.pid;
|
|
@@ -20028,7 +20231,10 @@ var SessionHostRuntimeTransport = class {
|
|
|
20028
20231
|
clientId: client.clientId,
|
|
20029
20232
|
type: client.type,
|
|
20030
20233
|
readOnly: client.readOnly
|
|
20031
|
-
}))
|
|
20234
|
+
})),
|
|
20235
|
+
restoredFromStorage: record.meta?.restoredFromStorage === true,
|
|
20236
|
+
recoveryState: typeof record.meta?.runtimeRecoveryState === "string" ? String(record.meta.runtimeRecoveryState) : null,
|
|
20237
|
+
recoveryError: typeof record.meta?.runtimeRecoveryError === "string" ? String(record.meta.runtimeRecoveryError) : null
|
|
20032
20238
|
};
|
|
20033
20239
|
}
|
|
20034
20240
|
enqueue(action) {
|
|
@@ -20472,6 +20678,7 @@ async function initDaemonComponents(config) {
|
|
|
20472
20678
|
onIdeConnected: () => poller?.start(),
|
|
20473
20679
|
onStatusChange: config.onStatusChange,
|
|
20474
20680
|
onPostChatCommand: config.onPostChatCommand,
|
|
20681
|
+
sessionHostControl: config.sessionHostControl,
|
|
20475
20682
|
getCdpLogFn: config.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
|
|
20476
20683
|
});
|
|
20477
20684
|
poller = new AgentStreamPoller({
|