adhdev 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/cli/index.js +1359 -417
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +396 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/vendor/session-host-daemon/index.d.mts +16 -0
- package/vendor/session-host-daemon/index.d.ts +16 -0
- package/vendor/session-host-daemon/index.js +200 -4
- package/vendor/session-host-daemon/index.js.map +1 -1
- package/vendor/session-host-daemon/index.mjs +200 -4
- package/vendor/session-host-daemon/index.mjs.map +1 -1
- package/vendor/session-host-daemon/node_modules/@adhdev/session-host-core/index.d.mts +72 -1
- package/vendor/session-host-daemon/node_modules/@adhdev/session-host-core/index.d.ts +72 -1
- package/vendor/session-host-daemon/node_modules/@adhdev/session-host-core/index.js.map +1 -1
package/dist/index.js
CHANGED
|
@@ -2852,6 +2852,7 @@ var init_extension_provider_instance = __esm({
|
|
|
2852
2852
|
currentStatus = "idle";
|
|
2853
2853
|
agentStreams = [];
|
|
2854
2854
|
messages = [];
|
|
2855
|
+
prevMessageHashes = /* @__PURE__ */ new Map();
|
|
2855
2856
|
activeModal = null;
|
|
2856
2857
|
currentModel = "";
|
|
2857
2858
|
currentMode = "";
|
|
@@ -2917,7 +2918,7 @@ var init_extension_provider_instance = __esm({
|
|
|
2917
2918
|
onEvent(event, data) {
|
|
2918
2919
|
if (event === "stream_update") {
|
|
2919
2920
|
if (data?.streams) this.agentStreams = data.streams;
|
|
2920
|
-
if (data?.messages) this.messages = data.messages;
|
|
2921
|
+
if (data?.messages) this.messages = this.assignReceivedAt(data.messages);
|
|
2921
2922
|
if (data?.activeModal !== void 0) this.activeModal = data.activeModal;
|
|
2922
2923
|
if (data?.model) this.currentModel = data.model;
|
|
2923
2924
|
if (data?.mode) this.currentMode = data.mode;
|
|
@@ -2943,6 +2944,7 @@ var init_extension_provider_instance = __esm({
|
|
|
2943
2944
|
dispose() {
|
|
2944
2945
|
this.agentStreams = [];
|
|
2945
2946
|
this.messages = [];
|
|
2947
|
+
this.prevMessageHashes.clear();
|
|
2946
2948
|
this.monitor.reset();
|
|
2947
2949
|
this.appliedEffectKeys.clear();
|
|
2948
2950
|
this.runtimeMessages = [];
|
|
@@ -3098,6 +3100,23 @@ var init_extension_provider_instance = __esm({
|
|
|
3098
3100
|
this.chatId || this.instanceId
|
|
3099
3101
|
);
|
|
3100
3102
|
}
|
|
3103
|
+
/**
|
|
3104
|
+
* Assign stable receivedAt to extension messages.
|
|
3105
|
+
* Same pattern as IdeProviderInstance.readChat() prevByHash —
|
|
3106
|
+
* preserves first-seen timestamp across polling cycles.
|
|
3107
|
+
*/
|
|
3108
|
+
assignReceivedAt(messages) {
|
|
3109
|
+
const now = Date.now();
|
|
3110
|
+
const nextHashes = /* @__PURE__ */ new Map();
|
|
3111
|
+
for (const msg of messages) {
|
|
3112
|
+
const hash2 = `${msg.role}:${(msg.content || "").slice(0, 100)}`;
|
|
3113
|
+
const prevTime = this.prevMessageHashes.get(hash2);
|
|
3114
|
+
msg.receivedAt = prevTime || now;
|
|
3115
|
+
nextHashes.set(hash2, msg.receivedAt);
|
|
3116
|
+
}
|
|
3117
|
+
this.prevMessageHashes = nextHashes;
|
|
3118
|
+
return messages;
|
|
3119
|
+
}
|
|
3101
3120
|
mergeConversationMessages(messages) {
|
|
3102
3121
|
if (this.runtimeMessages.length === 0) return messages;
|
|
3103
3122
|
return [...messages, ...this.runtimeMessages.map((entry) => entry.message)].map((message, index) => ({ message, index })).sort((a, b) => {
|
|
@@ -3154,6 +3173,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
3154
3173
|
}
|
|
3155
3174
|
this.agentStreams = [];
|
|
3156
3175
|
this.messages = [];
|
|
3176
|
+
this.prevMessageHashes.clear();
|
|
3157
3177
|
this.activeModal = null;
|
|
3158
3178
|
this.currentModel = "";
|
|
3159
3179
|
this.currentMode = "";
|
|
@@ -4161,16 +4181,28 @@ function trimMessageForStatus(message, stringLimit) {
|
|
|
4161
4181
|
if (!message || typeof message !== "object") return message;
|
|
4162
4182
|
return trimStructuredStrings(message, stringLimit);
|
|
4163
4183
|
}
|
|
4184
|
+
function normalizeMessageTime(message) {
|
|
4185
|
+
if (!message || typeof message !== "object") return message;
|
|
4186
|
+
const msg = message;
|
|
4187
|
+
if (msg.receivedAt == null) {
|
|
4188
|
+
const fallback = msg.timestamp ?? msg.createdAt;
|
|
4189
|
+
if (fallback != null) {
|
|
4190
|
+
const ts2 = typeof fallback === "string" ? Date.parse(fallback) : Number(fallback);
|
|
4191
|
+
if (Number.isFinite(ts2) && ts2 > 0) msg.receivedAt = ts2;
|
|
4192
|
+
}
|
|
4193
|
+
}
|
|
4194
|
+
return msg;
|
|
4195
|
+
}
|
|
4164
4196
|
function trimMessagesForStatus(messages) {
|
|
4165
4197
|
if (!Array.isArray(messages) || messages.length === 0) return [];
|
|
4166
4198
|
const recent = messages.slice(-STATUS_ACTIVE_CHAT_MESSAGE_LIMIT);
|
|
4167
4199
|
const kept = [];
|
|
4168
4200
|
let totalBytes = 0;
|
|
4169
4201
|
for (let i = recent.length - 1; i >= 0; i -= 1) {
|
|
4170
|
-
let normalized = trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_STRING_LIMIT);
|
|
4202
|
+
let normalized = normalizeMessageTime(trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_STRING_LIMIT));
|
|
4171
4203
|
let size = estimateBytes(normalized);
|
|
4172
4204
|
if (size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {
|
|
4173
|
-
normalized = trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT);
|
|
4205
|
+
normalized = normalizeMessageTime(trimMessageForStatus(recent[i], STATUS_ACTIVE_CHAT_FALLBACK_STRING_LIMIT));
|
|
4174
4206
|
size = estimateBytes(normalized);
|
|
4175
4207
|
}
|
|
4176
4208
|
if (kept.length > 0 && totalBytes + size > STATUS_ACTIVE_CHAT_TOTAL_BYTES_LIMIT) {
|
|
@@ -4820,7 +4852,7 @@ async function handleSendChat(h, args) {
|
|
|
4820
4852
|
if (isExtensionTransport(transport)) {
|
|
4821
4853
|
_log(`Extension: ${provider?.type || "unknown_extension"}`);
|
|
4822
4854
|
try {
|
|
4823
|
-
const evalResult = await h.evaluateProviderScript("sendMessage", {
|
|
4855
|
+
const evalResult = await h.evaluateProviderScript("sendMessage", { message: text }, 3e4);
|
|
4824
4856
|
if (evalResult?.result) {
|
|
4825
4857
|
const parsed = parseMaybeJson(evalResult.result);
|
|
4826
4858
|
if (didProviderConfirmSend(parsed)) {
|
|
@@ -4851,7 +4883,7 @@ async function handleSendChat(h, args) {
|
|
|
4851
4883
|
return { success: false, error: `CDP for ${managerKey || "unknown"} not connected` };
|
|
4852
4884
|
}
|
|
4853
4885
|
_log(`Targeting IDE: ${getCurrentManagerKey(h)}`);
|
|
4854
|
-
const sendScript = h.getProviderScript("sendMessage", {
|
|
4886
|
+
const sendScript = h.getProviderScript("sendMessage", { message: text });
|
|
4855
4887
|
if (sendScript) {
|
|
4856
4888
|
try {
|
|
4857
4889
|
const result = await targetCdp.evaluate(sendScript, 3e4);
|
|
@@ -5859,10 +5891,10 @@ function getCliScriptCommand(payload) {
|
|
|
5859
5891
|
}
|
|
5860
5892
|
const command = payload.command;
|
|
5861
5893
|
if (!command || typeof command !== "object") return null;
|
|
5862
|
-
if (command.type !== "send_message") return null;
|
|
5894
|
+
if (command.type !== "send_message" && command.type !== "pty_write") return null;
|
|
5863
5895
|
const text = typeof command.text === "string" ? command.text.trim() : typeof command.message === "string" ? command.message.trim() : "";
|
|
5864
5896
|
if (!text) return null;
|
|
5865
|
-
return { type:
|
|
5897
|
+
return { type: command.type, text };
|
|
5866
5898
|
}
|
|
5867
5899
|
function applyProviderPatch(h, args, payload) {
|
|
5868
5900
|
if (!payload || typeof payload !== "object") return;
|
|
@@ -5903,6 +5935,8 @@ async function executeProviderScript(h, args, scriptName) {
|
|
|
5903
5935
|
const cliCommand = getCliScriptCommand(parsed.payload);
|
|
5904
5936
|
if (cliCommand?.type === "send_message" && cliCommand.text) {
|
|
5905
5937
|
await adapter.sendMessage(cliCommand.text);
|
|
5938
|
+
} else if (cliCommand?.type === "pty_write" && cliCommand.text && adapter.writeRaw) {
|
|
5939
|
+
adapter.writeRaw(cliCommand.text + "\r");
|
|
5906
5940
|
}
|
|
5907
5941
|
applyProviderPatch(h, args, parsed.payload);
|
|
5908
5942
|
return { success: true, ...parsed.payload && typeof parsed.payload === "object" ? parsed.payload : { result: parsed.payload } };
|
|
@@ -6293,9 +6327,26 @@ var init_handler = __esm({
|
|
|
6293
6327
|
if (provider?.scripts) {
|
|
6294
6328
|
const fn = provider.scripts[scriptName];
|
|
6295
6329
|
if (typeof fn === "function") {
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6330
|
+
if (params && Object.keys(params).length > 0) {
|
|
6331
|
+
const firstVal = Object.values(params)[0];
|
|
6332
|
+
if (scriptName === "sendMessage" && typeof firstVal === "string") {
|
|
6333
|
+
const legacyScript = fn(firstVal);
|
|
6334
|
+
if (legacyScript) return legacyScript;
|
|
6335
|
+
}
|
|
6336
|
+
const script = fn(params);
|
|
6337
|
+
if (script) {
|
|
6338
|
+
const likelyLegacyObjectLeak = typeof script === "string" && script.includes("[object Object]") && typeof firstVal === "string";
|
|
6339
|
+
if (!likelyLegacyObjectLeak) return script;
|
|
6340
|
+
}
|
|
6341
|
+
if (firstVal !== void 0) {
|
|
6342
|
+
const legacyScript = fn(firstVal);
|
|
6343
|
+
if (legacyScript) return legacyScript;
|
|
6344
|
+
}
|
|
6345
|
+
if (script) return script;
|
|
6346
|
+
} else {
|
|
6347
|
+
const script = fn();
|
|
6348
|
+
if (script) return script;
|
|
6349
|
+
}
|
|
6299
6350
|
}
|
|
6300
6351
|
}
|
|
6301
6352
|
return null;
|
|
@@ -9300,6 +9351,7 @@ var init_cli_provider_instance = __esm({
|
|
|
9300
9351
|
this.detectStatusTransition();
|
|
9301
9352
|
});
|
|
9302
9353
|
await this.adapter.spawn();
|
|
9354
|
+
this.maybeAppendRuntimeRecoveryMessage(this.adapter.getRuntimeMetadata());
|
|
9303
9355
|
if (this.providerSessionId) {
|
|
9304
9356
|
const restoredHistory = readChatHistory(this.type, 0, 200, this.providerSessionId);
|
|
9305
9357
|
if (restoredHistory.messages.length > 0) {
|
|
@@ -9394,6 +9446,7 @@ var init_cli_provider_instance = __esm({
|
|
|
9394
9446
|
this.promoteProviderSessionId(parsedProviderSessionId);
|
|
9395
9447
|
}
|
|
9396
9448
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
9449
|
+
this.maybeAppendRuntimeRecoveryMessage(runtime);
|
|
9397
9450
|
const parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
|
|
9398
9451
|
const controlValues = extractProviderControlValues(this.provider.controls, parsedStatus);
|
|
9399
9452
|
if (controlValues) {
|
|
@@ -9720,6 +9773,28 @@ ${effect.notification.body || ""}`.trim();
|
|
|
9720
9773
|
const pad = (value) => String(value).padStart(2, "0");
|
|
9721
9774
|
return `${date5.getFullYear()}-${pad(date5.getMonth() + 1)}-${pad(date5.getDate())} ${pad(date5.getHours())}:${pad(date5.getMinutes())}:${pad(date5.getSeconds())}`;
|
|
9722
9775
|
}
|
|
9776
|
+
maybeAppendRuntimeRecoveryMessage(runtime) {
|
|
9777
|
+
if (!runtime?.restoredFromStorage || !runtime.runtimeId) return;
|
|
9778
|
+
const recoveryState = String(runtime.recoveryState || "").trim();
|
|
9779
|
+
if (!recoveryState) return;
|
|
9780
|
+
let content = "";
|
|
9781
|
+
if (recoveryState === "auto_resumed") {
|
|
9782
|
+
content = "Session host restored this CLI after restart and reattached it from a saved snapshot.";
|
|
9783
|
+
} else if (recoveryState === "resume_failed") {
|
|
9784
|
+
const errorSuffix = runtime.recoveryError ? ` Resume failed: ${runtime.recoveryError}` : "";
|
|
9785
|
+
content = `Session host found this CLI after restart, but automatic resume failed.${errorSuffix}`;
|
|
9786
|
+
} else if (recoveryState === "host_restart_interrupted") {
|
|
9787
|
+
content = "Session host found this CLI in interrupted state after restart and is attempting to resume it.";
|
|
9788
|
+
} else if (recoveryState === "orphan_snapshot") {
|
|
9789
|
+
content = "Session host restored the last snapshot for this CLI, but the original runtime was not resumed automatically.";
|
|
9790
|
+
} else {
|
|
9791
|
+
content = `Session host restored this CLI after restart (${recoveryState}).`;
|
|
9792
|
+
}
|
|
9793
|
+
this.appendRuntimeSystemMessage(
|
|
9794
|
+
content,
|
|
9795
|
+
`runtime_recovery:${runtime.runtimeId}:${recoveryState}`
|
|
9796
|
+
);
|
|
9797
|
+
}
|
|
9723
9798
|
appendRuntimeSystemMessage(content, dedupKey, receivedAt = Date.now()) {
|
|
9724
9799
|
const normalizedContent = String(content || "").trim();
|
|
9725
9800
|
if (!normalizedContent) return;
|
|
@@ -31097,17 +31172,17 @@ function parseMessageTime(value) {
|
|
|
31097
31172
|
function getSessionMessageUpdatedAt(session) {
|
|
31098
31173
|
const lastMessage = session.activeChat?.messages?.at?.(-1);
|
|
31099
31174
|
if (!lastMessage) return 0;
|
|
31100
|
-
return parseMessageTime(lastMessage.
|
|
31175
|
+
return parseMessageTime(lastMessage.receivedAt) || 0;
|
|
31101
31176
|
}
|
|
31102
31177
|
function getSessionCompletionMarker(session) {
|
|
31103
31178
|
const lastMessage = session.activeChat?.messages?.at?.(-1);
|
|
31104
31179
|
if (!lastMessage) return "";
|
|
31105
31180
|
const role = typeof lastMessage.role === "string" ? lastMessage.role : "";
|
|
31106
|
-
if (role === "user" || role === "human") return "";
|
|
31181
|
+
if (role === "user" || role === "human" || role === "system") return "";
|
|
31107
31182
|
if (typeof lastMessage._turnKey === "string" && lastMessage._turnKey) return `turn:${lastMessage._turnKey}`;
|
|
31108
31183
|
if (typeof lastMessage.id === "string" && lastMessage.id) return `id:${lastMessage.id}`;
|
|
31109
31184
|
if (typeof lastMessage.index === "number" && Number.isFinite(lastMessage.index)) return `idx:${lastMessage.index}`;
|
|
31110
|
-
const timestamp = parseMessageTime(lastMessage.
|
|
31185
|
+
const timestamp = parseMessageTime(lastMessage.receivedAt);
|
|
31111
31186
|
return timestamp > 0 ? `ts:${timestamp}` : "";
|
|
31112
31187
|
}
|
|
31113
31188
|
function getSessionLastUsedAt(session) {
|
|
@@ -31124,7 +31199,7 @@ function getUnreadState(hasContentChange, status, lastUsedAt, lastSeenAt, lastRo
|
|
|
31124
31199
|
if (status === "generating" || status === "starting") {
|
|
31125
31200
|
return { unread: false, inboxBucket: "working" };
|
|
31126
31201
|
}
|
|
31127
|
-
const unread = completionMarker ? completionMarker !== seenCompletionMarker : hasContentChange && lastUsedAt > lastSeenAt && lastRole !== "user" && lastRole !== "human";
|
|
31202
|
+
const unread = completionMarker ? completionMarker !== seenCompletionMarker : hasContentChange && lastUsedAt > lastSeenAt && lastRole !== "user" && lastRole !== "human" && lastRole !== "system";
|
|
31128
31203
|
return { unread, inboxBucket: unread ? "task_complete" : "idle" };
|
|
31129
31204
|
}
|
|
31130
31205
|
function buildRecentLaunches(recentActivity) {
|
|
@@ -31422,6 +31497,25 @@ var init_upgrade_helper = __esm({
|
|
|
31422
31497
|
});
|
|
31423
31498
|
|
|
31424
31499
|
// ../../oss/packages/daemon-core/src/commands/router.ts
|
|
31500
|
+
function toHostedCliRuntimeDescriptor(record2) {
|
|
31501
|
+
if (!record2 || typeof record2 !== "object") return null;
|
|
31502
|
+
const runtimeId = typeof record2.sessionId === "string" ? record2.sessionId : "";
|
|
31503
|
+
const cliType = typeof record2.providerType === "string" ? record2.providerType : "";
|
|
31504
|
+
const workspace = typeof record2.workspace === "string" ? record2.workspace : "";
|
|
31505
|
+
if (!runtimeId || !cliType || !workspace) return null;
|
|
31506
|
+
return {
|
|
31507
|
+
runtimeId,
|
|
31508
|
+
runtimeKey: typeof record2.runtimeKey === "string" ? record2.runtimeKey : void 0,
|
|
31509
|
+
displayName: typeof record2.displayName === "string" ? record2.displayName : void 0,
|
|
31510
|
+
workspaceLabel: typeof record2.workspaceLabel === "string" ? record2.workspaceLabel : void 0,
|
|
31511
|
+
lifecycle: typeof record2.lifecycle === "string" ? record2.lifecycle : void 0,
|
|
31512
|
+
recoveryState: typeof record2.meta?.runtimeRecoveryState === "string" ? String(record2.meta.runtimeRecoveryState) : null,
|
|
31513
|
+
cliType,
|
|
31514
|
+
workspace,
|
|
31515
|
+
cliArgs: Array.isArray(record2.meta?.cliArgs) ? record2.meta.cliArgs : [],
|
|
31516
|
+
providerSessionId: typeof record2.meta?.providerSessionId === "string" ? String(record2.meta.providerSessionId) : void 0
|
|
31517
|
+
};
|
|
31518
|
+
}
|
|
31425
31519
|
var fs9, CHAT_COMMANDS, READ_DEBUG_ENABLED2, DaemonCommandRouter;
|
|
31426
31520
|
var init_router = __esm({
|
|
31427
31521
|
"../../oss/packages/daemon-core/src/commands/router.ts"() {
|
|
@@ -31525,6 +31619,90 @@ var init_router = __esm({
|
|
|
31525
31619
|
return { success: false, error: e.message };
|
|
31526
31620
|
}
|
|
31527
31621
|
}
|
|
31622
|
+
case "session_host_get_diagnostics": {
|
|
31623
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
31624
|
+
const diagnostics = await this.deps.sessionHostControl.getDiagnostics({
|
|
31625
|
+
includeSessions: args?.includeSessions !== false,
|
|
31626
|
+
limit: Number(args?.limit) || void 0
|
|
31627
|
+
});
|
|
31628
|
+
return { success: true, diagnostics };
|
|
31629
|
+
}
|
|
31630
|
+
case "session_host_list_sessions": {
|
|
31631
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
31632
|
+
const sessions = await this.deps.sessionHostControl.listSessions();
|
|
31633
|
+
return { success: true, sessions };
|
|
31634
|
+
}
|
|
31635
|
+
case "session_host_stop_session": {
|
|
31636
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
31637
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
31638
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
31639
|
+
const record2 = await this.deps.sessionHostControl.stopSession(sessionId);
|
|
31640
|
+
return { success: true, record: record2 };
|
|
31641
|
+
}
|
|
31642
|
+
case "session_host_resume_session": {
|
|
31643
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
31644
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
31645
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
31646
|
+
const record2 = await this.deps.sessionHostControl.resumeSession(sessionId);
|
|
31647
|
+
const hosted = toHostedCliRuntimeDescriptor(record2);
|
|
31648
|
+
if (hosted) {
|
|
31649
|
+
await this.deps.cliManager.restoreHostedSessions([hosted]);
|
|
31650
|
+
}
|
|
31651
|
+
return { success: true, record: record2 };
|
|
31652
|
+
}
|
|
31653
|
+
case "session_host_restart_session": {
|
|
31654
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
31655
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
31656
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
31657
|
+
const record2 = await this.deps.sessionHostControl.restartSession(sessionId);
|
|
31658
|
+
const hosted = toHostedCliRuntimeDescriptor(record2);
|
|
31659
|
+
if (hosted) {
|
|
31660
|
+
await this.deps.cliManager.restoreHostedSessions([hosted]);
|
|
31661
|
+
}
|
|
31662
|
+
return { success: true, record: record2 };
|
|
31663
|
+
}
|
|
31664
|
+
case "session_host_send_signal": {
|
|
31665
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
31666
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
31667
|
+
const signal = typeof args?.signal === "string" ? args.signal : "";
|
|
31668
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
31669
|
+
if (!signal) return { success: false, error: "signal required" };
|
|
31670
|
+
const record2 = await this.deps.sessionHostControl.sendSignal(sessionId, signal);
|
|
31671
|
+
return { success: true, record: record2 };
|
|
31672
|
+
}
|
|
31673
|
+
case "session_host_force_detach_client": {
|
|
31674
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
31675
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
31676
|
+
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
31677
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
31678
|
+
if (!clientId) return { success: false, error: "clientId required" };
|
|
31679
|
+
const record2 = await this.deps.sessionHostControl.forceDetachClient(sessionId, clientId);
|
|
31680
|
+
return { success: true, record: record2 };
|
|
31681
|
+
}
|
|
31682
|
+
case "session_host_acquire_write": {
|
|
31683
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
31684
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
31685
|
+
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
31686
|
+
const ownerType = args?.ownerType === "agent" ? "agent" : "user";
|
|
31687
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
31688
|
+
if (!clientId) return { success: false, error: "clientId required" };
|
|
31689
|
+
const record2 = await this.deps.sessionHostControl.acquireWrite({
|
|
31690
|
+
sessionId,
|
|
31691
|
+
clientId,
|
|
31692
|
+
ownerType,
|
|
31693
|
+
force: args?.force !== false
|
|
31694
|
+
});
|
|
31695
|
+
return { success: true, record: record2 };
|
|
31696
|
+
}
|
|
31697
|
+
case "session_host_release_write": {
|
|
31698
|
+
if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
|
|
31699
|
+
const sessionId = typeof args?.sessionId === "string" ? args.sessionId : "";
|
|
31700
|
+
const clientId = typeof args?.clientId === "string" ? args.clientId : "";
|
|
31701
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
31702
|
+
if (!clientId) return { success: false, error: "clientId required" };
|
|
31703
|
+
const record2 = await this.deps.sessionHostControl.releaseWrite({ sessionId, clientId });
|
|
31704
|
+
return { success: true, record: record2 };
|
|
31705
|
+
}
|
|
31528
31706
|
case "list_saved_sessions": {
|
|
31529
31707
|
const providerType = typeof args?.providerType === "string" ? args.providerType.trim() : typeof args?.agentType === "string" ? args.agentType.trim() : "";
|
|
31530
31708
|
const kind = args?.kind === "acp" ? "acp" : "cli";
|
|
@@ -32071,6 +32249,14 @@ var init_provider_adapter = __esm({
|
|
|
32071
32249
|
hasScript(name) {
|
|
32072
32250
|
return typeof this.provider.scripts?.[name] === "function";
|
|
32073
32251
|
}
|
|
32252
|
+
parseMaybeJson(raw) {
|
|
32253
|
+
if (typeof raw !== "string") return raw;
|
|
32254
|
+
try {
|
|
32255
|
+
return JSON.parse(raw);
|
|
32256
|
+
} catch {
|
|
32257
|
+
return raw;
|
|
32258
|
+
}
|
|
32259
|
+
}
|
|
32074
32260
|
summarizeRaw(raw) {
|
|
32075
32261
|
try {
|
|
32076
32262
|
if (typeof raw === "string") return raw.replace(/\s+/g, " ").trim().slice(0, 240);
|
|
@@ -32131,12 +32317,30 @@ var init_provider_adapter = __esm({
|
|
|
32131
32317
|
}
|
|
32132
32318
|
}
|
|
32133
32319
|
async sendMessage(evaluate, text) {
|
|
32134
|
-
const
|
|
32320
|
+
const params = { message: text };
|
|
32321
|
+
const script = this.callScript("sendMessage", params) || this.callScript("sendMessage", text);
|
|
32135
32322
|
if (!script) throw new Error(`[${this.agentName}] sendMessage script not available`);
|
|
32136
32323
|
const result = await evaluate(script);
|
|
32137
32324
|
if (result && typeof result === "string" && result.startsWith("error:")) {
|
|
32138
32325
|
throw new Error(`[${this.agentName}] sendMessage failed: ${result}`);
|
|
32139
32326
|
}
|
|
32327
|
+
const parsed = this.parseMaybeJson(result);
|
|
32328
|
+
if (parsed === true) return;
|
|
32329
|
+
if (typeof parsed === "string") {
|
|
32330
|
+
const normalized = parsed.trim().toLowerCase();
|
|
32331
|
+
if (normalized === "ok" || normalized === "sent" || normalized === "success" || normalized === "true") {
|
|
32332
|
+
return;
|
|
32333
|
+
}
|
|
32334
|
+
}
|
|
32335
|
+
if (parsed && typeof parsed === "object") {
|
|
32336
|
+
if (parsed.sent === true || parsed.success === true || parsed.ok === true || parsed.submitted === true || parsed.dispatched === true) {
|
|
32337
|
+
return;
|
|
32338
|
+
}
|
|
32339
|
+
if (typeof parsed.error === "string" && parsed.error.trim()) {
|
|
32340
|
+
throw new Error(`[${this.agentName}] sendMessage failed: ${parsed.error}`);
|
|
32341
|
+
}
|
|
32342
|
+
}
|
|
32343
|
+
throw new Error(`[${this.agentName}] sendMessage was not confirmed`);
|
|
32140
32344
|
}
|
|
32141
32345
|
async resolveAction(evaluate, action, button) {
|
|
32142
32346
|
const script = this.callScript("resolveAction", { action, button });
|
|
@@ -38471,6 +38675,7 @@ var init_session_host_transport = __esm({
|
|
|
38471
38675
|
}
|
|
38472
38676
|
}
|
|
38473
38677
|
handleEvent(event) {
|
|
38678
|
+
if (!("sessionId" in event)) return;
|
|
38474
38679
|
if (event.sessionId !== this.options.runtimeId) return;
|
|
38475
38680
|
if ((event.type === "session_started" || event.type === "session_resumed") && typeof event.pid === "number") {
|
|
38476
38681
|
this.currentPid = event.pid;
|
|
@@ -38546,7 +38751,10 @@ var init_session_host_transport = __esm({
|
|
|
38546
38751
|
clientId: client.clientId,
|
|
38547
38752
|
type: client.type,
|
|
38548
38753
|
readOnly: client.readOnly
|
|
38549
|
-
}))
|
|
38754
|
+
})),
|
|
38755
|
+
restoredFromStorage: record2.meta?.restoredFromStorage === true,
|
|
38756
|
+
recoveryState: typeof record2.meta?.runtimeRecoveryState === "string" ? String(record2.meta.runtimeRecoveryState) : null,
|
|
38757
|
+
recoveryError: typeof record2.meta?.runtimeRecoveryError === "string" ? String(record2.meta.runtimeRecoveryError) : null
|
|
38550
38758
|
};
|
|
38551
38759
|
}
|
|
38552
38760
|
enqueue(action) {
|
|
@@ -39008,6 +39216,7 @@ async function initDaemonComponents(config2) {
|
|
|
39008
39216
|
onIdeConnected: () => poller?.start(),
|
|
39009
39217
|
onStatusChange: config2.onStatusChange,
|
|
39010
39218
|
onPostChatCommand: config2.onPostChatCommand,
|
|
39219
|
+
sessionHostControl: config2.sessionHostControl,
|
|
39011
39220
|
getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn())
|
|
39012
39221
|
});
|
|
39013
39222
|
poller = new AgentStreamPoller({
|
|
@@ -47257,6 +47466,151 @@ var init_session_host = __esm({
|
|
|
47257
47466
|
}
|
|
47258
47467
|
});
|
|
47259
47468
|
|
|
47469
|
+
// src/session-host-controller.ts
|
|
47470
|
+
var SessionHostController;
|
|
47471
|
+
var init_session_host_controller = __esm({
|
|
47472
|
+
"src/session-host-controller.ts"() {
|
|
47473
|
+
"use strict";
|
|
47474
|
+
init_src();
|
|
47475
|
+
init_dist();
|
|
47476
|
+
SessionHostController = class {
|
|
47477
|
+
constructor(endpoint, onEvent) {
|
|
47478
|
+
this.onEvent = onEvent;
|
|
47479
|
+
this.client = new SessionHostClient({ endpoint });
|
|
47480
|
+
}
|
|
47481
|
+
client;
|
|
47482
|
+
reconnectTimer = null;
|
|
47483
|
+
unsubscribe = null;
|
|
47484
|
+
started = false;
|
|
47485
|
+
async start() {
|
|
47486
|
+
if (this.started) return;
|
|
47487
|
+
this.started = true;
|
|
47488
|
+
this.unsubscribe = this.client.onEvent((event) => this.handleEvent(event));
|
|
47489
|
+
await this.ensureConnected();
|
|
47490
|
+
this.reconnectTimer = setInterval(() => {
|
|
47491
|
+
void this.ensureConnected();
|
|
47492
|
+
}, 2e3);
|
|
47493
|
+
}
|
|
47494
|
+
async stop() {
|
|
47495
|
+
this.started = false;
|
|
47496
|
+
if (this.reconnectTimer) {
|
|
47497
|
+
clearInterval(this.reconnectTimer);
|
|
47498
|
+
this.reconnectTimer = null;
|
|
47499
|
+
}
|
|
47500
|
+
try {
|
|
47501
|
+
this.unsubscribe?.();
|
|
47502
|
+
this.unsubscribe = null;
|
|
47503
|
+
} catch {
|
|
47504
|
+
}
|
|
47505
|
+
await this.client.close().catch(() => {
|
|
47506
|
+
});
|
|
47507
|
+
}
|
|
47508
|
+
async getDiagnostics(payload = {}) {
|
|
47509
|
+
return this.request({
|
|
47510
|
+
type: "get_host_diagnostics",
|
|
47511
|
+
payload
|
|
47512
|
+
});
|
|
47513
|
+
}
|
|
47514
|
+
async listSessions() {
|
|
47515
|
+
return this.request({
|
|
47516
|
+
type: "list_sessions",
|
|
47517
|
+
payload: {}
|
|
47518
|
+
});
|
|
47519
|
+
}
|
|
47520
|
+
async stopSession(sessionId) {
|
|
47521
|
+
return this.request({
|
|
47522
|
+
type: "stop_session",
|
|
47523
|
+
payload: { sessionId }
|
|
47524
|
+
});
|
|
47525
|
+
}
|
|
47526
|
+
async resumeSession(sessionId) {
|
|
47527
|
+
return this.request({
|
|
47528
|
+
type: "resume_session",
|
|
47529
|
+
payload: { sessionId }
|
|
47530
|
+
});
|
|
47531
|
+
}
|
|
47532
|
+
async restartSession(sessionId) {
|
|
47533
|
+
return this.request({
|
|
47534
|
+
type: "restart_session",
|
|
47535
|
+
payload: { sessionId }
|
|
47536
|
+
});
|
|
47537
|
+
}
|
|
47538
|
+
async sendSignal(sessionId, signal) {
|
|
47539
|
+
return this.request({
|
|
47540
|
+
type: "send_signal",
|
|
47541
|
+
payload: { sessionId, signal }
|
|
47542
|
+
});
|
|
47543
|
+
}
|
|
47544
|
+
async forceDetachClient(sessionId, clientId) {
|
|
47545
|
+
return this.request({
|
|
47546
|
+
type: "force_detach_client",
|
|
47547
|
+
payload: { sessionId, clientId }
|
|
47548
|
+
});
|
|
47549
|
+
}
|
|
47550
|
+
async acquireWrite(payload) {
|
|
47551
|
+
return this.request({
|
|
47552
|
+
type: "acquire_write",
|
|
47553
|
+
payload
|
|
47554
|
+
});
|
|
47555
|
+
}
|
|
47556
|
+
async releaseWrite(payload) {
|
|
47557
|
+
return this.request({
|
|
47558
|
+
type: "release_write",
|
|
47559
|
+
payload
|
|
47560
|
+
});
|
|
47561
|
+
}
|
|
47562
|
+
async request(request) {
|
|
47563
|
+
await this.ensureConnected();
|
|
47564
|
+
const response = await this.client.request(request);
|
|
47565
|
+
if (!response.success) {
|
|
47566
|
+
throw new Error(response.error || `Session host request failed: ${request.type}`);
|
|
47567
|
+
}
|
|
47568
|
+
return response.result ?? null;
|
|
47569
|
+
}
|
|
47570
|
+
async ensureConnected() {
|
|
47571
|
+
try {
|
|
47572
|
+
await this.client.connect();
|
|
47573
|
+
} catch (error48) {
|
|
47574
|
+
if (!this.started) return;
|
|
47575
|
+
LOG.debug("SessionHost", `connect failed: ${error48?.message || error48}`);
|
|
47576
|
+
}
|
|
47577
|
+
}
|
|
47578
|
+
handleEvent(event) {
|
|
47579
|
+
if (event.type === "host_log") {
|
|
47580
|
+
const line = event.entry.sessionId ? `${event.entry.message} (session=${event.entry.sessionId})` : event.entry.message;
|
|
47581
|
+
switch (event.entry.level) {
|
|
47582
|
+
case "debug":
|
|
47583
|
+
LOG.debug("SessionHost", line);
|
|
47584
|
+
break;
|
|
47585
|
+
case "warn":
|
|
47586
|
+
LOG.warn("SessionHost", line);
|
|
47587
|
+
break;
|
|
47588
|
+
case "error":
|
|
47589
|
+
LOG.error("SessionHost", line);
|
|
47590
|
+
break;
|
|
47591
|
+
default:
|
|
47592
|
+
LOG.info("SessionHost", line);
|
|
47593
|
+
break;
|
|
47594
|
+
}
|
|
47595
|
+
} else if (event.type === "request_trace") {
|
|
47596
|
+
const line = `${event.trace.type} ${event.trace.success ? "ok" : "failed"} ${event.trace.durationMs}ms` + (event.trace.sessionId ? ` session=${event.trace.sessionId}` : "") + (event.trace.error ? ` error=${event.trace.error}` : "");
|
|
47597
|
+
if (event.trace.success) LOG.debug("SessionHost", line);
|
|
47598
|
+
else LOG.warn("SessionHost", line);
|
|
47599
|
+
} else if (event.type === "runtime_transition") {
|
|
47600
|
+
const line = `${event.transition.action} ${event.transition.success === false ? "failed" : "ok"}` + (event.transition.lifecycle ? ` lifecycle=${event.transition.lifecycle}` : "") + (event.transition.detail ? ` detail=${event.transition.detail}` : "") + (event.transition.error ? ` error=${event.transition.error}` : "");
|
|
47601
|
+
if (event.transition.success === false) LOG.warn("SessionHost", `[${event.transition.sessionId}] ${line}`);
|
|
47602
|
+
else LOG.info("SessionHost", `[${event.transition.sessionId}] ${line}`);
|
|
47603
|
+
}
|
|
47604
|
+
try {
|
|
47605
|
+
this.onEvent?.(event);
|
|
47606
|
+
} catch (error48) {
|
|
47607
|
+
LOG.warn("SessionHost", `event callback failed: ${error48?.message || error48}`);
|
|
47608
|
+
}
|
|
47609
|
+
}
|
|
47610
|
+
};
|
|
47611
|
+
}
|
|
47612
|
+
});
|
|
47613
|
+
|
|
47260
47614
|
// src/version.ts
|
|
47261
47615
|
function resolvePackageVersion(options) {
|
|
47262
47616
|
const injectedVersion = options?.injectedVersion || "unknown";
|
|
@@ -47351,6 +47705,7 @@ var init_adhdev_daemon = __esm({
|
|
|
47351
47705
|
init_screenshot_controller();
|
|
47352
47706
|
init_session_host();
|
|
47353
47707
|
init_dist();
|
|
47708
|
+
init_session_host_controller();
|
|
47354
47709
|
os21 = __toESM(require("os"));
|
|
47355
47710
|
fs17 = __toESM(require("fs"));
|
|
47356
47711
|
path21 = __toESM(require("path"));
|
|
@@ -47358,7 +47713,7 @@ var init_adhdev_daemon = __esm({
|
|
|
47358
47713
|
import_ws3 = require("ws");
|
|
47359
47714
|
import_chalk2 = __toESM(require("chalk"));
|
|
47360
47715
|
init_version();
|
|
47361
|
-
pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.
|
|
47716
|
+
pkgVersion = resolvePackageVersion({ injectedVersion: "0.8.27" });
|
|
47362
47717
|
DANGEROUS_PATTERNS = [
|
|
47363
47718
|
/\brm\s+(-[a-z]*f|-[a-z]*r|--force|--recursive)/i,
|
|
47364
47719
|
/\bsudo\b/i,
|
|
@@ -47381,6 +47736,7 @@ var init_adhdev_daemon = __esm({
|
|
|
47381
47736
|
statusReporter = null;
|
|
47382
47737
|
components = null;
|
|
47383
47738
|
sessionHostEndpoint = null;
|
|
47739
|
+
sessionHostController = null;
|
|
47384
47740
|
running = false;
|
|
47385
47741
|
localPort;
|
|
47386
47742
|
ideType = "unknown";
|
|
@@ -47431,6 +47787,11 @@ ${err?.stack || ""}`);
|
|
|
47431
47787
|
}
|
|
47432
47788
|
const sessionHostEndpoint = await ensureSessionHostReady2();
|
|
47433
47789
|
this.sessionHostEndpoint = sessionHostEndpoint;
|
|
47790
|
+
this.sessionHostController = new SessionHostController(
|
|
47791
|
+
sessionHostEndpoint,
|
|
47792
|
+
(event) => this.broadcastLocalIpcMessage("daemon:session_host_event", event)
|
|
47793
|
+
);
|
|
47794
|
+
await this.sessionHostController.start();
|
|
47434
47795
|
this.components = await initDaemonComponents({
|
|
47435
47796
|
providerLogFn: LOG.forComponent("Provider").asLogFn(),
|
|
47436
47797
|
cliManagerDeps: {
|
|
@@ -47468,6 +47829,7 @@ ${err?.stack || ""}`);
|
|
|
47468
47829
|
setTimeout(() => this.statusReporter?.throttledReport(), 1e3);
|
|
47469
47830
|
setTimeout(() => this.statusReporter?.throttledReport(), 3e3);
|
|
47470
47831
|
},
|
|
47832
|
+
sessionHostControl: this.sessionHostController,
|
|
47471
47833
|
getCdpLogFn: (ideType) => LOG.forComponent(`CDP:${ideType}`).asLogFn(),
|
|
47472
47834
|
onCdpManagerSetup: (ideType) => {
|
|
47473
47835
|
if (this.ideType === "unknown") this.ideType = ideType;
|
|
@@ -47824,13 +48186,24 @@ ${err?.stack || ""}`);
|
|
|
47824
48186
|
serverConnected: this.serverConn?.isConnected() ?? false,
|
|
47825
48187
|
cdpConnected: (this.components?.cdpManagers.size || 0) > 0,
|
|
47826
48188
|
localPort: this.localPort,
|
|
47827
|
-
cliAgents
|
|
48189
|
+
cliAgents,
|
|
48190
|
+
sessionHostConnected: !!this.sessionHostController
|
|
47828
48191
|
}
|
|
47829
48192
|
}));
|
|
47830
48193
|
} catch (error48) {
|
|
47831
48194
|
LOG.warn("IPC", `Failed to send welcome: ${error48?.message || error48}`);
|
|
47832
48195
|
}
|
|
47833
48196
|
}
|
|
48197
|
+
broadcastLocalIpcMessage(type, payload) {
|
|
48198
|
+
const message = JSON.stringify({ type, payload });
|
|
48199
|
+
for (const client of this.localClients) {
|
|
48200
|
+
if (client.readyState !== import_ws3.WebSocket.OPEN) continue;
|
|
48201
|
+
try {
|
|
48202
|
+
client.send(message);
|
|
48203
|
+
} catch {
|
|
48204
|
+
}
|
|
48205
|
+
}
|
|
48206
|
+
}
|
|
47834
48207
|
async handleLocalIpcMessage(ws, raw) {
|
|
47835
48208
|
let msg;
|
|
47836
48209
|
try {
|
|
@@ -47921,6 +48294,11 @@ ${err?.stack || ""}`);
|
|
|
47921
48294
|
this.serverConn?.disconnect();
|
|
47922
48295
|
} catch {
|
|
47923
48296
|
}
|
|
48297
|
+
try {
|
|
48298
|
+
await this.sessionHostController?.stop();
|
|
48299
|
+
this.sessionHostController = null;
|
|
48300
|
+
} catch {
|
|
48301
|
+
}
|
|
47924
48302
|
try {
|
|
47925
48303
|
for (const client of this.localClients) {
|
|
47926
48304
|
client.close();
|