adhdev 0.6.79 → 0.7.0
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 +810 -717
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +809 -713
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -1664,7 +1664,11 @@ var init_manager = __esm({
|
|
|
1664
1664
|
async attachToAgent(target) {
|
|
1665
1665
|
if (!this.isConnected) return null;
|
|
1666
1666
|
for (const [sid, t] of this.agentSessions) {
|
|
1667
|
-
if (t.
|
|
1667
|
+
if (t.targetId === target.targetId) return sid;
|
|
1668
|
+
if (t.agentType === target.agentType && t.targetId !== target.targetId) {
|
|
1669
|
+
await this.detachAgent(sid).catch(() => {
|
|
1670
|
+
});
|
|
1671
|
+
}
|
|
1668
1672
|
}
|
|
1669
1673
|
try {
|
|
1670
1674
|
const sendFn = this._browserConnected ? this.sendBrowser.bind(this) : this.sendInternal.bind(this);
|
|
@@ -1788,6 +1792,20 @@ var init_manager = __esm({
|
|
|
1788
1792
|
}
|
|
1789
1793
|
async getCurrentPageWebviewUrls() {
|
|
1790
1794
|
if (!this.isConnected) return /* @__PURE__ */ new Set();
|
|
1795
|
+
try {
|
|
1796
|
+
const urls = /* @__PURE__ */ new Set();
|
|
1797
|
+
const { frameTree } = await this.sendInternal("Page.getFrameTree", {}, 5e3);
|
|
1798
|
+
const visit = (node) => {
|
|
1799
|
+
const url2 = node?.frame?.url;
|
|
1800
|
+
if (typeof url2 === "string" && url2.includes("vscode-webview")) {
|
|
1801
|
+
urls.add(url2);
|
|
1802
|
+
}
|
|
1803
|
+
for (const child of node?.childFrames || []) visit(child);
|
|
1804
|
+
};
|
|
1805
|
+
if (frameTree) visit(frameTree);
|
|
1806
|
+
if (urls.size > 0) return urls;
|
|
1807
|
+
} catch {
|
|
1808
|
+
}
|
|
1791
1809
|
try {
|
|
1792
1810
|
const raw = await this.evaluate(
|
|
1793
1811
|
`JSON.stringify(Array.from(document.querySelectorAll('iframe,webview'))
|
|
@@ -2973,7 +2991,7 @@ function registerExtensionProviders(providerLoader, manager, ideType) {
|
|
|
2973
2991
|
manager.setExtensionProviders(enabledExtProviders);
|
|
2974
2992
|
}
|
|
2975
2993
|
async function setupIdeInstance(ctx, opts) {
|
|
2976
|
-
const { providerLoader, instanceManager,
|
|
2994
|
+
const { providerLoader, instanceManager, sessionRegistry } = ctx;
|
|
2977
2995
|
const { ideType, manager, settings } = opts;
|
|
2978
2996
|
const managerKey = opts.managerKey || ideType;
|
|
2979
2997
|
registerExtensionProviders(providerLoader, manager, ideType);
|
|
@@ -2989,14 +3007,30 @@ async function setupIdeInstance(ctx, opts) {
|
|
|
2989
3007
|
serverConn: ctx.serverConn,
|
|
2990
3008
|
settings: resolvedSettings
|
|
2991
3009
|
});
|
|
2992
|
-
|
|
3010
|
+
sessionRegistry.register({
|
|
3011
|
+
sessionId: ideInstance.getInstanceId(),
|
|
3012
|
+
parentSessionId: null,
|
|
3013
|
+
providerType: ideType,
|
|
3014
|
+
providerCategory: "ide",
|
|
3015
|
+
transport: "cdp-page",
|
|
3016
|
+
cdpManagerKey: managerKey,
|
|
3017
|
+
instanceKey: `ide:${managerKey}`
|
|
3018
|
+
});
|
|
2993
3019
|
const extensionProviders = providerLoader.getEnabledByCategory("extension", ideType);
|
|
2994
3020
|
for (const extProvider of extensionProviders) {
|
|
2995
3021
|
const extSettings = providerLoader.getSettings(extProvider.type);
|
|
2996
3022
|
await ideInstance.addExtension(extProvider, extSettings);
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3023
|
+
}
|
|
3024
|
+
for (const ext of ideInstance.getExtensionInstances()) {
|
|
3025
|
+
sessionRegistry.register({
|
|
3026
|
+
sessionId: ext.getInstanceId(),
|
|
3027
|
+
parentSessionId: ideInstance.getInstanceId(),
|
|
3028
|
+
providerType: ext.type,
|
|
3029
|
+
providerCategory: "extension",
|
|
3030
|
+
transport: "cdp-webview",
|
|
3031
|
+
cdpManagerKey: managerKey,
|
|
3032
|
+
instanceKey: `ide:${managerKey}`
|
|
3033
|
+
});
|
|
3000
3034
|
}
|
|
3001
3035
|
return ideInstance;
|
|
3002
3036
|
}
|
|
@@ -3235,6 +3269,7 @@ var init_initializer = __esm({
|
|
|
3235
3269
|
async connectIdePort(port, ide) {
|
|
3236
3270
|
const { providerLoader, cdpManagers } = this.config;
|
|
3237
3271
|
const targets = await DaemonCdpManager.listAllTargets(port);
|
|
3272
|
+
await this.pruneStaleManagers(port, ide, targets);
|
|
3238
3273
|
if (targets.length === 0) {
|
|
3239
3274
|
if (cdpManagers.has(ide)) return;
|
|
3240
3275
|
if (!await probeCdpPort(port)) return;
|
|
@@ -3287,6 +3322,34 @@ var init_initializer = __esm({
|
|
|
3287
3322
|
}
|
|
3288
3323
|
}
|
|
3289
3324
|
}
|
|
3325
|
+
async pruneStaleManagers(port, ide, targets) {
|
|
3326
|
+
const trackedTargetIds = new Set(targets.map((target) => target.id));
|
|
3327
|
+
const removals = [];
|
|
3328
|
+
for (const [key, manager] of this.config.cdpManagers.entries()) {
|
|
3329
|
+
if (!(key === ide || key.startsWith(`${ide}_`))) continue;
|
|
3330
|
+
if (manager.getPort() !== port) continue;
|
|
3331
|
+
if (targets.length === 0) {
|
|
3332
|
+
removals.push({ key, manager, reason: "ide_closed" });
|
|
3333
|
+
continue;
|
|
3334
|
+
}
|
|
3335
|
+
if (manager.targetId && !trackedTargetIds.has(manager.targetId)) {
|
|
3336
|
+
removals.push({ key, manager, reason: "target_closed" });
|
|
3337
|
+
continue;
|
|
3338
|
+
}
|
|
3339
|
+
if (key === ide && !manager.targetId && targets.length > 1) {
|
|
3340
|
+
removals.push({ key, manager, reason: "target_rekeyed" });
|
|
3341
|
+
}
|
|
3342
|
+
}
|
|
3343
|
+
for (const { key, manager, reason } of removals) {
|
|
3344
|
+
try {
|
|
3345
|
+
manager.disconnect();
|
|
3346
|
+
} catch {
|
|
3347
|
+
}
|
|
3348
|
+
this.config.cdpManagers.delete(key);
|
|
3349
|
+
LOG.info("CDP", `Removed stale manager: ${key} (${reason})`);
|
|
3350
|
+
await this.config.onDisconnected?.(ide, manager, key, reason);
|
|
3351
|
+
}
|
|
3352
|
+
}
|
|
3290
3353
|
// ─── Periodic scanning ───
|
|
3291
3354
|
/**
|
|
3292
3355
|
* Start periodic scanning for newly opened IDEs.
|
|
@@ -3398,112 +3461,191 @@ function isCdpConnected(cdpManagers, key) {
|
|
|
3398
3461
|
const m = findCdpManager(cdpManagers, key);
|
|
3399
3462
|
return m?.isConnected ?? false;
|
|
3400
3463
|
}
|
|
3401
|
-
function
|
|
3402
|
-
const
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
currentPlan: state.currentPlan,
|
|
3426
|
-
currentAutoApprove: state.currentAutoApprove
|
|
3427
|
-
});
|
|
3428
|
-
}
|
|
3429
|
-
if (opts?.detectedIdes) {
|
|
3430
|
-
const coveredTypes = new Set(ideStates.map((s15) => s15.type));
|
|
3431
|
-
for (const ide of opts.detectedIdes) {
|
|
3432
|
-
if (!ide.installed || coveredTypes.has(ide.id)) continue;
|
|
3433
|
-
if (!isCdpConnected(cdpManagers, ide.id)) continue;
|
|
3434
|
-
result.push({
|
|
3435
|
-
ideType: ide.id,
|
|
3436
|
-
ideVersion: "",
|
|
3437
|
-
instanceId: ide.id,
|
|
3438
|
-
workspace: null,
|
|
3439
|
-
terminals: 0,
|
|
3440
|
-
aiAgents: [],
|
|
3441
|
-
activeChat: null,
|
|
3442
|
-
chats: [],
|
|
3443
|
-
agentStreams: [],
|
|
3444
|
-
cdpConnected: true,
|
|
3445
|
-
currentModel: void 0,
|
|
3446
|
-
currentPlan: void 0
|
|
3447
|
-
});
|
|
3448
|
-
}
|
|
3449
|
-
}
|
|
3450
|
-
return result;
|
|
3464
|
+
function buildIdeWorkspaceSession(state, cdpManagers) {
|
|
3465
|
+
const activeChat = normalizeActiveChatData(state.activeChat);
|
|
3466
|
+
const title = activeChat?.title || state.name;
|
|
3467
|
+
return {
|
|
3468
|
+
id: state.instanceId || state.type,
|
|
3469
|
+
parentId: null,
|
|
3470
|
+
providerType: state.type,
|
|
3471
|
+
providerName: state.name,
|
|
3472
|
+
kind: "workspace",
|
|
3473
|
+
transport: "cdp-page",
|
|
3474
|
+
status: normalizeManagedStatus(activeChat?.status || state.status, {
|
|
3475
|
+
activeModal: activeChat?.activeModal || null
|
|
3476
|
+
}),
|
|
3477
|
+
title,
|
|
3478
|
+
workspace: state.workspace || null,
|
|
3479
|
+
activeChat,
|
|
3480
|
+
capabilities: IDE_SESSION_CAPABILITIES,
|
|
3481
|
+
cdpConnected: state.cdpConnected ?? isCdpConnected(cdpManagers, state.type),
|
|
3482
|
+
currentModel: state.currentModel,
|
|
3483
|
+
currentPlan: state.currentPlan,
|
|
3484
|
+
currentAutoApprove: state.currentAutoApprove,
|
|
3485
|
+
errorMessage: state.errorMessage,
|
|
3486
|
+
errorReason: state.errorReason
|
|
3487
|
+
};
|
|
3451
3488
|
}
|
|
3452
|
-
function
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3489
|
+
function buildExtensionAgentSession(parent, ext) {
|
|
3490
|
+
const activeChat = normalizeActiveChatData(ext.activeChat);
|
|
3491
|
+
return {
|
|
3492
|
+
id: ext.instanceId || `${parent.instanceId}:${ext.type}`,
|
|
3493
|
+
parentId: parent.instanceId || parent.type,
|
|
3494
|
+
providerType: ext.type,
|
|
3495
|
+
providerName: ext.name,
|
|
3496
|
+
kind: "agent",
|
|
3497
|
+
transport: "cdp-webview",
|
|
3498
|
+
status: normalizeManagedStatus(activeChat?.status || ext.status, {
|
|
3499
|
+
activeModal: activeChat?.activeModal || null
|
|
3500
|
+
}),
|
|
3501
|
+
title: activeChat?.title || ext.name,
|
|
3502
|
+
workspace: parent.workspace || null,
|
|
3503
|
+
activeChat,
|
|
3504
|
+
capabilities: EXTENSION_SESSION_CAPABILITIES,
|
|
3505
|
+
currentModel: ext.currentModel,
|
|
3506
|
+
currentPlan: ext.currentPlan,
|
|
3507
|
+
errorMessage: ext.errorMessage,
|
|
3508
|
+
errorReason: ext.errorReason
|
|
3509
|
+
};
|
|
3463
3510
|
}
|
|
3464
|
-
function
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3511
|
+
function buildCliSession(state) {
|
|
3512
|
+
const activeChat = normalizeActiveChatData(state.activeChat);
|
|
3513
|
+
return {
|
|
3514
|
+
id: state.instanceId,
|
|
3515
|
+
parentId: null,
|
|
3516
|
+
providerType: state.type,
|
|
3517
|
+
providerName: state.name,
|
|
3518
|
+
kind: "agent",
|
|
3519
|
+
transport: "pty",
|
|
3520
|
+
status: normalizeManagedStatus(activeChat?.status || state.status, {
|
|
3521
|
+
activeModal: activeChat?.activeModal || null
|
|
3522
|
+
}),
|
|
3523
|
+
title: activeChat?.title || state.name,
|
|
3524
|
+
workspace: state.workspace || null,
|
|
3525
|
+
activeChat,
|
|
3526
|
+
capabilities: PTY_SESSION_CAPABILITIES,
|
|
3527
|
+
errorMessage: state.errorMessage,
|
|
3528
|
+
errorReason: state.errorReason
|
|
3529
|
+
};
|
|
3530
|
+
}
|
|
3531
|
+
function buildAcpSession(state) {
|
|
3532
|
+
const activeChat = normalizeActiveChatData(state.activeChat);
|
|
3533
|
+
return {
|
|
3534
|
+
id: state.instanceId,
|
|
3535
|
+
parentId: null,
|
|
3536
|
+
providerType: state.type,
|
|
3537
|
+
providerName: state.name,
|
|
3538
|
+
kind: "agent",
|
|
3539
|
+
transport: "acp",
|
|
3540
|
+
status: normalizeManagedStatus(activeChat?.status || state.status, {
|
|
3541
|
+
activeModal: activeChat?.activeModal || null
|
|
3542
|
+
}),
|
|
3543
|
+
title: activeChat?.title || state.name,
|
|
3544
|
+
workspace: state.workspace || null,
|
|
3545
|
+
activeChat,
|
|
3546
|
+
capabilities: ACP_SESSION_CAPABILITIES,
|
|
3547
|
+
currentModel: state.currentModel,
|
|
3548
|
+
currentPlan: state.currentPlan,
|
|
3549
|
+
acpConfigOptions: state.acpConfigOptions,
|
|
3550
|
+
acpModes: state.acpModes,
|
|
3551
|
+
errorMessage: state.errorMessage,
|
|
3552
|
+
errorReason: state.errorReason
|
|
3553
|
+
};
|
|
3480
3554
|
}
|
|
3481
|
-
function
|
|
3555
|
+
function buildSessionEntries(allStates, cdpManagers) {
|
|
3556
|
+
const sessions = [];
|
|
3482
3557
|
const ideStates = allStates.filter((s15) => s15.category === "ide");
|
|
3483
3558
|
const cliStates = allStates.filter((s15) => s15.category === "cli");
|
|
3484
3559
|
const acpStates = allStates.filter((s15) => s15.category === "acp");
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3560
|
+
for (const state of ideStates) {
|
|
3561
|
+
sessions.push(buildIdeWorkspaceSession(state, cdpManagers));
|
|
3562
|
+
for (const ext of state.extensions) {
|
|
3563
|
+
sessions.push(buildExtensionAgentSession(state, ext));
|
|
3564
|
+
}
|
|
3565
|
+
}
|
|
3566
|
+
for (const state of cliStates) {
|
|
3567
|
+
sessions.push(buildCliSession(state));
|
|
3568
|
+
}
|
|
3569
|
+
for (const state of acpStates) {
|
|
3570
|
+
sessions.push(buildAcpSession(state));
|
|
3571
|
+
}
|
|
3572
|
+
return sessions;
|
|
3490
3573
|
}
|
|
3574
|
+
var IDE_SESSION_CAPABILITIES, EXTENSION_SESSION_CAPABILITIES, PTY_SESSION_CAPABILITIES, ACP_SESSION_CAPABILITIES;
|
|
3491
3575
|
var init_builders = __esm({
|
|
3492
3576
|
"../../oss/packages/daemon-core/src/status/builders.ts"() {
|
|
3493
3577
|
"use strict";
|
|
3494
3578
|
init_normalize();
|
|
3579
|
+
IDE_SESSION_CAPABILITIES = [
|
|
3580
|
+
"read_chat",
|
|
3581
|
+
"send_message",
|
|
3582
|
+
"new_session",
|
|
3583
|
+
"list_sessions",
|
|
3584
|
+
"switch_session",
|
|
3585
|
+
"resolve_action",
|
|
3586
|
+
"change_model",
|
|
3587
|
+
"set_mode",
|
|
3588
|
+
"set_thought_level"
|
|
3589
|
+
];
|
|
3590
|
+
EXTENSION_SESSION_CAPABILITIES = [
|
|
3591
|
+
"read_chat",
|
|
3592
|
+
"send_message",
|
|
3593
|
+
"new_session",
|
|
3594
|
+
"list_sessions",
|
|
3595
|
+
"switch_session",
|
|
3596
|
+
"resolve_action",
|
|
3597
|
+
"change_model",
|
|
3598
|
+
"set_mode"
|
|
3599
|
+
];
|
|
3600
|
+
PTY_SESSION_CAPABILITIES = [
|
|
3601
|
+
"read_chat",
|
|
3602
|
+
"send_message",
|
|
3603
|
+
"resolve_action",
|
|
3604
|
+
"terminal_io",
|
|
3605
|
+
"resize_terminal"
|
|
3606
|
+
];
|
|
3607
|
+
ACP_SESSION_CAPABILITIES = [
|
|
3608
|
+
"read_chat",
|
|
3609
|
+
"send_message",
|
|
3610
|
+
"new_session",
|
|
3611
|
+
"resolve_action",
|
|
3612
|
+
"change_model",
|
|
3613
|
+
"set_mode",
|
|
3614
|
+
"set_thought_level"
|
|
3615
|
+
];
|
|
3495
3616
|
}
|
|
3496
3617
|
});
|
|
3497
3618
|
|
|
3498
3619
|
// ../../oss/packages/daemon-core/src/commands/chat-commands.ts
|
|
3620
|
+
function getCurrentProviderType(h, fallback = "") {
|
|
3621
|
+
return h.currentSession?.providerType || h.currentProviderType || fallback;
|
|
3622
|
+
}
|
|
3623
|
+
function getCurrentManagerKey(h) {
|
|
3624
|
+
return h.currentSession?.cdpManagerKey || h.currentManagerKey || "";
|
|
3625
|
+
}
|
|
3499
3626
|
function getTargetedCliAdapter(h, args, providerType) {
|
|
3500
|
-
return h.getCliAdapter(args?.
|
|
3627
|
+
return h.getCliAdapter(args?.targetSessionId || providerType || h.currentSession?.providerType || h.currentManagerKey);
|
|
3628
|
+
}
|
|
3629
|
+
function buildRecentSendKey(h, args, provider, text) {
|
|
3630
|
+
const target = args?.targetSessionId || args?.agentType || h.currentSession?.providerType || h.currentProviderType || h.currentManagerKey || "unknown";
|
|
3631
|
+
return `${provider?.category || "unknown"}:${target}:${text.trim()}`;
|
|
3632
|
+
}
|
|
3633
|
+
function isRecentDuplicateSend(key) {
|
|
3634
|
+
const now = Date.now();
|
|
3635
|
+
for (const [candidate, ts3] of recentSendByTarget.entries()) {
|
|
3636
|
+
if (now - ts3 > RECENT_SEND_WINDOW_MS) recentSendByTarget.delete(candidate);
|
|
3637
|
+
}
|
|
3638
|
+
const previous = recentSendByTarget.get(key);
|
|
3639
|
+
if (previous && now - previous <= RECENT_SEND_WINDOW_MS) return true;
|
|
3640
|
+
recentSendByTarget.set(key, now);
|
|
3641
|
+
return false;
|
|
3501
3642
|
}
|
|
3502
3643
|
async function handleChatHistory(h, args) {
|
|
3503
|
-
const { agentType, offset, limit
|
|
3644
|
+
const { agentType, offset, limit } = args;
|
|
3645
|
+
const instanceId = args?.targetSessionId;
|
|
3504
3646
|
try {
|
|
3505
3647
|
const provider = h.getProvider(agentType);
|
|
3506
|
-
const agentStr = provider?.type || agentType || h
|
|
3648
|
+
const agentStr = provider?.type || agentType || getCurrentProviderType(h);
|
|
3507
3649
|
const result = readChatHistory(agentStr, offset || 0, limit || 30, instanceId);
|
|
3508
3650
|
return { success: true, ...result, agent: agentStr };
|
|
3509
3651
|
} catch (e) {
|
|
@@ -3547,7 +3689,7 @@ async function handleReadChat(h, args) {
|
|
|
3547
3689
|
provider.type || "unknown_extension",
|
|
3548
3690
|
parsed.messages || [],
|
|
3549
3691
|
parsed.title,
|
|
3550
|
-
args?.
|
|
3692
|
+
args?.targetSessionId
|
|
3551
3693
|
);
|
|
3552
3694
|
return { success: true, ...parsed };
|
|
3553
3695
|
}
|
|
@@ -3557,15 +3699,18 @@ async function handleReadChat(h, args) {
|
|
|
3557
3699
|
}
|
|
3558
3700
|
if (h.agentStream) {
|
|
3559
3701
|
const cdp2 = h.getCdp();
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
const stream =
|
|
3702
|
+
const parentSessionId = h.currentSession?.parentSessionId;
|
|
3703
|
+
if (cdp2 && parentSessionId) {
|
|
3704
|
+
const stream = await h.agentStream.collectActiveSession(cdp2, parentSessionId);
|
|
3705
|
+
if (stream?.agentType !== provider.type) {
|
|
3706
|
+
return { success: true, messages: [], status: "idle" };
|
|
3707
|
+
}
|
|
3563
3708
|
if (stream) {
|
|
3564
3709
|
h.historyWriter.appendNewMessages(
|
|
3565
3710
|
stream.agentType,
|
|
3566
3711
|
stream.messages || [],
|
|
3567
3712
|
void 0,
|
|
3568
|
-
args?.
|
|
3713
|
+
args?.targetSessionId
|
|
3569
3714
|
);
|
|
3570
3715
|
return { success: true, messages: stream.messages || [], status: stream.status, agentType: stream.agentType };
|
|
3571
3716
|
}
|
|
@@ -3592,10 +3737,10 @@ async function handleReadChat(h, args) {
|
|
|
3592
3737
|
if (parsed && typeof parsed === "object") {
|
|
3593
3738
|
_log(`Webview OK: ${parsed.messages?.length || 0} msgs`);
|
|
3594
3739
|
h.historyWriter.appendNewMessages(
|
|
3595
|
-
provider?.type || h
|
|
3740
|
+
provider?.type || getCurrentProviderType(h, "unknown_webview"),
|
|
3596
3741
|
parsed.messages || [],
|
|
3597
3742
|
parsed.title,
|
|
3598
|
-
args?.
|
|
3743
|
+
args?.targetSessionId
|
|
3599
3744
|
);
|
|
3600
3745
|
return { success: true, ...parsed };
|
|
3601
3746
|
}
|
|
@@ -3619,10 +3764,10 @@ async function handleReadChat(h, args) {
|
|
|
3619
3764
|
if (parsed && typeof parsed === "object" && parsed.messages?.length > 0) {
|
|
3620
3765
|
_log(`OK: ${parsed.messages?.length} msgs`);
|
|
3621
3766
|
h.historyWriter.appendNewMessages(
|
|
3622
|
-
provider?.type || h
|
|
3767
|
+
provider?.type || getCurrentProviderType(h, "unknown_ide"),
|
|
3623
3768
|
parsed.messages || [],
|
|
3624
3769
|
parsed.title,
|
|
3625
|
-
args?.
|
|
3770
|
+
args?.targetSessionId
|
|
3626
3771
|
);
|
|
3627
3772
|
return { success: true, ...parsed };
|
|
3628
3773
|
}
|
|
@@ -3637,16 +3782,21 @@ async function handleSendChat(h, args) {
|
|
|
3637
3782
|
if (!text) return { success: false, error: "text required" };
|
|
3638
3783
|
const _log = (msg) => LOG.debug("Command", `[send_chat] ${msg}`);
|
|
3639
3784
|
const provider = h.getProvider(args?.agentType);
|
|
3785
|
+
const dedupeKey = buildRecentSendKey(h, args, provider, text);
|
|
3640
3786
|
const _logSendSuccess = (method, targetAgent) => {
|
|
3641
3787
|
h.historyWriter.appendNewMessages(
|
|
3642
|
-
targetAgent || provider?.type || h
|
|
3788
|
+
targetAgent || provider?.type || getCurrentProviderType(h, "unknown_agent"),
|
|
3643
3789
|
[{ role: "user", content: text, receivedAt: Date.now() }],
|
|
3644
3790
|
void 0,
|
|
3645
3791
|
// title
|
|
3646
|
-
args?.
|
|
3792
|
+
args?.targetSessionId
|
|
3647
3793
|
);
|
|
3648
3794
|
return { success: true, sent: true, method, targetAgent };
|
|
3649
3795
|
};
|
|
3796
|
+
if (isRecentDuplicateSend(dedupeKey)) {
|
|
3797
|
+
_log(`Suppressed duplicate send for ${dedupeKey}`);
|
|
3798
|
+
return { success: true, sent: false, deduplicated: true };
|
|
3799
|
+
}
|
|
3650
3800
|
if (provider?.category === "cli" || provider?.category === "acp") {
|
|
3651
3801
|
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
3652
3802
|
if (adapter) {
|
|
@@ -3682,8 +3832,9 @@ async function handleSendChat(h, args) {
|
|
|
3682
3832
|
} catch (e) {
|
|
3683
3833
|
_log(`Extension script error: ${e.message}`);
|
|
3684
3834
|
}
|
|
3685
|
-
|
|
3686
|
-
|
|
3835
|
+
const extensionSessionId = h.currentSession?.sessionId;
|
|
3836
|
+
if (h.agentStream && h.getCdp() && extensionSessionId) {
|
|
3837
|
+
const ok = await h.agentStream.sendToSession(h.getCdp(), extensionSessionId, text);
|
|
3687
3838
|
if (ok) {
|
|
3688
3839
|
_log(`AgentStreamManager sent OK`);
|
|
3689
3840
|
return _logSendSuccess("agent-stream");
|
|
@@ -3693,45 +3844,11 @@ async function handleSendChat(h, args) {
|
|
|
3693
3844
|
}
|
|
3694
3845
|
const targetCdp = h.getCdp();
|
|
3695
3846
|
if (!targetCdp?.isConnected) {
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
_log(`Targeting IDE: ${h.currentIdeType}`);
|
|
3700
|
-
if (provider?.webviewMatchText && provider?.scripts?.webviewSendMessage) {
|
|
3701
|
-
try {
|
|
3702
|
-
const webviewScript = provider.scripts.webviewSendMessage(text);
|
|
3703
|
-
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
3704
|
-
const matchText = provider.webviewMatchText;
|
|
3705
|
-
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
3706
|
-
const wvResult = await targetCdp.evaluateInWebviewFrame(webviewScript, matchFn);
|
|
3707
|
-
let wvParsed = wvResult;
|
|
3708
|
-
if (typeof wvResult === "string") {
|
|
3709
|
-
try {
|
|
3710
|
-
wvParsed = JSON.parse(wvResult);
|
|
3711
|
-
} catch {
|
|
3712
|
-
}
|
|
3713
|
-
}
|
|
3714
|
-
if (wvParsed?.sent) {
|
|
3715
|
-
_log(`webviewSendMessage (priority) OK`);
|
|
3716
|
-
return _logSendSuccess("webview-script-priority");
|
|
3717
|
-
}
|
|
3718
|
-
_log(`webviewSendMessage (priority) did not confirm sent, falling through`);
|
|
3719
|
-
}
|
|
3720
|
-
} catch (e) {
|
|
3721
|
-
_log(`webviewSendMessage (priority) failed: ${e.message}, falling through`);
|
|
3722
|
-
}
|
|
3723
|
-
}
|
|
3724
|
-
if (provider?.inputMethod === "cdp-type-and-send" && provider.inputSelector) {
|
|
3725
|
-
try {
|
|
3726
|
-
const sent = await targetCdp.typeAndSend(provider.inputSelector, text);
|
|
3727
|
-
if (sent) {
|
|
3728
|
-
_log(`typeAndSend(provider.inputSelector=${provider.inputSelector}) success`);
|
|
3729
|
-
return _logSendSuccess("typeAndSend-provider");
|
|
3730
|
-
}
|
|
3731
|
-
} catch (e) {
|
|
3732
|
-
_log(`typeAndSend(provider) failed: ${e.message}`);
|
|
3733
|
-
}
|
|
3847
|
+
const managerKey = getCurrentManagerKey(h);
|
|
3848
|
+
_log(`No CDP for ${managerKey}`);
|
|
3849
|
+
return { success: false, error: `CDP for ${managerKey || "unknown"} not connected` };
|
|
3734
3850
|
}
|
|
3851
|
+
_log(`Targeting IDE: ${getCurrentManagerKey(h)}`);
|
|
3735
3852
|
const sendScript = h.getProviderScript("sendMessage", { MESSAGE: text });
|
|
3736
3853
|
if (sendScript) {
|
|
3737
3854
|
try {
|
|
@@ -3758,7 +3875,30 @@ async function handleSendChat(h, args) {
|
|
|
3758
3875
|
_log(`typeAndSend(script.selector) failed: ${e.message}`);
|
|
3759
3876
|
}
|
|
3760
3877
|
}
|
|
3761
|
-
if (parsed?.needsTypeAndSend &&
|
|
3878
|
+
if (parsed?.needsTypeAndSend && parsed?.clickCoords) {
|
|
3879
|
+
try {
|
|
3880
|
+
const { x, y } = parsed.clickCoords;
|
|
3881
|
+
const sent = await targetCdp.typeAndSendAt(x, y, text);
|
|
3882
|
+
if (sent) {
|
|
3883
|
+
_log(`typeAndSendAt(${x},${y}) success`);
|
|
3884
|
+
return _logSendSuccess("typeAndSendAt-script");
|
|
3885
|
+
}
|
|
3886
|
+
} catch (e) {
|
|
3887
|
+
_log(`typeAndSendAt failed: ${e.message}`);
|
|
3888
|
+
}
|
|
3889
|
+
}
|
|
3890
|
+
if (parsed?.needsTypeAndSend && provider?.inputMethod === "cdp-type-and-send" && provider.inputSelector) {
|
|
3891
|
+
try {
|
|
3892
|
+
const sent = await targetCdp.typeAndSend(provider.inputSelector, text);
|
|
3893
|
+
if (sent) {
|
|
3894
|
+
_log(`typeAndSend(provider.inputSelector=${provider.inputSelector}) success`);
|
|
3895
|
+
return _logSendSuccess("typeAndSend-provider");
|
|
3896
|
+
}
|
|
3897
|
+
} catch (e) {
|
|
3898
|
+
_log(`typeAndSend(provider) failed: ${e.message}`);
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3901
|
+
if (parsed?.needsTypeAndSend && provider?.webviewMatchText && provider?.scripts?.webviewSendMessage) {
|
|
3762
3902
|
try {
|
|
3763
3903
|
const webviewScript = provider.scripts.webviewSendMessage(text);
|
|
3764
3904
|
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
@@ -3781,20 +3921,44 @@ async function handleSendChat(h, args) {
|
|
|
3781
3921
|
_log(`webviewSendMessage failed: ${e.message}`);
|
|
3782
3922
|
}
|
|
3783
3923
|
}
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3924
|
+
return { success: false, error: parsed?.error || "Provider sendMessage did not confirm send" };
|
|
3925
|
+
} catch (e) {
|
|
3926
|
+
_log(`sendMessage script failed: ${e.message}`);
|
|
3927
|
+
return { success: false, error: `Provider sendMessage failed: ${e.message}` };
|
|
3928
|
+
}
|
|
3929
|
+
}
|
|
3930
|
+
if (provider?.webviewMatchText && provider?.scripts?.webviewSendMessage) {
|
|
3931
|
+
try {
|
|
3932
|
+
const webviewScript = provider.scripts.webviewSendMessage(text);
|
|
3933
|
+
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
3934
|
+
const matchText = provider.webviewMatchText;
|
|
3935
|
+
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
3936
|
+
const wvResult = await targetCdp.evaluateInWebviewFrame(webviewScript, matchFn);
|
|
3937
|
+
let wvParsed = wvResult;
|
|
3938
|
+
if (typeof wvResult === "string") {
|
|
3939
|
+
try {
|
|
3940
|
+
wvParsed = JSON.parse(wvResult);
|
|
3941
|
+
} catch {
|
|
3791
3942
|
}
|
|
3792
|
-
}
|
|
3793
|
-
|
|
3943
|
+
}
|
|
3944
|
+
if (wvParsed?.sent) {
|
|
3945
|
+
_log(`webviewSendMessage OK`);
|
|
3946
|
+
return _logSendSuccess("webview-script");
|
|
3794
3947
|
}
|
|
3795
3948
|
}
|
|
3796
3949
|
} catch (e) {
|
|
3797
|
-
_log(`
|
|
3950
|
+
_log(`webviewSendMessage failed: ${e.message}`);
|
|
3951
|
+
}
|
|
3952
|
+
}
|
|
3953
|
+
if (provider?.inputMethod === "cdp-type-and-send" && provider.inputSelector) {
|
|
3954
|
+
try {
|
|
3955
|
+
const sent = await targetCdp.typeAndSend(provider.inputSelector, text);
|
|
3956
|
+
if (sent) {
|
|
3957
|
+
_log(`typeAndSend(provider.inputSelector=${provider.inputSelector}) success`);
|
|
3958
|
+
return _logSendSuccess("typeAndSend-provider");
|
|
3959
|
+
}
|
|
3960
|
+
} catch (e) {
|
|
3961
|
+
_log(`typeAndSend(provider) failed: ${e.message}`);
|
|
3798
3962
|
}
|
|
3799
3963
|
}
|
|
3800
3964
|
_log("All methods failed");
|
|
@@ -3802,9 +3966,9 @@ async function handleSendChat(h, args) {
|
|
|
3802
3966
|
}
|
|
3803
3967
|
async function handleListChats(h, args) {
|
|
3804
3968
|
const provider = h.getProvider(args?.agentType);
|
|
3805
|
-
if (provider?.category === "extension" && h.agentStream && h.getCdp() && h.
|
|
3969
|
+
if (provider?.category === "extension" && h.agentStream && h.getCdp() && h.currentSession?.sessionId) {
|
|
3806
3970
|
try {
|
|
3807
|
-
const chats = await h.agentStream.
|
|
3971
|
+
const chats = await h.agentStream.listSessionChats(h.getCdp(), h.currentSession.sessionId);
|
|
3808
3972
|
LOG.info("Command", `[list_chats] Extension: ${chats.length} chats`);
|
|
3809
3973
|
return { success: true, chats };
|
|
3810
3974
|
} catch (e) {
|
|
@@ -3863,8 +4027,8 @@ async function handleNewChat(h, args) {
|
|
|
3863
4027
|
}
|
|
3864
4028
|
return { success: false, error: "new_chat not supported by this CLI provider" };
|
|
3865
4029
|
}
|
|
3866
|
-
if (provider?.category === "extension" && h.agentStream && h.getCdp() && h.
|
|
3867
|
-
const ok = await h.agentStream.
|
|
4030
|
+
if (provider?.category === "extension" && h.agentStream && h.getCdp() && h.currentSession?.sessionId) {
|
|
4031
|
+
const ok = await h.agentStream.newSession(h.getCdp(), h.currentSession.sessionId);
|
|
3868
4032
|
return { success: ok };
|
|
3869
4033
|
}
|
|
3870
4034
|
try {
|
|
@@ -3888,15 +4052,15 @@ async function handleNewChat(h, args) {
|
|
|
3888
4052
|
}
|
|
3889
4053
|
async function handleSwitchChat(h, args) {
|
|
3890
4054
|
const provider = h.getProvider(args?.agentType);
|
|
3891
|
-
const
|
|
4055
|
+
const managerKey = getCurrentManagerKey(h);
|
|
3892
4056
|
const sessionId = args?.sessionId || args?.id || args?.chatId;
|
|
3893
4057
|
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
3894
|
-
LOG.info("Command", `[switch_chat] sessionId=${sessionId},
|
|
3895
|
-
if (provider?.category === "extension" && h.agentStream && h.getCdp() && h.
|
|
3896
|
-
const ok = await h.agentStream.
|
|
4058
|
+
LOG.info("Command", `[switch_chat] sessionId=${sessionId}, manager=${managerKey}`);
|
|
4059
|
+
if (provider?.category === "extension" && h.agentStream && h.getCdp() && h.currentSession?.sessionId) {
|
|
4060
|
+
const ok = await h.agentStream.switchConversation(h.getCdp(), h.currentSession.sessionId, sessionId);
|
|
3897
4061
|
return { success: ok, result: ok ? "switched" : "failed" };
|
|
3898
4062
|
}
|
|
3899
|
-
const cdp = h.getCdp(
|
|
4063
|
+
const cdp = h.getCdp(managerKey);
|
|
3900
4064
|
if (!cdp?.isConnected) return { success: false, error: "CDP not connected" };
|
|
3901
4065
|
try {
|
|
3902
4066
|
const webviewScript = h.getProviderScript("webviewSwitchSession", { SESSION_ID: JSON.stringify(sessionId) });
|
|
@@ -4038,7 +4202,7 @@ async function handleSetMode(h, args) {
|
|
|
4038
4202
|
async function handleChangeModel(h, args) {
|
|
4039
4203
|
const provider = h.getProvider(args?.agentType);
|
|
4040
4204
|
const model = args?.model;
|
|
4041
|
-
LOG.info("Command", `[change_model] model=${model} provider=${provider?.type} category=${provider?.category}
|
|
4205
|
+
LOG.info("Command", `[change_model] model=${model} provider=${provider?.type} category=${provider?.category} manager=${getCurrentManagerKey(h)} providerType=${getCurrentProviderType(h)}`);
|
|
4042
4206
|
if (provider?.category === "acp") {
|
|
4043
4207
|
const adapter = getTargetedCliAdapter(h, args, provider.type);
|
|
4044
4208
|
LOG.info("Command", `[change_model] ACP adapter found: ${!!adapter}, type=${adapter?.cliType}, hasAcpInstance=${!!adapter?._acpInstance}`);
|
|
@@ -4159,14 +4323,8 @@ async function handleResolveAction(h, args) {
|
|
|
4159
4323
|
LOG.info("Command", `[resolveAction] CLI PTY \u2192 buttonIndex=${buttonIndex} "${buttons[buttonIndex] ?? "?"}"`);
|
|
4160
4324
|
return { success: true, buttonIndex, button: buttons[buttonIndex] ?? button };
|
|
4161
4325
|
}
|
|
4162
|
-
if (provider?.category === "extension" && h.agentStream && h.getCdp() && h.
|
|
4163
|
-
const ok = await h.agentStream.
|
|
4164
|
-
h.getCdp(),
|
|
4165
|
-
h.currentIdeType,
|
|
4166
|
-
provider.type,
|
|
4167
|
-
action,
|
|
4168
|
-
h.currentIdeType
|
|
4169
|
-
);
|
|
4326
|
+
if (provider?.category === "extension" && h.agentStream && h.getCdp() && h.currentSession?.sessionId) {
|
|
4327
|
+
const ok = await h.agentStream.resolveSessionAction(h.getCdp(), h.currentSession.sessionId, action);
|
|
4170
4328
|
return { success: ok };
|
|
4171
4329
|
}
|
|
4172
4330
|
if (provider?.scripts?.webviewResolveAction || provider?.scripts?.webview_resolve_action) {
|
|
@@ -4244,11 +4402,14 @@ async function handleResolveAction(h, args) {
|
|
|
4244
4402
|
}
|
|
4245
4403
|
return { success: false, error: "resolveAction script not available for this provider" };
|
|
4246
4404
|
}
|
|
4405
|
+
var RECENT_SEND_WINDOW_MS, recentSendByTarget;
|
|
4247
4406
|
var init_chat_commands = __esm({
|
|
4248
4407
|
"../../oss/packages/daemon-core/src/commands/chat-commands.ts"() {
|
|
4249
4408
|
"use strict";
|
|
4250
4409
|
init_chat_history();
|
|
4251
4410
|
init_logger();
|
|
4411
|
+
RECENT_SEND_WINDOW_MS = 1200;
|
|
4412
|
+
recentSendByTarget = /* @__PURE__ */ new Map();
|
|
4252
4413
|
}
|
|
4253
4414
|
});
|
|
4254
4415
|
|
|
@@ -4537,157 +4698,37 @@ var init_cdp_commands = __esm({
|
|
|
4537
4698
|
});
|
|
4538
4699
|
|
|
4539
4700
|
// ../../oss/packages/daemon-core/src/commands/stream-commands.ts
|
|
4540
|
-
async function
|
|
4541
|
-
if (!h.agentStream || !h.getCdp() || !h.currentIdeType) return { success: false, error: "AgentStream or CDP not available" };
|
|
4542
|
-
const agentType = args?.agentType || args?.agent || null;
|
|
4543
|
-
await h.agentStream.switchActiveAgent(h.getCdp(), h.currentIdeType, agentType);
|
|
4544
|
-
return { success: true, activeAgent: agentType };
|
|
4545
|
-
}
|
|
4546
|
-
async function handleAgentStreamRead(h, args) {
|
|
4547
|
-
if (!h.agentStream || !h.getCdp() || !h.currentIdeType) return { success: false, error: "AgentStream or CDP not available" };
|
|
4548
|
-
const streams = await h.agentStream.collectAgentStreams(h.getCdp(), h.currentIdeType);
|
|
4549
|
-
return { success: true, streams };
|
|
4550
|
-
}
|
|
4551
|
-
async function handleAgentStreamSend(h, args) {
|
|
4552
|
-
const agentType = args?.agentType || args?.agent;
|
|
4553
|
-
const text = args?.text || args?.message;
|
|
4554
|
-
if (!text) return { success: false, error: "text required" };
|
|
4555
|
-
if (agentType && h.ctx.adapters) {
|
|
4556
|
-
for (const [key, adapter] of h.ctx.adapters.entries()) {
|
|
4557
|
-
if (adapter.cliType === agentType || key.includes(agentType)) {
|
|
4558
|
-
LOG.info("Command", `[agent_stream_send] Routing to CLI adapter: ${adapter.cliType}`);
|
|
4559
|
-
try {
|
|
4560
|
-
await adapter.sendMessage(text);
|
|
4561
|
-
return { success: true, sent: true, targetAgent: adapter.cliType };
|
|
4562
|
-
} catch (e) {
|
|
4563
|
-
LOG.info("Command", `[agent_stream_send] CLI adapter failed: ${e.message}`);
|
|
4564
|
-
return { success: false, error: `CLI send failed: ${e.message}` };
|
|
4565
|
-
}
|
|
4566
|
-
}
|
|
4567
|
-
}
|
|
4568
|
-
}
|
|
4569
|
-
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
4570
|
-
const resolvedAgent = agentType || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
|
|
4571
|
-
if (!resolvedAgent) return { success: false, error: "agentType required" };
|
|
4572
|
-
if (!h.currentIdeType) return { success: false, error: "ideType required" };
|
|
4573
|
-
const ok = await h.agentStream.sendToAgent(h.getCdp(), h.currentIdeType, resolvedAgent, text, h.currentIdeType);
|
|
4574
|
-
return { success: ok };
|
|
4575
|
-
}
|
|
4576
|
-
async function handleAgentStreamResolve(h, args) {
|
|
4577
|
-
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
4578
|
-
const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
|
|
4579
|
-
const action = args?.action || "approve";
|
|
4580
|
-
if (!agentType) return { success: false, error: "agentType required" };
|
|
4581
|
-
if (!h.currentIdeType) return { success: false, error: "ideType required" };
|
|
4582
|
-
const ok = await h.agentStream.resolveAgentAction(h.getCdp(), h.currentIdeType, agentType, action, h.currentIdeType);
|
|
4583
|
-
return { success: ok };
|
|
4584
|
-
}
|
|
4585
|
-
async function handleAgentStreamNew(h, args) {
|
|
4586
|
-
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
4587
|
-
const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
|
|
4588
|
-
if (!agentType) return { success: false, error: "agentType required" };
|
|
4589
|
-
if (!h.currentIdeType) return { success: false, error: "ideType required" };
|
|
4590
|
-
const ok = await h.agentStream.newAgentSession(h.getCdp(), h.currentIdeType, agentType, h.currentIdeType);
|
|
4591
|
-
return { success: ok };
|
|
4592
|
-
}
|
|
4593
|
-
async function handleAgentStreamListChats(h, args) {
|
|
4594
|
-
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
4595
|
-
const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
|
|
4596
|
-
if (!agentType) return { success: false, error: "agentType required" };
|
|
4597
|
-
if (!h.currentIdeType) return { success: false, error: "ideType required" };
|
|
4598
|
-
const chats = await h.agentStream.listAgentChats(h.getCdp(), h.currentIdeType, agentType);
|
|
4599
|
-
return { success: true, chats };
|
|
4600
|
-
}
|
|
4601
|
-
async function handleAgentStreamSwitchSession(h, args) {
|
|
4602
|
-
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
4603
|
-
const agentType = args?.agentType || args?.agent || (h.currentIdeType ? h.agentStream.getActiveAgentType(h.currentIdeType) : null);
|
|
4604
|
-
const sessionId = args?.sessionId || args?.id;
|
|
4605
|
-
if (!agentType || !sessionId) return { success: false, error: "agentType and sessionId required" };
|
|
4606
|
-
if (!h.currentIdeType) return { success: false, error: "ideType required" };
|
|
4607
|
-
const ok = await h.agentStream.switchAgentSession(h.getCdp(), h.currentIdeType, agentType, sessionId);
|
|
4608
|
-
return { success: ok };
|
|
4609
|
-
}
|
|
4610
|
-
async function handleAgentStreamFocus(h, args) {
|
|
4701
|
+
async function handleFocusSession(h, args) {
|
|
4611
4702
|
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
4612
|
-
const
|
|
4613
|
-
if (!
|
|
4614
|
-
await h.agentStream.
|
|
4615
|
-
if (!h.currentIdeType) return { success: false, error: "ideType required" };
|
|
4616
|
-
const ok = await h.agentStream.focusAgentEditor(h.getCdp(), h.currentIdeType, agentType);
|
|
4703
|
+
const sessionId = args?.targetSessionId || h.currentSession?.sessionId;
|
|
4704
|
+
if (!sessionId) return { success: false, error: "targetSessionId required" };
|
|
4705
|
+
const ok = await h.agentStream.focusSession(h.getCdp(), sessionId);
|
|
4617
4706
|
return { success: ok };
|
|
4618
4707
|
}
|
|
4619
4708
|
function handlePtyInput(h, args) {
|
|
4620
|
-
const { cliType, data } = args || {};
|
|
4709
|
+
const { cliType, data, targetSessionId } = args || {};
|
|
4621
4710
|
if (!data) return { success: false, error: "data required" };
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
const first = h.ctx.adapters.values().next().value;
|
|
4626
|
-
if (first && typeof first.writeRaw === "function") {
|
|
4627
|
-
first.writeRaw(data);
|
|
4628
|
-
return { success: true };
|
|
4629
|
-
}
|
|
4630
|
-
}
|
|
4631
|
-
const directAdapter = h.ctx.adapters.get(targetCli);
|
|
4632
|
-
if (directAdapter && typeof directAdapter.writeRaw === "function") {
|
|
4633
|
-
directAdapter.writeRaw(data);
|
|
4634
|
-
return { success: true };
|
|
4635
|
-
}
|
|
4636
|
-
for (const [, adapter] of h.ctx.adapters) {
|
|
4637
|
-
if (adapter.cliType === targetCli && typeof adapter.writeRaw === "function") {
|
|
4638
|
-
adapter.writeRaw(data);
|
|
4639
|
-
return { success: true };
|
|
4640
|
-
}
|
|
4641
|
-
}
|
|
4642
|
-
for (const [key, adapter] of h.ctx.adapters) {
|
|
4643
|
-
if ((key.startsWith(targetCli) || targetCli.startsWith(adapter.cliType)) && typeof adapter.writeRaw === "function") {
|
|
4644
|
-
adapter.writeRaw(data);
|
|
4645
|
-
return { success: true };
|
|
4646
|
-
}
|
|
4647
|
-
}
|
|
4711
|
+
const adapter = h.getCliAdapter(targetSessionId || cliType);
|
|
4712
|
+
if (!adapter || typeof adapter.writeRaw !== "function") {
|
|
4713
|
+
return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
|
|
4648
4714
|
}
|
|
4649
|
-
|
|
4715
|
+
adapter.writeRaw(data);
|
|
4716
|
+
return { success: true };
|
|
4650
4717
|
}
|
|
4651
4718
|
function handlePtyResize(h, args) {
|
|
4652
|
-
const { cliType, cols, rows, force } = args || {};
|
|
4719
|
+
const { cliType, cols, rows, force, targetSessionId } = args || {};
|
|
4653
4720
|
if (!cols || !rows) return { success: false, error: "cols and rows required" };
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
first.resize(cols, rows);
|
|
4664
|
-
}
|
|
4665
|
-
return { success: true };
|
|
4666
|
-
}
|
|
4667
|
-
}
|
|
4668
|
-
const directAdapter = h.ctx.adapters.get(targetCli);
|
|
4669
|
-
if (directAdapter && typeof directAdapter.resize === "function") {
|
|
4670
|
-
if (force) {
|
|
4671
|
-
directAdapter.resize(cols - 1, rows);
|
|
4672
|
-
setTimeout(() => directAdapter.resize(cols, rows), 50);
|
|
4673
|
-
} else {
|
|
4674
|
-
directAdapter.resize(cols, rows);
|
|
4675
|
-
}
|
|
4676
|
-
return { success: true };
|
|
4677
|
-
}
|
|
4678
|
-
for (const [key, adapter] of h.ctx.adapters) {
|
|
4679
|
-
if ((adapter.cliType === targetCli || key.startsWith(targetCli) || targetCli.startsWith(adapter.cliType)) && typeof adapter.resize === "function") {
|
|
4680
|
-
if (force) {
|
|
4681
|
-
adapter.resize(cols - 1, rows);
|
|
4682
|
-
setTimeout(() => adapter.resize(cols, rows), 50);
|
|
4683
|
-
} else {
|
|
4684
|
-
adapter.resize(cols, rows);
|
|
4685
|
-
}
|
|
4686
|
-
return { success: true };
|
|
4687
|
-
}
|
|
4688
|
-
}
|
|
4721
|
+
const adapter = h.getCliAdapter(targetSessionId || cliType);
|
|
4722
|
+
if (!adapter || typeof adapter.resize !== "function") {
|
|
4723
|
+
return { success: false, error: `CLI adapter not found: ${targetSessionId || cliType || "unknown"}` };
|
|
4724
|
+
}
|
|
4725
|
+
if (force) {
|
|
4726
|
+
adapter.resize(cols - 1, rows);
|
|
4727
|
+
setTimeout(() => adapter.resize(cols, rows), 50);
|
|
4728
|
+
} else {
|
|
4729
|
+
adapter.resize(cols, rows);
|
|
4689
4730
|
}
|
|
4690
|
-
return { success:
|
|
4731
|
+
return { success: true };
|
|
4691
4732
|
}
|
|
4692
4733
|
function handleGetProviderSettings(h, args) {
|
|
4693
4734
|
const loader = h.ctx.providerLoader;
|
|
@@ -4723,7 +4764,7 @@ function handleSetProviderSetting(h, args) {
|
|
|
4723
4764
|
}
|
|
4724
4765
|
async function handleExtensionScript(h, args, scriptName) {
|
|
4725
4766
|
const { agentType, ideType } = args || {};
|
|
4726
|
-
LOG.info("Command", `[ExtScript] ${scriptName} agentType=${agentType} ideType=${ideType}
|
|
4767
|
+
LOG.info("Command", `[ExtScript] ${scriptName} agentType=${agentType} ideType=${ideType} session=${h.currentSession?.sessionId || ""}`);
|
|
4727
4768
|
if (!agentType) return { success: false, error: "agentType is required" };
|
|
4728
4769
|
const loader = h.ctx.providerLoader;
|
|
4729
4770
|
if (!loader) return { success: false, error: "ProviderLoader not initialized" };
|
|
@@ -4744,21 +4785,22 @@ async function handleExtensionScript(h, args, scriptName) {
|
|
|
4744
4785
|
}
|
|
4745
4786
|
const scriptCode = scriptFn(normalizedArgs);
|
|
4746
4787
|
if (!scriptCode) return { success: false, error: `Script '${actualScriptName}' returned null` };
|
|
4747
|
-
const cdpKey = provider.category === "ide" ? h.
|
|
4788
|
+
const cdpKey = provider.category === "ide" ? h.currentSession?.cdpManagerKey || h.currentManagerKey || agentType : h.currentSession?.cdpManagerKey || h.currentManagerKey || ideType;
|
|
4748
4789
|
LOG.info("Command", `[ExtScript] provider=${provider.type} category=${provider.category} cdpKey=${cdpKey}`);
|
|
4749
4790
|
const cdp = h.getCdp(cdpKey);
|
|
4750
4791
|
if (!cdp?.isConnected) return { success: false, error: `No CDP connection for ${cdpKey || "any"}` };
|
|
4751
4792
|
try {
|
|
4752
4793
|
let result;
|
|
4753
4794
|
if (provider.category === "extension") {
|
|
4754
|
-
const
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4795
|
+
const runtimeSessionId = h.currentSession?.sessionId || args?.targetSessionId;
|
|
4796
|
+
if (!runtimeSessionId) return { success: false, error: `No target session found for ${agentType}` };
|
|
4797
|
+
const parentSessionId = h.currentSession?.parentSessionId;
|
|
4798
|
+
if (parentSessionId) {
|
|
4799
|
+
await h.agentStream?.setActiveSession(cdp, parentSessionId, runtimeSessionId);
|
|
4800
|
+
await h.agentStream?.syncActiveSession(cdp, parentSessionId);
|
|
4801
|
+
}
|
|
4802
|
+
const managed = runtimeSessionId ? h.agentStream?.getManagedSession(runtimeSessionId) : null;
|
|
4803
|
+
const targetSessionId = managed?.cdpSessionId || null;
|
|
4762
4804
|
const IDE_LEVEL_SCRIPTS = ["listModes", "setMode", "listModels", "setModel"];
|
|
4763
4805
|
if (IDE_LEVEL_SCRIPTS.includes(scriptName)) {
|
|
4764
4806
|
if (targetSessionId) {
|
|
@@ -4829,7 +4871,7 @@ function handleGetIdeExtensions(h, args) {
|
|
|
4829
4871
|
enabled: config2.ideSettings?.[ide]?.extensions?.[p.type]?.enabled === true
|
|
4830
4872
|
}));
|
|
4831
4873
|
}
|
|
4832
|
-
return { success: true,
|
|
4874
|
+
return { success: true, ideExtensions: result };
|
|
4833
4875
|
}
|
|
4834
4876
|
function handleSetIdeExtension(h, args) {
|
|
4835
4877
|
const { ideType, extensionType, enabled } = args || {};
|
|
@@ -4968,10 +5010,8 @@ var init_handler = __esm({
|
|
|
4968
5010
|
_agentStream = null;
|
|
4969
5011
|
domHandlers;
|
|
4970
5012
|
_historyWriter;
|
|
4971
|
-
/** Current
|
|
4972
|
-
|
|
4973
|
-
/** Current provider type — agentType priority, ideType use */
|
|
4974
|
-
_currentProviderType;
|
|
5013
|
+
/** Current request route context */
|
|
5014
|
+
_currentRoute = {};
|
|
4975
5015
|
constructor(ctx) {
|
|
4976
5016
|
this._ctx = ctx;
|
|
4977
5017
|
this.domHandlers = new CdpDomHandlers((ideType) => this.getCdp(ideType));
|
|
@@ -4987,20 +5027,25 @@ var init_handler = __esm({
|
|
|
4987
5027
|
get historyWriter() {
|
|
4988
5028
|
return this._historyWriter;
|
|
4989
5029
|
}
|
|
5030
|
+
get currentManagerKey() {
|
|
5031
|
+
return this._currentRoute.managerKey;
|
|
5032
|
+
}
|
|
4990
5033
|
get currentIdeType() {
|
|
4991
|
-
return this.
|
|
5034
|
+
return this._currentRoute.managerKey;
|
|
4992
5035
|
}
|
|
4993
5036
|
get currentProviderType() {
|
|
4994
|
-
return this.
|
|
5037
|
+
return this._currentRoute.providerType;
|
|
5038
|
+
}
|
|
5039
|
+
get currentSession() {
|
|
5040
|
+
return this._currentRoute.session;
|
|
4995
5041
|
}
|
|
4996
|
-
/** Get CDP manager for a specific
|
|
4997
|
-
* Supports exact match, multi-window prefix match, and instanceIdMap UUID lookup.
|
|
4998
|
-
* Returns null if no match — never falls back to another IDE. */
|
|
5042
|
+
/** Get CDP manager for a specific session or manager key. */
|
|
4999
5043
|
getCdp(ideType) {
|
|
5000
|
-
const
|
|
5001
|
-
if (!
|
|
5002
|
-
const
|
|
5003
|
-
const
|
|
5044
|
+
const requested = ideType || this._currentRoute.session?.sessionId || this._currentRoute.managerKey;
|
|
5045
|
+
if (!requested) return null;
|
|
5046
|
+
const session = this._ctx.sessionRegistry?.get(requested);
|
|
5047
|
+
const managerKey = session?.cdpManagerKey || requested;
|
|
5048
|
+
const m = findCdpManager(this._ctx.cdpManagers, managerKey);
|
|
5004
5049
|
if (m?.isConnected) return m;
|
|
5005
5050
|
return null;
|
|
5006
5051
|
}
|
|
@@ -5008,7 +5053,7 @@ var init_handler = __esm({
|
|
|
5008
5053
|
* Get provider module — _currentProviderType (agentType priority) use.
|
|
5009
5054
|
*/
|
|
5010
5055
|
getProvider(overrideType) {
|
|
5011
|
-
const key = overrideType || this.
|
|
5056
|
+
const key = overrideType || this._currentRoute.providerType || this._currentRoute.session?.providerType || this._currentRoute.managerKey;
|
|
5012
5057
|
if (!key || !this._ctx.providerLoader) return void 0;
|
|
5013
5058
|
const result = this._ctx.providerLoader.resolve(key);
|
|
5014
5059
|
if (result) return result;
|
|
@@ -5041,14 +5086,22 @@ var init_handler = __esm({
|
|
|
5041
5086
|
const cdp = this.getCdp();
|
|
5042
5087
|
if (!cdp?.isConnected) return null;
|
|
5043
5088
|
if (provider?.category === "extension") {
|
|
5044
|
-
let sessionId = this.
|
|
5045
|
-
if (!sessionId && this.
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5089
|
+
let sessionId = this._currentRoute.session?.sessionId || null;
|
|
5090
|
+
if (!sessionId && this._currentRoute.session?.parentSessionId) {
|
|
5091
|
+
sessionId = this._agentStream?.resolveSessionForAgent(this._currentRoute.session.parentSessionId, provider.type) || null;
|
|
5092
|
+
}
|
|
5093
|
+
if (sessionId && this._agentStream) {
|
|
5094
|
+
const target = this._ctx.sessionRegistry?.get(sessionId);
|
|
5095
|
+
if (target?.parentSessionId) {
|
|
5096
|
+
await this._agentStream.setActiveSession(cdp, target.parentSessionId, sessionId);
|
|
5097
|
+
await this._agentStream.syncActiveSession(cdp, target.parentSessionId);
|
|
5098
|
+
}
|
|
5049
5099
|
}
|
|
5050
5100
|
if (!sessionId) return null;
|
|
5051
|
-
const
|
|
5101
|
+
const managed = this._agentStream?.getManagedSession(sessionId);
|
|
5102
|
+
const cdpSessionId = managed?.cdpSessionId;
|
|
5103
|
+
if (!cdpSessionId) return null;
|
|
5104
|
+
const result2 = await cdp.evaluateInSessionFrame(cdpSessionId, script, timeout);
|
|
5052
5105
|
return { result: result2, category: "extension" };
|
|
5053
5106
|
}
|
|
5054
5107
|
const result = await cdp.evaluate(script, timeout);
|
|
@@ -5056,57 +5109,37 @@ var init_handler = __esm({
|
|
|
5056
5109
|
}
|
|
5057
5110
|
/** CLI adapter search */
|
|
5058
5111
|
getCliAdapter(type) {
|
|
5059
|
-
const target = type || this.
|
|
5112
|
+
const target = type || this._currentRoute.session?.sessionId || this._currentRoute.providerType || this._currentRoute.managerKey;
|
|
5060
5113
|
if (!target || !this._ctx.adapters) return null;
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
const direct = this._ctx.adapters.get(normalizedTarget);
|
|
5065
|
-
if (direct) return direct;
|
|
5066
|
-
for (const [key, adapter] of this._ctx.adapters.entries()) {
|
|
5067
|
-
if (adapter.cliType === target || adapter.cliType === normalizedTarget || key === normalizedTarget || key.startsWith(target) || key.startsWith(normalizedTarget)) {
|
|
5068
|
-
return adapter;
|
|
5069
|
-
}
|
|
5114
|
+
const session = this._ctx.sessionRegistry?.get(target);
|
|
5115
|
+
if (session?.adapterKey) {
|
|
5116
|
+
return this._ctx.adapters.get(session.adapterKey) || null;
|
|
5070
5117
|
}
|
|
5071
|
-
return null;
|
|
5118
|
+
return this._ctx.adapters.get(target) || null;
|
|
5072
5119
|
}
|
|
5073
5120
|
// ─── Private helpers ──────────────────────────────
|
|
5074
|
-
|
|
5075
|
-
if (
|
|
5076
|
-
const
|
|
5077
|
-
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
const
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
const managerKey = instanceKey.slice(4);
|
|
5088
|
-
this._ctx.instanceIdMap?.set(instanceId, managerKey);
|
|
5089
|
-
return managerKey;
|
|
5090
|
-
}
|
|
5091
|
-
if (typeof instance?.getExtensionInstances === "function") {
|
|
5092
|
-
for (const ext of instance.getExtensionInstances() || []) {
|
|
5093
|
-
if (typeof ext?.getInstanceId === "function" && ext.getInstanceId() === instanceId) {
|
|
5094
|
-
const managerKey = instanceKey.slice(4);
|
|
5095
|
-
this._ctx.instanceIdMap?.set(instanceId, managerKey);
|
|
5096
|
-
return managerKey;
|
|
5097
|
-
}
|
|
5098
|
-
}
|
|
5099
|
-
}
|
|
5100
|
-
}
|
|
5101
|
-
return void 0;
|
|
5102
|
-
}
|
|
5103
|
-
/** Extract ideType from _targetInstance or explicit ideType */
|
|
5121
|
+
inferProviderType(key) {
|
|
5122
|
+
if (!key) return void 0;
|
|
5123
|
+
const session = this._ctx.sessionRegistry?.get(key);
|
|
5124
|
+
if (session?.providerType) return session.providerType;
|
|
5125
|
+
return key.split("_")[0];
|
|
5126
|
+
}
|
|
5127
|
+
resolveRoute(args) {
|
|
5128
|
+
const session = this._ctx.sessionRegistry?.get(args?.targetSessionId);
|
|
5129
|
+
const managerKey = this.extractIdeType(args);
|
|
5130
|
+
const providerType = args?.agentType || args?.providerType || session?.providerType || this.inferProviderType(managerKey);
|
|
5131
|
+
return { session, managerKey, providerType };
|
|
5132
|
+
}
|
|
5133
|
+
/** Extract CDP scope key from target session or explicit ideType */
|
|
5104
5134
|
extractIdeType(args) {
|
|
5135
|
+
if (args?.targetSessionId) {
|
|
5136
|
+
const target = this._ctx.sessionRegistry?.get(args.targetSessionId);
|
|
5137
|
+
if (target?.cdpManagerKey) return target.cdpManagerKey;
|
|
5138
|
+
if (this._ctx.cdpManagers.has(args.targetSessionId)) return args.targetSessionId;
|
|
5139
|
+
}
|
|
5105
5140
|
if (args?.ideType) {
|
|
5106
|
-
const
|
|
5107
|
-
if (
|
|
5108
|
-
return mappedKey;
|
|
5109
|
-
}
|
|
5141
|
+
const target = this._ctx.sessionRegistry?.get(args.ideType);
|
|
5142
|
+
if (target?.cdpManagerKey) return target.cdpManagerKey;
|
|
5110
5143
|
if (this._ctx.cdpManagers.has(args.ideType)) {
|
|
5111
5144
|
return args.ideType;
|
|
5112
5145
|
}
|
|
@@ -5117,34 +5150,6 @@ var init_handler = __esm({
|
|
|
5117
5150
|
}
|
|
5118
5151
|
}
|
|
5119
5152
|
}
|
|
5120
|
-
if (args?._targetInstance) {
|
|
5121
|
-
let raw = args._targetInstance;
|
|
5122
|
-
const ideMatch = raw.match(/:ide:(.+)$/);
|
|
5123
|
-
const cliMatch = raw.match(/:cli:(.+)$/);
|
|
5124
|
-
const acpMatch = raw.match(/:acp:(.+)$/);
|
|
5125
|
-
if (ideMatch) raw = ideMatch[1];
|
|
5126
|
-
else if (cliMatch) raw = cliMatch[1];
|
|
5127
|
-
else if (acpMatch) raw = acpMatch[1];
|
|
5128
|
-
const mappedKey = this.resolveManagerKeyFromInstanceId(raw);
|
|
5129
|
-
if (mappedKey) {
|
|
5130
|
-
return mappedKey;
|
|
5131
|
-
}
|
|
5132
|
-
if (this._ctx.cdpManagers.has(raw)) {
|
|
5133
|
-
return raw;
|
|
5134
|
-
}
|
|
5135
|
-
const found = findCdpManager(this._ctx.cdpManagers, raw);
|
|
5136
|
-
if (found) {
|
|
5137
|
-
for (const [k, m] of this._ctx.cdpManagers.entries()) {
|
|
5138
|
-
if (m === found) return k;
|
|
5139
|
-
}
|
|
5140
|
-
}
|
|
5141
|
-
const lastUnderscore = raw.lastIndexOf("_");
|
|
5142
|
-
if (lastUnderscore > 0) {
|
|
5143
|
-
const stripped = raw.substring(0, lastUnderscore);
|
|
5144
|
-
if (this._ctx.cdpManagers.has(stripped)) return stripped;
|
|
5145
|
-
}
|
|
5146
|
-
return raw;
|
|
5147
|
-
}
|
|
5148
5153
|
return void 0;
|
|
5149
5154
|
}
|
|
5150
5155
|
setAgentStreamManager(manager) {
|
|
@@ -5152,12 +5157,11 @@ var init_handler = __esm({
|
|
|
5152
5157
|
}
|
|
5153
5158
|
// ─── Command Dispatcher ──────────────────────────
|
|
5154
5159
|
async handle(cmd, args) {
|
|
5155
|
-
this.
|
|
5156
|
-
this.
|
|
5157
|
-
if (!this._currentIdeType && !this._currentProviderType) {
|
|
5160
|
+
this._currentRoute = this.resolveRoute(args);
|
|
5161
|
+
if (!this._currentRoute.session && !this._currentRoute.managerKey && !this._currentRoute.providerType) {
|
|
5158
5162
|
const cdpCommands = ["send_chat", "read_chat", "list_chats", "new_chat", "switch_chat", "set_mode", "change_model", "set_thought_level", "resolve_action"];
|
|
5159
5163
|
if (cdpCommands.includes(cmd)) {
|
|
5160
|
-
return { success: false, error: "No
|
|
5164
|
+
return { success: false, error: "No targetSessionId specified \u2014 cannot route command" };
|
|
5161
5165
|
}
|
|
5162
5166
|
}
|
|
5163
5167
|
try {
|
|
@@ -5248,22 +5252,8 @@ var init_handler = __esm({
|
|
|
5248
5252
|
case "refresh_scripts":
|
|
5249
5253
|
return this.handleRefreshScripts(args);
|
|
5250
5254
|
// ─── Stream commands (stream-commands.ts) ───────────
|
|
5251
|
-
case "
|
|
5252
|
-
return
|
|
5253
|
-
case "agent_stream_read":
|
|
5254
|
-
return handleAgentStreamRead(this, args);
|
|
5255
|
-
case "agent_stream_send":
|
|
5256
|
-
return handleAgentStreamSend(this, args);
|
|
5257
|
-
case "agent_stream_resolve":
|
|
5258
|
-
return handleAgentStreamResolve(this, args);
|
|
5259
|
-
case "agent_stream_new":
|
|
5260
|
-
return handleAgentStreamNew(this, args);
|
|
5261
|
-
case "agent_stream_list_chats":
|
|
5262
|
-
return handleAgentStreamListChats(this, args);
|
|
5263
|
-
case "agent_stream_switch_session":
|
|
5264
|
-
return handleAgentStreamSwitchSession(this, args);
|
|
5265
|
-
case "agent_stream_focus":
|
|
5266
|
-
return handleAgentStreamFocus(this, args);
|
|
5255
|
+
case "focus_session":
|
|
5256
|
+
return handleFocusSession(this, args);
|
|
5267
5257
|
// ─── PTY Raw I/O (stream-commands.ts) ─────────
|
|
5268
5258
|
case "pty_input":
|
|
5269
5259
|
return handlePtyInput(this, args);
|
|
@@ -8689,8 +8679,7 @@ var init_router = __esm({
|
|
|
8689
8679
|
"new_chat",
|
|
8690
8680
|
"switch_chat",
|
|
8691
8681
|
"set_mode",
|
|
8692
|
-
"change_model"
|
|
8693
|
-
"agent_stream_send"
|
|
8682
|
+
"change_model"
|
|
8694
8683
|
];
|
|
8695
8684
|
DaemonCommandRouter = class {
|
|
8696
8685
|
deps;
|
|
@@ -8928,6 +8917,7 @@ var init_router = __esm({
|
|
|
8928
8917
|
} catch {
|
|
8929
8918
|
}
|
|
8930
8919
|
this.deps.cdpManagers.delete(key);
|
|
8920
|
+
this.deps.sessionRegistry.unregisterByManagerKey(key);
|
|
8931
8921
|
LOG.info("StopIDE", `CDP disconnected: ${key}`);
|
|
8932
8922
|
}
|
|
8933
8923
|
}
|
|
@@ -8940,14 +8930,6 @@ var init_router = __esm({
|
|
|
8940
8930
|
for (const instanceKey of keysToRemove) {
|
|
8941
8931
|
const ideInstance = this.deps.instanceManager.getInstance(instanceKey);
|
|
8942
8932
|
if (ideInstance) {
|
|
8943
|
-
if (ideInstance.getInstanceId) {
|
|
8944
|
-
this.deps.instanceIdMap.delete(ideInstance.getInstanceId());
|
|
8945
|
-
}
|
|
8946
|
-
if (ideInstance.getExtensionInstances) {
|
|
8947
|
-
for (const ext of ideInstance.getExtensionInstances()) {
|
|
8948
|
-
if (ext.getInstanceId) this.deps.instanceIdMap.delete(ext.getInstanceId());
|
|
8949
|
-
}
|
|
8950
|
-
}
|
|
8951
8933
|
this.deps.instanceManager.removeInstance(instanceKey);
|
|
8952
8934
|
LOG.info("StopIDE", `Instance removed: ${instanceKey}`);
|
|
8953
8935
|
}
|
|
@@ -8956,14 +8938,6 @@ var init_router = __esm({
|
|
|
8956
8938
|
const instanceKey = `ide:${ideType}`;
|
|
8957
8939
|
const ideInstance = this.deps.instanceManager.getInstance(instanceKey);
|
|
8958
8940
|
if (ideInstance) {
|
|
8959
|
-
if (ideInstance.getInstanceId) {
|
|
8960
|
-
this.deps.instanceIdMap.delete(ideInstance.getInstanceId());
|
|
8961
|
-
}
|
|
8962
|
-
if (ideInstance.getExtensionInstances) {
|
|
8963
|
-
for (const ext of ideInstance.getExtensionInstances()) {
|
|
8964
|
-
if (ext.getInstanceId) this.deps.instanceIdMap.delete(ext.getInstanceId());
|
|
8965
|
-
}
|
|
8966
|
-
}
|
|
8967
8941
|
this.deps.instanceManager.removeInstance(instanceKey);
|
|
8968
8942
|
LOG.info("StopIDE", `Instance removed: ${instanceKey}`);
|
|
8969
8943
|
}
|
|
@@ -9012,15 +8986,9 @@ function buildStatusSnapshot(options) {
|
|
|
9012
8986
|
const cfg = loadConfig();
|
|
9013
8987
|
const wsState = getWorkspaceState(cfg);
|
|
9014
8988
|
const memSnap = getHostMemorySnapshot();
|
|
9015
|
-
const
|
|
8989
|
+
const sessions = buildSessionEntries(
|
|
9016
8990
|
options.allStates,
|
|
9017
|
-
options.cdpManagers
|
|
9018
|
-
{
|
|
9019
|
-
detectedIdes: options.detectedIdes.map((ide) => ({
|
|
9020
|
-
id: ide.id,
|
|
9021
|
-
installed: ide.installed !== false
|
|
9022
|
-
}))
|
|
9023
|
-
}
|
|
8991
|
+
options.cdpManagers
|
|
9024
8992
|
);
|
|
9025
8993
|
return {
|
|
9026
8994
|
instanceId: options.instanceId,
|
|
@@ -9042,9 +9010,7 @@ function buildStatusSnapshot(options) {
|
|
|
9042
9010
|
timestamp: options.timestamp ?? Date.now(),
|
|
9043
9011
|
detectedIdes: buildDetectedIdeInfos(options.detectedIdes, options.cdpManagers),
|
|
9044
9012
|
...options.p2p ? { p2p: options.p2p } : {},
|
|
9045
|
-
|
|
9046
|
-
managedClis,
|
|
9047
|
-
managedAcps,
|
|
9013
|
+
sessions,
|
|
9048
9014
|
workspaces: wsState.workspaces,
|
|
9049
9015
|
defaultWorkspaceId: wsState.defaultWorkspaceId,
|
|
9050
9016
|
defaultWorkspacePath: wsState.defaultWorkspacePath,
|
|
@@ -9175,7 +9141,7 @@ var init_reporter = __esm({
|
|
|
9175
9141
|
LOG.info("StatusReport", `\u2192${target} ${baseSummary}`);
|
|
9176
9142
|
}
|
|
9177
9143
|
}
|
|
9178
|
-
const
|
|
9144
|
+
const sessions = buildSessionEntries(
|
|
9179
9145
|
allStates,
|
|
9180
9146
|
this.deps.cdpManagers
|
|
9181
9147
|
);
|
|
@@ -9206,23 +9172,20 @@ var init_reporter = __esm({
|
|
|
9206
9172
|
if (opts?.p2pOnly) return;
|
|
9207
9173
|
const wsPayload = {
|
|
9208
9174
|
daemonMode: true,
|
|
9209
|
-
|
|
9210
|
-
|
|
9211
|
-
|
|
9212
|
-
|
|
9213
|
-
|
|
9214
|
-
|
|
9215
|
-
|
|
9216
|
-
|
|
9217
|
-
|
|
9218
|
-
|
|
9219
|
-
|
|
9220
|
-
|
|
9221
|
-
|
|
9222
|
-
|
|
9223
|
-
id: a.id,
|
|
9224
|
-
acpType: a.acpType,
|
|
9225
|
-
acpName: a.acpName
|
|
9175
|
+
sessions: sessions.map((session) => ({
|
|
9176
|
+
id: session.id,
|
|
9177
|
+
parentId: session.parentId,
|
|
9178
|
+
providerType: session.providerType,
|
|
9179
|
+
providerName: session.providerName,
|
|
9180
|
+
kind: session.kind,
|
|
9181
|
+
transport: session.transport,
|
|
9182
|
+
status: session.status,
|
|
9183
|
+
workspace: session.workspace,
|
|
9184
|
+
title: session.title,
|
|
9185
|
+
cdpConnected: session.cdpConnected,
|
|
9186
|
+
currentModel: session.currentModel,
|
|
9187
|
+
currentPlan: session.currentPlan,
|
|
9188
|
+
currentAutoApprove: session.currentAutoApprove
|
|
9226
9189
|
})),
|
|
9227
9190
|
p2p: payload.p2p,
|
|
9228
9191
|
timestamp: now
|
|
@@ -36203,6 +36166,9 @@ var init_acp_provider_instance = __esm({
|
|
|
36203
36166
|
);
|
|
36204
36167
|
}
|
|
36205
36168
|
}
|
|
36169
|
+
getInstanceId() {
|
|
36170
|
+
return this.instanceId;
|
|
36171
|
+
}
|
|
36206
36172
|
// ─── ACP Config Options & Modes ─────────────────────
|
|
36207
36173
|
parseConfigOptions(raw) {
|
|
36208
36174
|
if (!Array.isArray(raw)) return;
|
|
@@ -36999,6 +36965,7 @@ var init_cli_manager = __esm({
|
|
|
36999
36965
|
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
37000
36966
|
const provider = this.providerLoader.getByAlias(cliType);
|
|
37001
36967
|
const key = crypto4.randomUUID();
|
|
36968
|
+
const sessionRegistry = this.deps.getSessionRegistry?.() || null;
|
|
37002
36969
|
if (provider && provider.category === "acp") {
|
|
37003
36970
|
const instanceManager2 = this.deps.getInstanceManager();
|
|
37004
36971
|
if (!instanceManager2) throw new Error("InstanceManager not available");
|
|
@@ -37022,6 +36989,16 @@ ${installInfo}`
|
|
|
37022
36989
|
await instanceManager2.addInstance(key, acpInstance, {
|
|
37023
36990
|
settings: this.providerLoader.getSettings(normalizedType)
|
|
37024
36991
|
});
|
|
36992
|
+
const sessionId = acpInstance.getInstanceId();
|
|
36993
|
+
sessionRegistry?.register({
|
|
36994
|
+
sessionId,
|
|
36995
|
+
parentSessionId: null,
|
|
36996
|
+
providerType: normalizedType,
|
|
36997
|
+
providerCategory: "acp",
|
|
36998
|
+
transport: "acp",
|
|
36999
|
+
adapterKey: key,
|
|
37000
|
+
instanceKey: key
|
|
37001
|
+
});
|
|
37025
37002
|
this.adapters.set(key, {
|
|
37026
37003
|
cliType: normalizedType,
|
|
37027
37004
|
workingDir: resolvedDir,
|
|
@@ -37079,9 +37056,18 @@ ${installInfo}`
|
|
|
37079
37056
|
serverConn: this.deps.getServerConn(),
|
|
37080
37057
|
settings: {},
|
|
37081
37058
|
onPtyData: (data) => {
|
|
37082
|
-
this.deps.getP2p()?.broadcastPtyOutput(
|
|
37059
|
+
this.deps.getP2p()?.broadcastPtyOutput(cliInstance.instanceId, data);
|
|
37083
37060
|
}
|
|
37084
37061
|
});
|
|
37062
|
+
sessionRegistry?.register({
|
|
37063
|
+
sessionId: cliInstance.instanceId,
|
|
37064
|
+
parentSessionId: null,
|
|
37065
|
+
providerType: normalizedType,
|
|
37066
|
+
providerCategory: "cli",
|
|
37067
|
+
transport: "pty",
|
|
37068
|
+
adapterKey: key,
|
|
37069
|
+
instanceKey: key
|
|
37070
|
+
});
|
|
37085
37071
|
} catch (spawnErr) {
|
|
37086
37072
|
LOG.error("CLI", `[${cliType}] Spawn failed: ${spawnErr?.message}`);
|
|
37087
37073
|
instanceManager.removeInstance(key);
|
|
@@ -37103,6 +37089,7 @@ ${installInfo}`
|
|
|
37103
37089
|
if (this.adapters.has(key)) {
|
|
37104
37090
|
this.adapters.delete(key);
|
|
37105
37091
|
this.deps.removeAgentTracking(key);
|
|
37092
|
+
sessionRegistry?.unregisterByInstanceKey(key);
|
|
37106
37093
|
instanceManager.removeInstance(key);
|
|
37107
37094
|
LOG.info("CLI", `\u{1F9F9} Auto-cleaned ${status.status} CLI: ${cliType}`);
|
|
37108
37095
|
this.deps.onStatusChange();
|
|
@@ -37163,12 +37150,14 @@ ${installInfo}`
|
|
|
37163
37150
|
}
|
|
37164
37151
|
this.adapters.delete(key);
|
|
37165
37152
|
this.deps.removeAgentTracking(key);
|
|
37153
|
+
this.deps.getSessionRegistry?.()?.unregisterByInstanceKey(key);
|
|
37166
37154
|
this.deps.getInstanceManager()?.removeInstance(key);
|
|
37167
37155
|
LOG.info("CLI", `\u{1F6D1} Agent stopped: ${adapter.cliType} in ${adapter.workingDir}`);
|
|
37168
37156
|
this.deps.onStatusChange();
|
|
37169
37157
|
} else {
|
|
37170
37158
|
const im = this.deps.getInstanceManager();
|
|
37171
37159
|
if (im) {
|
|
37160
|
+
this.deps.getSessionRegistry?.()?.unregisterByInstanceKey(key);
|
|
37172
37161
|
im.removeInstance(key);
|
|
37173
37162
|
this.deps.removeAgentTracking(key);
|
|
37174
37163
|
LOG.warn("CLI", `\u{1F9F9} Force-removed orphan entry: ${key}`);
|
|
@@ -37183,7 +37172,7 @@ ${installInfo}`
|
|
|
37183
37172
|
// ─── Adapter search ─────────────────────────────
|
|
37184
37173
|
/**
|
|
37185
37174
|
* Search for CLI adapter. Priority order:
|
|
37186
|
-
* 0.
|
|
37175
|
+
* 0. sessionId (UUID direct match)
|
|
37187
37176
|
* 1. agentType + dir (iteration match)
|
|
37188
37177
|
* 2. agentType fuzzy match (⚠ returns first match when multiple sessions exist)
|
|
37189
37178
|
*/
|
|
@@ -37251,7 +37240,7 @@ ${installInfo}`
|
|
|
37251
37240
|
const cliType = args?.cliType;
|
|
37252
37241
|
const dir = args?.dir || "";
|
|
37253
37242
|
if (!cliType) throw new Error("cliType required");
|
|
37254
|
-
const found = this.findAdapter(cliType, { instanceKey: args?.
|
|
37243
|
+
const found = this.findAdapter(cliType, { instanceKey: args?.targetSessionId, dir });
|
|
37255
37244
|
if (found) {
|
|
37256
37245
|
await this.stopSession(found.key);
|
|
37257
37246
|
} else {
|
|
@@ -37283,7 +37272,7 @@ ${installInfo}`
|
|
|
37283
37272
|
}
|
|
37284
37273
|
const dir = rdir.path;
|
|
37285
37274
|
if (!cliType) throw new Error("cliType required");
|
|
37286
|
-
const found = this.findAdapter(cliType, { instanceKey: args?.
|
|
37275
|
+
const found = this.findAdapter(cliType, { instanceKey: args?.targetSessionId, dir });
|
|
37287
37276
|
if (found) await this.stopSession(found.key);
|
|
37288
37277
|
await this.startSession(cliType, dir);
|
|
37289
37278
|
this.persistRecentDir(cliType, dir);
|
|
@@ -37295,7 +37284,7 @@ ${installInfo}`
|
|
|
37295
37284
|
if (!agentType || !action) throw new Error("agentType and action required");
|
|
37296
37285
|
const found = this.findAdapter(agentType, {
|
|
37297
37286
|
dir: args?.dir,
|
|
37298
|
-
instanceKey: args?.
|
|
37287
|
+
instanceKey: args?.targetSessionId
|
|
37299
37288
|
});
|
|
37300
37289
|
if (!found) throw new Error(`CLI agent not running: ${agentType}`);
|
|
37301
37290
|
const { adapter, key } = found;
|
|
@@ -37460,14 +37449,8 @@ var init_manager2 = __esm({
|
|
|
37460
37449
|
init_provider_adapter();
|
|
37461
37450
|
init_logger();
|
|
37462
37451
|
DaemonAgentStreamManager = class {
|
|
37463
|
-
|
|
37464
|
-
|
|
37465
|
-
enabled = true;
|
|
37466
|
-
logFn;
|
|
37467
|
-
lastDiscoveryTimeByScope = /* @__PURE__ */ new Map();
|
|
37468
|
-
discoveryIntervalMsByScope = /* @__PURE__ */ new Map();
|
|
37469
|
-
activeAgentTypeByScope = /* @__PURE__ */ new Map();
|
|
37470
|
-
constructor(logFn, providerLoader) {
|
|
37452
|
+
constructor(logFn, providerLoader, sessionRegistry) {
|
|
37453
|
+
this.sessionRegistry = sessionRegistry;
|
|
37471
37454
|
this.logFn = logFn || LOG.forComponent("AgentStream").asLogFn();
|
|
37472
37455
|
if (providerLoader) {
|
|
37473
37456
|
const allExtProviders = providerLoader.getByCategory("extension");
|
|
@@ -37475,257 +37458,278 @@ var init_manager2 = __esm({
|
|
|
37475
37458
|
const resolved = providerLoader.resolve(p.type);
|
|
37476
37459
|
if (!resolved) continue;
|
|
37477
37460
|
const adapter = new ProviderStreamAdapter(resolved);
|
|
37478
|
-
this.
|
|
37461
|
+
this.adaptersByType.set(p.type, adapter);
|
|
37479
37462
|
this.logFn(`[AgentStream] Adapter created: ${p.type} (${p.name}) scripts=${Object.keys(resolved.scripts || {}).join(",") || "none"}`);
|
|
37480
37463
|
}
|
|
37481
37464
|
}
|
|
37482
37465
|
}
|
|
37466
|
+
adaptersByType = /* @__PURE__ */ new Map();
|
|
37467
|
+
managedBySessionId = /* @__PURE__ */ new Map();
|
|
37468
|
+
enabled = true;
|
|
37469
|
+
logFn;
|
|
37470
|
+
lastDiscoveryTimeByParent = /* @__PURE__ */ new Map();
|
|
37471
|
+
discoveryIntervalMsByParent = /* @__PURE__ */ new Map();
|
|
37472
|
+
activeSessionIdByParent = /* @__PURE__ */ new Map();
|
|
37483
37473
|
setEnabled(enabled) {
|
|
37484
37474
|
this.enabled = enabled;
|
|
37485
37475
|
}
|
|
37486
37476
|
get isEnabled() {
|
|
37487
37477
|
return this.enabled;
|
|
37488
37478
|
}
|
|
37489
|
-
|
|
37490
|
-
return this.
|
|
37479
|
+
getActiveSessionId(parentSessionId) {
|
|
37480
|
+
return this.activeSessionIdByParent.get(parentSessionId) || null;
|
|
37491
37481
|
}
|
|
37492
|
-
|
|
37493
|
-
|
|
37494
|
-
if (!managed) {
|
|
37495
|
-
managed = /* @__PURE__ */ new Map();
|
|
37496
|
-
this.managedByScope.set(scopeKey, managed);
|
|
37497
|
-
}
|
|
37498
|
-
return managed;
|
|
37482
|
+
getSessionTarget(sessionId) {
|
|
37483
|
+
return this.sessionRegistry?.get(sessionId);
|
|
37499
37484
|
}
|
|
37500
|
-
|
|
37501
|
-
this.
|
|
37502
|
-
this.
|
|
37503
|
-
this.
|
|
37504
|
-
|
|
37485
|
+
resetParentSession(parentSessionId) {
|
|
37486
|
+
const activeSessionId = this.activeSessionIdByParent.get(parentSessionId);
|
|
37487
|
+
if (activeSessionId) this.managedBySessionId.delete(activeSessionId);
|
|
37488
|
+
for (const child of this.sessionRegistry?.listChildren(parentSessionId) || []) {
|
|
37489
|
+
this.managedBySessionId.delete(child.sessionId);
|
|
37490
|
+
}
|
|
37491
|
+
this.activeSessionIdByParent.delete(parentSessionId);
|
|
37492
|
+
this.lastDiscoveryTimeByParent.delete(parentSessionId);
|
|
37493
|
+
this.discoveryIntervalMsByParent.delete(parentSessionId);
|
|
37505
37494
|
}
|
|
37506
37495
|
/** Panel focus based on provider.js focusPanel or extensionId (currently no-op) */
|
|
37507
|
-
async
|
|
37508
|
-
}
|
|
37509
|
-
async
|
|
37510
|
-
const
|
|
37511
|
-
|
|
37512
|
-
if (
|
|
37513
|
-
|
|
37514
|
-
const prev = managed.get(previousAgentType);
|
|
37496
|
+
async ensureSessionPanelOpen(_sessionId) {
|
|
37497
|
+
}
|
|
37498
|
+
async setActiveSession(cdp, parentSessionId, sessionId) {
|
|
37499
|
+
const previousSessionId = this.getActiveSessionId(parentSessionId);
|
|
37500
|
+
if (previousSessionId === sessionId) return;
|
|
37501
|
+
if (previousSessionId) {
|
|
37502
|
+
const prev = this.managedBySessionId.get(previousSessionId);
|
|
37515
37503
|
if (prev) {
|
|
37516
37504
|
try {
|
|
37517
|
-
await cdp.detachAgent(prev.
|
|
37505
|
+
await cdp.detachAgent(prev.cdpSessionId);
|
|
37518
37506
|
} catch {
|
|
37519
37507
|
}
|
|
37520
|
-
|
|
37521
|
-
this.logFn(`[AgentStream] Deactivated: ${prev.adapter.agentName} (${
|
|
37522
|
-
}
|
|
37523
|
-
}
|
|
37524
|
-
this.
|
|
37525
|
-
this.
|
|
37526
|
-
|
|
37527
|
-
|
|
37528
|
-
|
|
37529
|
-
this.
|
|
37508
|
+
this.managedBySessionId.delete(previousSessionId);
|
|
37509
|
+
this.logFn(`[AgentStream] Deactivated: ${prev.adapter.agentName} (${parentSessionId})`);
|
|
37510
|
+
}
|
|
37511
|
+
}
|
|
37512
|
+
this.activeSessionIdByParent.set(parentSessionId, sessionId);
|
|
37513
|
+
this.lastDiscoveryTimeByParent.set(parentSessionId, 0);
|
|
37514
|
+
this.logFn(`[AgentStream] Active session (${parentSessionId}): ${sessionId || "none"}`);
|
|
37515
|
+
}
|
|
37516
|
+
resolveSessionIdForTarget(parentSessionId, agentType) {
|
|
37517
|
+
const child = (this.sessionRegistry?.listChildren(parentSessionId) || []).find((entry) => entry.providerCategory === "extension" && entry.providerType === agentType);
|
|
37518
|
+
return child?.sessionId || null;
|
|
37519
|
+
}
|
|
37520
|
+
async connectManagedSession(cdp, parentSessionId, runtimeSessionId) {
|
|
37521
|
+
const target = this.getSessionTarget(runtimeSessionId);
|
|
37522
|
+
if (!target || target.providerCategory !== "extension") return null;
|
|
37523
|
+
const adapter = this.adaptersByType.get(target.providerType);
|
|
37524
|
+
if (!adapter) return null;
|
|
37525
|
+
const targets = await cdp.discoverAgentWebviews();
|
|
37526
|
+
const activeTarget = targets.find((entry) => entry.agentType === target.providerType);
|
|
37527
|
+
if (!activeTarget) return null;
|
|
37528
|
+
const cdpSessionId = await cdp.attachToAgent(activeTarget);
|
|
37529
|
+
if (!cdpSessionId) return null;
|
|
37530
|
+
const managed = {
|
|
37531
|
+
adapter,
|
|
37532
|
+
runtimeSessionId,
|
|
37533
|
+
parentSessionId,
|
|
37534
|
+
cdpSessionId,
|
|
37535
|
+
target: activeTarget,
|
|
37536
|
+
lastState: null,
|
|
37537
|
+
lastError: null,
|
|
37538
|
+
lastHiddenCheckTime: 0
|
|
37539
|
+
};
|
|
37540
|
+
this.managedBySessionId.set(runtimeSessionId, managed);
|
|
37541
|
+
this.logFn(`[AgentStream] Connected: ${adapter.agentName} (${parentSessionId})`);
|
|
37542
|
+
return managed;
|
|
37530
37543
|
}
|
|
37531
37544
|
/** Agent webview discovery + session connection */
|
|
37532
|
-
async
|
|
37533
|
-
const
|
|
37534
|
-
if (!this.enabled || !
|
|
37545
|
+
async syncActiveSession(cdp, parentSessionId) {
|
|
37546
|
+
const activeSessionId = this.getActiveSessionId(parentSessionId);
|
|
37547
|
+
if (!this.enabled || !activeSessionId) return;
|
|
37535
37548
|
const now = Date.now();
|
|
37536
|
-
const managed = this.
|
|
37537
|
-
const lastDiscoveryTime = this.
|
|
37538
|
-
const discoveryIntervalMs = this.
|
|
37539
|
-
if (managed
|
|
37549
|
+
const managed = this.managedBySessionId.get(activeSessionId);
|
|
37550
|
+
const lastDiscoveryTime = this.lastDiscoveryTimeByParent.get(parentSessionId) || 0;
|
|
37551
|
+
const discoveryIntervalMs = this.discoveryIntervalMsByParent.get(parentSessionId) || 1e4;
|
|
37552
|
+
if (managed && now - lastDiscoveryTime < discoveryIntervalMs) {
|
|
37540
37553
|
return;
|
|
37541
37554
|
}
|
|
37542
|
-
this.
|
|
37555
|
+
this.lastDiscoveryTimeByParent.set(parentSessionId, now);
|
|
37543
37556
|
try {
|
|
37544
|
-
|
|
37545
|
-
|
|
37546
|
-
if (activeTarget && !managed.has(activeAgentType)) {
|
|
37547
|
-
const adapter = this.allAdapters.find((a) => a.agentType === activeAgentType);
|
|
37548
|
-
if (adapter) {
|
|
37549
|
-
const sessionId = await cdp.attachToAgent(activeTarget);
|
|
37550
|
-
if (sessionId) {
|
|
37551
|
-
managed.set(activeAgentType, {
|
|
37552
|
-
adapter,
|
|
37553
|
-
sessionId,
|
|
37554
|
-
target: activeTarget,
|
|
37555
|
-
lastState: null,
|
|
37556
|
-
lastError: null,
|
|
37557
|
-
lastHiddenCheckTime: 0
|
|
37558
|
-
});
|
|
37559
|
-
this.logFn(`[AgentStream] Connected: ${adapter.agentName} (${scopeKey})`);
|
|
37560
|
-
}
|
|
37561
|
-
}
|
|
37557
|
+
if (!managed) {
|
|
37558
|
+
await this.connectManagedSession(cdp, parentSessionId, activeSessionId);
|
|
37562
37559
|
}
|
|
37563
|
-
|
|
37564
|
-
if (type !== activeAgentType) {
|
|
37565
|
-
await cdp.detachAgent(agent.sessionId);
|
|
37566
|
-
managed.delete(type);
|
|
37567
|
-
}
|
|
37568
|
-
}
|
|
37569
|
-
this.discoveryIntervalMsByScope.set(scopeKey, managed.has(activeAgentType) ? 3e4 : 1e4);
|
|
37560
|
+
this.discoveryIntervalMsByParent.set(parentSessionId, this.managedBySessionId.has(activeSessionId) ? 3e4 : 1e4);
|
|
37570
37561
|
} catch (e) {
|
|
37571
|
-
this.logFn(`[AgentStream] sync error (${
|
|
37562
|
+
this.logFn(`[AgentStream] sync error (${parentSessionId}): ${e.message}`);
|
|
37572
37563
|
}
|
|
37573
37564
|
}
|
|
37574
|
-
/** Collect active
|
|
37575
|
-
async
|
|
37576
|
-
if (!this.enabled) return
|
|
37577
|
-
const
|
|
37578
|
-
|
|
37579
|
-
|
|
37580
|
-
if (
|
|
37581
|
-
|
|
37582
|
-
|
|
37583
|
-
|
|
37584
|
-
|
|
37585
|
-
|
|
37586
|
-
|
|
37587
|
-
|
|
37565
|
+
/** Collect active extension session state */
|
|
37566
|
+
async collectActiveSession(cdp, parentSessionId) {
|
|
37567
|
+
if (!this.enabled) return null;
|
|
37568
|
+
const activeSessionId = this.getActiveSessionId(parentSessionId);
|
|
37569
|
+
if (!activeSessionId) return null;
|
|
37570
|
+
let agent = this.managedBySessionId.get(activeSessionId);
|
|
37571
|
+
if (!agent) {
|
|
37572
|
+
agent = await this.connectManagedSession(cdp, parentSessionId, activeSessionId) || void 0;
|
|
37573
|
+
}
|
|
37574
|
+
if (!agent) return null;
|
|
37575
|
+
const type = agent.adapter.agentType;
|
|
37576
|
+
const isHidden = agent.lastState?.status === "panel_hidden";
|
|
37577
|
+
const hiddenCacheFresh = isHidden && Date.now() - agent.lastHiddenCheckTime < 3e4;
|
|
37578
|
+
if (hiddenCacheFresh) return agent.lastState;
|
|
37579
|
+
try {
|
|
37580
|
+
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
37581
|
+
const state = await agent.adapter.readChat(evaluate);
|
|
37582
|
+
LOG.debug("AgentStream", `[AgentStream] readChat(${type}) result: status=${state.status} msgs=${state.messages?.length || 0} model=${state.model || ""}${state.status === "error" ? " error=" + JSON.stringify(state.error || state._error || "unknown") : ""}`);
|
|
37583
|
+
agent.lastState = state;
|
|
37584
|
+
agent.lastError = null;
|
|
37585
|
+
if (state.status === "panel_hidden") {
|
|
37586
|
+
agent.lastHiddenCheckTime = Date.now();
|
|
37587
|
+
}
|
|
37588
|
+
return state;
|
|
37589
|
+
} catch (e) {
|
|
37590
|
+
const errorMsg = e?.message || String(e);
|
|
37591
|
+
this.logFn(`[AgentStream] readChat(${type}) error: ${errorMsg.slice(0, 200)}`);
|
|
37592
|
+
agent.lastError = errorMsg;
|
|
37593
|
+
if (errorMsg.includes("timeout") || errorMsg.includes("not connected") || errorMsg.includes("Session")) {
|
|
37588
37594
|
try {
|
|
37589
|
-
|
|
37590
|
-
|
|
37591
|
-
LOG.debug("AgentStream", `[AgentStream] readChat(${type}) result: status=${state.status} msgs=${state.messages?.length || 0} model=${state.model || ""}${state.status === "error" ? " error=" + JSON.stringify(state.error || state._error || "unknown") : ""}`);
|
|
37592
|
-
agent.lastState = state;
|
|
37593
|
-
agent.lastError = null;
|
|
37594
|
-
if (state.status === "panel_hidden") {
|
|
37595
|
-
agent.lastHiddenCheckTime = Date.now();
|
|
37596
|
-
}
|
|
37597
|
-
results.push(state);
|
|
37598
|
-
} catch (e) {
|
|
37599
|
-
const errorMsg = e?.message || String(e);
|
|
37600
|
-
this.logFn(`[AgentStream] readChat(${type}) error: ${errorMsg.slice(0, 200)}`);
|
|
37601
|
-
agent.lastError = errorMsg;
|
|
37602
|
-
results.push({
|
|
37603
|
-
agentType: type,
|
|
37604
|
-
agentName: agent.adapter.agentName,
|
|
37605
|
-
extensionId: agent.adapter.extensionId,
|
|
37606
|
-
status: "disconnected",
|
|
37607
|
-
messages: agent.lastState?.messages || [],
|
|
37608
|
-
inputContent: ""
|
|
37609
|
-
});
|
|
37610
|
-
if (errorMsg.includes("timeout") || errorMsg.includes("not connected") || errorMsg.includes("Session")) {
|
|
37611
|
-
try {
|
|
37612
|
-
await cdp.detachAgent(agent.sessionId);
|
|
37613
|
-
} catch {
|
|
37614
|
-
}
|
|
37615
|
-
managed.delete(type);
|
|
37616
|
-
this.lastDiscoveryTimeByScope.set(scopeKey, 0);
|
|
37617
|
-
}
|
|
37595
|
+
await cdp.detachAgent(agent.cdpSessionId);
|
|
37596
|
+
} catch {
|
|
37618
37597
|
}
|
|
37598
|
+
this.managedBySessionId.delete(activeSessionId);
|
|
37599
|
+
this.lastDiscoveryTimeByParent.set(parentSessionId, 0);
|
|
37619
37600
|
}
|
|
37601
|
+
return {
|
|
37602
|
+
agentType: type,
|
|
37603
|
+
agentName: agent.adapter.agentName,
|
|
37604
|
+
extensionId: agent.adapter.extensionId,
|
|
37605
|
+
status: "disconnected",
|
|
37606
|
+
messages: agent.lastState?.messages || [],
|
|
37607
|
+
inputContent: ""
|
|
37608
|
+
};
|
|
37620
37609
|
}
|
|
37621
|
-
return results;
|
|
37622
37610
|
}
|
|
37623
|
-
async
|
|
37624
|
-
await this.
|
|
37625
|
-
const
|
|
37611
|
+
async sendToSession(cdp, sessionId, text) {
|
|
37612
|
+
await this.ensureSessionPanelOpen(sessionId);
|
|
37613
|
+
const target = this.getSessionTarget(sessionId);
|
|
37614
|
+
if (!target?.parentSessionId) return false;
|
|
37615
|
+
await this.setActiveSession(cdp, target.parentSessionId, sessionId);
|
|
37616
|
+
await this.syncActiveSession(cdp, target.parentSessionId);
|
|
37617
|
+
const agent = this.managedBySessionId.get(sessionId);
|
|
37626
37618
|
if (!agent) return false;
|
|
37627
37619
|
try {
|
|
37628
|
-
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.
|
|
37620
|
+
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
37629
37621
|
await agent.adapter.sendMessage(evaluate, text);
|
|
37630
37622
|
return true;
|
|
37631
37623
|
} catch (e) {
|
|
37632
|
-
this.logFn(`[AgentStream]
|
|
37624
|
+
this.logFn(`[AgentStream] sendToSession(${sessionId}) error: ${e.message}`);
|
|
37633
37625
|
return false;
|
|
37634
37626
|
}
|
|
37635
37627
|
}
|
|
37636
|
-
async
|
|
37637
|
-
await this.
|
|
37638
|
-
const
|
|
37628
|
+
async resolveSessionAction(cdp, sessionId, action) {
|
|
37629
|
+
await this.ensureSessionPanelOpen(sessionId);
|
|
37630
|
+
const target = this.getSessionTarget(sessionId);
|
|
37631
|
+
if (!target?.parentSessionId) return false;
|
|
37632
|
+
await this.setActiveSession(cdp, target.parentSessionId, sessionId);
|
|
37633
|
+
await this.syncActiveSession(cdp, target.parentSessionId);
|
|
37634
|
+
const agent = this.managedBySessionId.get(sessionId);
|
|
37639
37635
|
if (!agent) return false;
|
|
37640
37636
|
try {
|
|
37641
|
-
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.
|
|
37637
|
+
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
37642
37638
|
return await agent.adapter.resolveAction(evaluate, action);
|
|
37643
37639
|
} catch (e) {
|
|
37644
|
-
this.logFn(`[AgentStream] resolveAction(${
|
|
37640
|
+
this.logFn(`[AgentStream] resolveAction(${sessionId}) error: ${e.message}`);
|
|
37645
37641
|
return false;
|
|
37646
37642
|
}
|
|
37647
37643
|
}
|
|
37648
|
-
async
|
|
37649
|
-
await this.
|
|
37650
|
-
const
|
|
37644
|
+
async newSession(cdp, sessionId) {
|
|
37645
|
+
await this.ensureSessionPanelOpen(sessionId);
|
|
37646
|
+
const target = this.getSessionTarget(sessionId);
|
|
37647
|
+
if (!target?.parentSessionId) return false;
|
|
37648
|
+
await this.setActiveSession(cdp, target.parentSessionId, sessionId);
|
|
37649
|
+
await this.syncActiveSession(cdp, target.parentSessionId);
|
|
37650
|
+
const agent = this.managedBySessionId.get(sessionId);
|
|
37651
37651
|
if (!agent) return false;
|
|
37652
37652
|
try {
|
|
37653
|
-
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.
|
|
37653
|
+
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
37654
37654
|
await agent.adapter.newSession(evaluate);
|
|
37655
37655
|
return true;
|
|
37656
37656
|
} catch (e) {
|
|
37657
|
-
this.logFn(`[AgentStream] newSession(${
|
|
37657
|
+
this.logFn(`[AgentStream] newSession(${sessionId}) error: ${e.message}`);
|
|
37658
37658
|
return false;
|
|
37659
37659
|
}
|
|
37660
37660
|
}
|
|
37661
|
-
async
|
|
37662
|
-
|
|
37663
|
-
if (!
|
|
37664
|
-
|
|
37665
|
-
|
|
37666
|
-
|
|
37667
|
-
agent = this.getManagedAgent(agentType, scopeKey);
|
|
37668
|
-
}
|
|
37661
|
+
async listSessionChats(cdp, sessionId) {
|
|
37662
|
+
const target = this.getSessionTarget(sessionId);
|
|
37663
|
+
if (!target?.parentSessionId) return [];
|
|
37664
|
+
await this.setActiveSession(cdp, target.parentSessionId, sessionId);
|
|
37665
|
+
await this.syncActiveSession(cdp, target.parentSessionId);
|
|
37666
|
+
const agent = this.managedBySessionId.get(sessionId);
|
|
37669
37667
|
if (!agent || typeof agent.adapter.listChats !== "function") return [];
|
|
37670
37668
|
try {
|
|
37671
|
-
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.
|
|
37669
|
+
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
37672
37670
|
return await agent.adapter.listChats(evaluate);
|
|
37673
37671
|
} catch (e) {
|
|
37674
|
-
this.logFn(`[AgentStream] listChats(${
|
|
37672
|
+
this.logFn(`[AgentStream] listChats(${sessionId}) error: ${e.message}`);
|
|
37675
37673
|
return [];
|
|
37676
37674
|
}
|
|
37677
37675
|
}
|
|
37678
|
-
async
|
|
37679
|
-
|
|
37680
|
-
if (!
|
|
37681
|
-
|
|
37682
|
-
|
|
37683
|
-
|
|
37684
|
-
agent = this.getManagedAgent(agentType, scopeKey);
|
|
37685
|
-
}
|
|
37676
|
+
async switchConversation(cdp, sessionId, conversationId) {
|
|
37677
|
+
const target = this.getSessionTarget(sessionId);
|
|
37678
|
+
if (!target?.parentSessionId) return false;
|
|
37679
|
+
await this.setActiveSession(cdp, target.parentSessionId, sessionId);
|
|
37680
|
+
await this.syncActiveSession(cdp, target.parentSessionId);
|
|
37681
|
+
const agent = this.managedBySessionId.get(sessionId);
|
|
37686
37682
|
if (!agent || typeof agent.adapter.switchSession !== "function") return false;
|
|
37687
37683
|
try {
|
|
37688
|
-
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.
|
|
37689
|
-
return await agent.adapter.switchSession(evaluate,
|
|
37684
|
+
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
37685
|
+
return await agent.adapter.switchSession(evaluate, conversationId);
|
|
37690
37686
|
} catch (e) {
|
|
37691
|
-
this.logFn(`[AgentStream] switchSession(${
|
|
37687
|
+
this.logFn(`[AgentStream] switchSession(${sessionId}) error: ${e.message}`);
|
|
37692
37688
|
return false;
|
|
37693
37689
|
}
|
|
37694
37690
|
}
|
|
37695
|
-
async
|
|
37696
|
-
const
|
|
37691
|
+
async focusSession(cdp, sessionId) {
|
|
37692
|
+
const target = this.getSessionTarget(sessionId);
|
|
37693
|
+
if (!target?.parentSessionId) return false;
|
|
37694
|
+
await this.setActiveSession(cdp, target.parentSessionId, sessionId);
|
|
37695
|
+
await this.syncActiveSession(cdp, target.parentSessionId);
|
|
37696
|
+
const agent = this.managedBySessionId.get(sessionId);
|
|
37697
37697
|
if (!agent || typeof agent.adapter.focusEditor !== "function") return false;
|
|
37698
37698
|
try {
|
|
37699
|
-
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.
|
|
37699
|
+
const evaluate = (expr, timeout) => cdp.evaluateInSessionFrame(agent.cdpSessionId, expr, timeout);
|
|
37700
37700
|
await agent.adapter.focusEditor(evaluate);
|
|
37701
37701
|
return true;
|
|
37702
37702
|
} catch (e) {
|
|
37703
|
-
this.logFn(`[AgentStream] focusEditor(${
|
|
37703
|
+
this.logFn(`[AgentStream] focusEditor(${sessionId}) error: ${e.message}`);
|
|
37704
37704
|
return false;
|
|
37705
37705
|
}
|
|
37706
37706
|
}
|
|
37707
|
-
|
|
37708
|
-
if (
|
|
37709
|
-
|
|
37707
|
+
getConnectedSessions(parentSessionId) {
|
|
37708
|
+
if (parentSessionId) {
|
|
37709
|
+
return [...this.managedBySessionId.values()].filter((entry) => entry.parentSessionId === parentSessionId).map((entry) => entry.runtimeSessionId);
|
|
37710
|
+
}
|
|
37711
|
+
return [...this.managedBySessionId.keys()];
|
|
37710
37712
|
}
|
|
37711
|
-
|
|
37712
|
-
return this.
|
|
37713
|
+
getManagedSession(sessionId) {
|
|
37714
|
+
return this.managedBySessionId.get(sessionId);
|
|
37713
37715
|
}
|
|
37714
37716
|
async dispose(cdpManagers) {
|
|
37715
|
-
for (const
|
|
37716
|
-
const
|
|
37717
|
+
for (const managed of this.managedBySessionId.values()) {
|
|
37718
|
+
const managerKey = this.getSessionTarget(managed.runtimeSessionId)?.cdpManagerKey;
|
|
37719
|
+
const cdp = managerKey ? cdpManagers.get(managerKey) : null;
|
|
37717
37720
|
if (!cdp) continue;
|
|
37718
|
-
|
|
37719
|
-
|
|
37720
|
-
|
|
37721
|
-
} catch {
|
|
37722
|
-
}
|
|
37721
|
+
try {
|
|
37722
|
+
await cdp.detachAgent(managed.cdpSessionId);
|
|
37723
|
+
} catch {
|
|
37723
37724
|
}
|
|
37724
37725
|
}
|
|
37725
|
-
this.
|
|
37726
|
-
this.
|
|
37727
|
-
this.
|
|
37728
|
-
this.
|
|
37726
|
+
this.managedBySessionId.clear();
|
|
37727
|
+
this.activeSessionIdByParent.clear();
|
|
37728
|
+
this.lastDiscoveryTimeByParent.clear();
|
|
37729
|
+
this.discoveryIntervalMsByParent.clear();
|
|
37730
|
+
}
|
|
37731
|
+
resolveSessionForAgent(parentSessionId, agentType) {
|
|
37732
|
+
return this.resolveSessionIdForTarget(parentSessionId, agentType);
|
|
37729
37733
|
}
|
|
37730
37734
|
};
|
|
37731
37735
|
}
|
|
@@ -37756,8 +37760,8 @@ var init_poller = __esm({
|
|
|
37756
37760
|
return null;
|
|
37757
37761
|
}
|
|
37758
37762
|
/** Reset active IDE tracking (e.g., when IDE is stopped) */
|
|
37759
|
-
resetActiveIde(
|
|
37760
|
-
this.deps.agentStreamManager.
|
|
37763
|
+
resetActiveIde(parentSessionId) {
|
|
37764
|
+
this.deps.agentStreamManager.resetParentSession(parentSessionId);
|
|
37761
37765
|
}
|
|
37762
37766
|
/** Start polling (idempotent — ignored if already started) */
|
|
37763
37767
|
start(intervalMs = 5e3) {
|
|
@@ -37779,12 +37783,14 @@ var init_poller = __esm({
|
|
|
37779
37783
|
agentStreamManager,
|
|
37780
37784
|
providerLoader,
|
|
37781
37785
|
instanceManager,
|
|
37782
|
-
cdpManagers
|
|
37786
|
+
cdpManagers,
|
|
37787
|
+
sessionRegistry
|
|
37783
37788
|
} = this.deps;
|
|
37784
37789
|
if (!agentStreamManager || cdpManagers.size === 0) return;
|
|
37785
37790
|
for (const [ideType, cdp] of cdpManagers) {
|
|
37786
37791
|
registerExtensionProviders(providerLoader, cdp, ideType);
|
|
37787
37792
|
const ideInstance = instanceManager.getInstance(`ide:${ideType}`);
|
|
37793
|
+
const parentSessionId = ideInstance?.getInstanceId?.();
|
|
37788
37794
|
if (ideInstance?.getExtensionTypes && ideInstance?.addExtension && ideInstance?.removeExtension) {
|
|
37789
37795
|
const currentExtTypes = new Set(ideInstance.getExtensionTypes());
|
|
37790
37796
|
const enabledExtTypes = new Set(
|
|
@@ -37792,6 +37798,10 @@ var init_poller = __esm({
|
|
|
37792
37798
|
);
|
|
37793
37799
|
for (const extType of currentExtTypes) {
|
|
37794
37800
|
if (!enabledExtTypes.has(extType)) {
|
|
37801
|
+
const extInstance = ideInstance.getExtension?.(extType);
|
|
37802
|
+
if (extInstance?.getInstanceId) {
|
|
37803
|
+
sessionRegistry.unregister(extInstance.getInstanceId());
|
|
37804
|
+
}
|
|
37795
37805
|
ideInstance.removeExtension(extType);
|
|
37796
37806
|
LOG.info("AgentStream", `Extension removed: ${extType} (disabled for ${ideType})`);
|
|
37797
37807
|
}
|
|
@@ -37802,46 +37812,61 @@ var init_poller = __esm({
|
|
|
37802
37812
|
if (extProvider) {
|
|
37803
37813
|
const extSettings = providerLoader.getSettings(extType);
|
|
37804
37814
|
ideInstance.addExtension(extProvider, extSettings);
|
|
37815
|
+
const extInstance = ideInstance.getExtension?.(extType);
|
|
37816
|
+
if (parentSessionId && extInstance?.getInstanceId) {
|
|
37817
|
+
sessionRegistry.register({
|
|
37818
|
+
sessionId: extInstance.getInstanceId(),
|
|
37819
|
+
parentSessionId,
|
|
37820
|
+
providerType: extType,
|
|
37821
|
+
providerCategory: "extension",
|
|
37822
|
+
transport: "cdp-webview",
|
|
37823
|
+
cdpManagerKey: ideType,
|
|
37824
|
+
instanceKey: `ide:${ideType}`
|
|
37825
|
+
});
|
|
37826
|
+
}
|
|
37805
37827
|
LOG.info("AgentStream", `Extension added: ${extType} (enabled for ${ideType})`);
|
|
37806
37828
|
}
|
|
37807
37829
|
}
|
|
37808
37830
|
}
|
|
37809
37831
|
}
|
|
37810
|
-
const
|
|
37811
|
-
if (
|
|
37812
|
-
const
|
|
37813
|
-
|
|
37814
|
-
)
|
|
37815
|
-
|
|
37816
|
-
|
|
37817
|
-
await agentStreamManager.switchActiveAgent(cdp, ideType, null);
|
|
37832
|
+
const activeSessionId = parentSessionId ? agentStreamManager.getActiveSessionId(parentSessionId) : null;
|
|
37833
|
+
if (activeSessionId) {
|
|
37834
|
+
const activeTarget = sessionRegistry.get(activeSessionId);
|
|
37835
|
+
const enabledExtTypes = new Set(providerLoader.getEnabledExtensionProviders(ideType).map((p) => p.type));
|
|
37836
|
+
if (!activeTarget || !enabledExtTypes.has(activeTarget.providerType)) {
|
|
37837
|
+
LOG.info("AgentStream", `Active agent ${activeTarget?.providerType || activeSessionId} was disabled for ${ideType} \u2014 detaching`);
|
|
37838
|
+
await agentStreamManager.setActiveSession(cdp, parentSessionId, null);
|
|
37818
37839
|
this.deps.onStreamsUpdated?.(ideType, []);
|
|
37819
37840
|
}
|
|
37820
37841
|
}
|
|
37821
37842
|
if (!cdp.isConnected) {
|
|
37822
|
-
if (
|
|
37823
|
-
agentStreamManager.
|
|
37843
|
+
if (parentSessionId && activeSessionId) {
|
|
37844
|
+
agentStreamManager.resetParentSession(parentSessionId);
|
|
37824
37845
|
this.deps.onStreamsUpdated?.(ideType, []);
|
|
37825
37846
|
}
|
|
37826
37847
|
continue;
|
|
37827
37848
|
}
|
|
37828
|
-
let
|
|
37829
|
-
if (!
|
|
37849
|
+
let resolvedActiveSessionId = activeSessionId;
|
|
37850
|
+
if (!resolvedActiveSessionId && parentSessionId) {
|
|
37830
37851
|
try {
|
|
37831
37852
|
const discovered = await cdp.discoverAgentWebviews();
|
|
37832
|
-
|
|
37833
|
-
|
|
37834
|
-
|
|
37835
|
-
|
|
37853
|
+
for (const target of discovered) {
|
|
37854
|
+
const sessionId = agentStreamManager.resolveSessionForAgent(parentSessionId, target.agentType);
|
|
37855
|
+
if (sessionId) {
|
|
37856
|
+
resolvedActiveSessionId = sessionId;
|
|
37857
|
+
await agentStreamManager.setActiveSession(cdp, parentSessionId, sessionId);
|
|
37858
|
+
LOG.info("AgentStream", `Auto-activated: ${target.agentType} (${ideType})`);
|
|
37859
|
+
break;
|
|
37860
|
+
}
|
|
37836
37861
|
}
|
|
37837
37862
|
} catch {
|
|
37838
37863
|
}
|
|
37839
37864
|
}
|
|
37840
|
-
if (!
|
|
37865
|
+
if (!resolvedActiveSessionId || !parentSessionId) continue;
|
|
37841
37866
|
try {
|
|
37842
|
-
await agentStreamManager.
|
|
37843
|
-
const
|
|
37844
|
-
this.deps.onStreamsUpdated?.(ideType,
|
|
37867
|
+
await agentStreamManager.syncActiveSession(cdp, parentSessionId);
|
|
37868
|
+
const stream = await agentStreamManager.collectActiveSession(cdp, parentSessionId);
|
|
37869
|
+
this.deps.onStreamsUpdated?.(ideType, stream ? [stream] : []);
|
|
37845
37870
|
} catch {
|
|
37846
37871
|
}
|
|
37847
37872
|
}
|
|
@@ -37952,6 +37977,7 @@ var init_provider_instance_manager = __esm({
|
|
|
37952
37977
|
...event,
|
|
37953
37978
|
providerType: instance.type,
|
|
37954
37979
|
instanceId: state.instanceId,
|
|
37980
|
+
targetSessionId: state.instanceId,
|
|
37955
37981
|
providerCategory: state.category
|
|
37956
37982
|
});
|
|
37957
37983
|
}
|
|
@@ -41784,6 +41810,69 @@ var init_installer = __esm({
|
|
|
41784
41810
|
}
|
|
41785
41811
|
});
|
|
41786
41812
|
|
|
41813
|
+
// ../../oss/packages/daemon-core/src/sessions/registry.ts
|
|
41814
|
+
var SessionRegistry;
|
|
41815
|
+
var init_registry = __esm({
|
|
41816
|
+
"../../oss/packages/daemon-core/src/sessions/registry.ts"() {
|
|
41817
|
+
"use strict";
|
|
41818
|
+
SessionRegistry = class {
|
|
41819
|
+
bySessionId = /* @__PURE__ */ new Map();
|
|
41820
|
+
byManagerKey = /* @__PURE__ */ new Map();
|
|
41821
|
+
byInstanceKey = /* @__PURE__ */ new Map();
|
|
41822
|
+
byParentSessionId = /* @__PURE__ */ new Map();
|
|
41823
|
+
register(target) {
|
|
41824
|
+
this.unregister(target.sessionId);
|
|
41825
|
+
this.bySessionId.set(target.sessionId, target);
|
|
41826
|
+
if (target.cdpManagerKey) this.addIndex(this.byManagerKey, target.cdpManagerKey, target.sessionId);
|
|
41827
|
+
if (target.instanceKey) this.addIndex(this.byInstanceKey, target.instanceKey, target.sessionId);
|
|
41828
|
+
if (target.parentSessionId) this.addIndex(this.byParentSessionId, target.parentSessionId, target.sessionId);
|
|
41829
|
+
}
|
|
41830
|
+
get(sessionId) {
|
|
41831
|
+
if (!sessionId) return void 0;
|
|
41832
|
+
return this.bySessionId.get(sessionId);
|
|
41833
|
+
}
|
|
41834
|
+
unregister(sessionId) {
|
|
41835
|
+
if (!sessionId) return;
|
|
41836
|
+
const target = this.bySessionId.get(sessionId);
|
|
41837
|
+
if (!target) return;
|
|
41838
|
+
this.bySessionId.delete(sessionId);
|
|
41839
|
+
if (target.cdpManagerKey) this.removeIndex(this.byManagerKey, target.cdpManagerKey, sessionId);
|
|
41840
|
+
if (target.instanceKey) this.removeIndex(this.byInstanceKey, target.instanceKey, sessionId);
|
|
41841
|
+
if (target.parentSessionId) this.removeIndex(this.byParentSessionId, target.parentSessionId, sessionId);
|
|
41842
|
+
}
|
|
41843
|
+
unregisterByManagerKey(managerKey) {
|
|
41844
|
+
for (const sessionId of [...this.byManagerKey.get(managerKey) || []]) {
|
|
41845
|
+
this.unregister(sessionId);
|
|
41846
|
+
}
|
|
41847
|
+
}
|
|
41848
|
+
unregisterByInstanceKey(instanceKey) {
|
|
41849
|
+
for (const sessionId of [...this.byInstanceKey.get(instanceKey) || []]) {
|
|
41850
|
+
this.unregister(sessionId);
|
|
41851
|
+
}
|
|
41852
|
+
}
|
|
41853
|
+
listChildren(parentSessionId) {
|
|
41854
|
+
const ids = this.byParentSessionId.get(parentSessionId);
|
|
41855
|
+
if (!ids) return [];
|
|
41856
|
+
return [...ids].map((id) => this.bySessionId.get(id)).filter(Boolean);
|
|
41857
|
+
}
|
|
41858
|
+
addIndex(index, key, sessionId) {
|
|
41859
|
+
let set2 = index.get(key);
|
|
41860
|
+
if (!set2) {
|
|
41861
|
+
set2 = /* @__PURE__ */ new Set();
|
|
41862
|
+
index.set(key, set2);
|
|
41863
|
+
}
|
|
41864
|
+
set2.add(sessionId);
|
|
41865
|
+
}
|
|
41866
|
+
removeIndex(index, key, sessionId) {
|
|
41867
|
+
const set2 = index.get(key);
|
|
41868
|
+
if (!set2) return;
|
|
41869
|
+
set2.delete(sessionId);
|
|
41870
|
+
if (set2.size === 0) index.delete(key);
|
|
41871
|
+
}
|
|
41872
|
+
};
|
|
41873
|
+
}
|
|
41874
|
+
});
|
|
41875
|
+
|
|
41787
41876
|
// ../../oss/packages/daemon-core/src/boot/daemon-lifecycle.ts
|
|
41788
41877
|
async function initDaemonComponents(config2) {
|
|
41789
41878
|
installGlobalInterceptor();
|
|
@@ -41821,11 +41910,14 @@ async function initDaemonComponents(config2) {
|
|
|
41821
41910
|
});
|
|
41822
41911
|
const instanceManager = new ProviderInstanceManager();
|
|
41823
41912
|
const cdpManagers = /* @__PURE__ */ new Map();
|
|
41824
|
-
const
|
|
41913
|
+
const sessionRegistry = new SessionRegistry();
|
|
41825
41914
|
const detectedIdesRef = { value: [] };
|
|
41915
|
+
let agentStreamManager = null;
|
|
41916
|
+
let poller = null;
|
|
41826
41917
|
const cliManager = new DaemonCliManager({
|
|
41827
41918
|
...config2.cliManagerDeps,
|
|
41828
|
-
getInstanceManager: () => instanceManager
|
|
41919
|
+
getInstanceManager: () => instanceManager,
|
|
41920
|
+
getSessionRegistry: () => sessionRegistry
|
|
41829
41921
|
}, providerLoader);
|
|
41830
41922
|
LOG.info("Init", "Detecting IDEs...");
|
|
41831
41923
|
detectedIdesRef.value = await detectIDEs();
|
|
@@ -41835,7 +41927,7 @@ async function initDaemonComponents(config2) {
|
|
|
41835
41927
|
providerLoader,
|
|
41836
41928
|
instanceManager,
|
|
41837
41929
|
cdpManagers,
|
|
41838
|
-
|
|
41930
|
+
sessionRegistry
|
|
41839
41931
|
};
|
|
41840
41932
|
const cdpInitializer = new DaemonCdpInitializer({
|
|
41841
41933
|
providerLoader,
|
|
@@ -41844,6 +41936,19 @@ async function initDaemonComponents(config2) {
|
|
|
41844
41936
|
onConnected: async (ideType, manager, managerKey) => {
|
|
41845
41937
|
await setupIdeInstance(cdpSetupContext, { ideType, manager, managerKey });
|
|
41846
41938
|
await config2.onCdpManagerSetup?.(ideType, manager, managerKey);
|
|
41939
|
+
},
|
|
41940
|
+
onDisconnected: async (_ideType, _manager, managerKey) => {
|
|
41941
|
+
sessionRegistry.unregisterByManagerKey(managerKey);
|
|
41942
|
+
const instanceKey = `ide:${managerKey}`;
|
|
41943
|
+
const ideInstance = instanceManager.getInstance(instanceKey);
|
|
41944
|
+
if (ideInstance) {
|
|
41945
|
+
instanceManager.removeInstance(instanceKey);
|
|
41946
|
+
LOG.info("CDP", `Instance removed after disconnect: ${instanceKey}`);
|
|
41947
|
+
}
|
|
41948
|
+
if (ideInstance?.getInstanceId) {
|
|
41949
|
+
agentStreamManager?.resetParentSession(ideInstance.getInstanceId());
|
|
41950
|
+
}
|
|
41951
|
+
config2.onStatusChange?.();
|
|
41847
41952
|
}
|
|
41848
41953
|
});
|
|
41849
41954
|
await cdpInitializer.connectAll(detectedIdesRef.value);
|
|
@@ -41855,14 +41960,14 @@ async function initDaemonComponents(config2) {
|
|
|
41855
41960
|
adapters: cliManager.adapters,
|
|
41856
41961
|
providerLoader,
|
|
41857
41962
|
instanceManager,
|
|
41858
|
-
|
|
41963
|
+
sessionRegistry
|
|
41859
41964
|
});
|
|
41860
|
-
|
|
41965
|
+
agentStreamManager = new DaemonAgentStreamManager(
|
|
41861
41966
|
LOG.forComponent("AgentStream").asLogFn(),
|
|
41862
|
-
providerLoader
|
|
41967
|
+
providerLoader,
|
|
41968
|
+
sessionRegistry
|
|
41863
41969
|
);
|
|
41864
41970
|
commandHandler.setAgentStreamManager(agentStreamManager);
|
|
41865
|
-
let poller;
|
|
41866
41971
|
const router = new DaemonCommandRouter({
|
|
41867
41972
|
commandHandler,
|
|
41868
41973
|
cliManager,
|
|
@@ -41870,7 +41975,7 @@ async function initDaemonComponents(config2) {
|
|
|
41870
41975
|
providerLoader,
|
|
41871
41976
|
instanceManager,
|
|
41872
41977
|
detectedIdes: detectedIdesRef,
|
|
41873
|
-
|
|
41978
|
+
sessionRegistry,
|
|
41874
41979
|
onCdpManagerCreated: async (ideType, manager) => {
|
|
41875
41980
|
await setupIdeInstance(cdpSetupContext, { ideType, manager });
|
|
41876
41981
|
await config2.onCdpManagerSetup?.(ideType, manager, ideType);
|
|
@@ -41885,6 +41990,7 @@ async function initDaemonComponents(config2) {
|
|
|
41885
41990
|
providerLoader,
|
|
41886
41991
|
instanceManager,
|
|
41887
41992
|
cdpManagers,
|
|
41993
|
+
sessionRegistry,
|
|
41888
41994
|
onStreamsUpdated: config2.onStreamsUpdated
|
|
41889
41995
|
});
|
|
41890
41996
|
poller.start();
|
|
@@ -41899,7 +42005,7 @@ async function initDaemonComponents(config2) {
|
|
|
41899
42005
|
poller,
|
|
41900
42006
|
cdpInitializer,
|
|
41901
42007
|
cdpManagers,
|
|
41902
|
-
|
|
42008
|
+
sessionRegistry,
|
|
41903
42009
|
detectedIdes: detectedIdesRef
|
|
41904
42010
|
};
|
|
41905
42011
|
}
|
|
@@ -41964,6 +42070,7 @@ var init_daemon_lifecycle = __esm({
|
|
|
41964
42070
|
init_provider_instance_manager();
|
|
41965
42071
|
init_dev_server();
|
|
41966
42072
|
init_ide_detector();
|
|
42073
|
+
init_registry();
|
|
41967
42074
|
init_logger();
|
|
41968
42075
|
init_config();
|
|
41969
42076
|
}
|
|
@@ -41994,10 +42101,7 @@ __export(src_exports, {
|
|
|
41994
42101
|
ProviderLoader: () => ProviderLoader,
|
|
41995
42102
|
VersionArchive: () => VersionArchive,
|
|
41996
42103
|
addCliHistory: () => addCliHistory,
|
|
41997
|
-
|
|
41998
|
-
buildManagedAcps: () => buildManagedAcps,
|
|
41999
|
-
buildManagedClis: () => buildManagedClis,
|
|
42000
|
-
buildManagedIdes: () => buildManagedIdes,
|
|
42104
|
+
buildSessionEntries: () => buildSessionEntries,
|
|
42001
42105
|
buildStatusSnapshot: () => buildStatusSnapshot,
|
|
42002
42106
|
connectCdpManager: () => connectCdpManager,
|
|
42003
42107
|
detectAllVersions: () => detectAllVersions,
|
|
@@ -43391,7 +43495,7 @@ var init_adhdev_daemon = __esm({
|
|
|
43391
43495
|
fs12 = __toESM(require("fs"));
|
|
43392
43496
|
path14 = __toESM(require("path"));
|
|
43393
43497
|
import_chalk2 = __toESM(require("chalk"));
|
|
43394
|
-
pkgVersion = "0.
|
|
43498
|
+
pkgVersion = "0.7.0";
|
|
43395
43499
|
if (pkgVersion === "unknown") {
|
|
43396
43500
|
try {
|
|
43397
43501
|
const possiblePaths = [
|
|
@@ -43669,7 +43773,7 @@ ${err?.stack || ""}`);
|
|
|
43669
43773
|
});
|
|
43670
43774
|
}
|
|
43671
43775
|
async handleCommand(msg, cmd, args) {
|
|
43672
|
-
LOG.info("Command", `${cmd}${args?.
|
|
43776
|
+
LOG.info("Command", `${cmd}${args?.targetSessionId ? ` \u2192 session:${String(args.targetSessionId).split("_")[0]}` : ""}`);
|
|
43673
43777
|
const cmdStart = Date.now();
|
|
43674
43778
|
const source = msg.ipcWs ? "ext" : "ws";
|
|
43675
43779
|
try {
|
|
@@ -43785,24 +43889,13 @@ ${err?.stack || ""}`);
|
|
|
43785
43889
|
// ─── CDP helpers ─────────────────────────────
|
|
43786
43890
|
/** Return CDP manager for specific IDE.
|
|
43787
43891
|
* Lookup order:
|
|
43788
|
-
* 1.
|
|
43789
|
-
* 2.
|
|
43790
|
-
* 3. Prefix match (multi-window: "antigravity_WorkspaceName")
|
|
43892
|
+
* 1. Exact match on cdpManagers (full manager key)
|
|
43893
|
+
* 2. Prefix match on cdpManagers (ideType_workspace)
|
|
43791
43894
|
*/
|
|
43792
43895
|
getCdpFor(ideType) {
|
|
43793
43896
|
if (!this.components) return null;
|
|
43794
43897
|
const key = ideType.toLowerCase();
|
|
43795
|
-
|
|
43796
|
-
if (mappedKey) {
|
|
43797
|
-
const mapped = this.components.cdpManagers.get(mappedKey);
|
|
43798
|
-
if (mapped?.isConnected) return mapped;
|
|
43799
|
-
}
|
|
43800
|
-
const exact = this.components.cdpManagers.get(key);
|
|
43801
|
-
if (exact) return exact;
|
|
43802
|
-
for (const [k, m] of this.components.cdpManagers.entries()) {
|
|
43803
|
-
if (k.startsWith(key + "_") && m.isConnected) return m;
|
|
43804
|
-
}
|
|
43805
|
-
return null;
|
|
43898
|
+
return findCdpManager(this.components.cdpManagers, key);
|
|
43806
43899
|
}
|
|
43807
43900
|
};
|
|
43808
43901
|
}
|