@adhdev/daemon-core 0.8.69 → 0.8.70
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/manager.d.ts +2 -1
- package/dist/agent-stream/provider-adapter.d.ts +6 -2
- package/dist/agent-stream/types.d.ts +5 -2
- package/dist/commands/stream-commands.d.ts +2 -1
- package/dist/config/recent-activity.d.ts +4 -3
- package/dist/index.js +286 -64
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +286 -64
- package/dist/index.mjs.map +1 -1
- package/dist/providers/contracts.d.ts +10 -0
- package/dist/providers/extension-provider-instance.d.ts +1 -0
- package/dist/providers/open-panel-support.d.ts +6 -0
- package/dist/providers/provider-instance.d.ts +2 -1
- package/dist/shared-types.d.ts +1 -1
- package/dist/types.d.ts +1 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/agent-stream/forward.ts +1 -0
- package/src/agent-stream/manager.d.ts +2 -1
- package/src/agent-stream/manager.ts +20 -5
- package/src/agent-stream/provider-adapter.d.ts +3 -2
- package/src/agent-stream/provider-adapter.ts +123 -4
- package/src/agent-stream/types.d.ts +3 -2
- package/src/agent-stream/types.ts +5 -2
- package/src/cli-adapters/provider-cli-adapter.ts +3 -1
- package/src/commands/cli-manager.ts +12 -0
- package/src/commands/handler.ts +4 -2
- package/src/commands/router.ts +1 -0
- package/src/commands/stream-commands.d.ts +2 -1
- package/src/commands/stream-commands.ts +74 -2
- package/src/config/recent-activity.ts +25 -15
- package/src/daemon/dev-auto-implement.ts +2 -2
- package/src/daemon/dev-server.ts +2 -2
- package/src/daemon/scaffold-template.ts +12 -5
- package/src/providers/contracts.d.ts +10 -0
- package/src/providers/contracts.ts +14 -0
- package/src/providers/extension-provider-instance.ts +15 -2
- package/src/providers/ide-provider-instance.ts +2 -0
- package/src/providers/open-panel-support.ts +40 -0
- package/src/providers/provider-instance.d.ts +2 -1
- package/src/providers/provider-instance.ts +2 -1
- package/src/providers/provider-schema.ts +10 -0
- package/src/providers/read-chat-contract.ts +1 -0
- package/src/shared-types.d.ts +1 -1
- package/src/shared-types.ts +1 -0
- package/src/status/builders.ts +9 -23
- package/src/status/snapshot.ts +2 -2
- package/src/types.ts +1 -0
package/dist/index.mjs
CHANGED
|
@@ -865,6 +865,7 @@ function validateMessage(message, source, index) {
|
|
|
865
865
|
if (isFiniteNumber(message.index)) normalized.index = message.index;
|
|
866
866
|
if (isFiniteNumber(message.timestamp)) normalized.timestamp = message.timestamp;
|
|
867
867
|
if (isFiniteNumber(message.receivedAt)) normalized.receivedAt = message.receivedAt;
|
|
868
|
+
if (typeof message._turnKey === "string") normalized._turnKey = message._turnKey;
|
|
868
869
|
if (Array.isArray(message.toolCalls)) normalized.toolCalls = message.toolCalls;
|
|
869
870
|
if (isPlainObject3(message.meta)) normalized.meta = message.meta;
|
|
870
871
|
if (typeof message.senderName === "string") normalized.senderName = message.senderName;
|
|
@@ -3021,7 +3022,9 @@ ${data.message || ""}`.trim();
|
|
|
3021
3022
|
}
|
|
3022
3023
|
}
|
|
3023
3024
|
if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
|
|
3024
|
-
if (this.isWaitingForResponse)
|
|
3025
|
+
if (this.isWaitingForResponse) {
|
|
3026
|
+
throw new Error(`${this.cliName} is still processing the previous prompt`);
|
|
3027
|
+
}
|
|
3025
3028
|
const blockingModal = this.activeModal || this.getStartupConfirmationModal(this.terminalScreen.getText() || "");
|
|
3026
3029
|
if (blockingModal || this.currentStatus === "waiting_approval") {
|
|
3027
3030
|
throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
|
|
@@ -3814,27 +3817,37 @@ function getRecentActivity(state, limit = 20) {
|
|
|
3814
3817
|
})
|
|
3815
3818
|
})).sort((a, b) => b.lastUsedAt - a.lastUsedAt).slice(0, limit);
|
|
3816
3819
|
}
|
|
3817
|
-
function
|
|
3818
|
-
|
|
3820
|
+
function buildSessionReadStateKey(sessionId, providerSessionId) {
|
|
3821
|
+
const normalizedProviderSessionId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
|
|
3822
|
+
if (normalizedProviderSessionId) return `provider:${normalizedProviderSessionId}`;
|
|
3823
|
+
return sessionId;
|
|
3824
|
+
}
|
|
3825
|
+
function getSessionSeenAt(state, sessionId, providerSessionId) {
|
|
3826
|
+
const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
|
|
3827
|
+
return state.sessionReads?.[providerKey] || state.sessionReads?.[sessionId] || 0;
|
|
3819
3828
|
}
|
|
3820
|
-
function getSessionSeenMarker(state, sessionId) {
|
|
3821
|
-
|
|
3829
|
+
function getSessionSeenMarker(state, sessionId, providerSessionId) {
|
|
3830
|
+
const providerKey = buildSessionReadStateKey(sessionId, providerSessionId);
|
|
3831
|
+
return state.sessionReadMarkers?.[providerKey] || state.sessionReadMarkers?.[sessionId] || "";
|
|
3822
3832
|
}
|
|
3823
|
-
function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker) {
|
|
3833
|
+
function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker, providerSessionId) {
|
|
3824
3834
|
const prev = state.sessionReads || {};
|
|
3825
|
-
const nextSeenAt = Math.max(prev[sessionId] || 0, seenAt);
|
|
3826
3835
|
const prevMarkers = state.sessionReadMarkers || {};
|
|
3827
3836
|
const nextMarker = typeof completionMarker === "string" ? completionMarker : "";
|
|
3837
|
+
const readKeys = Array.from(new Set([
|
|
3838
|
+
sessionId,
|
|
3839
|
+
buildSessionReadStateKey(sessionId, providerSessionId)
|
|
3840
|
+
].filter(Boolean)));
|
|
3841
|
+
const nextSessionReads = { ...prev };
|
|
3842
|
+
const nextSessionReadMarkers = { ...prevMarkers };
|
|
3843
|
+
for (const key of readKeys) {
|
|
3844
|
+
nextSessionReads[key] = Math.max(prev[key] || 0, seenAt);
|
|
3845
|
+
if (nextMarker) nextSessionReadMarkers[key] = nextMarker;
|
|
3846
|
+
}
|
|
3828
3847
|
return {
|
|
3829
3848
|
...state,
|
|
3830
|
-
sessionReads:
|
|
3831
|
-
|
|
3832
|
-
[sessionId]: nextSeenAt
|
|
3833
|
-
},
|
|
3834
|
-
sessionReadMarkers: nextMarker ? {
|
|
3835
|
-
...prevMarkers,
|
|
3836
|
-
[sessionId]: nextMarker
|
|
3837
|
-
} : prevMarkers
|
|
3849
|
+
sessionReads: nextSessionReads,
|
|
3850
|
+
sessionReadMarkers: nextMarker ? nextSessionReadMarkers : prevMarkers
|
|
3838
3851
|
};
|
|
3839
3852
|
}
|
|
3840
3853
|
|
|
@@ -6434,6 +6447,39 @@ function resolveProviderStateSurface(params) {
|
|
|
6434
6447
|
|
|
6435
6448
|
// src/providers/extension-provider-instance.ts
|
|
6436
6449
|
init_chat_message_normalization();
|
|
6450
|
+
|
|
6451
|
+
// src/providers/open-panel-support.ts
|
|
6452
|
+
var IDE_PROVIDER_SESSION_CAPABILITIES_BASE = [
|
|
6453
|
+
"read_chat",
|
|
6454
|
+
"send_message",
|
|
6455
|
+
"new_session",
|
|
6456
|
+
"list_sessions",
|
|
6457
|
+
"switch_session",
|
|
6458
|
+
"resolve_action",
|
|
6459
|
+
"change_model",
|
|
6460
|
+
"set_mode",
|
|
6461
|
+
"set_thought_level"
|
|
6462
|
+
];
|
|
6463
|
+
var EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE = [
|
|
6464
|
+
"read_chat",
|
|
6465
|
+
"send_message",
|
|
6466
|
+
"new_session",
|
|
6467
|
+
"list_sessions",
|
|
6468
|
+
"switch_session",
|
|
6469
|
+
"resolve_action",
|
|
6470
|
+
"change_model",
|
|
6471
|
+
"set_mode"
|
|
6472
|
+
];
|
|
6473
|
+
function providerHasOpenPanelSupport(provider) {
|
|
6474
|
+
if (typeof provider.scripts?.openPanel === "function") return true;
|
|
6475
|
+
if (provider.category === "ide" && typeof provider.scripts?.webviewOpenPanel === "function") return true;
|
|
6476
|
+
return false;
|
|
6477
|
+
}
|
|
6478
|
+
function getProviderSessionCapabilities(provider, baseCapabilities) {
|
|
6479
|
+
return providerHasOpenPanelSupport(provider) ? [...baseCapabilities, "open_panel"] : [...baseCapabilities];
|
|
6480
|
+
}
|
|
6481
|
+
|
|
6482
|
+
// src/providers/extension-provider-instance.ts
|
|
6437
6483
|
var ExtensionProviderInstance = class {
|
|
6438
6484
|
type;
|
|
6439
6485
|
category = "extension";
|
|
@@ -6459,6 +6505,7 @@ var ExtensionProviderInstance = class {
|
|
|
6459
6505
|
instanceId;
|
|
6460
6506
|
ideType = "";
|
|
6461
6507
|
chatId = null;
|
|
6508
|
+
providerSessionId = null;
|
|
6462
6509
|
chatTitle = null;
|
|
6463
6510
|
agentName = "";
|
|
6464
6511
|
extensionId = "";
|
|
@@ -6492,8 +6539,10 @@ var ExtensionProviderInstance = class {
|
|
|
6492
6539
|
name: this.provider.name,
|
|
6493
6540
|
category: "extension",
|
|
6494
6541
|
status: this.currentStatus,
|
|
6542
|
+
providerSessionId: this.providerSessionId || this.chatId || void 0,
|
|
6543
|
+
sessionCapabilities: getProviderSessionCapabilities(this.provider, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE),
|
|
6495
6544
|
activeChat: this.messages.length > 0 || this.runtimeMessages.length > 0 ? {
|
|
6496
|
-
id: this.chatId || this.instanceId,
|
|
6545
|
+
id: this.providerSessionId || this.chatId || this.instanceId,
|
|
6497
6546
|
title: this.chatTitle || this.agentName || this.provider.name,
|
|
6498
6547
|
status: this.currentStatus,
|
|
6499
6548
|
messages: this.mergeConversationMessages(this.messages),
|
|
@@ -6523,7 +6572,11 @@ var ExtensionProviderInstance = class {
|
|
|
6523
6572
|
});
|
|
6524
6573
|
this.controlValues = patchedState.controlValues;
|
|
6525
6574
|
this.summaryMetadata = patchedState.summaryMetadata;
|
|
6526
|
-
|
|
6575
|
+
const nextProviderSessionId = typeof data?.providerSessionId === "string" && data.providerSessionId.trim() ? data.providerSessionId.trim() : typeof data?.sessionId === "string" && data.sessionId.trim() ? data.sessionId.trim() : "";
|
|
6576
|
+
if (nextProviderSessionId) {
|
|
6577
|
+
this.providerSessionId = nextProviderSessionId;
|
|
6578
|
+
this.chatId = nextProviderSessionId;
|
|
6579
|
+
}
|
|
6527
6580
|
if (typeof data?.title === "string" && data.title.trim()) this.chatTitle = data.title;
|
|
6528
6581
|
if (typeof data?.agentName === "string" && data.agentName.trim()) this.agentName = data.agentName;
|
|
6529
6582
|
if (typeof data?.extensionId === "string" && data.extensionId.trim()) this.extensionId = data.extensionId;
|
|
@@ -6809,6 +6862,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
6809
6862
|
this.controlValues = {};
|
|
6810
6863
|
this.currentStatus = "idle";
|
|
6811
6864
|
this.chatId = null;
|
|
6865
|
+
this.providerSessionId = null;
|
|
6812
6866
|
this.chatTitle = null;
|
|
6813
6867
|
this.agentName = "";
|
|
6814
6868
|
this.extensionId = "";
|
|
@@ -6963,6 +7017,7 @@ var IdeProviderInstance = class {
|
|
|
6963
7017
|
workspace: this.workspace || null,
|
|
6964
7018
|
extensions: extensionStates,
|
|
6965
7019
|
cdpConnected: cdp?.isConnected || false,
|
|
7020
|
+
sessionCapabilities: getProviderSessionCapabilities(this.provider, IDE_PROVIDER_SESSION_CAPABILITIES_BASE),
|
|
6966
7021
|
controlValues: surface.controlValues,
|
|
6967
7022
|
providerControls: this.provider.controls,
|
|
6968
7023
|
summaryMetadata: surface.summaryMetadata,
|
|
@@ -7989,27 +8044,8 @@ function isCdpConnected(cdpManagers, key) {
|
|
|
7989
8044
|
}
|
|
7990
8045
|
return false;
|
|
7991
8046
|
}
|
|
7992
|
-
var IDE_SESSION_CAPABILITIES = [
|
|
7993
|
-
|
|
7994
|
-
"send_message",
|
|
7995
|
-
"new_session",
|
|
7996
|
-
"list_sessions",
|
|
7997
|
-
"switch_session",
|
|
7998
|
-
"resolve_action",
|
|
7999
|
-
"change_model",
|
|
8000
|
-
"set_mode",
|
|
8001
|
-
"set_thought_level"
|
|
8002
|
-
];
|
|
8003
|
-
var EXTENSION_SESSION_CAPABILITIES = [
|
|
8004
|
-
"read_chat",
|
|
8005
|
-
"send_message",
|
|
8006
|
-
"new_session",
|
|
8007
|
-
"list_sessions",
|
|
8008
|
-
"switch_session",
|
|
8009
|
-
"resolve_action",
|
|
8010
|
-
"change_model",
|
|
8011
|
-
"set_mode"
|
|
8012
|
-
];
|
|
8047
|
+
var IDE_SESSION_CAPABILITIES = [...IDE_PROVIDER_SESSION_CAPABILITIES_BASE];
|
|
8048
|
+
var EXTENSION_SESSION_CAPABILITIES = [...EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE];
|
|
8013
8049
|
var PTY_SESSION_CAPABILITIES = [
|
|
8014
8050
|
"read_chat",
|
|
8015
8051
|
"send_message",
|
|
@@ -8053,7 +8089,7 @@ function buildIdeWorkspaceSession(state, cdpManagers, options) {
|
|
|
8053
8089
|
...includeSessionMetadata && { workspace: state.workspace || null },
|
|
8054
8090
|
activeChat,
|
|
8055
8091
|
...summaryMetadata && { summaryMetadata },
|
|
8056
|
-
...includeSessionMetadata && { capabilities: IDE_SESSION_CAPABILITIES },
|
|
8092
|
+
...includeSessionMetadata && { capabilities: state.sessionCapabilities || IDE_SESSION_CAPABILITIES },
|
|
8057
8093
|
cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
|
|
8058
8094
|
...includeSessionControls && {
|
|
8059
8095
|
...controlValues && { controlValues },
|
|
@@ -8076,6 +8112,7 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
8076
8112
|
parentId: parent.instanceId || parent.type,
|
|
8077
8113
|
providerType: ext.type,
|
|
8078
8114
|
...includeSessionMetadata && { providerName: ext.name },
|
|
8115
|
+
providerSessionId: ext.providerSessionId,
|
|
8079
8116
|
kind: "agent",
|
|
8080
8117
|
transport: "cdp-webview",
|
|
8081
8118
|
status: normalizeManagedStatus(activeChat?.status || ext.status, {
|
|
@@ -8085,7 +8122,7 @@ function buildExtensionAgentSession(parent, ext, options) {
|
|
|
8085
8122
|
...includeSessionMetadata && { workspace: parent.workspace || null },
|
|
8086
8123
|
activeChat,
|
|
8087
8124
|
...summaryMetadata && { summaryMetadata },
|
|
8088
|
-
...includeSessionMetadata && { capabilities: EXTENSION_SESSION_CAPABILITIES },
|
|
8125
|
+
...includeSessionMetadata && { capabilities: ext.sessionCapabilities || EXTENSION_SESSION_CAPABILITIES },
|
|
8089
8126
|
...includeSessionControls && {
|
|
8090
8127
|
...controlValues && { controlValues },
|
|
8091
8128
|
providerControls: ext.providerControls
|
|
@@ -10003,13 +10040,75 @@ function getCliPresentationMode(h, targetSessionId) {
|
|
|
10003
10040
|
const mode = instance.getPresentationMode?.();
|
|
10004
10041
|
return mode === "chat" || mode === "terminal" ? mode : null;
|
|
10005
10042
|
}
|
|
10006
|
-
|
|
10043
|
+
function normalizeOpenPanelCommandResult(result) {
|
|
10044
|
+
const payload = Object.prototype.hasOwnProperty.call(result, "result") ? result.result : result;
|
|
10045
|
+
if (payload === true) return { opened: true, visible: true, focused: false };
|
|
10046
|
+
if (!payload) return { opened: false, visible: false, focused: false };
|
|
10047
|
+
if (typeof payload === "string") {
|
|
10048
|
+
const normalized = payload.trim().toLowerCase();
|
|
10049
|
+
if (normalized === "visible") return { opened: false, visible: true, focused: false };
|
|
10050
|
+
if (normalized === "focused") return { opened: false, visible: true, focused: true };
|
|
10051
|
+
if (normalized === "opened" || normalized === "open" || normalized === "true" || normalized === "ok" || normalized === "success") {
|
|
10052
|
+
return { opened: true, visible: true, focused: false };
|
|
10053
|
+
}
|
|
10054
|
+
return { opened: false, visible: false, focused: false };
|
|
10055
|
+
}
|
|
10056
|
+
if (typeof payload === "object") {
|
|
10057
|
+
const record = payload;
|
|
10058
|
+
return {
|
|
10059
|
+
opened: record.opened === true,
|
|
10060
|
+
visible: record.visible === true || record.opened === true || record.focused === true,
|
|
10061
|
+
focused: record.focused === true
|
|
10062
|
+
};
|
|
10063
|
+
}
|
|
10064
|
+
return { opened: false, visible: false, focused: false };
|
|
10065
|
+
}
|
|
10066
|
+
function normalizeFocusEditorCommandResult(result) {
|
|
10067
|
+
const payload = Object.prototype.hasOwnProperty.call(result, "result") ? result.result : result;
|
|
10068
|
+
if (payload === true) return { focused: true };
|
|
10069
|
+
if (!payload) return { focused: false };
|
|
10070
|
+
if (typeof payload === "string") {
|
|
10071
|
+
const normalized = payload.trim().toLowerCase();
|
|
10072
|
+
return { focused: normalized === "focused" || normalized === "visible" || normalized === "true" || normalized === "ok" || normalized === "success" };
|
|
10073
|
+
}
|
|
10074
|
+
if (typeof payload === "object") {
|
|
10075
|
+
const record = payload;
|
|
10076
|
+
return { focused: record.focused === true || record.visible === true || record.success === true || record.ok === true };
|
|
10077
|
+
}
|
|
10078
|
+
return { focused: false };
|
|
10079
|
+
}
|
|
10080
|
+
async function handleSelectSession(h, args) {
|
|
10007
10081
|
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
10008
10082
|
const sessionId = args?.targetSessionId || h.currentSession?.sessionId;
|
|
10009
10083
|
if (!sessionId) return { success: false, error: "targetSessionId required" };
|
|
10010
|
-
const ok = await h.agentStream.
|
|
10084
|
+
const ok = await h.agentStream.selectSession(h.getCdp(), sessionId);
|
|
10011
10085
|
return { success: ok };
|
|
10012
10086
|
}
|
|
10087
|
+
async function handleOpenPanel(h, args) {
|
|
10088
|
+
const cdp = h.getCdp();
|
|
10089
|
+
if (!cdp) return { success: false, error: "AgentStream or CDP not available" };
|
|
10090
|
+
const sessionId = args?.targetSessionId || h.currentSession?.sessionId;
|
|
10091
|
+
if (!sessionId) return { success: false, error: "targetSessionId required" };
|
|
10092
|
+
const currentTransport = h.currentSession?.transport;
|
|
10093
|
+
const shouldUseAgentStream = !!h.agentStream && currentTransport !== "cdp-page" && currentTransport !== "pty" && currentTransport !== "acp";
|
|
10094
|
+
if (shouldUseAgentStream) {
|
|
10095
|
+
const ok = await h.agentStream.openSessionPanel(cdp, sessionId);
|
|
10096
|
+
return { success: ok };
|
|
10097
|
+
}
|
|
10098
|
+
const openResult = await executeProviderScript(h, args, "openPanel");
|
|
10099
|
+
if (!openResult.success) return openResult;
|
|
10100
|
+
const revealState = normalizeOpenPanelCommandResult(openResult);
|
|
10101
|
+
let focusState = { focused: false };
|
|
10102
|
+
const focusResult = await executeProviderScript(h, args, "focusEditor");
|
|
10103
|
+
if (focusResult.success) {
|
|
10104
|
+
focusState = normalizeFocusEditorCommandResult(focusResult);
|
|
10105
|
+
}
|
|
10106
|
+
return {
|
|
10107
|
+
...openResult,
|
|
10108
|
+
...focusState.focused ? { focused: true } : {},
|
|
10109
|
+
success: revealState.visible || focusState.focused
|
|
10110
|
+
};
|
|
10111
|
+
}
|
|
10013
10112
|
function handlePtyInput(h, args) {
|
|
10014
10113
|
const { cliType, data, targetSessionId } = args || {};
|
|
10015
10114
|
if (!data) return { success: false, error: "data required" };
|
|
@@ -10699,7 +10798,8 @@ var DaemonCommandHandler = class {
|
|
|
10699
10798
|
"change_model",
|
|
10700
10799
|
"set_thought_level",
|
|
10701
10800
|
"resolve_action",
|
|
10702
|
-
"
|
|
10801
|
+
"select_session",
|
|
10802
|
+
"open_panel",
|
|
10703
10803
|
"pty_input",
|
|
10704
10804
|
"pty_resize",
|
|
10705
10805
|
"invoke_provider_script"
|
|
@@ -10797,8 +10897,10 @@ var DaemonCommandHandler = class {
|
|
|
10797
10897
|
case "refresh_scripts":
|
|
10798
10898
|
return this.handleRefreshScripts(args);
|
|
10799
10899
|
// ─── Stream commands (stream-commands.ts) ───────────
|
|
10800
|
-
case "
|
|
10801
|
-
return
|
|
10900
|
+
case "select_session":
|
|
10901
|
+
return handleSelectSession(this, args);
|
|
10902
|
+
case "open_panel":
|
|
10903
|
+
return handleOpenPanel(this, args);
|
|
10802
10904
|
// ─── PTY Raw I/O (stream-commands.ts) ─────────
|
|
10803
10905
|
case "pty_input":
|
|
10804
10906
|
return handlePtyInput(this, args);
|
|
@@ -13500,6 +13602,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
13500
13602
|
if (!cliType) throw new Error("cliType required");
|
|
13501
13603
|
const found = this.findAdapter(cliType, { instanceKey: args?.targetSessionId, dir });
|
|
13502
13604
|
if (found) {
|
|
13605
|
+
if (!args?.targetSessionId && !dir) {
|
|
13606
|
+
const matchCount = [...this.adapters.values()].filter((a) => a.cliType === cliType).length;
|
|
13607
|
+
if (matchCount > 1) {
|
|
13608
|
+
return {
|
|
13609
|
+
success: false,
|
|
13610
|
+
error: `Multiple ${cliType} sessions running \u2014 provide targetSessionId to stop a specific session`,
|
|
13611
|
+
code: "AMBIGUOUS_SESSION"
|
|
13612
|
+
};
|
|
13613
|
+
}
|
|
13614
|
+
}
|
|
13503
13615
|
await this.stopSessionWithMode(found.key, mode);
|
|
13504
13616
|
} else {
|
|
13505
13617
|
console.log(colorize("yellow", ` \u26A0 No adapter found for ${cliType}`));
|
|
@@ -13681,6 +13793,7 @@ function validateProviderDefinition(raw) {
|
|
|
13681
13793
|
warnings.push("disableUpstream is deprecated in provider definitions; use machine-level provider source policy instead");
|
|
13682
13794
|
}
|
|
13683
13795
|
const category = provider.category;
|
|
13796
|
+
const typedProvider = provider;
|
|
13684
13797
|
const controls = Array.isArray(provider.controls) ? provider.controls : [];
|
|
13685
13798
|
if (category === "cli" || category === "acp") {
|
|
13686
13799
|
const spawn4 = provider.spawn;
|
|
@@ -13703,6 +13816,9 @@ function validateProviderDefinition(raw) {
|
|
|
13703
13816
|
for (const control of controls) {
|
|
13704
13817
|
validateControl(control, errors);
|
|
13705
13818
|
}
|
|
13819
|
+
if ((category === "ide" || category === "extension") && typeof typedProvider.scripts?.focusEditor === "function" && !providerHasOpenPanelSupport(typedProvider)) {
|
|
13820
|
+
warnings.push("scripts.focusEditor is present without scripts.openPanel/webviewOpenPanel; open_panel capability will remain disabled");
|
|
13821
|
+
}
|
|
13706
13822
|
return { errors, warnings };
|
|
13707
13823
|
}
|
|
13708
13824
|
function validateCapabilities(provider, controls, errors) {
|
|
@@ -15778,8 +15894,8 @@ function buildStatusSnapshot(options) {
|
|
|
15778
15894
|
for (const sourceSession of unreadSourceSessions) {
|
|
15779
15895
|
const session = sessionsById.get(sourceSession.id);
|
|
15780
15896
|
if (!session) continue;
|
|
15781
|
-
const lastSeenAt = getSessionSeenAt(state, sourceSession.id);
|
|
15782
|
-
const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id);
|
|
15897
|
+
const lastSeenAt = getSessionSeenAt(state, sourceSession.id, sourceSession.providerSessionId);
|
|
15898
|
+
const seenCompletionMarker = getSessionSeenMarker(state, sourceSession.id, sourceSession.providerSessionId);
|
|
15783
15899
|
const lastUsedAt = getSessionLastUsedAt(sourceSession);
|
|
15784
15900
|
const completionMarker = getSessionCompletionMarker(sourceSession);
|
|
15785
15901
|
const { unread, inboxBucket } = sourceSession.surfaceHidden ? { unread: false, inboxBucket: "idle" } : getUnreadState(
|
|
@@ -16595,7 +16711,8 @@ var DaemonCommandRouter = class {
|
|
|
16595
16711
|
currentState,
|
|
16596
16712
|
sessionId,
|
|
16597
16713
|
typeof args?.seenAt === "number" ? args.seenAt : Date.now(),
|
|
16598
|
-
completionMarker
|
|
16714
|
+
completionMarker,
|
|
16715
|
+
targetSession?.providerSessionId
|
|
16599
16716
|
);
|
|
16600
16717
|
if (READ_DEBUG_ENABLED2) {
|
|
16601
16718
|
LOG.info("RecentRead", `mark_session_seen sessionId=${sessionId} seenAt=${String(args?.seenAt || "")} prevSeenAt=${String(prevSeenAt)} nextSeenAt=${String(next.sessionReads?.[sessionId] || 0)} marker=${completionMarker || "-"}`);
|
|
@@ -17028,6 +17145,77 @@ var ProviderStreamAdapter = class {
|
|
|
17028
17145
|
return raw;
|
|
17029
17146
|
}
|
|
17030
17147
|
}
|
|
17148
|
+
getOptionalError(raw) {
|
|
17149
|
+
return typeof raw === "string" && raw.trim() ? raw.trim() : void 0;
|
|
17150
|
+
}
|
|
17151
|
+
normalizeFocusEditorResult(raw) {
|
|
17152
|
+
const data = this.parseMaybeJson(raw);
|
|
17153
|
+
if (data === true) return { focused: true };
|
|
17154
|
+
if (data === false || data == null) return { focused: false };
|
|
17155
|
+
if (typeof data === "string") {
|
|
17156
|
+
const trimmed = data.trim();
|
|
17157
|
+
const normalized = trimmed.toLowerCase();
|
|
17158
|
+
if (normalized === "true" || normalized === "ok" || normalized === "success" || normalized === "focused" || normalized === "visible") {
|
|
17159
|
+
return { focused: true };
|
|
17160
|
+
}
|
|
17161
|
+
if (normalized === "false" || normalized === "not_found" || normalized === "not found" || normalized === "missing" || normalized === "panel_hidden" || normalized === "hidden") {
|
|
17162
|
+
return { focused: false };
|
|
17163
|
+
}
|
|
17164
|
+
return { focused: false, ...trimmed ? { error: trimmed } : {} };
|
|
17165
|
+
}
|
|
17166
|
+
if (data && typeof data === "object") {
|
|
17167
|
+
const error = this.getOptionalError(data.error);
|
|
17168
|
+
if (data.focused === true || data.success === true || data.ok === true || data.visible === true) {
|
|
17169
|
+
return { focused: true };
|
|
17170
|
+
}
|
|
17171
|
+
if (data.focused === false || data.success === false || data.ok === false || error) {
|
|
17172
|
+
return { focused: false, ...error ? { error } : {} };
|
|
17173
|
+
}
|
|
17174
|
+
}
|
|
17175
|
+
return { focused: false };
|
|
17176
|
+
}
|
|
17177
|
+
normalizeOpenPanelResult(raw) {
|
|
17178
|
+
const data = this.parseMaybeJson(raw);
|
|
17179
|
+
if (data === true) return { opened: true, visible: true };
|
|
17180
|
+
if (data === false || data == null) return { opened: false, visible: false };
|
|
17181
|
+
if (typeof data === "string") {
|
|
17182
|
+
const trimmed = data.trim();
|
|
17183
|
+
const normalized = trimmed.toLowerCase();
|
|
17184
|
+
if (normalized === "true" || normalized === "ok" || normalized === "opened" || normalized === "open" || normalized === "success") {
|
|
17185
|
+
return { opened: true, visible: true };
|
|
17186
|
+
}
|
|
17187
|
+
if (normalized === "visible") {
|
|
17188
|
+
return { opened: false, visible: true };
|
|
17189
|
+
}
|
|
17190
|
+
if (normalized === "focused") {
|
|
17191
|
+
return { opened: false, visible: true, focused: true };
|
|
17192
|
+
}
|
|
17193
|
+
if (normalized === "false" || normalized === "panel_hidden" || normalized === "hidden" || normalized === "not_found" || normalized === "not found" || normalized === "missing") {
|
|
17194
|
+
return { opened: false, visible: false };
|
|
17195
|
+
}
|
|
17196
|
+
return { opened: false, visible: false, ...trimmed ? { error: trimmed } : {} };
|
|
17197
|
+
}
|
|
17198
|
+
if (data && typeof data === "object") {
|
|
17199
|
+
const error = this.getOptionalError(data.error);
|
|
17200
|
+
const focused = data.focused === true;
|
|
17201
|
+
const visible = data.visible === true || data.opened === true || focused || data.success === true || data.ok === true;
|
|
17202
|
+
if (visible) {
|
|
17203
|
+
return {
|
|
17204
|
+
opened: data.opened === true,
|
|
17205
|
+
visible: true,
|
|
17206
|
+
...focused ? { focused: true } : {}
|
|
17207
|
+
};
|
|
17208
|
+
}
|
|
17209
|
+
if (data.opened === false || data.visible === false || data.success === false || data.ok === false || error) {
|
|
17210
|
+
return {
|
|
17211
|
+
opened: false,
|
|
17212
|
+
visible: false,
|
|
17213
|
+
...error ? { error } : {}
|
|
17214
|
+
};
|
|
17215
|
+
}
|
|
17216
|
+
}
|
|
17217
|
+
return { opened: false, visible: false };
|
|
17218
|
+
}
|
|
17031
17219
|
summarizeRaw(raw) {
|
|
17032
17220
|
try {
|
|
17033
17221
|
if (typeof raw === "string") return raw.replace(/\s+/g, " ").trim().slice(0, 240);
|
|
@@ -17114,6 +17302,11 @@ var ProviderStreamAdapter = class {
|
|
|
17114
17302
|
if (typeof validated.title === "string" && validated.title.trim()) {
|
|
17115
17303
|
state.title = validated.title.trim();
|
|
17116
17304
|
}
|
|
17305
|
+
const providerSessionId = typeof validated.providerSessionId === "string" && validated.providerSessionId.trim() ? validated.providerSessionId.trim() : "";
|
|
17306
|
+
if (providerSessionId) {
|
|
17307
|
+
state.sessionId = providerSessionId;
|
|
17308
|
+
state.providerSessionId = providerSessionId;
|
|
17309
|
+
}
|
|
17117
17310
|
const controlValues = extractProviderControlValues(this.provider.controls, validated);
|
|
17118
17311
|
const surface = resolveProviderStateSurface({
|
|
17119
17312
|
controlValues,
|
|
@@ -17236,8 +17429,15 @@ var ProviderStreamAdapter = class {
|
|
|
17236
17429
|
}
|
|
17237
17430
|
async focusEditor(evaluate) {
|
|
17238
17431
|
const script = this.callScript("focusEditor");
|
|
17239
|
-
if (!script) return;
|
|
17240
|
-
await evaluate(script);
|
|
17432
|
+
if (!script) return { focused: false };
|
|
17433
|
+
const raw = await evaluate(script);
|
|
17434
|
+
return this.normalizeFocusEditorResult(raw);
|
|
17435
|
+
}
|
|
17436
|
+
async openPanel(evaluate) {
|
|
17437
|
+
const script = this.callScript("openPanel");
|
|
17438
|
+
if (!script) return { opened: false, visible: false };
|
|
17439
|
+
const raw = await evaluate(script);
|
|
17440
|
+
return this.normalizeOpenPanelResult(raw);
|
|
17241
17441
|
}
|
|
17242
17442
|
errorState(message) {
|
|
17243
17443
|
return {
|
|
@@ -17507,19 +17707,33 @@ var DaemonAgentStreamManager = class {
|
|
|
17507
17707
|
return false;
|
|
17508
17708
|
}
|
|
17509
17709
|
}
|
|
17510
|
-
async
|
|
17710
|
+
async selectSession(cdp, sessionId) {
|
|
17511
17711
|
const target = this.getSessionTarget(sessionId);
|
|
17512
17712
|
if (!target?.parentSessionId) return false;
|
|
17513
17713
|
await this.setActiveSession(cdp, target.parentSessionId, sessionId);
|
|
17514
17714
|
await this.syncActiveSession(cdp, target.parentSessionId);
|
|
17715
|
+
return this.managedBySessionId.has(sessionId);
|
|
17716
|
+
}
|
|
17717
|
+
async openSessionPanel(cdp, sessionId) {
|
|
17718
|
+
const selected = await this.selectSession(cdp, sessionId);
|
|
17719
|
+
if (!selected) return false;
|
|
17515
17720
|
const agent = this.managedBySessionId.get(sessionId);
|
|
17516
|
-
if (!agent
|
|
17721
|
+
if (!agent) return false;
|
|
17722
|
+
let panelVisible = false;
|
|
17723
|
+
let editorFocused = false;
|
|
17517
17724
|
try {
|
|
17518
17725
|
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
17519
|
-
|
|
17520
|
-
|
|
17726
|
+
if (typeof agent.adapter.openPanel === "function") {
|
|
17727
|
+
const result = await agent.adapter.openPanel(evaluate);
|
|
17728
|
+
panelVisible = result.visible;
|
|
17729
|
+
}
|
|
17730
|
+
if (typeof agent.adapter.focusEditor === "function") {
|
|
17731
|
+
const result = await agent.adapter.focusEditor(evaluate);
|
|
17732
|
+
editorFocused = result.focused;
|
|
17733
|
+
}
|
|
17734
|
+
return panelVisible || editorFocused;
|
|
17521
17735
|
} catch (e) {
|
|
17522
|
-
this.logFn(`[AgentStream]
|
|
17736
|
+
this.logFn(`[AgentStream] openPanel(${sessionId}) error: ${e.message}`);
|
|
17523
17737
|
return false;
|
|
17524
17738
|
}
|
|
17525
17739
|
}
|
|
@@ -17745,6 +17959,7 @@ function forwardAgentStreamsToIdeInstance(instanceManager, ideType, streams) {
|
|
|
17745
17959
|
summaryMetadata: stream.summaryMetadata || void 0,
|
|
17746
17960
|
effects: stream.effects || void 0,
|
|
17747
17961
|
sessionId: stream.sessionId || stream.instanceId || void 0,
|
|
17962
|
+
providerSessionId: stream.providerSessionId || stream.sessionId || void 0,
|
|
17748
17963
|
title: stream.title || stream.agentName || void 0,
|
|
17749
17964
|
agentType: stream.agentType || void 0,
|
|
17750
17965
|
agentName: stream.agentName || void 0,
|
|
@@ -18397,9 +18612,14 @@ module.exports.setMode = (params) => {
|
|
|
18397
18612
|
(() => {
|
|
18398
18613
|
try {
|
|
18399
18614
|
const input = document.querySelector('${meta.inputSelector || '[contenteditable="true"]'}');
|
|
18400
|
-
if (input) {
|
|
18401
|
-
|
|
18402
|
-
|
|
18615
|
+
if (input) {
|
|
18616
|
+
input.focus();
|
|
18617
|
+
return JSON.stringify({ focused: true });
|
|
18618
|
+
}
|
|
18619
|
+
return JSON.stringify({ focused: false, error: 'not_found' });
|
|
18620
|
+
} catch(e) {
|
|
18621
|
+
return JSON.stringify({ focused: false, error: e.message });
|
|
18622
|
+
}
|
|
18403
18623
|
})()
|
|
18404
18624
|
`;
|
|
18405
18625
|
files[`${scriptDir}/open_panel.js`] = `/**
|
|
@@ -18410,8 +18630,10 @@ module.exports.setMode = (params) => {
|
|
|
18410
18630
|
(() => {
|
|
18411
18631
|
try {
|
|
18412
18632
|
// TODO: Check if panel visible, if not find toggle button
|
|
18413
|
-
return 'not_found';
|
|
18414
|
-
} catch(e) {
|
|
18633
|
+
return JSON.stringify({ opened: false, visible: false, error: 'not_found' });
|
|
18634
|
+
} catch(e) {
|
|
18635
|
+
return JSON.stringify({ opened: false, visible: false, error: e.message });
|
|
18636
|
+
}
|
|
18415
18637
|
})()
|
|
18416
18638
|
`;
|
|
18417
18639
|
files[`${scriptDir}/resolve_action.js`] = `/**
|
|
@@ -21223,8 +21445,8 @@ function buildAutoImplPrompt(ctx, type, provider, providerDir, functions, domCon
|
|
|
21223
21445
|
lines.push("| setModel | `{ success: true/false }` |");
|
|
21224
21446
|
lines.push("| listModes | `{ modes: [{ name, id }], current }` |");
|
|
21225
21447
|
lines.push("| setMode | `{ success: true/false }` |");
|
|
21226
|
-
lines.push("| focusEditor | `{ focused: true/false }` |");
|
|
21227
|
-
lines.push("| openPanel | `{ opened: true/false }` |");
|
|
21448
|
+
lines.push("| focusEditor | `{ focused: true/false, error? }` |");
|
|
21449
|
+
lines.push("| openPanel | `{ opened: true/false, visible: true/false, focused?: true, error? }` |");
|
|
21228
21450
|
lines.push("");
|
|
21229
21451
|
lines.push("## \u{1F534} CRITICAL: readChat `status` Lifecycle");
|
|
21230
21452
|
lines.push("The `status` field in readChat controls how the dashboard and daemon auto-approve-loop behave.");
|
|
@@ -22858,8 +23080,8 @@ var DevServer = class _DevServer {
|
|
|
22858
23080
|
lines.push("| setModel | `{ success: true/false }` |");
|
|
22859
23081
|
lines.push("| listModes | `{ modes: [{ name, id }], current }` |");
|
|
22860
23082
|
lines.push("| setMode | `{ success: true/false }` |");
|
|
22861
|
-
lines.push("| focusEditor | `{ focused: true/false }` |");
|
|
22862
|
-
lines.push("| openPanel | `{ opened: true/false }` |");
|
|
23083
|
+
lines.push("| focusEditor | `{ focused: true/false, error? }` |");
|
|
23084
|
+
lines.push("| openPanel | `{ opened: true/false, visible: true/false, focused?: true, error? }` |");
|
|
22863
23085
|
lines.push("");
|
|
22864
23086
|
lines.push("## \u{1F534} CRITICAL: readChat `status` Lifecycle");
|
|
22865
23087
|
lines.push("The `status` field in readChat controls how the dashboard and daemon auto-approve-loop behave.");
|