adhdev 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-entrypoint.js +1747 -1626
- package/dist/cli-entrypoint.js.map +1 -1
- package/dist/index.js +1735 -1614
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli-entrypoint.js
CHANGED
|
@@ -16514,7 +16514,7 @@ var require_dist = __commonJS({
|
|
|
16514
16514
|
DaemonStatusReporter: () => DaemonStatusReporter2,
|
|
16515
16515
|
DevServer: () => DevServer2,
|
|
16516
16516
|
IdeProviderInstance: () => IdeProviderInstance,
|
|
16517
|
-
LOG: () =>
|
|
16517
|
+
LOG: () => LOG5,
|
|
16518
16518
|
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
16519
16519
|
ProviderInstanceManager: () => ProviderInstanceManager,
|
|
16520
16520
|
ProviderLoader: () => ProviderLoader3,
|
|
@@ -16818,7 +16818,7 @@ var require_dist = __commonJS({
|
|
|
16818
16818
|
origConsoleLog(line);
|
|
16819
16819
|
}
|
|
16820
16820
|
}
|
|
16821
|
-
var
|
|
16821
|
+
var LOG5 = {
|
|
16822
16822
|
debug: (category, msg) => daemonLog(category, msg, "debug"),
|
|
16823
16823
|
info: (category, msg) => daemonLog(category, msg, "info"),
|
|
16824
16824
|
warn: (category, msg) => daemonLog(category, msg, "warn"),
|
|
@@ -16932,7 +16932,7 @@ var require_dist = __commonJS({
|
|
|
16932
16932
|
this._targetId = targetId || null;
|
|
16933
16933
|
this._targetFilter = targetFilter || {};
|
|
16934
16934
|
this.logFn = logFn || ((msg) => {
|
|
16935
|
-
|
|
16935
|
+
LOG5.info("CDP", msg);
|
|
16936
16936
|
});
|
|
16937
16937
|
}
|
|
16938
16938
|
/** Set target filter (can be updated after construction) */
|
|
@@ -17705,7 +17705,7 @@ var require_dist = __commonJS({
|
|
|
17705
17705
|
} catch {
|
|
17706
17706
|
}
|
|
17707
17707
|
const result = await this.sendInternal("Page.captureScreenshot", {
|
|
17708
|
-
format: "
|
|
17708
|
+
format: "webp",
|
|
17709
17709
|
quality,
|
|
17710
17710
|
...clip ? { clip } : {},
|
|
17711
17711
|
optimizeForSpeed: true,
|
|
@@ -18402,14 +18402,14 @@ var require_dist = __commonJS({
|
|
|
18402
18402
|
try {
|
|
18403
18403
|
await ext.onTick();
|
|
18404
18404
|
} catch (e) {
|
|
18405
|
-
|
|
18405
|
+
LOG5.warn("IdeInstance", `[IdeInstance:${this.type}] Extension ${id} tick error: ${e?.message}`);
|
|
18406
18406
|
}
|
|
18407
18407
|
}
|
|
18408
18408
|
this.tickErrorCount = 0;
|
|
18409
18409
|
} catch (e) {
|
|
18410
18410
|
this.tickErrorCount++;
|
|
18411
18411
|
if (this.tickErrorCount <= 3 || this.tickErrorCount % 10 === 0) {
|
|
18412
|
-
|
|
18412
|
+
LOG5.warn("IdeInstance", `[IdeInstance:${this.type}] onTick error (${this.tickErrorCount}): ${e?.message || e}`);
|
|
18413
18413
|
}
|
|
18414
18414
|
} finally {
|
|
18415
18415
|
this.tickBusy = false;
|
|
@@ -18486,7 +18486,7 @@ var require_dist = __commonJS({
|
|
|
18486
18486
|
});
|
|
18487
18487
|
ext.onEvent("extension_connected", { ideType: this.type });
|
|
18488
18488
|
this.extensions.set(provider2.type, ext);
|
|
18489
|
-
|
|
18489
|
+
LOG5.info("IdeInstance", `[IdeInstance:${this.type}] Extension added: ${provider2.type}`);
|
|
18490
18490
|
}
|
|
18491
18491
|
/** Extension Instance remove */
|
|
18492
18492
|
removeExtension(type) {
|
|
@@ -18596,7 +18596,7 @@ var require_dist = __commonJS({
|
|
|
18596
18596
|
const msg = e?.message || String(e);
|
|
18597
18597
|
if (msg.includes("Timeout") || msg.includes("timeout") || msg.includes("Target closed")) {
|
|
18598
18598
|
} else {
|
|
18599
|
-
|
|
18599
|
+
LOG5.warn("IdeInstance", `[IdeInstance:${this.type}] readChat internal error: ${msg}`);
|
|
18600
18600
|
}
|
|
18601
18601
|
}
|
|
18602
18602
|
}
|
|
@@ -18791,7 +18791,7 @@ var require_dist = __commonJS({
|
|
|
18791
18791
|
// ── Internal ────────────────────────────
|
|
18792
18792
|
getLogFn(ideType) {
|
|
18793
18793
|
if (this.opts.logFn) return this.opts.logFn(ideType);
|
|
18794
|
-
return (msg) =>
|
|
18794
|
+
return (msg) => LOG5.info(`CDP:${ideType}`, msg);
|
|
18795
18795
|
}
|
|
18796
18796
|
/**
|
|
18797
18797
|
* Single-window connection (standalone mode).
|
|
@@ -18810,7 +18810,7 @@ var require_dist = __commonJS({
|
|
|
18810
18810
|
if (!manager) return;
|
|
18811
18811
|
registerExtensionProviders(this.ctx.providerLoader, manager, ide);
|
|
18812
18812
|
this.ctx.cdpManagers.set(ide, manager);
|
|
18813
|
-
|
|
18813
|
+
LOG5.info("CDP", `Connected: ${ide} (port ${port})`);
|
|
18814
18814
|
await setupIdeInstance(this.ctx, { ideType: ide, manager });
|
|
18815
18815
|
this.opts.onConnected?.(ide, ide, manager);
|
|
18816
18816
|
}
|
|
@@ -18843,7 +18843,7 @@ var require_dist = __commonJS({
|
|
|
18843
18843
|
);
|
|
18844
18844
|
if (!manager) continue;
|
|
18845
18845
|
this.ctx.cdpManagers.set(managerKey, manager);
|
|
18846
|
-
|
|
18846
|
+
LOG5.info("CDP", `Connected: ${managerKey} (port ${port}, page "${target.title}")`);
|
|
18847
18847
|
await setupIdeInstance(this.ctx, {
|
|
18848
18848
|
ideType: ide,
|
|
18849
18849
|
manager,
|
|
@@ -18885,9 +18885,9 @@ var require_dist = __commonJS({
|
|
|
18885
18885
|
await this.connectIdePort(port, ide);
|
|
18886
18886
|
}
|
|
18887
18887
|
if (cdpManagers.size > 0) {
|
|
18888
|
-
|
|
18888
|
+
LOG5.info("CDP", `${cdpManagers.size} IDE(s) connected: ${[...cdpManagers.entries()].map(([k, m]) => `${k}:${m.getPort()}`).join(", ")}`);
|
|
18889
18889
|
} else {
|
|
18890
|
-
|
|
18890
|
+
LOG5.warn("CDP", `No IDEs connected \u2014 tried: ${filtered.map((p) => `${p.ide}:${p.port}`).join(", ")}`);
|
|
18891
18891
|
}
|
|
18892
18892
|
}
|
|
18893
18893
|
// ─── Per-port connection (multi-window aware) ───
|
|
@@ -18903,7 +18903,7 @@ var require_dist = __commonJS({
|
|
|
18903
18903
|
const provider2 = providerLoader.getMeta(ide);
|
|
18904
18904
|
const manager = new DaemonCdpManager2(
|
|
18905
18905
|
port,
|
|
18906
|
-
|
|
18906
|
+
LOG5.forComponent(`CDP:${ide}`).asLogFn(),
|
|
18907
18907
|
void 0,
|
|
18908
18908
|
provider2?.targetFilter
|
|
18909
18909
|
);
|
|
@@ -18911,7 +18911,7 @@ var require_dist = __commonJS({
|
|
|
18911
18911
|
if (connected) {
|
|
18912
18912
|
registerExtensionProviders(providerLoader, manager, ide);
|
|
18913
18913
|
cdpManagers.set(ide, manager);
|
|
18914
|
-
|
|
18914
|
+
LOG5.info("CDP", `Connected: ${ide} (port ${port})`);
|
|
18915
18915
|
await this.config.onConnected?.(ide, manager, ide);
|
|
18916
18916
|
}
|
|
18917
18917
|
return;
|
|
@@ -18929,7 +18929,7 @@ var require_dist = __commonJS({
|
|
|
18929
18929
|
const provider2 = providerLoader.getMeta(ide);
|
|
18930
18930
|
const manager = new DaemonCdpManager2(
|
|
18931
18931
|
port,
|
|
18932
|
-
|
|
18932
|
+
LOG5.forComponent(`CDP:${managerKey}`).asLogFn(),
|
|
18933
18933
|
target.id,
|
|
18934
18934
|
provider2?.targetFilter
|
|
18935
18935
|
);
|
|
@@ -18937,7 +18937,7 @@ var require_dist = __commonJS({
|
|
|
18937
18937
|
if (connected) {
|
|
18938
18938
|
registerExtensionProviders(providerLoader, manager, ide);
|
|
18939
18939
|
cdpManagers.set(managerKey, manager);
|
|
18940
|
-
|
|
18940
|
+
LOG5.info("CDP", `Connected: ${managerKey} (port ${port}${targets.length > 1 ? `, page "${target.title}"` : ""})`);
|
|
18941
18941
|
await this.config.onConnected?.(ide, manager, managerKey);
|
|
18942
18942
|
}
|
|
18943
18943
|
}
|
|
@@ -18987,1475 +18987,1438 @@ var require_dist = __commonJS({
|
|
|
18987
18987
|
}
|
|
18988
18988
|
}
|
|
18989
18989
|
};
|
|
18990
|
-
var fs32 = __toESM2(require("fs"));
|
|
18991
|
-
var path32 = __toESM2(require("path"));
|
|
18992
|
-
var os4 = __toESM2(require("os"));
|
|
18993
18990
|
init_config();
|
|
18994
|
-
|
|
18995
|
-
|
|
18996
|
-
|
|
18997
|
-
|
|
18998
|
-
|
|
18999
|
-
|
|
19000
|
-
|
|
19001
|
-
|
|
19002
|
-
|
|
19003
|
-
if (!key) {
|
|
19004
|
-
return null;
|
|
19005
|
-
}
|
|
19006
|
-
const m = this.ctx.cdpManagers.get(key.toLowerCase());
|
|
19007
|
-
if (m?.isConnected) return m;
|
|
19008
|
-
return null;
|
|
19009
|
-
}
|
|
19010
|
-
/** Current IDE type extracted from command args (per-request) */
|
|
19011
|
-
_currentIdeType;
|
|
19012
|
-
/** Current provider type — agentType priority, ideType use */
|
|
19013
|
-
_currentProviderType;
|
|
19014
|
-
historyWriter;
|
|
19015
|
-
/** Extract ideType from _targetInstance
|
|
19016
|
-
* UUID-based: query directly from instanceIdMap
|
|
19017
|
-
* Legacy: composite ID parsing ('doId:ide:uuid' → uuid → map lookup)
|
|
19018
|
-
*/
|
|
19019
|
-
extractIdeType(args) {
|
|
19020
|
-
if (args?._targetInstance) {
|
|
19021
|
-
let raw = args._targetInstance;
|
|
19022
|
-
const ideMatch = raw.match(/:ide:(.+)$/);
|
|
19023
|
-
const cliMatch = raw.match(/:cli:(.+)$/);
|
|
19024
|
-
const acpMatch = raw.match(/:acp:(.+)$/);
|
|
19025
|
-
if (ideMatch) raw = ideMatch[1];
|
|
19026
|
-
else if (cliMatch) raw = cliMatch[1];
|
|
19027
|
-
else if (acpMatch) raw = acpMatch[1];
|
|
19028
|
-
if (this.ctx.instanceIdMap?.has(raw)) {
|
|
19029
|
-
return this.ctx.instanceIdMap.get(raw);
|
|
19030
|
-
}
|
|
19031
|
-
const lastUnderscore = raw.lastIndexOf("_");
|
|
19032
|
-
if (lastUnderscore > 0) return raw.substring(0, lastUnderscore);
|
|
19033
|
-
return raw;
|
|
19034
|
-
}
|
|
19035
|
-
return void 0;
|
|
19036
|
-
}
|
|
19037
|
-
constructor(ctx) {
|
|
19038
|
-
this.ctx = ctx;
|
|
19039
|
-
this.domHandlers = new CdpDomHandlers((ideType) => this.getCdp(ideType));
|
|
19040
|
-
this.historyWriter = new ChatHistoryWriter();
|
|
19041
|
-
}
|
|
19042
|
-
/**
|
|
19043
|
-
* Get provider module — _currentProviderType (agentType priority) use.
|
|
19044
|
-
* Extension: agentType='cline' → provider.type='cline' (category=extension)
|
|
19045
|
-
* CLI: ideType='gemini-cli' → provider.type='gemini-cli' (category=cli)
|
|
19046
|
-
* IDE: ideType='cursor' → provider.type='cursor' (category=ide)
|
|
19047
|
-
*/
|
|
19048
|
-
getProvider(overrideType) {
|
|
19049
|
-
const key = overrideType || this._currentProviderType || this._currentIdeType;
|
|
19050
|
-
if (!key || !this.ctx.providerLoader) return void 0;
|
|
19051
|
-
const result = this.ctx.providerLoader.resolve(key);
|
|
19052
|
-
if (result) return result;
|
|
19053
|
-
const baseType = key.split("_")[0];
|
|
19054
|
-
if (baseType !== key) return this.ctx.providerLoader.resolve(baseType);
|
|
19055
|
-
return void 0;
|
|
19056
|
-
}
|
|
19057
|
-
/** Get a provider script by name from ProviderLoader.
|
|
19058
|
-
* Returns the script string or null. */
|
|
19059
|
-
getProviderScript(scriptName, params, ideType) {
|
|
19060
|
-
const provider2 = this.getProvider(ideType);
|
|
19061
|
-
if (provider2?.scripts) {
|
|
19062
|
-
const fn = provider2.scripts[scriptName];
|
|
19063
|
-
if (typeof fn === "function") {
|
|
19064
|
-
const firstVal = params ? Object.values(params)[0] : void 0;
|
|
19065
|
-
const script = firstVal ? fn(firstVal) : fn();
|
|
19066
|
-
if (script) return script;
|
|
19067
|
-
}
|
|
19068
|
-
}
|
|
19069
|
-
return null;
|
|
19070
|
-
}
|
|
19071
|
-
// ─── Category dispatch engine ───────────────────
|
|
19072
|
-
/**
|
|
19073
|
-
* Look up Extension provider webview session ID from AgentStreamManager.
|
|
19074
|
-
* provider.type (e.g. 'cline') → ManagedAgent sessionId
|
|
19075
|
-
*/
|
|
19076
|
-
getExtensionSessionId(provider2) {
|
|
19077
|
-
if (provider2.category !== "extension" || !this.agentStream) return null;
|
|
19078
|
-
const managed = this.agentStream.getManagedAgent(provider2.type);
|
|
19079
|
-
return managed?.sessionId || null;
|
|
19080
|
-
}
|
|
19081
|
-
/**
|
|
19082
|
-
* per-category CDP script execute:
|
|
19083
|
-
* IDE → cdp.evaluate(script) (main window)
|
|
19084
|
-
* Extension → cdp.evaluateInSession(sessionId, script) (webview)
|
|
19085
|
-
* CLI → null (separate handling needed)
|
|
19086
|
-
*/
|
|
19087
|
-
async evaluateProviderScript(scriptName, params, timeout = 3e4) {
|
|
19088
|
-
const provider2 = this.getProvider();
|
|
19089
|
-
const script = this.getProviderScript(scriptName, params);
|
|
19090
|
-
if (!script) return null;
|
|
19091
|
-
const cdp2 = this.getCdp();
|
|
19092
|
-
if (!cdp2?.isConnected) return null;
|
|
19093
|
-
if (provider2?.category === "extension") {
|
|
19094
|
-
let sessionId = this.getExtensionSessionId(provider2);
|
|
19095
|
-
if (!sessionId && this.agentStream) {
|
|
19096
|
-
await this.agentStream.switchActiveAgent(cdp2, provider2.type);
|
|
19097
|
-
await this.agentStream.syncAgentSessions(cdp2);
|
|
19098
|
-
sessionId = this.getExtensionSessionId(provider2);
|
|
19099
|
-
}
|
|
19100
|
-
if (!sessionId) return null;
|
|
19101
|
-
const result2 = await cdp2.evaluateInSession(sessionId, script, timeout);
|
|
19102
|
-
return { result: result2, category: "extension" };
|
|
19103
|
-
}
|
|
19104
|
-
const result = await cdp2.evaluate(script, timeout);
|
|
19105
|
-
return { result, category: provider2?.category || "ide" };
|
|
19106
|
-
}
|
|
19107
|
-
/**
|
|
19108
|
-
* CLI adapter search: provider.type or agentTypeas match
|
|
19109
|
-
*/
|
|
19110
|
-
getCliAdapter(type) {
|
|
19111
|
-
const target = type || this._currentIdeType;
|
|
19112
|
-
if (!target || !this.ctx.adapters) return null;
|
|
19113
|
-
for (const [key, adapter] of this.ctx.adapters.entries()) {
|
|
19114
|
-
if (adapter.cliType === target || key.startsWith(target)) {
|
|
19115
|
-
return adapter;
|
|
19116
|
-
}
|
|
19117
|
-
}
|
|
19118
|
-
return null;
|
|
19119
|
-
}
|
|
19120
|
-
setAgentStreamManager(manager) {
|
|
19121
|
-
this.agentStream = manager;
|
|
18991
|
+
async function handleChatHistory(h, args) {
|
|
18992
|
+
const { agentType, offset, limit, instanceId } = args;
|
|
18993
|
+
try {
|
|
18994
|
+
const provider2 = h.getProvider(agentType);
|
|
18995
|
+
const agentStr = provider2?.type || agentType || h.currentIdeType || "";
|
|
18996
|
+
const result = readChatHistory2(agentStr, offset || 0, limit || 30, instanceId);
|
|
18997
|
+
return { success: true, ...result, agent: agentStr };
|
|
18998
|
+
} catch (e) {
|
|
18999
|
+
return { success: false, error: e.message };
|
|
19122
19000
|
}
|
|
19123
|
-
|
|
19124
|
-
|
|
19125
|
-
|
|
19126
|
-
|
|
19127
|
-
|
|
19128
|
-
|
|
19129
|
-
|
|
19130
|
-
}
|
|
19131
|
-
|
|
19132
|
-
|
|
19133
|
-
|
|
19134
|
-
case "read_chat":
|
|
19135
|
-
return this.handleReadChat(args);
|
|
19136
|
-
case "chat_history":
|
|
19137
|
-
return this.handleChatHistory(args);
|
|
19138
|
-
case "send_chat":
|
|
19139
|
-
return this.handleSendChat(args);
|
|
19140
|
-
case "list_chats":
|
|
19141
|
-
return this.handleListChats(args);
|
|
19142
|
-
case "new_chat":
|
|
19143
|
-
return this.handleNewChat(args);
|
|
19144
|
-
case "switch_chat":
|
|
19145
|
-
return this.handleSwitchChat(args);
|
|
19146
|
-
case "set_mode":
|
|
19147
|
-
return this.handleSetMode(args);
|
|
19148
|
-
case "change_model":
|
|
19149
|
-
return this.handleChangeModel(args);
|
|
19150
|
-
case "set_thought_level":
|
|
19151
|
-
return this.handleSetThoughtLevel(args);
|
|
19152
|
-
case "resolve_action":
|
|
19153
|
-
return this.handleResolveAction(args);
|
|
19154
|
-
case "cdp_eval":
|
|
19155
|
-
return this.handleCdpEval(args);
|
|
19156
|
-
case "cdp_screenshot":
|
|
19157
|
-
case "screenshot":
|
|
19158
|
-
return this.handleScreenshot(args);
|
|
19159
|
-
case "cdp_command_exec":
|
|
19160
|
-
return this.handleCdpCommand(args);
|
|
19161
|
-
case "cdp_batch":
|
|
19162
|
-
return this.handleCdpBatch(args);
|
|
19163
|
-
case "cdp_remote_action":
|
|
19164
|
-
return this.handleCdpRemoteAction(args);
|
|
19165
|
-
case "cdp_discover_agents":
|
|
19166
|
-
return this.handleDiscoverAgents(args);
|
|
19167
|
-
case "cdp_dom_dump":
|
|
19168
|
-
return this.domHandlers.handleDomDump(args);
|
|
19169
|
-
case "cdp_dom_query":
|
|
19170
|
-
return this.domHandlers.handleDomQuery(args);
|
|
19171
|
-
case "cdp_dom_debug":
|
|
19172
|
-
return this.domHandlers.handleDomDebug(args);
|
|
19173
|
-
// ─── file directly handle ──────────────────
|
|
19174
|
-
case "file_read":
|
|
19175
|
-
return this.handleFileRead(args);
|
|
19176
|
-
case "file_write":
|
|
19177
|
-
return this.handleFileWrite(args);
|
|
19178
|
-
case "file_list":
|
|
19179
|
-
return this.handleFileList(args);
|
|
19180
|
-
case "file_list_browse":
|
|
19181
|
-
return this.handleFileListBrowse(args);
|
|
19182
|
-
// ─── vscode API → Extension delegate ────
|
|
19183
|
-
case "vscode_command_exec":
|
|
19184
|
-
case "execute_vscode_command": {
|
|
19185
|
-
const resolvedCmd = args?.commandId || args?.command;
|
|
19186
|
-
if (resolvedCmd === "adhdev.captureCdpScreenshot") {
|
|
19187
|
-
return this.handleScreenshot(args);
|
|
19188
|
-
}
|
|
19189
|
-
return this.delegateToExtension(resolvedCmd || cmd, args?.args);
|
|
19001
|
+
}
|
|
19002
|
+
async function handleReadChat(h, args) {
|
|
19003
|
+
const provider2 = h.getProvider();
|
|
19004
|
+
const _log = (msg) => LOG5.debug("Command", `[read_chat] ${msg}`);
|
|
19005
|
+
if (provider2?.category === "cli" || provider2?.category === "acp") {
|
|
19006
|
+
const adapter = h.getCliAdapter(provider2.type);
|
|
19007
|
+
if (adapter) {
|
|
19008
|
+
_log(`${provider2.category} adapter: ${adapter.cliType}`);
|
|
19009
|
+
const status = adapter.getStatus?.();
|
|
19010
|
+
if (status) {
|
|
19011
|
+
return { success: true, messages: status.messages || [], status: status.status, activeModal: status.activeModal };
|
|
19190
19012
|
}
|
|
19191
|
-
case "get_open_editors":
|
|
19192
|
-
return this.delegateToExtension("adhdev.getOpenEditors", [args]);
|
|
19193
|
-
case "open_tab":
|
|
19194
|
-
return this.delegateToExtension("vscode.open", [args?.uri || args?.path]);
|
|
19195
|
-
case "close_tab":
|
|
19196
|
-
return this.delegateToExtension("workbench.action.closeActiveEditor", []);
|
|
19197
|
-
case "open_folder":
|
|
19198
|
-
return this.delegateToExtension("vscode.openFolder", [args?.path]);
|
|
19199
|
-
case "open_folder_picker":
|
|
19200
|
-
return this.delegateToExtension("workbench.action.files.openFolder", []);
|
|
19201
|
-
case "open_recent":
|
|
19202
|
-
return this.delegateToExtension("workbench.action.openRecent", []);
|
|
19203
|
-
case "get_commands":
|
|
19204
|
-
return this.delegateToExtension("adhdev.getCommands", []);
|
|
19205
|
-
case "get_recent_workspaces":
|
|
19206
|
-
return this.handleGetRecentWorkspaces(args);
|
|
19207
|
-
// ─── script manage ───────────────────
|
|
19208
|
-
case "refresh_scripts":
|
|
19209
|
-
return this.handleRefreshScripts(args);
|
|
19210
|
-
// ─── Agent Stream commands ───────────────
|
|
19211
|
-
case "agent_stream_switch":
|
|
19212
|
-
return this.handleAgentStreamSwitch(args);
|
|
19213
|
-
case "agent_stream_read":
|
|
19214
|
-
return this.handleAgentStreamRead(args);
|
|
19215
|
-
case "agent_stream_send":
|
|
19216
|
-
return this.handleAgentStreamSend(args);
|
|
19217
|
-
case "agent_stream_resolve":
|
|
19218
|
-
return this.handleAgentStreamResolve(args);
|
|
19219
|
-
case "agent_stream_new":
|
|
19220
|
-
return this.handleAgentStreamNew(args);
|
|
19221
|
-
case "agent_stream_list_chats":
|
|
19222
|
-
return this.handleAgentStreamListChats(args);
|
|
19223
|
-
case "agent_stream_switch_session":
|
|
19224
|
-
return this.handleAgentStreamSwitchSession(args);
|
|
19225
|
-
case "agent_stream_focus":
|
|
19226
|
-
return this.handleAgentStreamFocus(args);
|
|
19227
|
-
// ─── PTY Raw I/O (terminal view) ─────────
|
|
19228
|
-
case "pty_input":
|
|
19229
|
-
return this.handlePtyInput(args);
|
|
19230
|
-
case "pty_resize":
|
|
19231
|
-
return this.handlePtyResize(args);
|
|
19232
|
-
// ─── Provider Settings ──────────────
|
|
19233
|
-
case "get_provider_settings":
|
|
19234
|
-
return this.handleGetProviderSettings(args);
|
|
19235
|
-
case "set_provider_setting":
|
|
19236
|
-
return this.handleSetProviderSetting(args);
|
|
19237
|
-
// ─── IDE Extension Settings (per-IDE on/off) ──────────────
|
|
19238
|
-
case "get_ide_extensions":
|
|
19239
|
-
return this.handleGetIdeExtensions(args);
|
|
19240
|
-
case "set_ide_extension":
|
|
19241
|
-
return this.handleSetIdeExtension(args);
|
|
19242
|
-
// ─── Extension Model / Mode Control ──────────────
|
|
19243
|
-
case "list_extension_models":
|
|
19244
|
-
return await this.handleExtensionScript(args, "listModels");
|
|
19245
|
-
case "set_extension_model":
|
|
19246
|
-
return await this.handleExtensionScript(args, "setModel");
|
|
19247
|
-
case "list_extension_modes":
|
|
19248
|
-
return await this.handleExtensionScript(args, "listModes");
|
|
19249
|
-
case "set_extension_mode":
|
|
19250
|
-
return await this.handleExtensionScript(args, "setMode");
|
|
19251
|
-
default:
|
|
19252
|
-
return { success: false, error: `Unknown command: ${cmd}` };
|
|
19253
19013
|
}
|
|
19014
|
+
return { success: false, error: `${provider2.category} adapter not found` };
|
|
19254
19015
|
}
|
|
19255
|
-
|
|
19256
|
-
async handleChatHistory(args) {
|
|
19257
|
-
const { agentType, offset, limit, instanceId } = args;
|
|
19016
|
+
if (provider2?.category === "extension") {
|
|
19258
19017
|
try {
|
|
19259
|
-
const
|
|
19260
|
-
|
|
19261
|
-
|
|
19262
|
-
|
|
19263
|
-
|
|
19264
|
-
|
|
19265
|
-
|
|
19266
|
-
}
|
|
19267
|
-
async handleReadChat(args) {
|
|
19268
|
-
const provider2 = this.getProvider();
|
|
19269
|
-
const _log = (msg) => LOG4.debug("Command", `[read_chat] ${msg}`);
|
|
19270
|
-
if (provider2?.category === "cli" || provider2?.category === "acp") {
|
|
19271
|
-
const adapter = this.getCliAdapter(provider2.type);
|
|
19272
|
-
if (adapter) {
|
|
19273
|
-
_log(`${provider2.category} adapter: ${adapter.cliType}`);
|
|
19274
|
-
const status = adapter.getStatus?.();
|
|
19275
|
-
if (status) {
|
|
19276
|
-
return { success: true, messages: status.messages || [], status: status.status, activeModal: status.activeModal };
|
|
19277
|
-
}
|
|
19278
|
-
}
|
|
19279
|
-
return { success: false, error: `${provider2.category} adapter not found` };
|
|
19280
|
-
}
|
|
19281
|
-
if (provider2?.category === "extension") {
|
|
19282
|
-
try {
|
|
19283
|
-
const evalResult = await this.evaluateProviderScript("readChat", void 0, 5e4);
|
|
19284
|
-
if (evalResult?.result) {
|
|
19285
|
-
let parsed = evalResult.result;
|
|
19286
|
-
if (typeof parsed === "string") {
|
|
19287
|
-
try {
|
|
19288
|
-
parsed = JSON.parse(parsed);
|
|
19289
|
-
} catch {
|
|
19290
|
-
}
|
|
19291
|
-
}
|
|
19292
|
-
if (parsed && typeof parsed === "object") {
|
|
19293
|
-
_log(`Extension OK: ${parsed.messages?.length || 0} msgs`);
|
|
19294
|
-
this.historyWriter.appendNewMessages(
|
|
19295
|
-
provider2.type || "unknown_extension",
|
|
19296
|
-
parsed.messages || [],
|
|
19297
|
-
parsed.title,
|
|
19298
|
-
args?.instanceId
|
|
19299
|
-
);
|
|
19300
|
-
return { success: true, ...parsed };
|
|
19018
|
+
const evalResult = await h.evaluateProviderScript("readChat", void 0, 5e4);
|
|
19019
|
+
if (evalResult?.result) {
|
|
19020
|
+
let parsed = evalResult.result;
|
|
19021
|
+
if (typeof parsed === "string") {
|
|
19022
|
+
try {
|
|
19023
|
+
parsed = JSON.parse(parsed);
|
|
19024
|
+
} catch {
|
|
19301
19025
|
}
|
|
19302
19026
|
}
|
|
19303
|
-
|
|
19304
|
-
|
|
19305
|
-
|
|
19306
|
-
|
|
19307
|
-
|
|
19308
|
-
|
|
19309
|
-
|
|
19310
|
-
|
|
19311
|
-
|
|
19312
|
-
this.historyWriter.appendNewMessages(
|
|
19313
|
-
stream.agentType,
|
|
19314
|
-
stream.messages || [],
|
|
19315
|
-
void 0,
|
|
19316
|
-
args?.instanceId
|
|
19317
|
-
);
|
|
19318
|
-
return { success: true, messages: stream.messages || [], status: stream.status, agentType: stream.agentType };
|
|
19319
|
-
}
|
|
19027
|
+
if (parsed && typeof parsed === "object") {
|
|
19028
|
+
_log(`Extension OK: ${parsed.messages?.length || 0} msgs`);
|
|
19029
|
+
h.historyWriter.appendNewMessages(
|
|
19030
|
+
provider2.type || "unknown_extension",
|
|
19031
|
+
parsed.messages || [],
|
|
19032
|
+
parsed.title,
|
|
19033
|
+
args?.instanceId
|
|
19034
|
+
);
|
|
19035
|
+
return { success: true, ...parsed };
|
|
19320
19036
|
}
|
|
19321
19037
|
}
|
|
19322
|
-
|
|
19323
|
-
|
|
19324
|
-
|
|
19325
|
-
if (
|
|
19326
|
-
|
|
19327
|
-
|
|
19328
|
-
|
|
19329
|
-
const
|
|
19330
|
-
|
|
19331
|
-
|
|
19332
|
-
|
|
19333
|
-
|
|
19334
|
-
|
|
19335
|
-
|
|
19336
|
-
|
|
19337
|
-
|
|
19338
|
-
}
|
|
19339
|
-
}
|
|
19340
|
-
if (parsed && typeof parsed === "object") {
|
|
19341
|
-
_log(`Webview OK: ${parsed.messages?.length || 0} msgs`);
|
|
19342
|
-
this.historyWriter.appendNewMessages(
|
|
19343
|
-
provider2?.type || this._currentIdeType || "unknown_webview",
|
|
19344
|
-
parsed.messages || [],
|
|
19345
|
-
parsed.title,
|
|
19346
|
-
args?.instanceId
|
|
19347
|
-
);
|
|
19348
|
-
return { success: true, ...parsed };
|
|
19349
|
-
}
|
|
19038
|
+
} catch (e) {
|
|
19039
|
+
_log(`Extension error: ${e.message}`);
|
|
19040
|
+
}
|
|
19041
|
+
if (h.agentStream) {
|
|
19042
|
+
const cdp22 = h.getCdp();
|
|
19043
|
+
if (cdp22) {
|
|
19044
|
+
const streams = await h.agentStream.collectAgentStreams(cdp22);
|
|
19045
|
+
const stream = streams.find((s) => s.agentType === provider2.type);
|
|
19046
|
+
if (stream) {
|
|
19047
|
+
h.historyWriter.appendNewMessages(
|
|
19048
|
+
stream.agentType,
|
|
19049
|
+
stream.messages || [],
|
|
19050
|
+
void 0,
|
|
19051
|
+
args?.instanceId
|
|
19052
|
+
);
|
|
19053
|
+
return { success: true, messages: stream.messages || [], status: stream.status, agentType: stream.agentType };
|
|
19350
19054
|
}
|
|
19351
|
-
} catch (e) {
|
|
19352
|
-
_log(`Webview readChat error: ${e.message}`);
|
|
19353
19055
|
}
|
|
19354
|
-
return { success: true, messages: [], status: "idle" };
|
|
19355
19056
|
}
|
|
19356
|
-
|
|
19357
|
-
|
|
19358
|
-
|
|
19359
|
-
|
|
19360
|
-
|
|
19057
|
+
return { success: true, messages: [], status: "idle" };
|
|
19058
|
+
}
|
|
19059
|
+
const cdp2 = h.getCdp();
|
|
19060
|
+
if (!cdp2?.isConnected) return { success: false, error: "CDP not connected" };
|
|
19061
|
+
const webviewScript = h.getProviderScript("webviewReadChat") || h.getProviderScript("webview_read_chat");
|
|
19062
|
+
if (webviewScript) {
|
|
19063
|
+
try {
|
|
19064
|
+
const matchText = provider2?.webviewMatchText;
|
|
19065
|
+
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19066
|
+
const raw = await cdp2.evaluateInWebviewFrame(webviewScript, matchFn);
|
|
19067
|
+
if (raw) {
|
|
19068
|
+
let parsed = raw;
|
|
19361
19069
|
if (typeof parsed === "string") {
|
|
19362
19070
|
try {
|
|
19363
19071
|
parsed = JSON.parse(parsed);
|
|
19364
19072
|
} catch {
|
|
19365
19073
|
}
|
|
19366
19074
|
}
|
|
19367
|
-
if (parsed && typeof parsed === "object"
|
|
19368
|
-
_log(`OK: ${parsed.messages?.length} msgs`);
|
|
19369
|
-
|
|
19370
|
-
provider2?.type ||
|
|
19075
|
+
if (parsed && typeof parsed === "object") {
|
|
19076
|
+
_log(`Webview OK: ${parsed.messages?.length || 0} msgs`);
|
|
19077
|
+
h.historyWriter.appendNewMessages(
|
|
19078
|
+
provider2?.type || h.currentIdeType || "unknown_webview",
|
|
19371
19079
|
parsed.messages || [],
|
|
19372
19080
|
parsed.title,
|
|
19373
19081
|
args?.instanceId
|
|
19374
19082
|
);
|
|
19375
19083
|
return { success: true, ...parsed };
|
|
19376
19084
|
}
|
|
19377
|
-
} catch (e) {
|
|
19378
|
-
LOG4.info("Command", `[read_chat] Script error: ${e.message}`);
|
|
19379
19085
|
}
|
|
19086
|
+
} catch (e) {
|
|
19087
|
+
_log(`Webview readChat error: ${e.message}`);
|
|
19380
19088
|
}
|
|
19381
19089
|
return { success: true, messages: [], status: "idle" };
|
|
19382
19090
|
}
|
|
19383
|
-
|
|
19384
|
-
|
|
19385
|
-
|
|
19386
|
-
|
|
19387
|
-
|
|
19388
|
-
|
|
19389
|
-
const adapter = this.getCliAdapter(provider2.type);
|
|
19390
|
-
if (adapter) {
|
|
19391
|
-
_log(`${provider2.category} adapter: ${adapter.cliType}`);
|
|
19091
|
+
const script = h.getProviderScript("readChat") || h.getProviderScript("read_chat");
|
|
19092
|
+
if (script) {
|
|
19093
|
+
try {
|
|
19094
|
+
const result = await cdp2.evaluate(script, 5e4);
|
|
19095
|
+
let parsed = result;
|
|
19096
|
+
if (typeof parsed === "string") {
|
|
19392
19097
|
try {
|
|
19393
|
-
|
|
19394
|
-
|
|
19395
|
-
} catch (e) {
|
|
19396
|
-
return { success: false, error: `${provider2.category} send failed: ${e.message}` };
|
|
19397
|
-
}
|
|
19398
|
-
}
|
|
19399
|
-
}
|
|
19400
|
-
if (provider2?.category === "extension") {
|
|
19401
|
-
_log(`Extension: ${provider2.type}`);
|
|
19402
|
-
try {
|
|
19403
|
-
const evalResult = await this.evaluateProviderScript("sendMessage", { MESSAGE: text }, 3e4);
|
|
19404
|
-
if (evalResult?.result) {
|
|
19405
|
-
let parsed = evalResult.result;
|
|
19406
|
-
if (typeof parsed === "string") {
|
|
19407
|
-
try {
|
|
19408
|
-
parsed = JSON.parse(parsed);
|
|
19409
|
-
} catch {
|
|
19410
|
-
}
|
|
19411
|
-
}
|
|
19412
|
-
if (parsed?.sent) {
|
|
19413
|
-
_log(`Extension script sent OK`);
|
|
19414
|
-
return { success: true, sent: true, method: "extension-script" };
|
|
19415
|
-
}
|
|
19416
|
-
if (parsed?.needsTypeAndSend) {
|
|
19417
|
-
_log(`Extension needsTypeAndSend \u2192 AgentStreamManager`);
|
|
19418
|
-
}
|
|
19419
|
-
}
|
|
19420
|
-
} catch (e) {
|
|
19421
|
-
_log(`Extension script error: ${e.message}`);
|
|
19422
|
-
}
|
|
19423
|
-
if (this.agentStream && this.getCdp()) {
|
|
19424
|
-
const ok = await this.agentStream.sendToAgent(this.getCdp(), provider2.type, text, this._currentIdeType);
|
|
19425
|
-
if (ok) {
|
|
19426
|
-
_log(`AgentStreamManager sent OK`);
|
|
19427
|
-
return { success: true, sent: true, method: "agent-stream" };
|
|
19428
|
-
}
|
|
19429
|
-
}
|
|
19430
|
-
return { success: false, error: `Extension '${provider2.type}' send failed` };
|
|
19431
|
-
}
|
|
19432
|
-
const targetCdp = this.getCdp();
|
|
19433
|
-
if (!targetCdp?.isConnected) {
|
|
19434
|
-
_log(`No CDP for ${this._currentIdeType}`);
|
|
19435
|
-
return { success: false, error: `CDP for ${this._currentIdeType || "unknown"} not connected` };
|
|
19436
|
-
}
|
|
19437
|
-
_log(`Targeting IDE: ${this._currentIdeType}`);
|
|
19438
|
-
if (provider2?.webviewMatchText && provider2?.scripts?.webviewSendMessage) {
|
|
19439
|
-
try {
|
|
19440
|
-
const webviewScript = provider2.scripts.webviewSendMessage(text);
|
|
19441
|
-
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
19442
|
-
const matchText = provider2.webviewMatchText;
|
|
19443
|
-
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19444
|
-
const wvResult = await targetCdp.evaluateInWebviewFrame(webviewScript, matchFn);
|
|
19445
|
-
let wvParsed = wvResult;
|
|
19446
|
-
if (typeof wvResult === "string") {
|
|
19447
|
-
try {
|
|
19448
|
-
wvParsed = JSON.parse(wvResult);
|
|
19449
|
-
} catch {
|
|
19450
|
-
}
|
|
19451
|
-
}
|
|
19452
|
-
if (wvParsed?.sent) {
|
|
19453
|
-
_log(`webviewSendMessage (priority) OK`);
|
|
19454
|
-
return { success: true, sent: true, method: "webview-script-priority" };
|
|
19455
|
-
}
|
|
19456
|
-
_log(`webviewSendMessage (priority) did not confirm sent, falling through`);
|
|
19457
|
-
}
|
|
19458
|
-
} catch (e) {
|
|
19459
|
-
_log(`webviewSendMessage (priority) failed: ${e.message}, falling through`);
|
|
19460
|
-
}
|
|
19461
|
-
}
|
|
19462
|
-
if (provider2?.inputMethod === "cdp-type-and-send" && provider2.inputSelector) {
|
|
19463
|
-
try {
|
|
19464
|
-
const sent = await targetCdp.typeAndSend(provider2.inputSelector, text);
|
|
19465
|
-
if (sent) {
|
|
19466
|
-
_log(`typeAndSend(provider.inputSelector=${provider2.inputSelector}) success`);
|
|
19467
|
-
return { success: true, sent: true, method: "typeAndSend-provider" };
|
|
19098
|
+
parsed = JSON.parse(parsed);
|
|
19099
|
+
} catch {
|
|
19468
19100
|
}
|
|
19469
|
-
} catch (e) {
|
|
19470
|
-
_log(`typeAndSend(provider) failed: ${e.message}`);
|
|
19471
19101
|
}
|
|
19472
|
-
|
|
19473
|
-
|
|
19474
|
-
|
|
19475
|
-
|
|
19476
|
-
|
|
19477
|
-
|
|
19478
|
-
|
|
19479
|
-
|
|
19480
|
-
|
|
19481
|
-
} catch {
|
|
19482
|
-
}
|
|
19483
|
-
}
|
|
19484
|
-
if (parsed?.sent) {
|
|
19485
|
-
_log(`sendMessage script OK`);
|
|
19486
|
-
return { success: true, sent: true, method: "script" };
|
|
19487
|
-
}
|
|
19488
|
-
if (parsed?.needsTypeAndSend && parsed?.selector) {
|
|
19489
|
-
try {
|
|
19490
|
-
const sent = await targetCdp.typeAndSend(parsed.selector, text);
|
|
19491
|
-
if (sent) {
|
|
19492
|
-
_log(`typeAndSend(script.selector=${parsed.selector}) success`);
|
|
19493
|
-
return { success: true, sent: true, method: "typeAndSend-script" };
|
|
19494
|
-
}
|
|
19495
|
-
} catch (e) {
|
|
19496
|
-
_log(`typeAndSend(script.selector) failed: ${e.message}`);
|
|
19497
|
-
}
|
|
19498
|
-
}
|
|
19499
|
-
if (parsed?.needsTypeAndSend && provider2?.scripts?.webviewSendMessage) {
|
|
19500
|
-
try {
|
|
19501
|
-
const webviewScript = provider2.scripts.webviewSendMessage(text);
|
|
19502
|
-
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
19503
|
-
const matchText = provider2.webviewMatchText;
|
|
19504
|
-
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19505
|
-
const wvResult = await targetCdp.evaluateInWebviewFrame(webviewScript, matchFn);
|
|
19506
|
-
let wvParsed = wvResult;
|
|
19507
|
-
if (typeof wvResult === "string") {
|
|
19508
|
-
try {
|
|
19509
|
-
wvParsed = JSON.parse(wvResult);
|
|
19510
|
-
} catch {
|
|
19511
|
-
}
|
|
19512
|
-
}
|
|
19513
|
-
if (wvParsed?.sent) {
|
|
19514
|
-
_log(`webviewSendMessage OK`);
|
|
19515
|
-
return { success: true, sent: true, method: "webview-script" };
|
|
19516
|
-
}
|
|
19517
|
-
}
|
|
19518
|
-
} catch (e) {
|
|
19519
|
-
_log(`webviewSendMessage failed: ${e.message}`);
|
|
19520
|
-
}
|
|
19521
|
-
}
|
|
19522
|
-
if (parsed?.needsTypeAndSend && parsed?.clickCoords) {
|
|
19523
|
-
try {
|
|
19524
|
-
const { x, y } = parsed.clickCoords;
|
|
19525
|
-
const sent = await targetCdp.typeAndSendAt(x, y, text);
|
|
19526
|
-
if (sent) {
|
|
19527
|
-
_log(`typeAndSendAt(${x},${y}) success`);
|
|
19528
|
-
return { success: true, sent: true, method: "typeAndSendAt-script" };
|
|
19529
|
-
}
|
|
19530
|
-
} catch (e) {
|
|
19531
|
-
_log(`typeAndSendAt failed: ${e.message}`);
|
|
19532
|
-
}
|
|
19533
|
-
}
|
|
19534
|
-
} catch (e) {
|
|
19535
|
-
_log(`sendMessage script failed: ${e.message}`);
|
|
19102
|
+
if (parsed && typeof parsed === "object" && parsed.messages?.length > 0) {
|
|
19103
|
+
_log(`OK: ${parsed.messages?.length} msgs`);
|
|
19104
|
+
h.historyWriter.appendNewMessages(
|
|
19105
|
+
provider2?.type || h.currentIdeType || "unknown_ide",
|
|
19106
|
+
parsed.messages || [],
|
|
19107
|
+
parsed.title,
|
|
19108
|
+
args?.instanceId
|
|
19109
|
+
);
|
|
19110
|
+
return { success: true, ...parsed };
|
|
19536
19111
|
}
|
|
19112
|
+
} catch (e) {
|
|
19113
|
+
LOG5.info("Command", `[read_chat] Script error: ${e.message}`);
|
|
19537
19114
|
}
|
|
19538
|
-
_log("All methods failed");
|
|
19539
|
-
return { success: false, error: "No provider method could send the message" };
|
|
19540
19115
|
}
|
|
19541
|
-
|
|
19542
|
-
|
|
19543
|
-
|
|
19116
|
+
return { success: true, messages: [], status: "idle" };
|
|
19117
|
+
}
|
|
19118
|
+
async function handleSendChat(h, args) {
|
|
19119
|
+
const text = args?.text || args?.message;
|
|
19120
|
+
if (!text) return { success: false, error: "text required" };
|
|
19121
|
+
const _log = (msg) => LOG5.debug("Command", `[send_chat] ${msg}`);
|
|
19122
|
+
const provider2 = h.getProvider();
|
|
19123
|
+
if (provider2?.category === "cli" || provider2?.category === "acp") {
|
|
19124
|
+
const adapter = h.getCliAdapter(provider2.type);
|
|
19125
|
+
if (adapter) {
|
|
19126
|
+
_log(`${provider2.category} adapter: ${adapter.cliType}`);
|
|
19544
19127
|
try {
|
|
19545
|
-
|
|
19546
|
-
|
|
19547
|
-
return { success: true, chats };
|
|
19128
|
+
await adapter.sendMessage(text);
|
|
19129
|
+
return { success: true, sent: true, method: `${provider2.category}-adapter`, targetAgent: adapter.cliType };
|
|
19548
19130
|
} catch (e) {
|
|
19549
|
-
|
|
19131
|
+
return { success: false, error: `${provider2.category} send failed: ${e.message}` };
|
|
19550
19132
|
}
|
|
19551
19133
|
}
|
|
19134
|
+
}
|
|
19135
|
+
if (provider2?.category === "extension") {
|
|
19136
|
+
_log(`Extension: ${provider2.type}`);
|
|
19552
19137
|
try {
|
|
19553
|
-
const
|
|
19554
|
-
if (
|
|
19555
|
-
|
|
19556
|
-
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19557
|
-
const raw = await this.getCdp()?.evaluateInWebviewFrame?.(webviewScript, matchFn);
|
|
19558
|
-
let parsed = raw;
|
|
19138
|
+
const evalResult = await h.evaluateProviderScript("sendMessage", { MESSAGE: text }, 3e4);
|
|
19139
|
+
if (evalResult?.result) {
|
|
19140
|
+
let parsed = evalResult.result;
|
|
19559
19141
|
if (typeof parsed === "string") {
|
|
19560
19142
|
try {
|
|
19561
19143
|
parsed = JSON.parse(parsed);
|
|
19562
19144
|
} catch {
|
|
19563
19145
|
}
|
|
19564
19146
|
}
|
|
19565
|
-
if (parsed?.
|
|
19566
|
-
|
|
19567
|
-
return { success: true,
|
|
19147
|
+
if (parsed?.sent) {
|
|
19148
|
+
_log(`Extension script sent OK`);
|
|
19149
|
+
return { success: true, sent: true, method: "extension-script" };
|
|
19150
|
+
}
|
|
19151
|
+
if (parsed?.needsTypeAndSend) {
|
|
19152
|
+
_log(`Extension needsTypeAndSend \u2192 AgentStreamManager`);
|
|
19568
19153
|
}
|
|
19569
19154
|
}
|
|
19570
19155
|
} catch (e) {
|
|
19571
|
-
|
|
19156
|
+
_log(`Extension script error: ${e.message}`);
|
|
19157
|
+
}
|
|
19158
|
+
if (h.agentStream && h.getCdp()) {
|
|
19159
|
+
const ok = await h.agentStream.sendToAgent(h.getCdp(), provider2.type, text, h.currentIdeType);
|
|
19160
|
+
if (ok) {
|
|
19161
|
+
_log(`AgentStreamManager sent OK`);
|
|
19162
|
+
return { success: true, sent: true, method: "agent-stream" };
|
|
19163
|
+
}
|
|
19572
19164
|
}
|
|
19165
|
+
return { success: false, error: `Extension '${provider2.type}' send failed` };
|
|
19166
|
+
}
|
|
19167
|
+
const targetCdp = h.getCdp();
|
|
19168
|
+
if (!targetCdp?.isConnected) {
|
|
19169
|
+
_log(`No CDP for ${h.currentIdeType}`);
|
|
19170
|
+
return { success: false, error: `CDP for ${h.currentIdeType || "unknown"} not connected` };
|
|
19171
|
+
}
|
|
19172
|
+
_log(`Targeting IDE: ${h.currentIdeType}`);
|
|
19173
|
+
if (provider2?.webviewMatchText && provider2?.scripts?.webviewSendMessage) {
|
|
19573
19174
|
try {
|
|
19574
|
-
const
|
|
19575
|
-
if (
|
|
19576
|
-
|
|
19577
|
-
|
|
19175
|
+
const webviewScript = provider2.scripts.webviewSendMessage(text);
|
|
19176
|
+
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
19177
|
+
const matchText = provider2.webviewMatchText;
|
|
19178
|
+
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19179
|
+
const wvResult = await targetCdp.evaluateInWebviewFrame(webviewScript, matchFn);
|
|
19180
|
+
let wvParsed = wvResult;
|
|
19181
|
+
if (typeof wvResult === "string") {
|
|
19578
19182
|
try {
|
|
19579
|
-
|
|
19183
|
+
wvParsed = JSON.parse(wvResult);
|
|
19580
19184
|
} catch {
|
|
19581
19185
|
}
|
|
19582
19186
|
}
|
|
19583
|
-
if (
|
|
19584
|
-
|
|
19585
|
-
return { success: true,
|
|
19187
|
+
if (wvParsed?.sent) {
|
|
19188
|
+
_log(`webviewSendMessage (priority) OK`);
|
|
19189
|
+
return { success: true, sent: true, method: "webview-script-priority" };
|
|
19586
19190
|
}
|
|
19191
|
+
_log(`webviewSendMessage (priority) did not confirm sent, falling through`);
|
|
19587
19192
|
}
|
|
19588
19193
|
} catch (e) {
|
|
19589
|
-
|
|
19194
|
+
_log(`webviewSendMessage (priority) failed: ${e.message}, falling through`);
|
|
19590
19195
|
}
|
|
19591
|
-
return { success: false, error: "listSessions script not available for this provider" };
|
|
19592
19196
|
}
|
|
19593
|
-
|
|
19594
|
-
const provider2 = this.getProvider();
|
|
19595
|
-
if (provider2?.category === "extension" && this.agentStream && this.getCdp()) {
|
|
19596
|
-
const ok = await this.agentStream.newAgentSession(this.getCdp(), provider2.type, this._currentIdeType);
|
|
19597
|
-
return { success: ok };
|
|
19598
|
-
}
|
|
19197
|
+
if (provider2?.inputMethod === "cdp-type-and-send" && provider2.inputSelector) {
|
|
19599
19198
|
try {
|
|
19600
|
-
const
|
|
19601
|
-
if (
|
|
19602
|
-
|
|
19603
|
-
|
|
19604
|
-
const raw = await this.getCdp()?.evaluateInWebviewFrame?.(webviewScript, matchFn);
|
|
19605
|
-
if (raw) return { success: true, result: raw };
|
|
19199
|
+
const sent = await targetCdp.typeAndSend(provider2.inputSelector, text);
|
|
19200
|
+
if (sent) {
|
|
19201
|
+
_log(`typeAndSend(provider.inputSelector=${provider2.inputSelector}) success`);
|
|
19202
|
+
return { success: true, sent: true, method: "typeAndSend-provider" };
|
|
19606
19203
|
}
|
|
19607
19204
|
} catch (e) {
|
|
19608
|
-
|
|
19609
|
-
}
|
|
19610
|
-
try {
|
|
19611
|
-
const evalResult = await this.evaluateProviderScript("newSession");
|
|
19612
|
-
if (evalResult) return { success: true };
|
|
19613
|
-
} catch (e) {
|
|
19614
|
-
return { success: false, error: `newSession failed: ${e.message}` };
|
|
19205
|
+
_log(`typeAndSend(provider) failed: ${e.message}`);
|
|
19615
19206
|
}
|
|
19616
|
-
return { success: false, error: "newSession script not available for this provider" };
|
|
19617
19207
|
}
|
|
19618
|
-
|
|
19619
|
-
|
|
19620
|
-
const ideType = this._currentIdeType;
|
|
19621
|
-
const sessionId = args?.sessionId || args?.id || args?.chatId;
|
|
19622
|
-
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
19623
|
-
LOG4.info("Command", `[switch_chat] sessionId=${sessionId}, ideType=${ideType}`);
|
|
19624
|
-
if (provider2?.category === "extension" && this.agentStream && this.getCdp()) {
|
|
19625
|
-
const ok = await this.agentStream.switchAgentSession(this.getCdp(), provider2.type, sessionId);
|
|
19626
|
-
return { success: ok, result: ok ? "switched" : "failed" };
|
|
19627
|
-
}
|
|
19628
|
-
const cdp2 = this.getCdp(ideType);
|
|
19629
|
-
if (!cdp2?.isConnected) return { success: false, error: "CDP not connected" };
|
|
19630
|
-
try {
|
|
19631
|
-
const webviewScript = this.getProviderScript("webviewSwitchSession", { SESSION_ID: JSON.stringify(sessionId) });
|
|
19632
|
-
if (webviewScript) {
|
|
19633
|
-
const matchText = provider2?.webviewMatchText;
|
|
19634
|
-
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19635
|
-
const raw = await cdp2.evaluateInWebviewFrame?.(webviewScript, matchFn);
|
|
19636
|
-
if (raw) return { success: true, result: raw };
|
|
19637
|
-
}
|
|
19638
|
-
} catch (e) {
|
|
19639
|
-
return { success: false, error: `webviewSwitchSession failed: ${e.message}` };
|
|
19640
|
-
}
|
|
19641
|
-
const script = this.getProviderScript("switchSession", { SESSION_ID: JSON.stringify(sessionId) }) || this.getProviderScript("switch_session", { SESSION_ID: JSON.stringify(sessionId) });
|
|
19642
|
-
if (!script) return { success: false, error: "switch_session script not available" };
|
|
19208
|
+
const sendScript = h.getProviderScript("sendMessage", { MESSAGE: text });
|
|
19209
|
+
if (sendScript) {
|
|
19643
19210
|
try {
|
|
19644
|
-
const
|
|
19645
|
-
|
|
19646
|
-
|
|
19647
|
-
|
|
19648
|
-
|
|
19649
|
-
|
|
19650
|
-
}
|
|
19651
|
-
if (parsed?.action === "click" && parsed.clickX && parsed.clickY) {
|
|
19652
|
-
const x = Math.round(parsed.clickX);
|
|
19653
|
-
const y = Math.round(parsed.clickY);
|
|
19654
|
-
LOG4.info("Command", `[switch_chat] CDP click at (${x}, ${y}) for "${parsed.title}"`);
|
|
19655
|
-
await cdp2.send("Input.dispatchMouseEvent", {
|
|
19656
|
-
type: "mousePressed",
|
|
19657
|
-
x,
|
|
19658
|
-
y,
|
|
19659
|
-
button: "left",
|
|
19660
|
-
clickCount: 1
|
|
19661
|
-
});
|
|
19662
|
-
await cdp2.send("Input.dispatchMouseEvent", {
|
|
19663
|
-
type: "mouseReleased",
|
|
19664
|
-
x,
|
|
19665
|
-
y,
|
|
19666
|
-
button: "left",
|
|
19667
|
-
clickCount: 1
|
|
19668
|
-
});
|
|
19669
|
-
await new Promise((r) => setTimeout(r, 2e3));
|
|
19670
|
-
const wsResult = await cdp2.evaluate(`
|
|
19671
|
-
(() => {
|
|
19672
|
-
const inp = Array.from(document.querySelectorAll('input[type="text"]'))
|
|
19673
|
-
.find(i => i.offsetWidth > 0 && (i.placeholder || '').includes('Select where'));
|
|
19674
|
-
if (!inp) return null;
|
|
19675
|
-
const rows = inp.closest('[class*="quickInput"]')?.querySelectorAll('[class*="cursor-pointer"]');
|
|
19676
|
-
if (rows && rows.length > 0) {
|
|
19677
|
-
const r = rows[0].getBoundingClientRect();
|
|
19678
|
-
return JSON.stringify({ x: Math.round(r.left + r.width/2), y: Math.round(r.top + r.height/2) });
|
|
19679
|
-
}
|
|
19680
|
-
return null;
|
|
19681
|
-
})()
|
|
19682
|
-
`, 5e3);
|
|
19683
|
-
if (wsResult) {
|
|
19684
|
-
try {
|
|
19685
|
-
const ws = JSON.parse(wsResult);
|
|
19686
|
-
await cdp2.send("Input.dispatchMouseEvent", {
|
|
19687
|
-
type: "mousePressed",
|
|
19688
|
-
x: ws.x,
|
|
19689
|
-
y: ws.y,
|
|
19690
|
-
button: "left",
|
|
19691
|
-
clickCount: 1
|
|
19692
|
-
});
|
|
19693
|
-
await cdp2.send("Input.dispatchMouseEvent", {
|
|
19694
|
-
type: "mouseReleased",
|
|
19695
|
-
x: ws.x,
|
|
19696
|
-
y: ws.y,
|
|
19697
|
-
button: "left",
|
|
19698
|
-
clickCount: 1
|
|
19699
|
-
});
|
|
19700
|
-
} catch {
|
|
19701
|
-
}
|
|
19211
|
+
const result = await targetCdp.evaluate(sendScript, 3e4);
|
|
19212
|
+
let parsed = result;
|
|
19213
|
+
if (typeof result === "string") {
|
|
19214
|
+
try {
|
|
19215
|
+
parsed = JSON.parse(result);
|
|
19216
|
+
} catch {
|
|
19702
19217
|
}
|
|
19703
|
-
return { success: true, result: "switched" };
|
|
19704
19218
|
}
|
|
19705
|
-
if (parsed?.
|
|
19706
|
-
|
|
19219
|
+
if (parsed?.sent) {
|
|
19220
|
+
_log(`sendMessage script OK`);
|
|
19221
|
+
return { success: true, sent: true, method: "script" };
|
|
19707
19222
|
}
|
|
19708
|
-
|
|
19709
|
-
|
|
19710
|
-
|
|
19711
|
-
|
|
19712
|
-
|
|
19713
|
-
|
|
19714
|
-
|
|
19715
|
-
|
|
19716
|
-
|
|
19717
|
-
if (provider2?.category === "acp") {
|
|
19718
|
-
const adapter = this.getCliAdapter(provider2.type);
|
|
19719
|
-
if (adapter) {
|
|
19720
|
-
const acpInstance = adapter._acpInstance;
|
|
19721
|
-
if (acpInstance && typeof acpInstance.onEvent === "function") {
|
|
19722
|
-
acpInstance.onEvent("set_mode", { mode });
|
|
19723
|
-
return { success: true, mode };
|
|
19223
|
+
if (parsed?.needsTypeAndSend && parsed?.selector) {
|
|
19224
|
+
try {
|
|
19225
|
+
const sent = await targetCdp.typeAndSend(parsed.selector, text);
|
|
19226
|
+
if (sent) {
|
|
19227
|
+
_log(`typeAndSend(script.selector=${parsed.selector}) success`);
|
|
19228
|
+
return { success: true, sent: true, method: "typeAndSend-script" };
|
|
19229
|
+
}
|
|
19230
|
+
} catch (e) {
|
|
19231
|
+
_log(`typeAndSend(script.selector) failed: ${e.message}`);
|
|
19724
19232
|
}
|
|
19725
19233
|
}
|
|
19726
|
-
|
|
19727
|
-
}
|
|
19728
|
-
const webviewScript = this.getProviderScript("webviewSetMode", { MODE: JSON.stringify(mode) });
|
|
19729
|
-
if (webviewScript) {
|
|
19730
|
-
const cdp2 = this.getCdp();
|
|
19731
|
-
if (cdp2?.isConnected) {
|
|
19234
|
+
if (parsed?.needsTypeAndSend && provider2?.scripts?.webviewSendMessage) {
|
|
19732
19235
|
try {
|
|
19733
|
-
const
|
|
19734
|
-
|
|
19735
|
-
|
|
19736
|
-
|
|
19737
|
-
|
|
19738
|
-
|
|
19739
|
-
|
|
19740
|
-
|
|
19236
|
+
const webviewScript = provider2.scripts.webviewSendMessage(text);
|
|
19237
|
+
if (webviewScript && targetCdp.evaluateInWebviewFrame) {
|
|
19238
|
+
const matchText = provider2.webviewMatchText;
|
|
19239
|
+
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19240
|
+
const wvResult = await targetCdp.evaluateInWebviewFrame(webviewScript, matchFn);
|
|
19241
|
+
let wvParsed = wvResult;
|
|
19242
|
+
if (typeof wvResult === "string") {
|
|
19243
|
+
try {
|
|
19244
|
+
wvParsed = JSON.parse(wvResult);
|
|
19245
|
+
} catch {
|
|
19246
|
+
}
|
|
19247
|
+
}
|
|
19248
|
+
if (wvParsed?.sent) {
|
|
19249
|
+
_log(`webviewSendMessage OK`);
|
|
19250
|
+
return { success: true, sent: true, method: "webview-script" };
|
|
19741
19251
|
}
|
|
19742
19252
|
}
|
|
19743
|
-
if (result?.success) return { success: true, mode, method: "webview-script" };
|
|
19744
19253
|
} catch (e) {
|
|
19745
|
-
|
|
19254
|
+
_log(`webviewSendMessage failed: ${e.message}`);
|
|
19746
19255
|
}
|
|
19747
19256
|
}
|
|
19748
|
-
|
|
19749
|
-
|
|
19750
|
-
|
|
19751
|
-
|
|
19752
|
-
|
|
19753
|
-
|
|
19754
|
-
|
|
19755
|
-
if (typeof parsed === "string") {
|
|
19756
|
-
try {
|
|
19757
|
-
parsed = JSON.parse(parsed);
|
|
19758
|
-
} catch {
|
|
19759
|
-
}
|
|
19257
|
+
if (parsed?.needsTypeAndSend && parsed?.clickCoords) {
|
|
19258
|
+
try {
|
|
19259
|
+
const { x, y } = parsed.clickCoords;
|
|
19260
|
+
const sent = await targetCdp.typeAndSendAt(x, y, text);
|
|
19261
|
+
if (sent) {
|
|
19262
|
+
_log(`typeAndSendAt(${x},${y}) success`);
|
|
19263
|
+
return { success: true, sent: true, method: "typeAndSendAt-script" };
|
|
19760
19264
|
}
|
|
19761
|
-
|
|
19265
|
+
} catch (e) {
|
|
19266
|
+
_log(`typeAndSendAt failed: ${e.message}`);
|
|
19762
19267
|
}
|
|
19763
|
-
} catch (e) {
|
|
19764
|
-
LOG4.info("Command", `[set_mode] script error: ${e.message}`);
|
|
19765
19268
|
}
|
|
19269
|
+
} catch (e) {
|
|
19270
|
+
_log(`sendMessage script failed: ${e.message}`);
|
|
19766
19271
|
}
|
|
19767
|
-
return this.delegateToExtension(`composerMode.${mode}`, []);
|
|
19768
19272
|
}
|
|
19769
|
-
|
|
19770
|
-
|
|
19771
|
-
|
|
19772
|
-
|
|
19773
|
-
|
|
19774
|
-
|
|
19775
|
-
|
|
19776
|
-
|
|
19777
|
-
|
|
19778
|
-
|
|
19779
|
-
|
|
19780
|
-
|
|
19781
|
-
|
|
19782
|
-
|
|
19783
|
-
|
|
19784
|
-
|
|
19785
|
-
}
|
|
19786
|
-
const webviewScript = this.getProviderScript("webviewSetModel", { MODEL: JSON.stringify(model) });
|
|
19273
|
+
_log("All methods failed");
|
|
19274
|
+
return { success: false, error: "No provider method could send the message" };
|
|
19275
|
+
}
|
|
19276
|
+
async function handleListChats(h, args) {
|
|
19277
|
+
const provider2 = h.getProvider();
|
|
19278
|
+
if (provider2?.category === "extension" && h.agentStream && h.getCdp()) {
|
|
19279
|
+
try {
|
|
19280
|
+
const chats = await h.agentStream.listAgentChats(h.getCdp(), provider2.type);
|
|
19281
|
+
LOG5.info("Command", `[list_chats] Extension: ${chats.length} chats`);
|
|
19282
|
+
return { success: true, chats };
|
|
19283
|
+
} catch (e) {
|
|
19284
|
+
LOG5.info("Command", `[list_chats] Extension error: ${e.message}`);
|
|
19285
|
+
}
|
|
19286
|
+
}
|
|
19287
|
+
try {
|
|
19288
|
+
const webviewScript = h.getProviderScript("webviewListSessions") || h.getProviderScript("webview_list_sessions");
|
|
19787
19289
|
if (webviewScript) {
|
|
19788
|
-
const
|
|
19789
|
-
|
|
19290
|
+
const matchText = provider2?.webviewMatchText;
|
|
19291
|
+
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19292
|
+
const raw = await h.getCdp()?.evaluateInWebviewFrame?.(webviewScript, matchFn);
|
|
19293
|
+
let parsed = raw;
|
|
19294
|
+
if (typeof parsed === "string") {
|
|
19790
19295
|
try {
|
|
19791
|
-
|
|
19792
|
-
|
|
19793
|
-
const raw = await cdp2.evaluateInWebviewFrame?.(webviewScript, matchFn);
|
|
19794
|
-
let result = raw;
|
|
19795
|
-
if (typeof raw === "string") {
|
|
19796
|
-
try {
|
|
19797
|
-
result = JSON.parse(raw);
|
|
19798
|
-
} catch {
|
|
19799
|
-
}
|
|
19800
|
-
}
|
|
19801
|
-
if (result?.success) return { success: true, model, method: "webview-script" };
|
|
19802
|
-
} catch (e) {
|
|
19803
|
-
LOG4.info("Command", `[change_model] webview script error: ${e.message}`);
|
|
19296
|
+
parsed = JSON.parse(parsed);
|
|
19297
|
+
} catch {
|
|
19804
19298
|
}
|
|
19805
19299
|
}
|
|
19300
|
+
if (parsed?.sessions) {
|
|
19301
|
+
LOG5.info("Command", `[list_chats] Webview OK: ${parsed.sessions.length} chats`);
|
|
19302
|
+
return { success: true, chats: parsed.sessions };
|
|
19303
|
+
}
|
|
19806
19304
|
}
|
|
19807
|
-
|
|
19808
|
-
|
|
19809
|
-
|
|
19810
|
-
|
|
19811
|
-
|
|
19812
|
-
|
|
19813
|
-
|
|
19814
|
-
|
|
19815
|
-
|
|
19816
|
-
|
|
19817
|
-
|
|
19818
|
-
}
|
|
19819
|
-
if (parsed?.success) return { success: true, model, method: "script" };
|
|
19305
|
+
} catch (e) {
|
|
19306
|
+
LOG5.info("Command", `[list_chats] Webview error: ${e.message}`);
|
|
19307
|
+
}
|
|
19308
|
+
try {
|
|
19309
|
+
const evalResult = await h.evaluateProviderScript("listSessions");
|
|
19310
|
+
if (evalResult) {
|
|
19311
|
+
let parsed = evalResult.result;
|
|
19312
|
+
if (typeof parsed === "string") {
|
|
19313
|
+
try {
|
|
19314
|
+
parsed = JSON.parse(parsed);
|
|
19315
|
+
} catch {
|
|
19820
19316
|
}
|
|
19821
|
-
}
|
|
19822
|
-
|
|
19317
|
+
}
|
|
19318
|
+
if (Array.isArray(parsed)) {
|
|
19319
|
+
LOG5.info("Command", `[list_chats] OK: ${parsed.length} chats`);
|
|
19320
|
+
return { success: true, chats: parsed };
|
|
19823
19321
|
}
|
|
19824
19322
|
}
|
|
19825
|
-
|
|
19826
|
-
|
|
19827
|
-
|
|
19323
|
+
} catch (e) {
|
|
19324
|
+
LOG5.info("Command", `[list_chats] error: ${e.message}`);
|
|
19325
|
+
}
|
|
19326
|
+
return { success: false, error: "listSessions script not available for this provider" };
|
|
19327
|
+
}
|
|
19328
|
+
async function handleNewChat(h, args) {
|
|
19329
|
+
const provider2 = h.getProvider();
|
|
19330
|
+
if (provider2?.category === "extension" && h.agentStream && h.getCdp()) {
|
|
19331
|
+
const ok = await h.agentStream.newAgentSession(h.getCdp(), provider2.type, h.currentIdeType);
|
|
19332
|
+
return { success: ok };
|
|
19333
|
+
}
|
|
19334
|
+
try {
|
|
19335
|
+
const webviewScript = h.getProviderScript("webviewNewSession") || h.getProviderScript("webview_new_session");
|
|
19336
|
+
if (webviewScript) {
|
|
19337
|
+
const matchText = provider2?.webviewMatchText;
|
|
19338
|
+
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19339
|
+
const raw = await h.getCdp()?.evaluateInWebviewFrame?.(webviewScript, matchFn);
|
|
19340
|
+
if (raw) return { success: true, result: raw };
|
|
19828
19341
|
}
|
|
19829
|
-
|
|
19342
|
+
} catch (e) {
|
|
19343
|
+
return { success: false, error: `webviewNewSession failed: ${e.message}` };
|
|
19830
19344
|
}
|
|
19831
|
-
|
|
19832
|
-
|
|
19833
|
-
|
|
19834
|
-
|
|
19835
|
-
|
|
19836
|
-
|
|
19837
|
-
|
|
19838
|
-
|
|
19345
|
+
try {
|
|
19346
|
+
const evalResult = await h.evaluateProviderScript("newSession");
|
|
19347
|
+
if (evalResult) return { success: true };
|
|
19348
|
+
} catch (e) {
|
|
19349
|
+
return { success: false, error: `newSession failed: ${e.message}` };
|
|
19350
|
+
}
|
|
19351
|
+
return { success: false, error: "newSession script not available for this provider" };
|
|
19352
|
+
}
|
|
19353
|
+
async function handleSwitchChat(h, args) {
|
|
19354
|
+
const provider2 = h.getProvider();
|
|
19355
|
+
const ideType = h.currentIdeType;
|
|
19356
|
+
const sessionId = args?.sessionId || args?.id || args?.chatId;
|
|
19357
|
+
if (!sessionId) return { success: false, error: "sessionId required" };
|
|
19358
|
+
LOG5.info("Command", `[switch_chat] sessionId=${sessionId}, ideType=${ideType}`);
|
|
19359
|
+
if (provider2?.category === "extension" && h.agentStream && h.getCdp()) {
|
|
19360
|
+
const ok = await h.agentStream.switchAgentSession(h.getCdp(), provider2.type, sessionId);
|
|
19361
|
+
return { success: ok, result: ok ? "switched" : "failed" };
|
|
19362
|
+
}
|
|
19363
|
+
const cdp2 = h.getCdp(ideType);
|
|
19364
|
+
if (!cdp2?.isConnected) return { success: false, error: "CDP not connected" };
|
|
19365
|
+
try {
|
|
19366
|
+
const webviewScript = h.getProviderScript("webviewSwitchSession", { SESSION_ID: JSON.stringify(sessionId) });
|
|
19367
|
+
if (webviewScript) {
|
|
19368
|
+
const matchText = provider2?.webviewMatchText;
|
|
19369
|
+
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19370
|
+
const raw = await cdp2.evaluateInWebviewFrame?.(webviewScript, matchFn);
|
|
19371
|
+
if (raw) return { success: true, result: raw };
|
|
19839
19372
|
}
|
|
19840
|
-
|
|
19841
|
-
|
|
19842
|
-
|
|
19373
|
+
} catch (e) {
|
|
19374
|
+
return { success: false, error: `webviewSwitchSession failed: ${e.message}` };
|
|
19375
|
+
}
|
|
19376
|
+
const script = h.getProviderScript("switchSession", { SESSION_ID: JSON.stringify(sessionId) }) || h.getProviderScript("switch_session", { SESSION_ID: JSON.stringify(sessionId) });
|
|
19377
|
+
if (!script) return { success: false, error: "switch_session script not available" };
|
|
19378
|
+
try {
|
|
19379
|
+
const raw = await cdp2.evaluate(script, 15e3);
|
|
19380
|
+
LOG5.info("Command", `[switch_chat] result: ${raw}`);
|
|
19381
|
+
let parsed = null;
|
|
19843
19382
|
try {
|
|
19844
|
-
|
|
19845
|
-
|
|
19846
|
-
|
|
19847
|
-
|
|
19848
|
-
|
|
19383
|
+
parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
19384
|
+
} catch {
|
|
19385
|
+
}
|
|
19386
|
+
if (parsed?.action === "click" && parsed.clickX && parsed.clickY) {
|
|
19387
|
+
const x = Math.round(parsed.clickX);
|
|
19388
|
+
const y = Math.round(parsed.clickY);
|
|
19389
|
+
LOG5.info("Command", `[switch_chat] CDP click at (${x}, ${y}) for "${parsed.title}"`);
|
|
19390
|
+
await cdp2.send("Input.dispatchMouseEvent", {
|
|
19391
|
+
type: "mousePressed",
|
|
19392
|
+
x,
|
|
19393
|
+
y,
|
|
19394
|
+
button: "left",
|
|
19395
|
+
clickCount: 1
|
|
19396
|
+
});
|
|
19397
|
+
await cdp2.send("Input.dispatchMouseEvent", {
|
|
19398
|
+
type: "mouseReleased",
|
|
19399
|
+
x,
|
|
19400
|
+
y,
|
|
19401
|
+
button: "left",
|
|
19402
|
+
clickCount: 1
|
|
19403
|
+
});
|
|
19404
|
+
await new Promise((r) => setTimeout(r, 2e3));
|
|
19405
|
+
const wsResult = await cdp2.evaluate(`
|
|
19406
|
+
(() => {
|
|
19407
|
+
const inp = Array.from(document.querySelectorAll('input[type="text"]'))
|
|
19408
|
+
.find(i => i.offsetWidth > 0 && (i.placeholder || '').includes('Select where'));
|
|
19409
|
+
if (!inp) return null;
|
|
19410
|
+
const rows = inp.closest('[class*="quickInput"]')?.querySelectorAll('[class*="cursor-pointer"]');
|
|
19411
|
+
if (rows && rows.length > 0) {
|
|
19412
|
+
const r = rows[0].getBoundingClientRect();
|
|
19413
|
+
return JSON.stringify({ x: Math.round(r.left + r.width/2), y: Math.round(r.top + r.height/2) });
|
|
19414
|
+
}
|
|
19415
|
+
return null;
|
|
19416
|
+
})()
|
|
19417
|
+
`, 5e3);
|
|
19418
|
+
if (wsResult) {
|
|
19419
|
+
try {
|
|
19420
|
+
const ws = JSON.parse(wsResult);
|
|
19421
|
+
await cdp2.send("Input.dispatchMouseEvent", {
|
|
19422
|
+
type: "mousePressed",
|
|
19423
|
+
x: ws.x,
|
|
19424
|
+
y: ws.y,
|
|
19425
|
+
button: "left",
|
|
19426
|
+
clickCount: 1
|
|
19427
|
+
});
|
|
19428
|
+
await cdp2.send("Input.dispatchMouseEvent", {
|
|
19429
|
+
type: "mouseReleased",
|
|
19430
|
+
x: ws.x,
|
|
19431
|
+
y: ws.y,
|
|
19432
|
+
button: "left",
|
|
19433
|
+
clickCount: 1
|
|
19434
|
+
});
|
|
19435
|
+
} catch {
|
|
19436
|
+
}
|
|
19437
|
+
}
|
|
19438
|
+
return { success: true, result: "switched" };
|
|
19849
19439
|
}
|
|
19440
|
+
if (parsed?.error) return { success: false, error: parsed.error };
|
|
19441
|
+
return { success: true, result: raw };
|
|
19442
|
+
} catch (e) {
|
|
19443
|
+
LOG5.error("Command", `[switch_chat] error: ${e.message}`);
|
|
19444
|
+
return { success: false, error: e.message };
|
|
19850
19445
|
}
|
|
19851
|
-
|
|
19852
|
-
|
|
19853
|
-
|
|
19854
|
-
|
|
19855
|
-
|
|
19856
|
-
|
|
19857
|
-
if (
|
|
19858
|
-
const
|
|
19859
|
-
|
|
19860
|
-
|
|
19861
|
-
|
|
19862
|
-
|
|
19863
|
-
);
|
|
19864
|
-
return { success: ok };
|
|
19446
|
+
}
|
|
19447
|
+
async function handleSetMode(h, args) {
|
|
19448
|
+
const provider2 = h.getProvider();
|
|
19449
|
+
const mode = args?.mode || "agent";
|
|
19450
|
+
if (provider2?.category === "acp") {
|
|
19451
|
+
const adapter = h.getCliAdapter(provider2.type);
|
|
19452
|
+
if (adapter) {
|
|
19453
|
+
const acpInstance = adapter._acpInstance;
|
|
19454
|
+
if (acpInstance && typeof acpInstance.onEvent === "function") {
|
|
19455
|
+
acpInstance.onEvent("set_mode", { mode });
|
|
19456
|
+
return { success: true, mode };
|
|
19457
|
+
}
|
|
19865
19458
|
}
|
|
19866
|
-
|
|
19867
|
-
|
|
19868
|
-
|
|
19869
|
-
|
|
19870
|
-
|
|
19459
|
+
return { success: false, error: "ACP adapter not found" };
|
|
19460
|
+
}
|
|
19461
|
+
const webviewScript = h.getProviderScript("webviewSetMode", { MODE: JSON.stringify(mode) });
|
|
19462
|
+
if (webviewScript) {
|
|
19463
|
+
const cdp2 = h.getCdp();
|
|
19464
|
+
if (cdp2?.isConnected) {
|
|
19465
|
+
try {
|
|
19466
|
+
const matchText = provider2?.webviewMatchText;
|
|
19467
|
+
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19468
|
+
const raw = await cdp2.evaluateInWebviewFrame?.(webviewScript, matchFn);
|
|
19469
|
+
let result = raw;
|
|
19470
|
+
if (typeof raw === "string") {
|
|
19871
19471
|
try {
|
|
19872
|
-
|
|
19873
|
-
|
|
19874
|
-
const raw = await cdp2.evaluateInWebviewFrame?.(script, matchFn);
|
|
19875
|
-
let result = raw;
|
|
19876
|
-
if (typeof raw === "string") {
|
|
19877
|
-
try {
|
|
19878
|
-
result = JSON.parse(raw);
|
|
19879
|
-
} catch {
|
|
19880
|
-
}
|
|
19881
|
-
}
|
|
19882
|
-
LOG4.info("Command", `[resolveAction] webview script result: ${JSON.stringify(result)}`);
|
|
19883
|
-
if (result?.resolved) {
|
|
19884
|
-
return { success: true, clicked: result.clicked };
|
|
19885
|
-
}
|
|
19886
|
-
if (result?.found && result.x != null && result.y != null) {
|
|
19887
|
-
LOG4.info("Command", `[resolveAction] Webview coordinate click not fully supported via CDP. Click directly in script.`);
|
|
19888
|
-
}
|
|
19889
|
-
if (result?.found || result?.resolved) return { success: true };
|
|
19890
|
-
} catch (e) {
|
|
19891
|
-
return { success: false, error: `webviewResolveAction failed: ${e.message}` };
|
|
19472
|
+
result = JSON.parse(raw);
|
|
19473
|
+
} catch {
|
|
19892
19474
|
}
|
|
19893
19475
|
}
|
|
19476
|
+
if (result?.success) return { success: true, mode, method: "webview-script" };
|
|
19477
|
+
} catch (e) {
|
|
19478
|
+
LOG5.info("Command", `[set_mode] webview script error: ${e.message}`);
|
|
19894
19479
|
}
|
|
19895
19480
|
}
|
|
19896
|
-
|
|
19897
|
-
|
|
19898
|
-
|
|
19899
|
-
|
|
19900
|
-
|
|
19901
|
-
|
|
19902
|
-
|
|
19903
|
-
|
|
19904
|
-
|
|
19905
|
-
|
|
19906
|
-
|
|
19907
|
-
} catch {
|
|
19908
|
-
}
|
|
19909
|
-
}
|
|
19910
|
-
LOG4.info("Command", `[resolveAction] script result: ${JSON.stringify(result)}`);
|
|
19911
|
-
if (result?.resolved) {
|
|
19912
|
-
LOG4.info("Command", `[resolveAction] script-click resolved \u2014 "${result.clicked}"`);
|
|
19913
|
-
return { success: true, clicked: result.clicked };
|
|
19914
|
-
}
|
|
19915
|
-
if (result?.found && result.x != null && result.y != null) {
|
|
19916
|
-
const x = result.x;
|
|
19917
|
-
const y = result.y;
|
|
19918
|
-
await cdp2.send("Input.dispatchMouseEvent", {
|
|
19919
|
-
type: "mousePressed",
|
|
19920
|
-
x,
|
|
19921
|
-
y,
|
|
19922
|
-
button: "left",
|
|
19923
|
-
clickCount: 1
|
|
19924
|
-
});
|
|
19925
|
-
await cdp2.send("Input.dispatchMouseEvent", {
|
|
19926
|
-
type: "mouseReleased",
|
|
19927
|
-
x,
|
|
19928
|
-
y,
|
|
19929
|
-
button: "left",
|
|
19930
|
-
clickCount: 1
|
|
19931
|
-
});
|
|
19932
|
-
LOG4.info("Command", `[resolveAction] CDP click at (${x}, ${y}) \u2014 "${result.text}"`);
|
|
19933
|
-
return { success: true, clicked: result.text };
|
|
19481
|
+
}
|
|
19482
|
+
const mainScript = h.getProviderScript("setMode", { MODE: JSON.stringify(mode) });
|
|
19483
|
+
if (mainScript) {
|
|
19484
|
+
try {
|
|
19485
|
+
const evalResult = await h.evaluateProviderScript("setMode", { MODE: JSON.stringify(mode) }, 15e3);
|
|
19486
|
+
if (evalResult?.result) {
|
|
19487
|
+
let parsed = evalResult.result;
|
|
19488
|
+
if (typeof parsed === "string") {
|
|
19489
|
+
try {
|
|
19490
|
+
parsed = JSON.parse(parsed);
|
|
19491
|
+
} catch {
|
|
19934
19492
|
}
|
|
19935
|
-
return { success: false, error: result?.found === false ? `Button not found: ${button}` : "No coordinates" };
|
|
19936
|
-
} catch (e) {
|
|
19937
|
-
return { success: false, error: `resolveAction failed: ${e.message}` };
|
|
19938
19493
|
}
|
|
19494
|
+
if (parsed?.success) return { success: true, mode, method: "script" };
|
|
19939
19495
|
}
|
|
19496
|
+
} catch (e) {
|
|
19497
|
+
LOG5.info("Command", `[set_mode] script error: ${e.message}`);
|
|
19940
19498
|
}
|
|
19941
|
-
return { success: false, error: "resolveAction script not available for this provider" };
|
|
19942
19499
|
}
|
|
19943
|
-
|
|
19944
|
-
|
|
19945
|
-
|
|
19946
|
-
|
|
19947
|
-
|
|
19948
|
-
|
|
19949
|
-
|
|
19950
|
-
|
|
19951
|
-
}
|
|
19952
|
-
|
|
19500
|
+
return { success: false, error: `setMode '${mode}' not supported by this provider` };
|
|
19501
|
+
}
|
|
19502
|
+
async function handleChangeModel(h, args) {
|
|
19503
|
+
const provider2 = h.getProvider();
|
|
19504
|
+
const model = args?.model;
|
|
19505
|
+
LOG5.info("Command", `[change_model] model=${model} provider=${provider2?.type} category=${provider2?.category} ideType=${h.currentIdeType} providerType=${h.currentProviderType}`);
|
|
19506
|
+
if (provider2?.category === "acp") {
|
|
19507
|
+
const adapter = h.getCliAdapter(provider2.type);
|
|
19508
|
+
LOG5.info("Command", `[change_model] ACP adapter found: ${!!adapter}, type=${adapter?.cliType}, hasAcpInstance=${!!adapter?._acpInstance}`);
|
|
19509
|
+
if (adapter) {
|
|
19510
|
+
const acpInstance = adapter._acpInstance;
|
|
19511
|
+
if (acpInstance && typeof acpInstance.onEvent === "function") {
|
|
19512
|
+
acpInstance.onEvent("change_model", { model });
|
|
19513
|
+
LOG5.info("Command", `[change_model] Dispatched change_model event to ACP instance`);
|
|
19514
|
+
return { success: true, model };
|
|
19515
|
+
}
|
|
19953
19516
|
}
|
|
19517
|
+
return { success: false, error: "ACP adapter not found" };
|
|
19954
19518
|
}
|
|
19955
|
-
|
|
19956
|
-
|
|
19957
|
-
|
|
19958
|
-
|
|
19959
|
-
|
|
19960
|
-
const
|
|
19961
|
-
|
|
19519
|
+
const webviewScript = h.getProviderScript("webviewSetModel", { MODEL: JSON.stringify(model) });
|
|
19520
|
+
if (webviewScript) {
|
|
19521
|
+
const cdp2 = h.getCdp();
|
|
19522
|
+
if (cdp2?.isConnected) {
|
|
19523
|
+
try {
|
|
19524
|
+
const matchText = provider2?.webviewMatchText;
|
|
19525
|
+
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19526
|
+
const raw = await cdp2.evaluateInWebviewFrame?.(webviewScript, matchFn);
|
|
19527
|
+
let result = raw;
|
|
19528
|
+
if (typeof raw === "string") {
|
|
19529
|
+
try {
|
|
19530
|
+
result = JSON.parse(raw);
|
|
19531
|
+
} catch {
|
|
19532
|
+
}
|
|
19533
|
+
}
|
|
19534
|
+
if (result?.success) return { success: true, model, method: "webview-script" };
|
|
19535
|
+
} catch (e) {
|
|
19536
|
+
LOG5.info("Command", `[change_model] webview script error: ${e.message}`);
|
|
19962
19537
|
}
|
|
19963
|
-
return { success: false, error: "Screenshot failed" };
|
|
19964
|
-
} catch (e) {
|
|
19965
|
-
return { success: false, error: e.message };
|
|
19966
19538
|
}
|
|
19967
19539
|
}
|
|
19968
|
-
|
|
19969
|
-
|
|
19970
|
-
const method = args?.method;
|
|
19971
|
-
const params = args?.params || {};
|
|
19972
|
-
if (!method) return { success: false, error: "method required" };
|
|
19540
|
+
const mainScript = h.getProviderScript("setModel", { MODEL: JSON.stringify(model) });
|
|
19541
|
+
if (mainScript) {
|
|
19973
19542
|
try {
|
|
19974
|
-
const
|
|
19975
|
-
|
|
19543
|
+
const evalResult = await h.evaluateProviderScript("setModel", { MODEL: JSON.stringify(model) }, 15e3);
|
|
19544
|
+
if (evalResult?.result) {
|
|
19545
|
+
let parsed = evalResult.result;
|
|
19546
|
+
if (typeof parsed === "string") {
|
|
19547
|
+
try {
|
|
19548
|
+
parsed = JSON.parse(parsed);
|
|
19549
|
+
} catch {
|
|
19550
|
+
}
|
|
19551
|
+
}
|
|
19552
|
+
if (parsed?.success) return { success: true, model, method: "script" };
|
|
19553
|
+
}
|
|
19976
19554
|
} catch (e) {
|
|
19977
|
-
|
|
19555
|
+
LOG5.info("Command", `[change_model] script error: ${e.message}`);
|
|
19978
19556
|
}
|
|
19979
19557
|
}
|
|
19980
|
-
|
|
19981
|
-
|
|
19982
|
-
|
|
19983
|
-
|
|
19984
|
-
|
|
19985
|
-
|
|
19986
|
-
|
|
19987
|
-
|
|
19988
|
-
|
|
19989
|
-
|
|
19990
|
-
|
|
19991
|
-
|
|
19992
|
-
|
|
19558
|
+
return { success: false, error: "changeModel not supported by this IDE provider" };
|
|
19559
|
+
}
|
|
19560
|
+
async function handleSetThoughtLevel(h, args) {
|
|
19561
|
+
const configId = args?.configId;
|
|
19562
|
+
const value = args?.value;
|
|
19563
|
+
if (!configId || !value) return { success: false, error: "configId and value required" };
|
|
19564
|
+
const provider2 = h.getProvider();
|
|
19565
|
+
if (!provider2 || provider2.category !== "acp") {
|
|
19566
|
+
return { success: false, error: "set_thought_level only for ACP providers" };
|
|
19567
|
+
}
|
|
19568
|
+
const adapter = h.getCliAdapter(provider2.type);
|
|
19569
|
+
const acpInstance = adapter?._acpInstance;
|
|
19570
|
+
if (!acpInstance) return { success: false, error: "ACP instance not found" };
|
|
19571
|
+
try {
|
|
19572
|
+
await acpInstance.setConfigOption(configId, value);
|
|
19573
|
+
LOG5.info("Command", `[set_thought_level] ${configId}=${value} for ${provider2.type}`);
|
|
19574
|
+
return { success: true, configId, value };
|
|
19575
|
+
} catch (e) {
|
|
19576
|
+
return { success: false, error: e?.message };
|
|
19577
|
+
}
|
|
19578
|
+
}
|
|
19579
|
+
async function handleResolveAction(h, args) {
|
|
19580
|
+
const provider2 = h.getProvider();
|
|
19581
|
+
const action = args?.action || "approve";
|
|
19582
|
+
const button = args?.button || args?.buttonText || (action === "approve" ? "Accept" : action === "reject" ? "Reject" : "Accept");
|
|
19583
|
+
LOG5.info("Command", `[resolveAction] action=${action} button="${button}" provider=${provider2?.type}`);
|
|
19584
|
+
if (provider2?.category === "extension" && h.agentStream && h.getCdp()) {
|
|
19585
|
+
const ok = await h.agentStream.resolveAgentAction(
|
|
19586
|
+
h.getCdp(),
|
|
19587
|
+
provider2.type,
|
|
19588
|
+
action,
|
|
19589
|
+
h.currentIdeType
|
|
19590
|
+
);
|
|
19591
|
+
return { success: ok };
|
|
19592
|
+
}
|
|
19593
|
+
if (provider2?.scripts?.webviewResolveAction || provider2?.scripts?.webview_resolve_action) {
|
|
19594
|
+
const script = h.getProviderScript("webviewResolveAction", { action, button, buttonText: button }) || h.getProviderScript("webview_resolve_action", { action, button, buttonText: button });
|
|
19595
|
+
if (script) {
|
|
19596
|
+
const cdp2 = h.getCdp();
|
|
19597
|
+
if (cdp2?.isConnected) {
|
|
19598
|
+
try {
|
|
19599
|
+
const matchText = provider2?.webviewMatchText;
|
|
19600
|
+
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
19601
|
+
const raw = await cdp2.evaluateInWebviewFrame?.(script, matchFn);
|
|
19602
|
+
let result = raw;
|
|
19603
|
+
if (typeof raw === "string") {
|
|
19604
|
+
try {
|
|
19605
|
+
result = JSON.parse(raw);
|
|
19606
|
+
} catch {
|
|
19607
|
+
}
|
|
19608
|
+
}
|
|
19609
|
+
LOG5.info("Command", `[resolveAction] webview script result: ${JSON.stringify(result)}`);
|
|
19610
|
+
if (result?.resolved) return { success: true, clicked: result.clicked };
|
|
19611
|
+
if (result?.found && result.x != null && result.y != null) {
|
|
19612
|
+
LOG5.info("Command", `[resolveAction] Webview coordinate click not fully supported via CDP. Click directly in script.`);
|
|
19613
|
+
}
|
|
19614
|
+
if (result?.found || result?.resolved) return { success: true };
|
|
19615
|
+
} catch (e) {
|
|
19616
|
+
return { success: false, error: `webviewResolveAction failed: ${e.message}` };
|
|
19617
|
+
}
|
|
19993
19618
|
}
|
|
19994
19619
|
}
|
|
19995
|
-
return { success: true, results };
|
|
19996
19620
|
}
|
|
19997
|
-
|
|
19998
|
-
|
|
19999
|
-
|
|
20000
|
-
|
|
20001
|
-
|
|
20002
|
-
|
|
20003
|
-
|
|
20004
|
-
|
|
20005
|
-
|
|
20006
|
-
|
|
20007
|
-
|
|
20008
|
-
|
|
20009
|
-
...modifiers?.shift ? { modifiers: 8 } : {}
|
|
20010
|
-
});
|
|
20011
|
-
await this.getCdp().send("Input.dispatchKeyEvent", { type: "keyUp", key });
|
|
20012
|
-
return { success: true };
|
|
20013
|
-
}
|
|
20014
|
-
case "input_click": {
|
|
20015
|
-
let { x, y, nx, ny, button: btn } = params;
|
|
20016
|
-
if ((x === void 0 || y === void 0) && nx !== void 0 && ny !== void 0) {
|
|
20017
|
-
const viewport = await this.getCdp().evaluate(
|
|
20018
|
-
"JSON.stringify({ w: window.innerWidth, h: window.innerHeight })"
|
|
20019
|
-
);
|
|
20020
|
-
const { w, h } = JSON.parse(viewport);
|
|
20021
|
-
x = Math.round(nx * w);
|
|
20022
|
-
y = Math.round(ny * h);
|
|
20023
|
-
}
|
|
20024
|
-
if (x === void 0 || y === void 0) {
|
|
20025
|
-
return { success: false, error: "No coordinates provided (x,y or nx,ny required)" };
|
|
19621
|
+
if (provider2?.scripts?.resolveAction) {
|
|
19622
|
+
const script = provider2.scripts.resolveAction({ action, button, buttonText: button });
|
|
19623
|
+
if (script) {
|
|
19624
|
+
const cdp2 = h.getCdp();
|
|
19625
|
+
if (!cdp2?.isConnected) return { success: false, error: "CDP not connected" };
|
|
19626
|
+
try {
|
|
19627
|
+
const raw = await cdp2.evaluate(script, 3e4);
|
|
19628
|
+
let result = raw;
|
|
19629
|
+
if (typeof raw === "string") {
|
|
19630
|
+
try {
|
|
19631
|
+
result = JSON.parse(raw);
|
|
19632
|
+
} catch {
|
|
20026
19633
|
}
|
|
20027
|
-
|
|
19634
|
+
}
|
|
19635
|
+
LOG5.info("Command", `[resolveAction] script result: ${JSON.stringify(result)}`);
|
|
19636
|
+
if (result?.resolved) {
|
|
19637
|
+
LOG5.info("Command", `[resolveAction] script-click resolved \u2014 "${result.clicked}"`);
|
|
19638
|
+
return { success: true, clicked: result.clicked };
|
|
19639
|
+
}
|
|
19640
|
+
if (result?.found && result.x != null && result.y != null) {
|
|
19641
|
+
const x = result.x;
|
|
19642
|
+
const y = result.y;
|
|
19643
|
+
await cdp2.send("Input.dispatchMouseEvent", {
|
|
20028
19644
|
type: "mousePressed",
|
|
20029
19645
|
x,
|
|
20030
19646
|
y,
|
|
20031
|
-
button:
|
|
19647
|
+
button: "left",
|
|
20032
19648
|
clickCount: 1
|
|
20033
19649
|
});
|
|
20034
|
-
await
|
|
19650
|
+
await cdp2.send("Input.dispatchMouseEvent", {
|
|
20035
19651
|
type: "mouseReleased",
|
|
20036
19652
|
x,
|
|
20037
19653
|
y,
|
|
20038
|
-
button:
|
|
19654
|
+
button: "left",
|
|
20039
19655
|
clickCount: 1
|
|
20040
19656
|
});
|
|
20041
|
-
|
|
20042
|
-
|
|
20043
|
-
case "input_type": {
|
|
20044
|
-
const { text } = params;
|
|
20045
|
-
for (const char of text || "") {
|
|
20046
|
-
await this.getCdp().send("Input.dispatchKeyEvent", {
|
|
20047
|
-
type: "keyDown",
|
|
20048
|
-
text: char,
|
|
20049
|
-
key: char
|
|
20050
|
-
});
|
|
20051
|
-
await this.getCdp().send("Input.dispatchKeyEvent", { type: "keyUp", key: char });
|
|
20052
|
-
}
|
|
20053
|
-
return { success: true };
|
|
20054
|
-
}
|
|
20055
|
-
case "page_screenshot":
|
|
20056
|
-
return this.handleScreenshot(args);
|
|
20057
|
-
case "page_eval":
|
|
20058
|
-
return this.handleCdpEval(params);
|
|
20059
|
-
case "dom_query": {
|
|
20060
|
-
const html = await this.getCdp().querySelector(params?.selector);
|
|
20061
|
-
return { success: true, html };
|
|
20062
|
-
}
|
|
20063
|
-
case "input_wheel": {
|
|
20064
|
-
let { x, y, nx, ny, deltaX, deltaY } = params;
|
|
20065
|
-
if ((x === void 0 || y === void 0) && nx !== void 0 && ny !== void 0) {
|
|
20066
|
-
const viewport = await this.getCdp().evaluate(
|
|
20067
|
-
"JSON.stringify({ w: window.innerWidth, h: window.innerHeight })"
|
|
20068
|
-
);
|
|
20069
|
-
const { w, h } = JSON.parse(viewport);
|
|
20070
|
-
x = Math.round(nx * w);
|
|
20071
|
-
y = Math.round(ny * h);
|
|
20072
|
-
}
|
|
20073
|
-
await this.getCdp().send("Input.dispatchMouseEvent", {
|
|
20074
|
-
type: "mouseWheel",
|
|
20075
|
-
x: x || 0,
|
|
20076
|
-
y: y || 0,
|
|
20077
|
-
deltaX: deltaX || 0,
|
|
20078
|
-
deltaY: deltaY || 0
|
|
20079
|
-
});
|
|
20080
|
-
return { success: true };
|
|
19657
|
+
LOG5.info("Command", `[resolveAction] CDP click at (${x}, ${y}) \u2014 "${result.text}"`);
|
|
19658
|
+
return { success: true, clicked: result.text };
|
|
20081
19659
|
}
|
|
20082
|
-
|
|
20083
|
-
|
|
19660
|
+
return { success: false, error: result?.found === false ? `Button not found: ${button}` : "No coordinates" };
|
|
19661
|
+
} catch (e) {
|
|
19662
|
+
return { success: false, error: `resolveAction failed: ${e.message}` };
|
|
20084
19663
|
}
|
|
20085
|
-
} catch (e) {
|
|
20086
|
-
return { success: false, error: e.message };
|
|
20087
19664
|
}
|
|
20088
19665
|
}
|
|
20089
|
-
|
|
20090
|
-
|
|
20091
|
-
|
|
20092
|
-
|
|
19666
|
+
return { success: false, error: "resolveAction script not available for this provider" };
|
|
19667
|
+
}
|
|
19668
|
+
var fs32 = __toESM2(require("fs"));
|
|
19669
|
+
var path32 = __toESM2(require("path"));
|
|
19670
|
+
var os4 = __toESM2(require("os"));
|
|
19671
|
+
async function handleCdpEval(h, args) {
|
|
19672
|
+
if (!h.getCdp()?.isConnected) return { success: false, error: "CDP not connected" };
|
|
19673
|
+
const expression = args?.expression || args?.script;
|
|
19674
|
+
if (!expression) return { success: false, error: "expression required" };
|
|
19675
|
+
try {
|
|
19676
|
+
const result = await h.getCdp().evaluate(expression, 5e4);
|
|
19677
|
+
return { success: true, result };
|
|
19678
|
+
} catch (e) {
|
|
19679
|
+
return { success: false, error: e.message };
|
|
20093
19680
|
}
|
|
20094
|
-
|
|
20095
|
-
|
|
20096
|
-
|
|
20097
|
-
|
|
20098
|
-
|
|
20099
|
-
|
|
20100
|
-
|
|
20101
|
-
return { success:
|
|
19681
|
+
}
|
|
19682
|
+
async function handleScreenshot(h, args) {
|
|
19683
|
+
if (!h.getCdp()?.isConnected) return { success: false, error: "CDP not connected" };
|
|
19684
|
+
try {
|
|
19685
|
+
const buf = await h.getCdp().captureScreenshot();
|
|
19686
|
+
if (buf) {
|
|
19687
|
+
const b64 = buf.toString("base64");
|
|
19688
|
+
return { success: true, result: b64, base64: b64, screenshot: b64, format: "webp" };
|
|
20102
19689
|
}
|
|
19690
|
+
return { success: false, error: "Screenshot failed" };
|
|
19691
|
+
} catch (e) {
|
|
19692
|
+
return { success: false, error: e.message };
|
|
20103
19693
|
}
|
|
20104
|
-
|
|
20105
|
-
|
|
20106
|
-
|
|
20107
|
-
|
|
20108
|
-
|
|
20109
|
-
|
|
20110
|
-
|
|
20111
|
-
|
|
20112
|
-
}
|
|
19694
|
+
}
|
|
19695
|
+
async function handleCdpCommand(h, args) {
|
|
19696
|
+
if (!h.getCdp()?.isConnected) return { success: false, error: "CDP not connected" };
|
|
19697
|
+
const method = args?.method;
|
|
19698
|
+
const params = args?.params || {};
|
|
19699
|
+
if (!method) return { success: false, error: "method required" };
|
|
19700
|
+
try {
|
|
19701
|
+
const result = await h.getCdp().sendCdpCommand(method, params);
|
|
19702
|
+
return { success: true, result };
|
|
19703
|
+
} catch (e) {
|
|
19704
|
+
return { success: false, error: e.message };
|
|
20113
19705
|
}
|
|
20114
|
-
|
|
19706
|
+
}
|
|
19707
|
+
async function handleCdpBatch(h, args) {
|
|
19708
|
+
if (!h.getCdp()?.isConnected) return { success: false, error: "CDP not connected" };
|
|
19709
|
+
const commands = args?.commands;
|
|
19710
|
+
const stopOnError = args?.stopOnError !== false;
|
|
19711
|
+
if (!commands?.length) return { success: false, error: "commands array required" };
|
|
19712
|
+
const results = [];
|
|
19713
|
+
for (const cmd of commands) {
|
|
20115
19714
|
try {
|
|
20116
|
-
const
|
|
20117
|
-
|
|
20118
|
-
const files = entries.map((e) => ({
|
|
20119
|
-
name: e.name,
|
|
20120
|
-
type: e.isDirectory() ? "directory" : "file",
|
|
20121
|
-
size: e.isFile() ? fs32.statSync(path32.join(dirPath, e.name)).size : void 0
|
|
20122
|
-
}));
|
|
20123
|
-
return { success: true, files, path: dirPath };
|
|
19715
|
+
const result = await h.getCdp().sendCdpCommand(cmd.method, cmd.params || {});
|
|
19716
|
+
results.push({ method: cmd.method, success: true, result });
|
|
20124
19717
|
} catch (e) {
|
|
20125
|
-
|
|
19718
|
+
results.push({ method: cmd.method, success: false, error: e.message });
|
|
19719
|
+
if (stopOnError) break;
|
|
20126
19720
|
}
|
|
20127
19721
|
}
|
|
20128
|
-
|
|
20129
|
-
|
|
20130
|
-
|
|
20131
|
-
|
|
20132
|
-
|
|
20133
|
-
|
|
20134
|
-
|
|
20135
|
-
|
|
20136
|
-
|
|
20137
|
-
|
|
20138
|
-
|
|
20139
|
-
|
|
20140
|
-
|
|
20141
|
-
|
|
20142
|
-
|
|
20143
|
-
|
|
20144
|
-
|
|
20145
|
-
|
|
20146
|
-
|
|
20147
|
-
|
|
20148
|
-
|
|
20149
|
-
|
|
20150
|
-
|
|
20151
|
-
|
|
20152
|
-
|
|
20153
|
-
|
|
20154
|
-
|
|
20155
|
-
|
|
20156
|
-
|
|
20157
|
-
|
|
20158
|
-
|
|
20159
|
-
const merged = Array.from(/* @__PURE__ */ new Set([...cliRecent, ...result.result])).slice(0, 20);
|
|
20160
|
-
return { success: true, result: merged };
|
|
20161
|
-
}
|
|
19722
|
+
return { success: true, results };
|
|
19723
|
+
}
|
|
19724
|
+
async function handleCdpRemoteAction(h, args) {
|
|
19725
|
+
if (!h.getCdp()?.isConnected) return { success: false, error: "CDP not connected" };
|
|
19726
|
+
const action = args?.action;
|
|
19727
|
+
const params = args?.params || args;
|
|
19728
|
+
try {
|
|
19729
|
+
switch (action) {
|
|
19730
|
+
case "input_key": {
|
|
19731
|
+
const { key, modifiers } = params;
|
|
19732
|
+
await h.getCdp().send("Input.dispatchKeyEvent", {
|
|
19733
|
+
type: "keyDown",
|
|
19734
|
+
key,
|
|
19735
|
+
...modifiers?.ctrl ? { modifiers: 2 } : {},
|
|
19736
|
+
...modifiers?.shift ? { modifiers: 8 } : {}
|
|
19737
|
+
});
|
|
19738
|
+
await h.getCdp().send("Input.dispatchKeyEvent", { type: "keyUp", key });
|
|
19739
|
+
return { success: true };
|
|
19740
|
+
}
|
|
19741
|
+
case "input_click": {
|
|
19742
|
+
let { x, y, nx, ny, button: btn } = params;
|
|
19743
|
+
if ((x === void 0 || y === void 0) && nx !== void 0 && ny !== void 0) {
|
|
19744
|
+
const viewport = await h.getCdp().evaluate(
|
|
19745
|
+
"JSON.stringify({ w: window.innerWidth, h: window.innerHeight })"
|
|
19746
|
+
);
|
|
19747
|
+
const { w, h: vh } = JSON.parse(viewport);
|
|
19748
|
+
x = Math.round(nx * w);
|
|
19749
|
+
y = Math.round(ny * vh);
|
|
19750
|
+
}
|
|
19751
|
+
if (x === void 0 || y === void 0) {
|
|
19752
|
+
return { success: false, error: "No coordinates provided (x,y or nx,ny required)" };
|
|
20162
19753
|
}
|
|
19754
|
+
await h.getCdp().send("Input.dispatchMouseEvent", {
|
|
19755
|
+
type: "mousePressed",
|
|
19756
|
+
x,
|
|
19757
|
+
y,
|
|
19758
|
+
button: btn || "left",
|
|
19759
|
+
clickCount: 1
|
|
19760
|
+
});
|
|
19761
|
+
await h.getCdp().send("Input.dispatchMouseEvent", {
|
|
19762
|
+
type: "mouseReleased",
|
|
19763
|
+
x,
|
|
19764
|
+
y,
|
|
19765
|
+
button: btn || "left",
|
|
19766
|
+
clickCount: 1
|
|
19767
|
+
});
|
|
19768
|
+
return { success: true, x, y };
|
|
20163
19769
|
}
|
|
20164
|
-
|
|
20165
|
-
|
|
20166
|
-
|
|
20167
|
-
|
|
20168
|
-
|
|
20169
|
-
|
|
20170
|
-
|
|
20171
|
-
|
|
20172
|
-
|
|
20173
|
-
}
|
|
20174
|
-
return { success: false, error: "ProviderLoader not initialized" };
|
|
20175
|
-
}
|
|
20176
|
-
// ─── Agent Stream commands ───────────────────────
|
|
20177
|
-
async handleAgentStreamSwitch(args) {
|
|
20178
|
-
if (!this.agentStream || !this.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
20179
|
-
const agentType = args?.agentType || args?.agent || null;
|
|
20180
|
-
await this.agentStream.switchActiveAgent(this.getCdp(), agentType);
|
|
20181
|
-
return { success: true, activeAgent: agentType };
|
|
20182
|
-
}
|
|
20183
|
-
async handleAgentStreamRead(args) {
|
|
20184
|
-
if (!this.agentStream || !this.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
20185
|
-
const streams = await this.agentStream.collectAgentStreams(this.getCdp());
|
|
20186
|
-
return { success: true, streams };
|
|
20187
|
-
}
|
|
20188
|
-
async handleAgentStreamSend(args) {
|
|
20189
|
-
const agentType = args?.agentType || args?.agent;
|
|
20190
|
-
const text = args?.text || args?.message;
|
|
20191
|
-
if (!text) return { success: false, error: "text required" };
|
|
20192
|
-
if (agentType && this.ctx.adapters) {
|
|
20193
|
-
for (const [key, adapter] of this.ctx.adapters.entries()) {
|
|
20194
|
-
if (adapter.cliType === agentType || key.includes(agentType)) {
|
|
20195
|
-
LOG4.info("Command", `[agent_stream_send] Routing to CLI adapter: ${adapter.cliType}`);
|
|
20196
|
-
try {
|
|
20197
|
-
await adapter.sendMessage(text);
|
|
20198
|
-
return { success: true, sent: true, targetAgent: adapter.cliType };
|
|
20199
|
-
} catch (e) {
|
|
20200
|
-
LOG4.info("Command", `[agent_stream_send] CLI adapter failed: ${e.message}`);
|
|
20201
|
-
return { success: false, error: `CLI send failed: ${e.message}` };
|
|
20202
|
-
}
|
|
19770
|
+
case "input_type": {
|
|
19771
|
+
const { text } = params;
|
|
19772
|
+
for (const char of text || "") {
|
|
19773
|
+
await h.getCdp().send("Input.dispatchKeyEvent", {
|
|
19774
|
+
type: "keyDown",
|
|
19775
|
+
text: char,
|
|
19776
|
+
key: char
|
|
19777
|
+
});
|
|
19778
|
+
await h.getCdp().send("Input.dispatchKeyEvent", { type: "keyUp", key: char });
|
|
20203
19779
|
}
|
|
19780
|
+
return { success: true };
|
|
19781
|
+
}
|
|
19782
|
+
case "page_screenshot":
|
|
19783
|
+
return handleScreenshot(h, args);
|
|
19784
|
+
case "page_eval":
|
|
19785
|
+
return handleCdpEval(h, params);
|
|
19786
|
+
case "dom_query": {
|
|
19787
|
+
const html = await h.getCdp().querySelector(params?.selector);
|
|
19788
|
+
return { success: true, html };
|
|
19789
|
+
}
|
|
19790
|
+
case "input_wheel": {
|
|
19791
|
+
let { x, y, nx, ny, deltaX, deltaY } = params;
|
|
19792
|
+
if ((x === void 0 || y === void 0) && nx !== void 0 && ny !== void 0) {
|
|
19793
|
+
const viewport = await h.getCdp().evaluate(
|
|
19794
|
+
"JSON.stringify({ w: window.innerWidth, h: window.innerHeight })"
|
|
19795
|
+
);
|
|
19796
|
+
const { w, h: vh } = JSON.parse(viewport);
|
|
19797
|
+
x = Math.round(nx * w);
|
|
19798
|
+
y = Math.round(ny * vh);
|
|
19799
|
+
}
|
|
19800
|
+
await h.getCdp().send("Input.dispatchMouseEvent", {
|
|
19801
|
+
type: "mouseWheel",
|
|
19802
|
+
x: x || 0,
|
|
19803
|
+
y: y || 0,
|
|
19804
|
+
deltaX: deltaX || 0,
|
|
19805
|
+
deltaY: deltaY || 0
|
|
19806
|
+
});
|
|
19807
|
+
return { success: true };
|
|
20204
19808
|
}
|
|
19809
|
+
default:
|
|
19810
|
+
return { success: false, error: `Unknown remote action: ${action}` };
|
|
20205
19811
|
}
|
|
20206
|
-
|
|
20207
|
-
|
|
20208
|
-
if (!resolvedAgent) return { success: false, error: "agentType required" };
|
|
20209
|
-
const ok = await this.agentStream.sendToAgent(this.getCdp(), resolvedAgent, text, this._currentIdeType);
|
|
20210
|
-
return { success: ok };
|
|
19812
|
+
} catch (e) {
|
|
19813
|
+
return { success: false, error: e.message };
|
|
20211
19814
|
}
|
|
20212
|
-
|
|
20213
|
-
|
|
20214
|
-
|
|
20215
|
-
|
|
20216
|
-
|
|
20217
|
-
|
|
20218
|
-
|
|
19815
|
+
}
|
|
19816
|
+
async function handleDiscoverAgents(h, args) {
|
|
19817
|
+
if (!h.getCdp()?.isConnected) return { success: false, error: "CDP not connected" };
|
|
19818
|
+
const agents = await h.getCdp().discoverAgentWebviews();
|
|
19819
|
+
return { success: true, agents };
|
|
19820
|
+
}
|
|
19821
|
+
function resolveSafePath(requestedPath) {
|
|
19822
|
+
const home = os4.homedir();
|
|
19823
|
+
let resolved;
|
|
19824
|
+
if (requestedPath.startsWith("~")) {
|
|
19825
|
+
resolved = path32.join(home, requestedPath.slice(1));
|
|
19826
|
+
} else if (path32.isAbsolute(requestedPath)) {
|
|
19827
|
+
resolved = requestedPath;
|
|
19828
|
+
} else {
|
|
19829
|
+
resolved = path32.resolve(requestedPath);
|
|
20219
19830
|
}
|
|
20220
|
-
|
|
20221
|
-
|
|
20222
|
-
|
|
20223
|
-
|
|
20224
|
-
const
|
|
20225
|
-
|
|
19831
|
+
return resolved;
|
|
19832
|
+
}
|
|
19833
|
+
async function handleFileRead(h, args) {
|
|
19834
|
+
try {
|
|
19835
|
+
const filePath = resolveSafePath(args?.path);
|
|
19836
|
+
const content = fs32.readFileSync(filePath, "utf-8");
|
|
19837
|
+
return { success: true, content, path: filePath };
|
|
19838
|
+
} catch (e) {
|
|
19839
|
+
return { success: false, error: e.message };
|
|
20226
19840
|
}
|
|
20227
|
-
|
|
20228
|
-
|
|
20229
|
-
|
|
20230
|
-
|
|
20231
|
-
|
|
20232
|
-
|
|
20233
|
-
|
|
20234
|
-
|
|
20235
|
-
|
|
20236
|
-
const agentType = args?.agentType || args?.agent || this.agentStream.activeAgentType;
|
|
20237
|
-
const sessionId = args?.sessionId || args?.id;
|
|
20238
|
-
if (!agentType || !sessionId) return { success: false, error: "agentType and sessionId required" };
|
|
20239
|
-
const ok = await this.agentStream.switchAgentSession(this.getCdp(), agentType, sessionId);
|
|
20240
|
-
return { success: ok };
|
|
19841
|
+
}
|
|
19842
|
+
async function handleFileWrite(h, args) {
|
|
19843
|
+
try {
|
|
19844
|
+
const filePath = resolveSafePath(args?.path);
|
|
19845
|
+
fs32.mkdirSync(path32.dirname(filePath), { recursive: true });
|
|
19846
|
+
fs32.writeFileSync(filePath, args?.content || "", "utf-8");
|
|
19847
|
+
return { success: true, path: filePath };
|
|
19848
|
+
} catch (e) {
|
|
19849
|
+
return { success: false, error: e.message };
|
|
20241
19850
|
}
|
|
20242
|
-
|
|
20243
|
-
|
|
20244
|
-
|
|
20245
|
-
|
|
20246
|
-
|
|
20247
|
-
const
|
|
20248
|
-
|
|
19851
|
+
}
|
|
19852
|
+
async function handleFileList(h, args) {
|
|
19853
|
+
try {
|
|
19854
|
+
const dirPath = resolveSafePath(args?.path || ".");
|
|
19855
|
+
const entries = fs32.readdirSync(dirPath, { withFileTypes: true });
|
|
19856
|
+
const files = entries.map((e) => ({
|
|
19857
|
+
name: e.name,
|
|
19858
|
+
type: e.isDirectory() ? "directory" : "file",
|
|
19859
|
+
size: e.isFile() ? fs32.statSync(path32.join(dirPath, e.name)).size : void 0
|
|
19860
|
+
}));
|
|
19861
|
+
return { success: true, files, path: dirPath };
|
|
19862
|
+
} catch (e) {
|
|
19863
|
+
return { success: false, error: e.message };
|
|
19864
|
+
}
|
|
19865
|
+
}
|
|
19866
|
+
async function handleFileListBrowse(h, args) {
|
|
19867
|
+
return handleFileList(h, args);
|
|
19868
|
+
}
|
|
19869
|
+
init_config();
|
|
19870
|
+
async function handleAgentStreamSwitch(h, args) {
|
|
19871
|
+
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
19872
|
+
const agentType = args?.agentType || args?.agent || null;
|
|
19873
|
+
await h.agentStream.switchActiveAgent(h.getCdp(), agentType);
|
|
19874
|
+
return { success: true, activeAgent: agentType };
|
|
19875
|
+
}
|
|
19876
|
+
async function handleAgentStreamRead(h, args) {
|
|
19877
|
+
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
19878
|
+
const streams = await h.agentStream.collectAgentStreams(h.getCdp());
|
|
19879
|
+
return { success: true, streams };
|
|
19880
|
+
}
|
|
19881
|
+
async function handleAgentStreamSend(h, args) {
|
|
19882
|
+
const agentType = args?.agentType || args?.agent;
|
|
19883
|
+
const text = args?.text || args?.message;
|
|
19884
|
+
if (!text) return { success: false, error: "text required" };
|
|
19885
|
+
if (agentType && h.ctx.adapters) {
|
|
19886
|
+
for (const [key, adapter] of h.ctx.adapters.entries()) {
|
|
19887
|
+
if (adapter.cliType === agentType || key.includes(agentType)) {
|
|
19888
|
+
LOG5.info("Command", `[agent_stream_send] Routing to CLI adapter: ${adapter.cliType}`);
|
|
19889
|
+
try {
|
|
19890
|
+
await adapter.sendMessage(text);
|
|
19891
|
+
return { success: true, sent: true, targetAgent: adapter.cliType };
|
|
19892
|
+
} catch (e) {
|
|
19893
|
+
LOG5.info("Command", `[agent_stream_send] CLI adapter failed: ${e.message}`);
|
|
19894
|
+
return { success: false, error: `CLI send failed: ${e.message}` };
|
|
19895
|
+
}
|
|
19896
|
+
}
|
|
19897
|
+
}
|
|
20249
19898
|
}
|
|
20250
|
-
|
|
20251
|
-
|
|
20252
|
-
|
|
20253
|
-
|
|
20254
|
-
|
|
20255
|
-
|
|
20256
|
-
|
|
20257
|
-
|
|
20258
|
-
|
|
20259
|
-
|
|
20260
|
-
|
|
20261
|
-
|
|
20262
|
-
|
|
20263
|
-
|
|
20264
|
-
|
|
20265
|
-
|
|
19899
|
+
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
19900
|
+
const resolvedAgent = agentType || h.agentStream.activeAgentType;
|
|
19901
|
+
if (!resolvedAgent) return { success: false, error: "agentType required" };
|
|
19902
|
+
const ok = await h.agentStream.sendToAgent(h.getCdp(), resolvedAgent, text, h.currentIdeType);
|
|
19903
|
+
return { success: ok };
|
|
19904
|
+
}
|
|
19905
|
+
async function handleAgentStreamResolve(h, args) {
|
|
19906
|
+
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
19907
|
+
const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
|
|
19908
|
+
const action = args?.action || "approve";
|
|
19909
|
+
if (!agentType) return { success: false, error: "agentType required" };
|
|
19910
|
+
const ok = await h.agentStream.resolveAgentAction(h.getCdp(), agentType, action, h.currentIdeType);
|
|
19911
|
+
return { success: ok };
|
|
19912
|
+
}
|
|
19913
|
+
async function handleAgentStreamNew(h, args) {
|
|
19914
|
+
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
19915
|
+
const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
|
|
19916
|
+
if (!agentType) return { success: false, error: "agentType required" };
|
|
19917
|
+
const ok = await h.agentStream.newAgentSession(h.getCdp(), agentType, h.currentIdeType);
|
|
19918
|
+
return { success: ok };
|
|
19919
|
+
}
|
|
19920
|
+
async function handleAgentStreamListChats(h, args) {
|
|
19921
|
+
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
19922
|
+
const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
|
|
19923
|
+
if (!agentType) return { success: false, error: "agentType required" };
|
|
19924
|
+
const chats = await h.agentStream.listAgentChats(h.getCdp(), agentType);
|
|
19925
|
+
return { success: true, chats };
|
|
19926
|
+
}
|
|
19927
|
+
async function handleAgentStreamSwitchSession(h, args) {
|
|
19928
|
+
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
19929
|
+
const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
|
|
19930
|
+
const sessionId = args?.sessionId || args?.id;
|
|
19931
|
+
if (!agentType || !sessionId) return { success: false, error: "agentType and sessionId required" };
|
|
19932
|
+
const ok = await h.agentStream.switchAgentSession(h.getCdp(), agentType, sessionId);
|
|
19933
|
+
return { success: ok };
|
|
19934
|
+
}
|
|
19935
|
+
async function handleAgentStreamFocus(h, args) {
|
|
19936
|
+
if (!h.agentStream || !h.getCdp()) return { success: false, error: "AgentStream or CDP not available" };
|
|
19937
|
+
const agentType = args?.agentType || args?.agent || h.agentStream.activeAgentType;
|
|
19938
|
+
if (!agentType) return { success: false, error: "agentType required" };
|
|
19939
|
+
await h.agentStream.ensureAgentPanelOpen(agentType, h.currentIdeType);
|
|
19940
|
+
const ok = await h.agentStream.focusAgentEditor(h.getCdp(), agentType);
|
|
19941
|
+
return { success: ok };
|
|
19942
|
+
}
|
|
19943
|
+
function handlePtyInput(h, args) {
|
|
19944
|
+
const { cliType, data } = args || {};
|
|
19945
|
+
if (!data) return { success: false, error: "data required" };
|
|
19946
|
+
if (h.ctx.adapters) {
|
|
19947
|
+
const targetCli = cliType || "";
|
|
19948
|
+
if (!targetCli && h.ctx.adapters.size > 0) {
|
|
19949
|
+
const first = h.ctx.adapters.values().next().value;
|
|
19950
|
+
if (first && typeof first.writeRaw === "function") {
|
|
19951
|
+
first.writeRaw(data);
|
|
20266
19952
|
return { success: true };
|
|
20267
19953
|
}
|
|
20268
|
-
|
|
20269
|
-
|
|
20270
|
-
|
|
20271
|
-
|
|
20272
|
-
|
|
19954
|
+
}
|
|
19955
|
+
const directAdapter = h.ctx.adapters.get(targetCli);
|
|
19956
|
+
if (directAdapter && typeof directAdapter.writeRaw === "function") {
|
|
19957
|
+
directAdapter.writeRaw(data);
|
|
19958
|
+
return { success: true };
|
|
19959
|
+
}
|
|
19960
|
+
for (const [, adapter] of h.ctx.adapters) {
|
|
19961
|
+
if (adapter.cliType === targetCli && typeof adapter.writeRaw === "function") {
|
|
19962
|
+
adapter.writeRaw(data);
|
|
19963
|
+
return { success: true };
|
|
20273
19964
|
}
|
|
20274
|
-
|
|
20275
|
-
|
|
20276
|
-
|
|
20277
|
-
|
|
20278
|
-
}
|
|
19965
|
+
}
|
|
19966
|
+
for (const [key, adapter] of h.ctx.adapters) {
|
|
19967
|
+
if ((key.startsWith(targetCli) || targetCli.startsWith(adapter.cliType)) && typeof adapter.writeRaw === "function") {
|
|
19968
|
+
adapter.writeRaw(data);
|
|
19969
|
+
return { success: true };
|
|
20279
19970
|
}
|
|
20280
19971
|
}
|
|
20281
|
-
return { success: false, error: `CLI adapter not found: ${cliType}` };
|
|
20282
19972
|
}
|
|
20283
|
-
|
|
20284
|
-
|
|
20285
|
-
|
|
20286
|
-
|
|
20287
|
-
|
|
20288
|
-
|
|
20289
|
-
|
|
20290
|
-
|
|
20291
|
-
|
|
20292
|
-
|
|
20293
|
-
|
|
20294
|
-
|
|
20295
|
-
|
|
20296
|
-
|
|
20297
|
-
|
|
19973
|
+
return { success: false, error: `CLI adapter not found: ${cliType}` };
|
|
19974
|
+
}
|
|
19975
|
+
function handlePtyResize(h, args) {
|
|
19976
|
+
const { cliType, cols, rows, force } = args || {};
|
|
19977
|
+
if (!cols || !rows) return { success: false, error: "cols and rows required" };
|
|
19978
|
+
if (h.ctx.adapters) {
|
|
19979
|
+
const targetCli = cliType || "";
|
|
19980
|
+
if (!targetCli && h.ctx.adapters.size > 0) {
|
|
19981
|
+
const first = h.ctx.adapters.values().next().value;
|
|
19982
|
+
if (first && typeof first.resize === "function") {
|
|
19983
|
+
if (force) {
|
|
19984
|
+
first.resize(cols - 1, rows);
|
|
19985
|
+
setTimeout(() => first.resize(cols, rows), 50);
|
|
19986
|
+
} else {
|
|
19987
|
+
first.resize(cols, rows);
|
|
20298
19988
|
}
|
|
19989
|
+
return { success: true };
|
|
19990
|
+
}
|
|
19991
|
+
}
|
|
19992
|
+
const directAdapter = h.ctx.adapters.get(targetCli);
|
|
19993
|
+
if (directAdapter && typeof directAdapter.resize === "function") {
|
|
19994
|
+
if (force) {
|
|
19995
|
+
directAdapter.resize(cols - 1, rows);
|
|
19996
|
+
setTimeout(() => directAdapter.resize(cols, rows), 50);
|
|
19997
|
+
} else {
|
|
19998
|
+
directAdapter.resize(cols, rows);
|
|
20299
19999
|
}
|
|
20300
|
-
|
|
20301
|
-
|
|
20000
|
+
return { success: true };
|
|
20001
|
+
}
|
|
20002
|
+
for (const [key, adapter] of h.ctx.adapters) {
|
|
20003
|
+
if ((adapter.cliType === targetCli || key.startsWith(targetCli) || targetCli.startsWith(adapter.cliType)) && typeof adapter.resize === "function") {
|
|
20302
20004
|
if (force) {
|
|
20303
|
-
|
|
20304
|
-
setTimeout(() =>
|
|
20005
|
+
adapter.resize(cols - 1, rows);
|
|
20006
|
+
setTimeout(() => adapter.resize(cols, rows), 50);
|
|
20305
20007
|
} else {
|
|
20306
|
-
|
|
20008
|
+
adapter.resize(cols, rows);
|
|
20307
20009
|
}
|
|
20308
20010
|
return { success: true };
|
|
20309
20011
|
}
|
|
20310
|
-
|
|
20311
|
-
|
|
20312
|
-
|
|
20313
|
-
|
|
20314
|
-
|
|
20315
|
-
|
|
20316
|
-
|
|
20317
|
-
|
|
20318
|
-
|
|
20012
|
+
}
|
|
20013
|
+
}
|
|
20014
|
+
return { success: false, error: `CLI adapter not found: ${cliType}` };
|
|
20015
|
+
}
|
|
20016
|
+
function handleGetProviderSettings(h, args) {
|
|
20017
|
+
const loader = h.ctx.providerLoader;
|
|
20018
|
+
const { providerType } = args || {};
|
|
20019
|
+
if (providerType) {
|
|
20020
|
+
const schema = loader?.getPublicSettings(providerType) || [];
|
|
20021
|
+
const values = loader?.getSettings(providerType) || {};
|
|
20022
|
+
return { success: true, providerType, schema, values };
|
|
20023
|
+
}
|
|
20024
|
+
const allSettings = loader?.getAllPublicSettings() || {};
|
|
20025
|
+
const allValues = {};
|
|
20026
|
+
for (const type of Object.keys(allSettings)) {
|
|
20027
|
+
allValues[type] = loader?.getSettings(type) || {};
|
|
20028
|
+
}
|
|
20029
|
+
return { success: true, settings: allSettings, values: allValues };
|
|
20030
|
+
}
|
|
20031
|
+
function handleSetProviderSetting(h, args) {
|
|
20032
|
+
const loader = h.ctx.providerLoader;
|
|
20033
|
+
const { providerType, key, value } = args || {};
|
|
20034
|
+
if (!providerType || !key || value === void 0) {
|
|
20035
|
+
return { success: false, error: "providerType, key, and value are required" };
|
|
20036
|
+
}
|
|
20037
|
+
const result = loader?.setSetting(providerType, key, value);
|
|
20038
|
+
if (result) {
|
|
20039
|
+
if (h.ctx.instanceManager) {
|
|
20040
|
+
const allSettings = loader?.getSettings(providerType) || {};
|
|
20041
|
+
const updated = h.ctx.instanceManager.updateInstanceSettings(providerType, allSettings);
|
|
20042
|
+
LOG5.info("Command", `[set_provider_setting] ${providerType}.${key}=${JSON.stringify(value)} \u2192 ${updated} instance(s) updated`);
|
|
20043
|
+
}
|
|
20044
|
+
return { success: true, providerType, key, value };
|
|
20045
|
+
}
|
|
20046
|
+
return { success: false, error: `Failed to set ${providerType}.${key} \u2014 invalid key, value, or not a public setting` };
|
|
20047
|
+
}
|
|
20048
|
+
async function handleExtensionScript(h, args, scriptName) {
|
|
20049
|
+
const { agentType, ideType } = args || {};
|
|
20050
|
+
LOG5.info("Command", `[ExtScript] ${scriptName} agentType=${agentType} ideType=${ideType} _currentIdeType=${h.currentIdeType}`);
|
|
20051
|
+
if (!agentType) return { success: false, error: "agentType is required" };
|
|
20052
|
+
const loader = h.ctx.providerLoader;
|
|
20053
|
+
if (!loader) return { success: false, error: "ProviderLoader not initialized" };
|
|
20054
|
+
const provider2 = loader.resolve(agentType);
|
|
20055
|
+
if (!provider2) return { success: false, error: `Provider not found: ${agentType}` };
|
|
20056
|
+
const webviewScriptName = `webview${scriptName.charAt(0).toUpperCase() + scriptName.slice(1)}`;
|
|
20057
|
+
const hasWebviewScript = provider2.category === "ide" && !!provider2.scripts?.[webviewScriptName];
|
|
20058
|
+
const actualScriptName = hasWebviewScript ? webviewScriptName : scriptName;
|
|
20059
|
+
if (!provider2.scripts?.[actualScriptName]) {
|
|
20060
|
+
return { success: false, error: `Script '${actualScriptName}' not available for ${agentType}` };
|
|
20061
|
+
}
|
|
20062
|
+
const scriptFn = provider2.scripts[actualScriptName];
|
|
20063
|
+
const scriptCode = scriptFn(args);
|
|
20064
|
+
if (!scriptCode) return { success: false, error: `Script '${actualScriptName}' returned null` };
|
|
20065
|
+
const cdpKey = provider2.category === "ide" ? h.currentIdeType || agentType : h.currentIdeType || ideType;
|
|
20066
|
+
LOG5.info("Command", `[ExtScript] provider=${provider2.type} category=${provider2.category} cdpKey=${cdpKey}`);
|
|
20067
|
+
const cdp2 = h.getCdp(cdpKey);
|
|
20068
|
+
if (!cdp2?.isConnected) return { success: false, error: `No CDP connection for ${cdpKey || "any"}` };
|
|
20069
|
+
try {
|
|
20070
|
+
let result;
|
|
20071
|
+
if (provider2.category === "extension") {
|
|
20072
|
+
const sessions = cdp2.getAgentSessions();
|
|
20073
|
+
let targetSessionId = null;
|
|
20074
|
+
for (const [sessionId, target] of sessions) {
|
|
20075
|
+
if (target.agentType === agentType) {
|
|
20076
|
+
targetSessionId = sessionId;
|
|
20077
|
+
break;
|
|
20319
20078
|
}
|
|
20320
20079
|
}
|
|
20080
|
+
if (!targetSessionId) {
|
|
20081
|
+
return { success: false, error: `No active session found for ${agentType}` };
|
|
20082
|
+
}
|
|
20083
|
+
result = await cdp2.evaluateInSession(targetSessionId, scriptCode);
|
|
20084
|
+
} else if (hasWebviewScript && cdp2.evaluateInWebviewFrame) {
|
|
20085
|
+
const matchText = provider2.webviewMatchText;
|
|
20086
|
+
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
20087
|
+
result = await cdp2.evaluateInWebviewFrame(scriptCode, matchFn);
|
|
20088
|
+
} else {
|
|
20089
|
+
result = await cdp2.evaluate(scriptCode, 3e4);
|
|
20090
|
+
}
|
|
20091
|
+
if (typeof result === "string") {
|
|
20092
|
+
try {
|
|
20093
|
+
const parsed = JSON.parse(result);
|
|
20094
|
+
return { success: true, ...parsed };
|
|
20095
|
+
} catch {
|
|
20096
|
+
return { success: true, result };
|
|
20097
|
+
}
|
|
20098
|
+
}
|
|
20099
|
+
return { success: true, result };
|
|
20100
|
+
} catch (e) {
|
|
20101
|
+
return { success: false, error: `Script execution failed: ${e.message}` };
|
|
20102
|
+
}
|
|
20103
|
+
}
|
|
20104
|
+
function handleGetIdeExtensions(h, args) {
|
|
20105
|
+
const { ideType } = args || {};
|
|
20106
|
+
const loader = h.ctx.providerLoader;
|
|
20107
|
+
if (!loader) return { success: false, error: "ProviderLoader not initialized" };
|
|
20108
|
+
const allExtProviders = loader.getByCategory?.("extension") || [];
|
|
20109
|
+
const config2 = loadConfig4();
|
|
20110
|
+
if (ideType) {
|
|
20111
|
+
const extensions = allExtProviders.map((p) => ({
|
|
20112
|
+
type: p.type,
|
|
20113
|
+
name: p.name,
|
|
20114
|
+
extensionId: p.extensionId,
|
|
20115
|
+
enabled: config2.ideSettings?.[ideType]?.extensions?.[p.type]?.enabled === true
|
|
20116
|
+
}));
|
|
20117
|
+
return { success: true, ideType, extensions };
|
|
20118
|
+
}
|
|
20119
|
+
const connectedIdes = [...h.ctx.cdpManagers?.keys?.() || []];
|
|
20120
|
+
const result = {};
|
|
20121
|
+
for (const ide of connectedIdes) {
|
|
20122
|
+
result[ide] = allExtProviders.map((p) => ({
|
|
20123
|
+
type: p.type,
|
|
20124
|
+
name: p.name,
|
|
20125
|
+
extensionId: p.extensionId,
|
|
20126
|
+
enabled: config2.ideSettings?.[ide]?.extensions?.[p.type]?.enabled === true
|
|
20127
|
+
}));
|
|
20128
|
+
}
|
|
20129
|
+
return { success: true, ides: result };
|
|
20130
|
+
}
|
|
20131
|
+
function handleSetIdeExtension(h, args) {
|
|
20132
|
+
const { ideType, extensionType, enabled } = args || {};
|
|
20133
|
+
if (!ideType || !extensionType || enabled === void 0) {
|
|
20134
|
+
return { success: false, error: "ideType, extensionType, and enabled are required" };
|
|
20135
|
+
}
|
|
20136
|
+
const loader = h.ctx.providerLoader;
|
|
20137
|
+
if (!loader?.setIdeExtensionEnabled) {
|
|
20138
|
+
return { success: false, error: "ProviderLoader not initialized" };
|
|
20139
|
+
}
|
|
20140
|
+
const ok = loader.setIdeExtensionEnabled(ideType, extensionType, !!enabled);
|
|
20141
|
+
if (ok) {
|
|
20142
|
+
return { success: true, ideType, extensionType, enabled: !!enabled };
|
|
20143
|
+
}
|
|
20144
|
+
return { success: false, error: "Failed to save setting" };
|
|
20145
|
+
}
|
|
20146
|
+
var DaemonCommandHandler = class {
|
|
20147
|
+
_ctx;
|
|
20148
|
+
_agentStream = null;
|
|
20149
|
+
domHandlers;
|
|
20150
|
+
_historyWriter;
|
|
20151
|
+
/** Current IDE type extracted from command args (per-request) */
|
|
20152
|
+
_currentIdeType;
|
|
20153
|
+
/** Current provider type — agentType priority, ideType use */
|
|
20154
|
+
_currentProviderType;
|
|
20155
|
+
constructor(ctx) {
|
|
20156
|
+
this._ctx = ctx;
|
|
20157
|
+
this.domHandlers = new CdpDomHandlers((ideType) => this.getCdp(ideType));
|
|
20158
|
+
this._historyWriter = new ChatHistoryWriter();
|
|
20159
|
+
}
|
|
20160
|
+
// ─── CommandHelpers implementation ─────────────────
|
|
20161
|
+
get ctx() {
|
|
20162
|
+
return this._ctx;
|
|
20163
|
+
}
|
|
20164
|
+
get agentStream() {
|
|
20165
|
+
return this._agentStream;
|
|
20166
|
+
}
|
|
20167
|
+
get historyWriter() {
|
|
20168
|
+
return this._historyWriter;
|
|
20169
|
+
}
|
|
20170
|
+
get currentIdeType() {
|
|
20171
|
+
return this._currentIdeType;
|
|
20172
|
+
}
|
|
20173
|
+
get currentProviderType() {
|
|
20174
|
+
return this._currentProviderType;
|
|
20175
|
+
}
|
|
20176
|
+
/** Get CDP manager for a specific ideType.
|
|
20177
|
+
* Returns null if no match — never falls back to another IDE. */
|
|
20178
|
+
getCdp(ideType) {
|
|
20179
|
+
const key = ideType || this._currentIdeType;
|
|
20180
|
+
if (!key) return null;
|
|
20181
|
+
const m = this._ctx.cdpManagers.get(key.toLowerCase());
|
|
20182
|
+
if (m?.isConnected) return m;
|
|
20183
|
+
return null;
|
|
20184
|
+
}
|
|
20185
|
+
/**
|
|
20186
|
+
* Get provider module — _currentProviderType (agentType priority) use.
|
|
20187
|
+
*/
|
|
20188
|
+
getProvider(overrideType) {
|
|
20189
|
+
const key = overrideType || this._currentProviderType || this._currentIdeType;
|
|
20190
|
+
if (!key || !this._ctx.providerLoader) return void 0;
|
|
20191
|
+
const result = this._ctx.providerLoader.resolve(key);
|
|
20192
|
+
if (result) return result;
|
|
20193
|
+
const baseType = key.split("_")[0];
|
|
20194
|
+
if (baseType !== key) return this._ctx.providerLoader.resolve(baseType);
|
|
20195
|
+
return void 0;
|
|
20196
|
+
}
|
|
20197
|
+
/** Get a provider script by name from ProviderLoader. */
|
|
20198
|
+
getProviderScript(scriptName, params, ideType) {
|
|
20199
|
+
const provider2 = this.getProvider(ideType);
|
|
20200
|
+
if (provider2?.scripts) {
|
|
20201
|
+
const fn = provider2.scripts[scriptName];
|
|
20202
|
+
if (typeof fn === "function") {
|
|
20203
|
+
const firstVal = params ? Object.values(params)[0] : void 0;
|
|
20204
|
+
const script = firstVal ? fn(firstVal) : fn();
|
|
20205
|
+
if (script) return script;
|
|
20206
|
+
}
|
|
20207
|
+
}
|
|
20208
|
+
return null;
|
|
20209
|
+
}
|
|
20210
|
+
/**
|
|
20211
|
+
* per-category CDP script execute:
|
|
20212
|
+
* IDE → cdp.evaluate(script) (main window)
|
|
20213
|
+
* Extension → cdp.evaluateInSession(sessionId, script) (webview)
|
|
20214
|
+
*/
|
|
20215
|
+
async evaluateProviderScript(scriptName, params, timeout = 3e4) {
|
|
20216
|
+
const provider2 = this.getProvider();
|
|
20217
|
+
const script = this.getProviderScript(scriptName, params);
|
|
20218
|
+
if (!script) return null;
|
|
20219
|
+
const cdp2 = this.getCdp();
|
|
20220
|
+
if (!cdp2?.isConnected) return null;
|
|
20221
|
+
if (provider2?.category === "extension") {
|
|
20222
|
+
let sessionId = this.getExtensionSessionId(provider2);
|
|
20223
|
+
if (!sessionId && this._agentStream) {
|
|
20224
|
+
await this._agentStream.switchActiveAgent(cdp2, provider2.type);
|
|
20225
|
+
await this._agentStream.syncAgentSessions(cdp2);
|
|
20226
|
+
sessionId = this.getExtensionSessionId(provider2);
|
|
20227
|
+
}
|
|
20228
|
+
if (!sessionId) return null;
|
|
20229
|
+
const result2 = await cdp2.evaluateInSession(sessionId, script, timeout);
|
|
20230
|
+
return { result: result2, category: "extension" };
|
|
20231
|
+
}
|
|
20232
|
+
const result = await cdp2.evaluate(script, timeout);
|
|
20233
|
+
return { result, category: provider2?.category || "ide" };
|
|
20234
|
+
}
|
|
20235
|
+
/** CLI adapter search */
|
|
20236
|
+
getCliAdapter(type) {
|
|
20237
|
+
const target = type || this._currentIdeType;
|
|
20238
|
+
if (!target || !this._ctx.adapters) return null;
|
|
20239
|
+
for (const [key, adapter] of this._ctx.adapters.entries()) {
|
|
20240
|
+
if (adapter.cliType === target || key.startsWith(target)) {
|
|
20241
|
+
return adapter;
|
|
20242
|
+
}
|
|
20321
20243
|
}
|
|
20322
|
-
return
|
|
20244
|
+
return null;
|
|
20323
20245
|
}
|
|
20324
|
-
// ───
|
|
20325
|
-
|
|
20326
|
-
|
|
20327
|
-
|
|
20328
|
-
|
|
20329
|
-
const values = this.ctx.providerLoader?.getSettings?.(providerType) || {};
|
|
20330
|
-
return { success: true, providerType, schema, values };
|
|
20331
|
-
}
|
|
20332
|
-
const allSettings = this.ctx.providerLoader?.getAllPublicSettings?.() || {};
|
|
20333
|
-
const allValues = {};
|
|
20334
|
-
for (const type of Object.keys(allSettings)) {
|
|
20335
|
-
allValues[type] = this.ctx.providerLoader?.getSettings?.(type) || {};
|
|
20336
|
-
}
|
|
20337
|
-
return { success: true, settings: allSettings, values: allValues };
|
|
20246
|
+
// ─── Private helpers ──────────────────────────────
|
|
20247
|
+
getExtensionSessionId(provider2) {
|
|
20248
|
+
if (provider2.category !== "extension" || !this._agentStream) return null;
|
|
20249
|
+
const managed = this._agentStream.getManagedAgent(provider2.type);
|
|
20250
|
+
return managed?.sessionId || null;
|
|
20338
20251
|
}
|
|
20339
|
-
|
|
20340
|
-
|
|
20341
|
-
if (
|
|
20342
|
-
|
|
20343
|
-
|
|
20344
|
-
|
|
20345
|
-
|
|
20346
|
-
if (
|
|
20347
|
-
|
|
20348
|
-
|
|
20349
|
-
|
|
20252
|
+
/** Extract ideType from _targetInstance */
|
|
20253
|
+
extractIdeType(args) {
|
|
20254
|
+
if (args?._targetInstance) {
|
|
20255
|
+
let raw = args._targetInstance;
|
|
20256
|
+
const ideMatch = raw.match(/:ide:(.+)$/);
|
|
20257
|
+
const cliMatch = raw.match(/:cli:(.+)$/);
|
|
20258
|
+
const acpMatch = raw.match(/:acp:(.+)$/);
|
|
20259
|
+
if (ideMatch) raw = ideMatch[1];
|
|
20260
|
+
else if (cliMatch) raw = cliMatch[1];
|
|
20261
|
+
else if (acpMatch) raw = acpMatch[1];
|
|
20262
|
+
if (this._ctx.instanceIdMap?.has(raw)) {
|
|
20263
|
+
return this._ctx.instanceIdMap.get(raw);
|
|
20350
20264
|
}
|
|
20351
|
-
|
|
20265
|
+
const lastUnderscore = raw.lastIndexOf("_");
|
|
20266
|
+
if (lastUnderscore > 0) return raw.substring(0, lastUnderscore);
|
|
20267
|
+
return raw;
|
|
20352
20268
|
}
|
|
20353
|
-
return
|
|
20269
|
+
return void 0;
|
|
20354
20270
|
}
|
|
20355
|
-
|
|
20356
|
-
|
|
20357
|
-
|
|
20358
|
-
|
|
20359
|
-
|
|
20360
|
-
|
|
20361
|
-
|
|
20362
|
-
|
|
20363
|
-
|
|
20364
|
-
|
|
20365
|
-
|
|
20366
|
-
if (!loader) return { success: false, error: "ProviderLoader not initialized" };
|
|
20367
|
-
const provider2 = loader.resolve(agentType);
|
|
20368
|
-
if (!provider2) return { success: false, error: `Provider not found: ${agentType}` };
|
|
20369
|
-
const webviewScriptName = `webview${scriptName.charAt(0).toUpperCase() + scriptName.slice(1)}`;
|
|
20370
|
-
const hasWebviewScript = provider2.category === "ide" && !!provider2.scripts?.[webviewScriptName];
|
|
20371
|
-
const actualScriptName = hasWebviewScript ? webviewScriptName : scriptName;
|
|
20372
|
-
if (!provider2.scripts?.[actualScriptName]) {
|
|
20373
|
-
return { success: false, error: `Script '${actualScriptName}' not available for ${agentType}` };
|
|
20374
|
-
}
|
|
20375
|
-
const scriptFn = provider2.scripts[actualScriptName];
|
|
20376
|
-
const scriptCode = scriptFn(args);
|
|
20377
|
-
if (!scriptCode) return { success: false, error: `Script '${actualScriptName}' returned null` };
|
|
20378
|
-
const cdpKey = provider2.category === "ide" ? this._currentIdeType || agentType : this._currentIdeType || ideType;
|
|
20379
|
-
LOG4.info("Command", `[ExtScript] provider=${provider2.type} category=${provider2.category} cdpKey=${cdpKey}`);
|
|
20380
|
-
const cdp2 = this.getCdp(cdpKey);
|
|
20381
|
-
if (!cdp2?.isConnected) return { success: false, error: `No CDP connection for ${cdpKey || "any"}` };
|
|
20382
|
-
try {
|
|
20383
|
-
let result;
|
|
20384
|
-
if (provider2.category === "extension") {
|
|
20385
|
-
const sessions = cdp2.getAgentSessions();
|
|
20386
|
-
let targetSessionId = null;
|
|
20387
|
-
for (const [sessionId, target] of sessions) {
|
|
20388
|
-
if (target.agentType === agentType) {
|
|
20389
|
-
targetSessionId = sessionId;
|
|
20390
|
-
break;
|
|
20391
|
-
}
|
|
20392
|
-
}
|
|
20393
|
-
if (!targetSessionId) {
|
|
20394
|
-
return { success: false, error: `No active session found for ${agentType}` };
|
|
20395
|
-
}
|
|
20396
|
-
result = await cdp2.evaluateInSession(targetSessionId, scriptCode);
|
|
20397
|
-
} else if (hasWebviewScript && cdp2.evaluateInWebviewFrame) {
|
|
20398
|
-
const matchText = provider2.webviewMatchText;
|
|
20399
|
-
const matchFn = matchText ? (body) => body.includes(matchText) : void 0;
|
|
20400
|
-
result = await cdp2.evaluateInWebviewFrame(scriptCode, matchFn);
|
|
20401
|
-
} else {
|
|
20402
|
-
result = await cdp2.evaluate(scriptCode, 3e4);
|
|
20271
|
+
setAgentStreamManager(manager) {
|
|
20272
|
+
this._agentStream = manager;
|
|
20273
|
+
}
|
|
20274
|
+
// ─── Command Dispatcher ──────────────────────────
|
|
20275
|
+
async handle(cmd, args) {
|
|
20276
|
+
this._currentIdeType = this.extractIdeType(args);
|
|
20277
|
+
this._currentProviderType = args?.agentType || args?.providerType || this._currentIdeType;
|
|
20278
|
+
if (!this._currentIdeType && !this._currentProviderType) {
|
|
20279
|
+
const cdpCommands = ["send_chat", "read_chat", "list_chats", "new_chat", "switch_chat", "set_mode", "change_model", "set_thought_level", "resolve_action"];
|
|
20280
|
+
if (cdpCommands.includes(cmd)) {
|
|
20281
|
+
return { success: false, error: "No ideType specified \u2014 cannot route command" };
|
|
20403
20282
|
}
|
|
20404
|
-
|
|
20405
|
-
|
|
20406
|
-
|
|
20407
|
-
|
|
20408
|
-
|
|
20409
|
-
|
|
20283
|
+
}
|
|
20284
|
+
try {
|
|
20285
|
+
return await this.dispatch(cmd, args);
|
|
20286
|
+
} catch (e) {
|
|
20287
|
+
LOG5.error("Command", `[${cmd}] Unhandled error: ${e?.message || e}`);
|
|
20288
|
+
return { success: false, error: `Internal error: ${e?.message || "unknown"}` };
|
|
20289
|
+
}
|
|
20290
|
+
}
|
|
20291
|
+
async dispatch(cmd, args) {
|
|
20292
|
+
switch (cmd) {
|
|
20293
|
+
// ─── Chat commands (chat-commands.ts) ───────────────
|
|
20294
|
+
case "read_chat":
|
|
20295
|
+
return handleReadChat(this, args);
|
|
20296
|
+
case "chat_history":
|
|
20297
|
+
return handleChatHistory(this, args);
|
|
20298
|
+
case "send_chat":
|
|
20299
|
+
return handleSendChat(this, args);
|
|
20300
|
+
case "list_chats":
|
|
20301
|
+
return handleListChats(this, args);
|
|
20302
|
+
case "new_chat":
|
|
20303
|
+
return handleNewChat(this, args);
|
|
20304
|
+
case "switch_chat":
|
|
20305
|
+
return handleSwitchChat(this, args);
|
|
20306
|
+
case "set_mode":
|
|
20307
|
+
return handleSetMode(this, args);
|
|
20308
|
+
case "change_model":
|
|
20309
|
+
return handleChangeModel(this, args);
|
|
20310
|
+
case "set_thought_level":
|
|
20311
|
+
return handleSetThoughtLevel(this, args);
|
|
20312
|
+
case "resolve_action":
|
|
20313
|
+
return handleResolveAction(this, args);
|
|
20314
|
+
// ─── CDP commands (cdp-commands.ts) ───────────────
|
|
20315
|
+
case "cdp_eval":
|
|
20316
|
+
return handleCdpEval(this, args);
|
|
20317
|
+
case "cdp_screenshot":
|
|
20318
|
+
case "screenshot":
|
|
20319
|
+
return handleScreenshot(this, args);
|
|
20320
|
+
case "cdp_command_exec":
|
|
20321
|
+
return handleCdpCommand(this, args);
|
|
20322
|
+
case "cdp_batch":
|
|
20323
|
+
return handleCdpBatch(this, args);
|
|
20324
|
+
case "cdp_remote_action":
|
|
20325
|
+
return handleCdpRemoteAction(this, args);
|
|
20326
|
+
case "cdp_discover_agents":
|
|
20327
|
+
return handleDiscoverAgents(this, args);
|
|
20328
|
+
case "cdp_dom_dump":
|
|
20329
|
+
return this.domHandlers.handleDomDump(args);
|
|
20330
|
+
case "cdp_dom_query":
|
|
20331
|
+
return this.domHandlers.handleDomQuery(args);
|
|
20332
|
+
case "cdp_dom_debug":
|
|
20333
|
+
return this.domHandlers.handleDomDebug(args);
|
|
20334
|
+
// ─── File commands (cdp-commands.ts) ──────────────
|
|
20335
|
+
case "file_read":
|
|
20336
|
+
return handleFileRead(this, args);
|
|
20337
|
+
case "file_write":
|
|
20338
|
+
return handleFileWrite(this, args);
|
|
20339
|
+
case "file_list":
|
|
20340
|
+
return handleFileList(this, args);
|
|
20341
|
+
case "file_list_browse":
|
|
20342
|
+
return handleFileListBrowse(this, args);
|
|
20343
|
+
// ─── VSCode API commands (not available) ────
|
|
20344
|
+
case "vscode_command_exec":
|
|
20345
|
+
case "execute_vscode_command": {
|
|
20346
|
+
const resolvedCmd = args?.commandId || args?.command;
|
|
20347
|
+
if (resolvedCmd === "adhdev.captureCdpScreenshot") {
|
|
20348
|
+
return handleScreenshot(this, args);
|
|
20410
20349
|
}
|
|
20350
|
+
return { success: false, error: `VSCode command not available: ${resolvedCmd || cmd}` };
|
|
20411
20351
|
}
|
|
20412
|
-
|
|
20413
|
-
|
|
20414
|
-
|
|
20352
|
+
case "get_open_editors":
|
|
20353
|
+
case "open_tab":
|
|
20354
|
+
case "close_tab":
|
|
20355
|
+
case "open_folder":
|
|
20356
|
+
case "open_folder_picker":
|
|
20357
|
+
case "open_recent":
|
|
20358
|
+
case "get_commands":
|
|
20359
|
+
return { success: false, error: `${cmd} requires bridge-extension (removed)` };
|
|
20360
|
+
case "get_recent_workspaces":
|
|
20361
|
+
return this.handleGetRecentWorkspaces(args);
|
|
20362
|
+
// ─── Script manage ───────────────────
|
|
20363
|
+
case "refresh_scripts":
|
|
20364
|
+
return this.handleRefreshScripts(args);
|
|
20365
|
+
// ─── Stream commands (stream-commands.ts) ───────────
|
|
20366
|
+
case "agent_stream_switch":
|
|
20367
|
+
return handleAgentStreamSwitch(this, args);
|
|
20368
|
+
case "agent_stream_read":
|
|
20369
|
+
return handleAgentStreamRead(this, args);
|
|
20370
|
+
case "agent_stream_send":
|
|
20371
|
+
return handleAgentStreamSend(this, args);
|
|
20372
|
+
case "agent_stream_resolve":
|
|
20373
|
+
return handleAgentStreamResolve(this, args);
|
|
20374
|
+
case "agent_stream_new":
|
|
20375
|
+
return handleAgentStreamNew(this, args);
|
|
20376
|
+
case "agent_stream_list_chats":
|
|
20377
|
+
return handleAgentStreamListChats(this, args);
|
|
20378
|
+
case "agent_stream_switch_session":
|
|
20379
|
+
return handleAgentStreamSwitchSession(this, args);
|
|
20380
|
+
case "agent_stream_focus":
|
|
20381
|
+
return handleAgentStreamFocus(this, args);
|
|
20382
|
+
// ─── PTY Raw I/O (stream-commands.ts) ─────────
|
|
20383
|
+
case "pty_input":
|
|
20384
|
+
return handlePtyInput(this, args);
|
|
20385
|
+
case "pty_resize":
|
|
20386
|
+
return handlePtyResize(this, args);
|
|
20387
|
+
// ─── Provider Settings (stream-commands.ts) ──────────
|
|
20388
|
+
case "get_provider_settings":
|
|
20389
|
+
return handleGetProviderSettings(this, args);
|
|
20390
|
+
case "set_provider_setting":
|
|
20391
|
+
return handleSetProviderSetting(this, args);
|
|
20392
|
+
// ─── IDE Extension Settings (stream-commands.ts) ──────────
|
|
20393
|
+
case "get_ide_extensions":
|
|
20394
|
+
return handleGetIdeExtensions(this, args);
|
|
20395
|
+
case "set_ide_extension":
|
|
20396
|
+
return handleSetIdeExtension(this, args);
|
|
20397
|
+
// ─── Extension Model / Mode Control (stream-commands.ts) ──────────
|
|
20398
|
+
case "list_extension_models":
|
|
20399
|
+
return handleExtensionScript(this, args, "listModels");
|
|
20400
|
+
case "set_extension_model":
|
|
20401
|
+
return handleExtensionScript(this, args, "setModel");
|
|
20402
|
+
case "list_extension_modes":
|
|
20403
|
+
return handleExtensionScript(this, args, "listModes");
|
|
20404
|
+
case "set_extension_mode":
|
|
20405
|
+
return handleExtensionScript(this, args, "setMode");
|
|
20406
|
+
default:
|
|
20407
|
+
return { success: false, error: `Unknown command: ${cmd}` };
|
|
20415
20408
|
}
|
|
20416
20409
|
}
|
|
20417
|
-
// ───
|
|
20418
|
-
|
|
20419
|
-
const { ideType } = args || {};
|
|
20420
|
-
const loader = this.ctx.providerLoader;
|
|
20421
|
-
if (!loader) return { success: false, error: "ProviderLoader not initialized" };
|
|
20422
|
-
const allExtProviders = loader.getByCategory?.("extension") || [];
|
|
20410
|
+
// ─── Misc (kept in handler — too small to extract) ───────
|
|
20411
|
+
async handleGetRecentWorkspaces(args) {
|
|
20423
20412
|
const config2 = loadConfig4();
|
|
20424
|
-
|
|
20425
|
-
|
|
20426
|
-
type: p.type,
|
|
20427
|
-
name: p.name,
|
|
20428
|
-
extensionId: p.extensionId,
|
|
20429
|
-
enabled: config2.ideSettings?.[ideType]?.extensions?.[p.type]?.enabled === true
|
|
20430
|
-
}));
|
|
20431
|
-
return { success: true, ideType, extensions };
|
|
20432
|
-
}
|
|
20433
|
-
const connectedIdes = [...this.ctx.cdpManagers?.keys?.() || []];
|
|
20434
|
-
const result = {};
|
|
20435
|
-
for (const ide of connectedIdes) {
|
|
20436
|
-
result[ide] = allExtProviders.map((p) => ({
|
|
20437
|
-
type: p.type,
|
|
20438
|
-
name: p.name,
|
|
20439
|
-
extensionId: p.extensionId,
|
|
20440
|
-
enabled: config2.ideSettings?.[ide]?.extensions?.[p.type]?.enabled === true
|
|
20441
|
-
}));
|
|
20442
|
-
}
|
|
20443
|
-
return { success: true, ides: result };
|
|
20413
|
+
const cliRecent = config2.recentCliWorkspaces || [];
|
|
20414
|
+
return { success: true, result: cliRecent };
|
|
20444
20415
|
}
|
|
20445
|
-
|
|
20446
|
-
|
|
20447
|
-
|
|
20448
|
-
return { success:
|
|
20449
|
-
}
|
|
20450
|
-
const loader = this.ctx.providerLoader;
|
|
20451
|
-
if (!loader?.setIdeExtensionEnabled) {
|
|
20452
|
-
return { success: false, error: "ProviderLoader not initialized" };
|
|
20453
|
-
}
|
|
20454
|
-
const ok = loader.setIdeExtensionEnabled(ideType, extensionType, !!enabled);
|
|
20455
|
-
if (ok) {
|
|
20456
|
-
return { success: true, ideType, extensionType, enabled: !!enabled };
|
|
20416
|
+
async handleRefreshScripts(_args) {
|
|
20417
|
+
if (this._ctx.providerLoader) {
|
|
20418
|
+
this._ctx.providerLoader.reload();
|
|
20419
|
+
return { success: true };
|
|
20457
20420
|
}
|
|
20458
|
-
return { success: false, error: "
|
|
20421
|
+
return { success: false, error: "ProviderLoader not initialized" };
|
|
20459
20422
|
}
|
|
20460
20423
|
};
|
|
20461
20424
|
var import_child_process3 = require("child_process");
|
|
@@ -20473,6 +20436,7 @@ var require_dist = __commonJS({
|
|
|
20473
20436
|
watchers = [];
|
|
20474
20437
|
logFn;
|
|
20475
20438
|
versionArchive = null;
|
|
20439
|
+
scriptsCache = /* @__PURE__ */ new Map();
|
|
20476
20440
|
/** Inject VersionArchive so resolve() can auto-detect installed versions */
|
|
20477
20441
|
setVersionArchive(archive) {
|
|
20478
20442
|
this.versionArchive = archive;
|
|
@@ -20487,7 +20451,7 @@ var require_dist = __commonJS({
|
|
|
20487
20451
|
}
|
|
20488
20452
|
this.userDir = options?.userDir || path4.join(os5.homedir(), ".adhdev", "providers");
|
|
20489
20453
|
this.upstreamDir = path4.join(this.userDir, ".upstream");
|
|
20490
|
-
this.logFn = options?.logFn ||
|
|
20454
|
+
this.logFn = options?.logFn || LOG5.forComponent("Provider").asLogFn();
|
|
20491
20455
|
}
|
|
20492
20456
|
log(msg) {
|
|
20493
20457
|
this.logFn(`[ProviderLoader] ${msg}`);
|
|
@@ -20825,12 +20789,15 @@ var require_dist = __commonJS({
|
|
|
20825
20789
|
this.log(` [loadScriptsFromDir] ${type}: dir not found: ${dir}`);
|
|
20826
20790
|
return null;
|
|
20827
20791
|
}
|
|
20792
|
+
const cached2 = this.scriptsCache.get(dir);
|
|
20793
|
+
if (cached2) return cached2;
|
|
20828
20794
|
const scriptsJs = path4.join(dir, "scripts.js");
|
|
20829
20795
|
if (fs4.existsSync(scriptsJs)) {
|
|
20830
20796
|
try {
|
|
20831
20797
|
delete require.cache[require.resolve(scriptsJs)];
|
|
20832
20798
|
const loaded = require(scriptsJs);
|
|
20833
20799
|
this.log(` [loadScriptsFromDir] ${type}: loaded scripts.js from ${dir} (${Object.keys(loaded).length} exports)`);
|
|
20800
|
+
this.scriptsCache.set(dir, loaded);
|
|
20834
20801
|
return loaded;
|
|
20835
20802
|
} catch (e) {
|
|
20836
20803
|
this.log(` \u26A0 scripts.js load failed: ${scriptsJs}: ${e.message}`);
|
|
@@ -20838,6 +20805,7 @@ var require_dist = __commonJS({
|
|
|
20838
20805
|
}
|
|
20839
20806
|
const result = this.buildScriptWrappersFromDir(dir);
|
|
20840
20807
|
this.log(` [loadScriptsFromDir] ${type}: built wrappers from ${dir} (${Object.keys(result).length} scripts)`);
|
|
20808
|
+
this.scriptsCache.set(dir, result);
|
|
20841
20809
|
return result;
|
|
20842
20810
|
}
|
|
20843
20811
|
/**
|
|
@@ -20885,6 +20853,7 @@ var require_dist = __commonJS({
|
|
|
20885
20853
|
*/
|
|
20886
20854
|
reload() {
|
|
20887
20855
|
this.log("Reloading all providers...");
|
|
20856
|
+
this.scriptsCache.clear();
|
|
20888
20857
|
for (const key of Object.keys(require.cache)) {
|
|
20889
20858
|
if (key.includes("providers") && (key.endsWith(".js") || key.endsWith(".json"))) {
|
|
20890
20859
|
delete require.cache[key];
|
|
@@ -21926,18 +21895,18 @@ var require_dist = __commonJS({
|
|
|
21926
21895
|
case "launch_ide": {
|
|
21927
21896
|
const launchArgs = { ...args, ideId: args?.ideId || args?.ideType };
|
|
21928
21897
|
const ideKey = launchArgs.ideId;
|
|
21929
|
-
|
|
21898
|
+
LOG5.info("LaunchIDE", `target=${ideKey || "auto"}`);
|
|
21930
21899
|
const result = await launchWithCdp2(launchArgs);
|
|
21931
21900
|
if (result.success && result.port && result.ideId && !this.deps.cdpManagers.has(result.ideId)) {
|
|
21932
|
-
const logFn = this.deps.getCdpLogFn ? this.deps.getCdpLogFn(result.ideId) :
|
|
21901
|
+
const logFn = this.deps.getCdpLogFn ? this.deps.getCdpLogFn(result.ideId) : LOG5.forComponent(`CDP:${result.ideId}`).asLogFn();
|
|
21933
21902
|
const provider2 = this.deps.providerLoader.getMeta(result.ideId);
|
|
21934
21903
|
const manager = new DaemonCdpManager2(result.port, logFn, void 0, provider2?.targetFilter);
|
|
21935
21904
|
const connected = await manager.connect();
|
|
21936
21905
|
if (connected) {
|
|
21937
21906
|
registerExtensionProviders(this.deps.providerLoader, manager, result.ideId);
|
|
21938
21907
|
this.deps.cdpManagers.set(result.ideId, manager);
|
|
21939
|
-
|
|
21940
|
-
|
|
21908
|
+
LOG5.info("CDP", `Connected: ${result.ideId} (port ${result.port})`);
|
|
21909
|
+
LOG5.info("CDP", `${this.deps.cdpManagers.size} IDE(s) connected`);
|
|
21941
21910
|
this.deps.onCdpManagerCreated?.(result.ideId, manager);
|
|
21942
21911
|
}
|
|
21943
21912
|
}
|
|
@@ -21963,7 +21932,7 @@ var require_dist = __commonJS({
|
|
|
21963
21932
|
} catch {
|
|
21964
21933
|
}
|
|
21965
21934
|
this.deps.cdpManagers.delete(ideType);
|
|
21966
|
-
|
|
21935
|
+
LOG5.info("StopIDE", `CDP disconnected: ${ideType}`);
|
|
21967
21936
|
}
|
|
21968
21937
|
const instanceKey = `ide:${ideType}`;
|
|
21969
21938
|
const ideInstance = this.deps.instanceManager.getInstance(instanceKey);
|
|
@@ -21977,10 +21946,10 @@ var require_dist = __commonJS({
|
|
|
21977
21946
|
}
|
|
21978
21947
|
}
|
|
21979
21948
|
this.deps.instanceManager.removeInstance(instanceKey);
|
|
21980
|
-
|
|
21949
|
+
LOG5.info("StopIDE", `Instance removed: ${instanceKey}`);
|
|
21981
21950
|
}
|
|
21982
21951
|
this.deps.onStatusChange?.();
|
|
21983
|
-
|
|
21952
|
+
LOG5.info("StopIDE", `IDE stopped: ${ideType}`);
|
|
21984
21953
|
}
|
|
21985
21954
|
};
|
|
21986
21955
|
var os8 = __toESM2(require("os"));
|
|
@@ -21996,23 +21965,23 @@ var require_dist = __commonJS({
|
|
|
21996
21965
|
p2pTimer = null;
|
|
21997
21966
|
constructor(deps, opts) {
|
|
21998
21967
|
this.deps = deps;
|
|
21999
|
-
this.log = opts?.logFn ||
|
|
21968
|
+
this.log = opts?.logFn || LOG5.forComponent("Status").asLogFn();
|
|
22000
21969
|
}
|
|
22001
21970
|
// ─── Lifecycle ───────────────────────────────────
|
|
22002
21971
|
startReporting() {
|
|
22003
21972
|
setTimeout(() => {
|
|
22004
|
-
this.sendUnifiedStatusReport().catch((e) =>
|
|
21973
|
+
this.sendUnifiedStatusReport().catch((e) => LOG5.warn("Status", `Initial report failed: ${e?.message}`));
|
|
22005
21974
|
}, 2e3);
|
|
22006
21975
|
const scheduleServerReport = () => {
|
|
22007
21976
|
this.statusTimer = setTimeout(() => {
|
|
22008
|
-
this.sendUnifiedStatusReport().catch((e) =>
|
|
21977
|
+
this.sendUnifiedStatusReport().catch((e) => LOG5.warn("Status", `Periodic report failed: ${e?.message}`));
|
|
22009
21978
|
scheduleServerReport();
|
|
22010
21979
|
}, 3e4);
|
|
22011
21980
|
};
|
|
22012
21981
|
scheduleServerReport();
|
|
22013
21982
|
this.p2pTimer = setInterval(() => {
|
|
22014
21983
|
if (this.deps.p2p?.isConnected) {
|
|
22015
|
-
this.sendUnifiedStatusReport({ p2pOnly: true }).catch((e) =>
|
|
21984
|
+
this.sendUnifiedStatusReport({ p2pOnly: true }).catch((e) => LOG5.warn("Status", `P2P status send failed: ${e?.message}`));
|
|
22016
21985
|
}
|
|
22017
21986
|
}, 5e3);
|
|
22018
21987
|
}
|
|
@@ -22033,17 +22002,17 @@ var require_dist = __commonJS({
|
|
|
22033
22002
|
const now = Date.now();
|
|
22034
22003
|
const elapsed = now - this.lastStatusSentAt;
|
|
22035
22004
|
if (elapsed >= 5e3) {
|
|
22036
|
-
this.sendUnifiedStatusReport().catch((e) =>
|
|
22005
|
+
this.sendUnifiedStatusReport().catch((e) => LOG5.warn("Status", `Throttled report failed: ${e?.message}`));
|
|
22037
22006
|
} else if (!this.statusPendingThrottle) {
|
|
22038
22007
|
this.statusPendingThrottle = true;
|
|
22039
22008
|
setTimeout(() => {
|
|
22040
22009
|
this.statusPendingThrottle = false;
|
|
22041
|
-
this.sendUnifiedStatusReport().catch((e) =>
|
|
22010
|
+
this.sendUnifiedStatusReport().catch((e) => LOG5.warn("Status", `Deferred report failed: ${e?.message}`));
|
|
22042
22011
|
}, 5e3 - elapsed);
|
|
22043
22012
|
}
|
|
22044
22013
|
}
|
|
22045
22014
|
emitStatusEvent(event) {
|
|
22046
|
-
|
|
22015
|
+
LOG5.info("StatusEvent", `${event.event} (${event.providerType || event.ideType || ""})`);
|
|
22047
22016
|
this.deps.serverConn?.sendMessage("status_event", event);
|
|
22048
22017
|
}
|
|
22049
22018
|
removeAgentTracking(_key) {
|
|
@@ -22074,14 +22043,14 @@ var require_dist = __commonJS({
|
|
|
22074
22043
|
const acpSummary = acpStates.map((s) => `${s.type}(${s.status})`).join(", ");
|
|
22075
22044
|
const logLevel = opts?.p2pOnly ? "debug" : "info";
|
|
22076
22045
|
const summary = `\u2192${target} IDE: ${ideStates.length} [${ideSummary}] CLI: ${cliStates.length} [${cliSummary}] ACP: ${acpStates.length} [${acpSummary}]`;
|
|
22077
|
-
|
|
22078
|
-
|
|
22079
|
-
this.lastStatusSummary = summary;
|
|
22080
|
-
LOG4.debug("StatusReport", summary);
|
|
22081
|
-
}
|
|
22082
|
-
} else {
|
|
22046
|
+
const summaryChanged = summary !== this.lastStatusSummary;
|
|
22047
|
+
if (summaryChanged) {
|
|
22083
22048
|
this.lastStatusSummary = summary;
|
|
22084
|
-
|
|
22049
|
+
if (logLevel === "debug") {
|
|
22050
|
+
LOG5.debug("StatusReport", summary);
|
|
22051
|
+
} else {
|
|
22052
|
+
LOG5.info("StatusReport", summary);
|
|
22053
|
+
}
|
|
22085
22054
|
}
|
|
22086
22055
|
const managedIdes = ideStates.map((s) => ({
|
|
22087
22056
|
ideType: s.type,
|
|
@@ -22165,7 +22134,7 @@ var require_dist = __commonJS({
|
|
|
22165
22134
|
};
|
|
22166
22135
|
const p2pSent = this.sendP2PPayload(payload);
|
|
22167
22136
|
if (p2pSent) {
|
|
22168
|
-
|
|
22137
|
+
LOG5.debug("P2P", `sent (${JSON.stringify(payload).length} bytes)`);
|
|
22169
22138
|
}
|
|
22170
22139
|
if (opts?.p2pOnly) return;
|
|
22171
22140
|
const plan = serverConn.getUserPlan();
|
|
@@ -22196,7 +22165,7 @@ var require_dist = __commonJS({
|
|
|
22196
22165
|
timestamp: now
|
|
22197
22166
|
};
|
|
22198
22167
|
serverConn.sendMessage("status_report", wsPayload);
|
|
22199
|
-
|
|
22168
|
+
LOG5.debug("Server", `sent status_report (${JSON.stringify(wsPayload).length} bytes)`);
|
|
22200
22169
|
}
|
|
22201
22170
|
}
|
|
22202
22171
|
// ─── P2P ─────────────────────────────────────────
|
|
@@ -22233,7 +22202,7 @@ var require_dist = __commonJS({
|
|
|
22233
22202
|
try {
|
|
22234
22203
|
pty = require("node-pty");
|
|
22235
22204
|
} catch {
|
|
22236
|
-
|
|
22205
|
+
LOG5.error("CLI", "[ProviderCliAdapter] node-pty not found. Install: npm install node-pty@1.0.0");
|
|
22237
22206
|
}
|
|
22238
22207
|
function stripAnsi(str) {
|
|
22239
22208
|
return str.replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "").replace(/\x1B\][^\x07]*\x07/g, "").replace(/\x1B\][^\x1B]*\x1B\\/g, "");
|
|
@@ -22313,7 +22282,7 @@ var require_dist = __commonJS({
|
|
|
22313
22282
|
const binaryPath = findBinary(spawnConfig.command);
|
|
22314
22283
|
const isWin = os9.platform() === "win32";
|
|
22315
22284
|
const allArgs = [...spawnConfig.args, ...this.extraArgs];
|
|
22316
|
-
|
|
22285
|
+
LOG5.info("CLI", `[${this.cliType}] Spawning in ${this.workingDir}`);
|
|
22317
22286
|
let shellCmd;
|
|
22318
22287
|
let shellArgs;
|
|
22319
22288
|
if (spawnConfig.shell) {
|
|
@@ -22350,7 +22319,7 @@ var require_dist = __commonJS({
|
|
|
22350
22319
|
}
|
|
22351
22320
|
});
|
|
22352
22321
|
this.ptyProcess.onExit(({ exitCode }) => {
|
|
22353
|
-
|
|
22322
|
+
LOG5.info("CLI", `[${this.cliType}] Exit code ${exitCode}`);
|
|
22354
22323
|
this.ptyProcess = null;
|
|
22355
22324
|
this.currentStatus = "stopped";
|
|
22356
22325
|
this.ready = false;
|
|
@@ -22385,7 +22354,7 @@ var require_dist = __commonJS({
|
|
|
22385
22354
|
if (patterns.prompt.some((p) => p.test(this.startupBuffer))) {
|
|
22386
22355
|
this.ready = true;
|
|
22387
22356
|
this.currentStatus = "idle";
|
|
22388
|
-
|
|
22357
|
+
LOG5.info("CLI", `[${this.cliType}] \u2713 Ready`);
|
|
22389
22358
|
this.onStatusChange?.();
|
|
22390
22359
|
}
|
|
22391
22360
|
return;
|
|
@@ -22472,7 +22441,7 @@ var require_dist = __commonJS({
|
|
|
22472
22441
|
if (response) {
|
|
22473
22442
|
this.messages.push({ role: "assistant", content: response, timestamp: Date.now() });
|
|
22474
22443
|
if (this.messages.length > 200) this.messages = this.messages.slice(-200);
|
|
22475
|
-
|
|
22444
|
+
LOG5.info("CLI", `[${this.cliType}] Response (${response.length} chars)`);
|
|
22476
22445
|
}
|
|
22477
22446
|
this.responseBuffer = "";
|
|
22478
22447
|
this.isWaitingForResponse = false;
|
|
@@ -22712,6 +22681,10 @@ var require_dist = __commonJS({
|
|
|
22712
22681
|
var import_stream = require("stream");
|
|
22713
22682
|
var import_child_process5 = require("child_process");
|
|
22714
22683
|
var import_sdk = (init_acp(), __toCommonJS(acp_exports));
|
|
22684
|
+
function flattenContent(content) {
|
|
22685
|
+
if (typeof content === "string") return content;
|
|
22686
|
+
return content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
|
|
22687
|
+
}
|
|
22715
22688
|
var AcpProviderInstance = class {
|
|
22716
22689
|
constructor(provider2, workingDir, cliArgs = []) {
|
|
22717
22690
|
this.cliArgs = cliArgs;
|
|
@@ -22723,7 +22696,7 @@ var require_dist = __commonJS({
|
|
|
22723
22696
|
}
|
|
22724
22697
|
type;
|
|
22725
22698
|
category = "acp";
|
|
22726
|
-
log =
|
|
22699
|
+
log = LOG5.forComponent("ACP");
|
|
22727
22700
|
provider;
|
|
22728
22701
|
context = null;
|
|
22729
22702
|
settings = {};
|
|
@@ -22744,6 +22717,10 @@ var require_dist = __commonJS({
|
|
|
22744
22717
|
activeToolCalls = [];
|
|
22745
22718
|
stopReason = null;
|
|
22746
22719
|
partialContent = "";
|
|
22720
|
+
/** Rich content blocks accumulated during streaming */
|
|
22721
|
+
partialBlocks = [];
|
|
22722
|
+
/** Tool calls collected during current turn */
|
|
22723
|
+
turnToolCalls = [];
|
|
22747
22724
|
// Error tracking
|
|
22748
22725
|
errorMessage = null;
|
|
22749
22726
|
errorReason = null;
|
|
@@ -22778,18 +22755,23 @@ var require_dist = __commonJS({
|
|
|
22778
22755
|
}
|
|
22779
22756
|
getState() {
|
|
22780
22757
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
22781
|
-
const recentMessages = this.messages.slice(-50).map((m) =>
|
|
22782
|
-
|
|
22783
|
-
|
|
22784
|
-
|
|
22785
|
-
|
|
22786
|
-
|
|
22787
|
-
|
|
22788
|
-
|
|
22758
|
+
const recentMessages = this.messages.slice(-50).map((m) => {
|
|
22759
|
+
const content = this.truncateContent(m.content);
|
|
22760
|
+
return {
|
|
22761
|
+
role: m.role,
|
|
22762
|
+
content,
|
|
22763
|
+
timestamp: m.timestamp,
|
|
22764
|
+
toolCalls: m.toolCalls
|
|
22765
|
+
};
|
|
22766
|
+
});
|
|
22767
|
+
if (this.currentStatus === "generating" && (this.partialContent || this.partialBlocks.length > 0)) {
|
|
22768
|
+
const blocks = this.buildPartialBlocks();
|
|
22769
|
+
if (blocks.length > 0) {
|
|
22789
22770
|
recentMessages.push({
|
|
22790
22771
|
role: "assistant",
|
|
22791
|
-
content:
|
|
22792
|
-
timestamp: Date.now()
|
|
22772
|
+
content: blocks,
|
|
22773
|
+
timestamp: Date.now(),
|
|
22774
|
+
toolCalls: this.turnToolCalls.length > 0 ? [...this.turnToolCalls] : void 0
|
|
22793
22775
|
});
|
|
22794
22776
|
}
|
|
22795
22777
|
}
|
|
@@ -23235,49 +23217,49 @@ var require_dist = __commonJS({
|
|
|
23235
23217
|
this.currentStatus = "idle";
|
|
23236
23218
|
}
|
|
23237
23219
|
}
|
|
23238
|
-
async sendPrompt(text) {
|
|
23220
|
+
async sendPrompt(text, contentBlocks) {
|
|
23239
23221
|
if (!this.connection || !this.sessionId) {
|
|
23240
23222
|
this.log.warn(`[${this.type}] Cannot send prompt: no active connection/session`);
|
|
23241
23223
|
return;
|
|
23242
23224
|
}
|
|
23225
|
+
let promptParts;
|
|
23226
|
+
if (contentBlocks && contentBlocks.length > 0) {
|
|
23227
|
+
promptParts = contentBlocks.map((b) => {
|
|
23228
|
+
if (b.type === "text") return { type: "text", text: b.text };
|
|
23229
|
+
if (b.type === "image") return { type: "image", data: b.data, mimeType: b.mimeType };
|
|
23230
|
+
if (b.type === "resource_link") return { type: "resource_link", uri: b.uri, name: b.name };
|
|
23231
|
+
if (b.type === "resource") return { type: "resource", resource: b.resource };
|
|
23232
|
+
return { type: "text", text: flattenContent([b]) };
|
|
23233
|
+
});
|
|
23234
|
+
} else {
|
|
23235
|
+
promptParts = [{ type: "text", text }];
|
|
23236
|
+
}
|
|
23243
23237
|
this.messages.push({
|
|
23244
23238
|
role: "user",
|
|
23245
|
-
content: text,
|
|
23239
|
+
content: contentBlocks && contentBlocks.length > 0 ? contentBlocks : text,
|
|
23246
23240
|
timestamp: Date.now()
|
|
23247
23241
|
});
|
|
23248
23242
|
this.currentStatus = "generating";
|
|
23249
23243
|
this.partialContent = "";
|
|
23244
|
+
this.partialBlocks = [];
|
|
23245
|
+
this.turnToolCalls = [];
|
|
23250
23246
|
this.detectStatusTransition();
|
|
23251
|
-
this.log.info(`[${this.type}] Sending prompt: "${text.slice(0, 100)}"`);
|
|
23247
|
+
this.log.info(`[${this.type}] Sending prompt: "${text.slice(0, 100)}" (${promptParts.length} parts)`);
|
|
23252
23248
|
try {
|
|
23253
23249
|
const result = await this.connection.prompt({
|
|
23254
23250
|
sessionId: this.sessionId,
|
|
23255
|
-
prompt:
|
|
23251
|
+
prompt: promptParts
|
|
23256
23252
|
});
|
|
23257
23253
|
if (result?.stopReason) {
|
|
23258
23254
|
this.stopReason = result.stopReason;
|
|
23259
23255
|
}
|
|
23260
|
-
this.log.info(`[${this.type}] Prompt completed: stopReason=${result?.stopReason} partialContent=${this.partialContent.length} chars`);
|
|
23261
|
-
|
|
23262
|
-
this.messages.push({
|
|
23263
|
-
role: "assistant",
|
|
23264
|
-
content: this.partialContent.trim(),
|
|
23265
|
-
timestamp: Date.now()
|
|
23266
|
-
});
|
|
23267
|
-
this.partialContent = "";
|
|
23268
|
-
}
|
|
23256
|
+
this.log.info(`[${this.type}] Prompt completed: stopReason=${result?.stopReason} partialContent=${this.partialContent.length} chars partialBlocks=${this.partialBlocks.length}`);
|
|
23257
|
+
this.finalizeAssistantMessage();
|
|
23269
23258
|
this.currentStatus = "idle";
|
|
23270
23259
|
this.detectStatusTransition();
|
|
23271
23260
|
} catch (e) {
|
|
23272
23261
|
this.log.warn(`[${this.type}] prompt error: ${e?.message}`);
|
|
23273
|
-
|
|
23274
|
-
this.messages.push({
|
|
23275
|
-
role: "assistant",
|
|
23276
|
-
content: this.partialContent.trim(),
|
|
23277
|
-
timestamp: Date.now()
|
|
23278
|
-
});
|
|
23279
|
-
this.partialContent = "";
|
|
23280
|
-
}
|
|
23262
|
+
this.finalizeAssistantMessage();
|
|
23281
23263
|
this.currentStatus = "idle";
|
|
23282
23264
|
this.detectStatusTransition();
|
|
23283
23265
|
}
|
|
@@ -23311,6 +23293,27 @@ var require_dist = __commonJS({
|
|
|
23311
23293
|
const content = update.content;
|
|
23312
23294
|
if (content?.type === "text" && content.text) {
|
|
23313
23295
|
this.partialContent += content.text;
|
|
23296
|
+
} else if (content?.type === "image") {
|
|
23297
|
+
this.partialBlocks.push({
|
|
23298
|
+
type: "image",
|
|
23299
|
+
data: content.data || "",
|
|
23300
|
+
mimeType: content.mimeType || "image/png",
|
|
23301
|
+
uri: content.uri
|
|
23302
|
+
});
|
|
23303
|
+
} else if (content?.type === "resource_link") {
|
|
23304
|
+
this.partialBlocks.push({
|
|
23305
|
+
type: "resource_link",
|
|
23306
|
+
uri: content.uri || "",
|
|
23307
|
+
name: content.name || "resource",
|
|
23308
|
+
title: content.title,
|
|
23309
|
+
mimeType: content.mimeType,
|
|
23310
|
+
size: content.size
|
|
23311
|
+
});
|
|
23312
|
+
} else if (content?.type === "resource") {
|
|
23313
|
+
this.partialBlocks.push({
|
|
23314
|
+
type: "resource",
|
|
23315
|
+
resource: content.resource
|
|
23316
|
+
});
|
|
23314
23317
|
}
|
|
23315
23318
|
this.currentStatus = "generating";
|
|
23316
23319
|
break;
|
|
@@ -23320,12 +23323,26 @@ var require_dist = __commonJS({
|
|
|
23320
23323
|
break;
|
|
23321
23324
|
}
|
|
23322
23325
|
case "tool_call": {
|
|
23326
|
+
const tcId = update.toolCallId || `tc_${Date.now()}`;
|
|
23327
|
+
const tcTitle = update.title || "unknown";
|
|
23328
|
+
const tcKind = update.kind;
|
|
23329
|
+
const tcStatus = this.mapToolCallStatus(update.status);
|
|
23323
23330
|
this.activeToolCalls.push({
|
|
23324
|
-
id:
|
|
23325
|
-
name:
|
|
23326
|
-
status:
|
|
23331
|
+
id: tcId,
|
|
23332
|
+
name: tcTitle,
|
|
23333
|
+
status: tcStatus,
|
|
23327
23334
|
input: update.rawInput ? typeof update.rawInput === "string" ? update.rawInput : JSON.stringify(update.rawInput) : void 0
|
|
23328
23335
|
});
|
|
23336
|
+
const acpStatus = update.status || "in_progress";
|
|
23337
|
+
this.turnToolCalls.push({
|
|
23338
|
+
toolCallId: tcId,
|
|
23339
|
+
title: tcTitle,
|
|
23340
|
+
kind: tcKind,
|
|
23341
|
+
status: acpStatus,
|
|
23342
|
+
rawInput: update.rawInput,
|
|
23343
|
+
content: this.convertToolCallContent(update.content),
|
|
23344
|
+
locations: update.locations
|
|
23345
|
+
});
|
|
23329
23346
|
break;
|
|
23330
23347
|
}
|
|
23331
23348
|
case "tool_call_update": {
|
|
@@ -23335,6 +23352,13 @@ var require_dist = __commonJS({
|
|
|
23335
23352
|
if (update.status) existing.status = this.mapToolCallStatus(update.status);
|
|
23336
23353
|
if (update.rawOutput) existing.output = typeof update.rawOutput === "string" ? update.rawOutput : JSON.stringify(update.rawOutput);
|
|
23337
23354
|
}
|
|
23355
|
+
const tcInfo = this.turnToolCalls.find((t) => t.toolCallId === toolCallId);
|
|
23356
|
+
if (tcInfo) {
|
|
23357
|
+
if (update.status) tcInfo.status = update.status;
|
|
23358
|
+
if (update.rawOutput) tcInfo.rawOutput = update.rawOutput;
|
|
23359
|
+
if (update.content) tcInfo.content = this.convertToolCallContent(update.content);
|
|
23360
|
+
if (update.locations) tcInfo.locations = update.locations;
|
|
23361
|
+
}
|
|
23338
23362
|
break;
|
|
23339
23363
|
}
|
|
23340
23364
|
case "current_mode_update": {
|
|
@@ -23427,6 +23451,62 @@ var require_dist = __commonJS({
|
|
|
23427
23451
|
return "running";
|
|
23428
23452
|
}
|
|
23429
23453
|
}
|
|
23454
|
+
// ─── Rich Content Helpers ────────────────────────────
|
|
23455
|
+
/** Truncate content for transport (text: 2000 chars, images preserved) */
|
|
23456
|
+
truncateContent(content) {
|
|
23457
|
+
if (typeof content === "string") {
|
|
23458
|
+
return content.length > 2e3 ? content.slice(0, 2e3) + "\n... (truncated)" : content;
|
|
23459
|
+
}
|
|
23460
|
+
return content.map((b) => {
|
|
23461
|
+
if (b.type === "text" && b.text.length > 2e3) {
|
|
23462
|
+
return { ...b, text: b.text.slice(0, 2e3) + "\n... (truncated)" };
|
|
23463
|
+
}
|
|
23464
|
+
return b;
|
|
23465
|
+
});
|
|
23466
|
+
}
|
|
23467
|
+
/** Build ContentBlock[] from current partial state */
|
|
23468
|
+
buildPartialBlocks() {
|
|
23469
|
+
const blocks = [];
|
|
23470
|
+
if (this.partialContent.trim()) {
|
|
23471
|
+
blocks.push({ type: "text", text: this.partialContent.trim() + "..." });
|
|
23472
|
+
}
|
|
23473
|
+
blocks.push(...this.partialBlocks);
|
|
23474
|
+
return blocks;
|
|
23475
|
+
}
|
|
23476
|
+
/** Finalize streaming content into an assistant message */
|
|
23477
|
+
finalizeAssistantMessage() {
|
|
23478
|
+
const blocks = this.buildPartialBlocks();
|
|
23479
|
+
const finalBlocks = blocks.map((b) => {
|
|
23480
|
+
if (b.type === "text" && b.text.endsWith("...")) {
|
|
23481
|
+
return { ...b, text: b.text.slice(0, -3) };
|
|
23482
|
+
}
|
|
23483
|
+
return b;
|
|
23484
|
+
}).filter((b) => b.type !== "text" || b.text.trim());
|
|
23485
|
+
if (finalBlocks.length > 0) {
|
|
23486
|
+
this.messages.push({
|
|
23487
|
+
role: "assistant",
|
|
23488
|
+
content: finalBlocks.length === 1 && finalBlocks[0].type === "text" ? finalBlocks[0].text : finalBlocks,
|
|
23489
|
+
timestamp: Date.now(),
|
|
23490
|
+
toolCalls: this.turnToolCalls.length > 0 ? [...this.turnToolCalls] : void 0
|
|
23491
|
+
});
|
|
23492
|
+
}
|
|
23493
|
+
this.partialContent = "";
|
|
23494
|
+
this.partialBlocks = [];
|
|
23495
|
+
this.turnToolCalls = [];
|
|
23496
|
+
}
|
|
23497
|
+
/** Convert ACP ToolCallContent[] to our ToolCallContent[] */
|
|
23498
|
+
convertToolCallContent(acpContent) {
|
|
23499
|
+
if (!acpContent || !Array.isArray(acpContent)) return void 0;
|
|
23500
|
+
return acpContent.map((c) => {
|
|
23501
|
+
if (c.type === "diff") {
|
|
23502
|
+
return { type: "diff", path: c.path || "", oldText: c.oldText, newText: c.newText || "" };
|
|
23503
|
+
}
|
|
23504
|
+
if (c.type === "terminal") {
|
|
23505
|
+
return { type: "terminal", terminalId: c.terminalId || "" };
|
|
23506
|
+
}
|
|
23507
|
+
return { type: "content", content: c.content || { type: "text", text: JSON.stringify(c) } };
|
|
23508
|
+
});
|
|
23509
|
+
}
|
|
23430
23510
|
// ─── status transition detect ────────────────────────────
|
|
23431
23511
|
detectStatusTransition() {
|
|
23432
23512
|
const now = Date.now();
|
|
@@ -23564,13 +23644,13 @@ ${installInfo}`
|
|
|
23564
23644
|
await acpInstance.setConfigOption("model", initialModel);
|
|
23565
23645
|
console.log(import_chalk4.default.green(` \u{1F916} Initial model set: ${initialModel}`));
|
|
23566
23646
|
} catch (e) {
|
|
23567
|
-
|
|
23647
|
+
LOG5.warn("CLI", `[ACP] Initial model set failed: ${e?.message}`);
|
|
23568
23648
|
}
|
|
23569
23649
|
}
|
|
23570
23650
|
try {
|
|
23571
23651
|
addCliHistory({ cliType: normalizedType, dir: resolvedDir, cliArgs });
|
|
23572
23652
|
} catch (e) {
|
|
23573
|
-
|
|
23653
|
+
LOG5.warn("CLI", `ACP history save failed: ${e?.message}`);
|
|
23574
23654
|
}
|
|
23575
23655
|
this.deps.onStatusChange();
|
|
23576
23656
|
return;
|
|
@@ -23625,7 +23705,7 @@ ${installInfo}`
|
|
|
23625
23705
|
try {
|
|
23626
23706
|
addCliHistory({ cliType, dir: resolvedDir, cliArgs });
|
|
23627
23707
|
} catch (e) {
|
|
23628
|
-
|
|
23708
|
+
LOG5.warn("CLI", `CLI history save failed: ${e?.message}`);
|
|
23629
23709
|
}
|
|
23630
23710
|
this.deps.onStatusChange();
|
|
23631
23711
|
}
|
|
@@ -23874,7 +23954,7 @@ ${installInfo}`
|
|
|
23874
23954
|
discoveryIntervalMs = 1e4;
|
|
23875
23955
|
_activeAgentType = null;
|
|
23876
23956
|
constructor(logFn, providerLoader) {
|
|
23877
|
-
this.logFn = logFn ||
|
|
23957
|
+
this.logFn = logFn || LOG5.forComponent("AgentStream").asLogFn();
|
|
23878
23958
|
if (providerLoader) {
|
|
23879
23959
|
const allExtProviders = providerLoader.getByCategory("extension");
|
|
23880
23960
|
for (const p of allExtProviders) {
|
|
@@ -24149,7 +24229,7 @@ ${installInfo}`
|
|
|
24149
24229
|
for (const extType of currentExtTypes) {
|
|
24150
24230
|
if (!enabledExtTypes.has(extType)) {
|
|
24151
24231
|
ideInstance.removeExtension(extType);
|
|
24152
|
-
|
|
24232
|
+
LOG5.info("AgentStream", `Extension removed: ${extType} (disabled for ${ideType})`);
|
|
24153
24233
|
}
|
|
24154
24234
|
}
|
|
24155
24235
|
for (const extType of enabledExtTypes) {
|
|
@@ -24158,7 +24238,7 @@ ${installInfo}`
|
|
|
24158
24238
|
if (extProvider) {
|
|
24159
24239
|
const extSettings = providerLoader.getSettings(extType);
|
|
24160
24240
|
ideInstance.addExtension(extProvider, extSettings);
|
|
24161
|
-
|
|
24241
|
+
LOG5.info("AgentStream", `Extension added: ${extType} (enabled for ${ideType})`);
|
|
24162
24242
|
}
|
|
24163
24243
|
}
|
|
24164
24244
|
}
|
|
@@ -24185,7 +24265,7 @@ ${installInfo}`
|
|
|
24185
24265
|
if (discovered.length > 0) {
|
|
24186
24266
|
this._activeIdeType = ideType;
|
|
24187
24267
|
await agentStreamManager.switchActiveAgent(cdp2, discovered[0].agentType);
|
|
24188
|
-
|
|
24268
|
+
LOG5.info("AgentStream", `Auto-activated: ${discovered[0].agentType} (${ideType})`);
|
|
24189
24269
|
await agentStreamManager.syncAgentSessions(cdp2);
|
|
24190
24270
|
const streams = await agentStreamManager.collectAgentStreams(cdp2);
|
|
24191
24271
|
this.deps.onStreamsUpdated?.(ideType, streams);
|
|
@@ -24209,7 +24289,7 @@ ${installInfo}`
|
|
|
24209
24289
|
*/
|
|
24210
24290
|
async addInstance(id, instance, context) {
|
|
24211
24291
|
if (this.instances.has(id)) {
|
|
24212
|
-
|
|
24292
|
+
LOG5.warn("InstanceMgr", `[InstanceManager] Instance ${id} already exists, disposing old one`);
|
|
24213
24293
|
this.instances.get(id).dispose();
|
|
24214
24294
|
}
|
|
24215
24295
|
this.instances.set(id, instance);
|
|
@@ -24260,7 +24340,7 @@ ${installInfo}`
|
|
|
24260
24340
|
}
|
|
24261
24341
|
}
|
|
24262
24342
|
} catch (e) {
|
|
24263
|
-
|
|
24343
|
+
LOG5.warn("InstanceMgr", `[InstanceManager] Failed to collect state from ${id}: ${e.message}`);
|
|
24264
24344
|
}
|
|
24265
24345
|
}
|
|
24266
24346
|
return states;
|
|
@@ -24283,7 +24363,7 @@ ${installInfo}`
|
|
|
24283
24363
|
try {
|
|
24284
24364
|
await instance.onTick();
|
|
24285
24365
|
} catch (e) {
|
|
24286
|
-
|
|
24366
|
+
LOG5.warn("InstanceMgr", `[InstanceManager] Tick failed for ${id}: ${e.message}`);
|
|
24287
24367
|
}
|
|
24288
24368
|
}
|
|
24289
24369
|
}, this.tickInterval);
|
|
@@ -24859,11 +24939,67 @@ async (params) => {
|
|
|
24859
24939
|
constructor(options) {
|
|
24860
24940
|
this.providerLoader = options.providerLoader;
|
|
24861
24941
|
this.cdpManagers = options.cdpManagers;
|
|
24862
|
-
this.logFn = options.logFn ||
|
|
24942
|
+
this.logFn = options.logFn || LOG5.forComponent("DevServer").asLogFn();
|
|
24863
24943
|
}
|
|
24864
24944
|
log(msg) {
|
|
24865
24945
|
this.logFn(`[DevServer] ${msg}`);
|
|
24866
24946
|
}
|
|
24947
|
+
// ─── Route Table ─────────────────────────────────────
|
|
24948
|
+
routes = [
|
|
24949
|
+
// Static routes
|
|
24950
|
+
{ method: "GET", pattern: "/api/providers", handler: (q, s) => this.handleListProviders(q, s) },
|
|
24951
|
+
{ method: "GET", pattern: "/api/providers/versions", handler: (q, s) => this.handleDetectVersions(q, s) },
|
|
24952
|
+
{ method: "POST", pattern: "/api/providers/reload", handler: (q, s) => this.handleReload(q, s) },
|
|
24953
|
+
{ method: "POST", pattern: "/api/cdp/evaluate", handler: (q, s) => this.handleCdpEvaluate(q, s) },
|
|
24954
|
+
{ method: "POST", pattern: "/api/cdp/dom/query", handler: (q, s) => this.handleCdpDomQuery(q, s) },
|
|
24955
|
+
{ method: "POST", pattern: "/api/cdp/dom/inspect", handler: (q, s) => this.handleDomInspect(q, s) },
|
|
24956
|
+
{ method: "POST", pattern: "/api/cdp/dom/children", handler: (q, s) => this.handleDomChildren(q, s) },
|
|
24957
|
+
{ method: "POST", pattern: "/api/cdp/dom/analyze", handler: (q, s) => this.handleDomAnalyze(q, s) },
|
|
24958
|
+
{ method: "POST", pattern: "/api/cdp/dom/find-text", handler: (q, s) => this.handleFindByText(q, s) },
|
|
24959
|
+
{ method: "POST", pattern: "/api/cdp/dom/find-common", handler: (q, s) => this.handleFindCommon(q, s) },
|
|
24960
|
+
{ method: "GET", pattern: "/api/cdp/screenshot", handler: (q, s) => this.handleScreenshot(q, s) },
|
|
24961
|
+
{ method: "GET", pattern: "/api/cdp/targets", handler: (q, s) => this.handleCdpTargets(q, s) },
|
|
24962
|
+
{ method: "POST", pattern: "/api/scripts/run", handler: (q, s) => this.handleScriptsRun(q, s) },
|
|
24963
|
+
{ method: "GET", pattern: "/api/status", handler: (q, s) => this.handleStatus(q, s) },
|
|
24964
|
+
{ method: "POST", pattern: "/api/watch/start", handler: (q, s) => this.handleWatchStart(q, s) },
|
|
24965
|
+
{ method: "POST", pattern: "/api/watch/stop", handler: (q, s) => this.handleWatchStop(q, s) },
|
|
24966
|
+
{ method: "GET", pattern: "/api/watch/events", handler: (q, s) => this.handleSSE(q, s) },
|
|
24967
|
+
{ method: "POST", pattern: "/api/scaffold", handler: (q, s) => this.handleScaffold(q, s) },
|
|
24968
|
+
// Dynamic routes (provider :type param)
|
|
24969
|
+
{ method: "POST", pattern: /^\/api\/providers\/([^/]+)\/script$/, handler: (q, s, p) => this.handleRunScript(p[0], q, s) },
|
|
24970
|
+
{ method: "GET", pattern: /^\/api\/providers\/([^/]+)\/files$/, handler: (q, s, p) => this.handleListFiles(p[0], q, s) },
|
|
24971
|
+
{ method: "GET", pattern: /^\/api\/providers\/([^/]+)\/file$/, handler: (q, s, p) => this.handleReadFile(p[0], q, s) },
|
|
24972
|
+
{ method: "POST", pattern: /^\/api\/providers\/([^/]+)\/file$/, handler: (q, s, p) => this.handleWriteFile(p[0], q, s) },
|
|
24973
|
+
{ method: "GET", pattern: /^\/api\/providers\/([^/]+)\/source$/, handler: (q, s, p) => this.handleSource(p[0], q, s) },
|
|
24974
|
+
{ method: "POST", pattern: /^\/api\/providers\/([^/]+)\/save$/, handler: (q, s, p) => this.handleSave(p[0], q, s) },
|
|
24975
|
+
{ method: "GET", pattern: /^\/api\/providers\/([^/]+)\/config$/, handler: (q, s, p) => this.handleProviderConfig(p[0], q, s) },
|
|
24976
|
+
{ method: "POST", pattern: /^\/api\/providers\/([^/]+)\/dom-context$/, handler: (q, s, p) => this.handleDomContext(p[0], q, s) },
|
|
24977
|
+
{ method: "POST", pattern: /^\/api\/providers\/([^/]+)\/auto-implement$/, handler: (q, s, p) => this.handleAutoImplement(p[0], q, s) },
|
|
24978
|
+
{ method: "POST", pattern: /^\/api\/providers\/([^/]+)\/auto-implement\/cancel$/, handler: (q, s, p) => this.handleAutoImplCancel(p[0], q, s) },
|
|
24979
|
+
{ method: "GET", pattern: /^\/api\/providers\/([^/]+)\/auto-implement\/status$/, handler: (q, s, p) => this.handleAutoImplSSE(p[0], q, s) },
|
|
24980
|
+
{ method: "POST", pattern: /^\/api\/providers\/([^/]+)\/spawn-test$/, handler: (q, s, p) => this.handleSpawnTest(p[0], q, s) },
|
|
24981
|
+
{ method: "POST", pattern: /^\/api\/providers\/([^/]+)\/validate$/, handler: (q, s, p) => this.handleValidate(p[0], q, s) },
|
|
24982
|
+
{ method: "POST", pattern: /^\/api\/providers\/([^/]+)\/acp-chat$/, handler: (q, s, p) => this.handleAcpChat(p[0], q, s) },
|
|
24983
|
+
{ method: "GET", pattern: /^\/api\/providers\/([^/]+)\/script-hints$/, handler: (q, s, p) => this.handleScriptHints(p[0], q, s) }
|
|
24984
|
+
];
|
|
24985
|
+
matchRoute(method, pathname) {
|
|
24986
|
+
for (const route of this.routes) {
|
|
24987
|
+
if (route.method !== method) continue;
|
|
24988
|
+
if (typeof route.pattern === "string") {
|
|
24989
|
+
if (pathname === route.pattern) return { handler: route.handler };
|
|
24990
|
+
} else {
|
|
24991
|
+
const m = pathname.match(route.pattern);
|
|
24992
|
+
if (m) return { handler: route.handler, params: m.slice(1) };
|
|
24993
|
+
}
|
|
24994
|
+
}
|
|
24995
|
+
return null;
|
|
24996
|
+
}
|
|
24997
|
+
getEndpointList() {
|
|
24998
|
+
return this.routes.map((r) => {
|
|
24999
|
+
const path10 = typeof r.pattern === "string" ? r.pattern : r.pattern.source.replace(/\\\//g, "/").replace(/\(\[.*?\]\+\)/g, ":type").replace(/[\^$]/g, "");
|
|
25000
|
+
return `${r.method.padEnd(5)} ${path10}`;
|
|
25001
|
+
});
|
|
25002
|
+
}
|
|
24867
25003
|
async start(port = DEV_SERVER_PORT) {
|
|
24868
25004
|
this.server = http2.createServer(async (req, res) => {
|
|
24869
25005
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
@@ -24877,112 +25013,15 @@ async (params) => {
|
|
|
24877
25013
|
const url2 = new URL(req.url || "/", `http://localhost:${port}`);
|
|
24878
25014
|
const pathname = url2.pathname;
|
|
24879
25015
|
try {
|
|
24880
|
-
|
|
24881
|
-
|
|
24882
|
-
|
|
24883
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/script$/)[1];
|
|
24884
|
-
await this.handleRunScript(type, req, res);
|
|
24885
|
-
} else if (pathname === "/api/cdp/evaluate" && req.method === "POST") {
|
|
24886
|
-
await this.handleCdpEvaluate(req, res);
|
|
24887
|
-
} else if (pathname === "/api/cdp/dom/query" && req.method === "POST") {
|
|
24888
|
-
await this.handleCdpDomQuery(req, res);
|
|
24889
|
-
} else if (pathname === "/api/cdp/screenshot" && req.method === "GET") {
|
|
24890
|
-
await this.handleScreenshot(req, res);
|
|
24891
|
-
} else if (pathname === "/api/scripts/run" && req.method === "POST") {
|
|
24892
|
-
await this.handleScriptsRun(req, res);
|
|
24893
|
-
} else if (pathname === "/api/status" && req.method === "GET") {
|
|
24894
|
-
await this.handleStatus(req, res);
|
|
24895
|
-
} else if (pathname === "/api/providers/reload" && req.method === "POST") {
|
|
24896
|
-
await this.handleReload(req, res);
|
|
24897
|
-
} else if (pathname === "/api/providers/versions" && req.method === "GET") {
|
|
24898
|
-
await this.handleDetectVersions(req, res);
|
|
24899
|
-
} else if (pathname === "/api/watch/start" && req.method === "POST") {
|
|
24900
|
-
await this.handleWatchStart(req, res);
|
|
24901
|
-
} else if (pathname === "/api/watch/stop" && req.method === "POST") {
|
|
24902
|
-
await this.handleWatchStop(req, res);
|
|
24903
|
-
} else if (pathname === "/api/watch/events" && req.method === "GET") {
|
|
24904
|
-
this.handleSSE(req, res);
|
|
24905
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/files$/) && req.method === "GET") {
|
|
24906
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/files$/)[1];
|
|
24907
|
-
await this.handleListFiles(type, req, res);
|
|
24908
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/file$/) && req.method === "GET") {
|
|
24909
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/file$/)[1];
|
|
24910
|
-
await this.handleReadFile(type, req, res);
|
|
24911
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/file$/) && req.method === "POST") {
|
|
24912
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/file$/)[1];
|
|
24913
|
-
await this.handleWriteFile(type, req, res);
|
|
24914
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/source$/) && req.method === "GET") {
|
|
24915
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/source$/)[1];
|
|
24916
|
-
await this.handleSource(type, req, res);
|
|
24917
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/save$/) && req.method === "POST") {
|
|
24918
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/save$/)[1];
|
|
24919
|
-
await this.handleSave(type, req, res);
|
|
24920
|
-
} else if (pathname === "/api/cdp/dom/inspect" && req.method === "POST") {
|
|
24921
|
-
await this.handleDomInspect(req, res);
|
|
24922
|
-
} else if (pathname === "/api/cdp/dom/children" && req.method === "POST") {
|
|
24923
|
-
await this.handleDomChildren(req, res);
|
|
24924
|
-
} else if (pathname === "/api/cdp/dom/analyze" && req.method === "POST") {
|
|
24925
|
-
await this.handleDomAnalyze(req, res);
|
|
24926
|
-
} else if (pathname === "/api/cdp/dom/find-text" && req.method === "POST") {
|
|
24927
|
-
await this.handleFindByText(req, res);
|
|
24928
|
-
} else if (pathname === "/api/cdp/dom/find-common" && req.method === "POST") {
|
|
24929
|
-
await this.handleFindCommon(req, res);
|
|
24930
|
-
} else if (pathname === "/api/cdp/targets" && req.method === "GET") {
|
|
24931
|
-
await this.handleCdpTargets(req, res);
|
|
24932
|
-
} else if (pathname === "/api/scaffold" && req.method === "POST") {
|
|
24933
|
-
await this.handleScaffold(req, res);
|
|
24934
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/dom-context$/) && req.method === "POST") {
|
|
24935
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/dom-context$/)[1];
|
|
24936
|
-
await this.handleDomContext(type, req, res);
|
|
24937
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/auto-implement$/) && req.method === "POST") {
|
|
24938
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/auto-implement$/)[1];
|
|
24939
|
-
await this.handleAutoImplement(type, req, res);
|
|
24940
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/auto-implement\/cancel$/) && req.method === "POST") {
|
|
24941
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/auto-implement\/cancel$/)[1];
|
|
24942
|
-
this.handleAutoImplCancel(type, req, res);
|
|
24943
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/auto-implement\/status$/) && req.method === "GET") {
|
|
24944
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/auto-implement\/status$/)[1];
|
|
24945
|
-
this.handleAutoImplSSE(type, req, res);
|
|
24946
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/config$/) && req.method === "GET") {
|
|
24947
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/config$/)[1];
|
|
24948
|
-
await this.handleProviderConfig(type, req, res);
|
|
24949
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/spawn-test$/) && req.method === "POST") {
|
|
24950
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/spawn-test$/)[1];
|
|
24951
|
-
await this.handleSpawnTest(type, req, res);
|
|
24952
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/validate$/) && req.method === "POST") {
|
|
24953
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/validate$/)[1];
|
|
24954
|
-
await this.handleValidate(type, req, res);
|
|
24955
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/acp-chat$/) && req.method === "POST") {
|
|
24956
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/acp-chat$/)[1];
|
|
24957
|
-
await this.handleAcpChat(type, req, res);
|
|
24958
|
-
} else if (pathname.match(/^\/api\/providers\/([^/]+)\/script-hints$/) && req.method === "GET") {
|
|
24959
|
-
const type = pathname.match(/^\/api\/providers\/([^/]+)\/script-hints$/)[1];
|
|
24960
|
-
await this.handleScriptHints(type, req, res);
|
|
25016
|
+
const route = this.matchRoute(req.method || "GET", pathname);
|
|
25017
|
+
if (route) {
|
|
25018
|
+
await route.handler(req, res, route.params);
|
|
24961
25019
|
} else if (pathname.startsWith("/assets/") || pathname === "/favicon.ico") {
|
|
24962
25020
|
await this.serveStaticAsset(pathname, res);
|
|
24963
25021
|
} else if (pathname === "/" || pathname === "/console" || !pathname.startsWith("/api")) {
|
|
24964
25022
|
await this.serveConsole(req, res);
|
|
24965
25023
|
} else {
|
|
24966
|
-
this.json(res, 404, {
|
|
24967
|
-
error: "Not found",
|
|
24968
|
-
endpoints: [
|
|
24969
|
-
"GET / \u2014 DevConsole web UI",
|
|
24970
|
-
"GET /api/providers",
|
|
24971
|
-
"POST /api/providers/:type/script",
|
|
24972
|
-
"GET /api/providers/:type/source",
|
|
24973
|
-
"POST /api/providers/:type/save",
|
|
24974
|
-
"POST /api/cdp/evaluate",
|
|
24975
|
-
"POST /api/cdp/dom/query",
|
|
24976
|
-
"GET /api/cdp/screenshot",
|
|
24977
|
-
"GET /api/cdp/targets",
|
|
24978
|
-
"GET /api/status",
|
|
24979
|
-
"POST /api/providers/reload",
|
|
24980
|
-
"POST /api/watch/start",
|
|
24981
|
-
"POST /api/watch/stop",
|
|
24982
|
-
"GET /api/watch/events (SSE)",
|
|
24983
|
-
"POST /api/scaffold"
|
|
24984
|
-
]
|
|
24985
|
-
});
|
|
25024
|
+
this.json(res, 404, { error: "Not found", endpoints: this.getEndpointList() });
|
|
24986
25025
|
}
|
|
24987
25026
|
} catch (e) {
|
|
24988
25027
|
this.log(`Error: ${e.message}`);
|
|
@@ -25249,7 +25288,7 @@ async (params) => {
|
|
|
25249
25288
|
const buf = await cdp2.captureScreenshot();
|
|
25250
25289
|
if (buf) {
|
|
25251
25290
|
res.writeHead(200, {
|
|
25252
|
-
"Content-Type": "image/
|
|
25291
|
+
"Content-Type": "image/webp",
|
|
25253
25292
|
"X-Viewport-Width": String(vpW),
|
|
25254
25293
|
"X-Viewport-Height": String(vpH)
|
|
25255
25294
|
});
|
|
@@ -27386,10 +27425,10 @@ data: ${JSON.stringify(msg.data)}
|
|
|
27386
27425
|
...config2.cliManagerDeps,
|
|
27387
27426
|
getInstanceManager: () => instanceManager
|
|
27388
27427
|
}, providerLoader);
|
|
27389
|
-
|
|
27428
|
+
LOG5.info("Init", "Detecting IDEs...");
|
|
27390
27429
|
detectedIdesRef.value = await detectIDEs3();
|
|
27391
27430
|
const installed = detectedIdesRef.value.filter((i) => i.installed);
|
|
27392
|
-
|
|
27431
|
+
LOG5.info("Init", `Found ${installed.length} IDE(s): ${installed.map((i) => i.id).join(", ") || "none"}`);
|
|
27393
27432
|
const cdpSetupContext = {
|
|
27394
27433
|
providerLoader,
|
|
27395
27434
|
instanceManager,
|
|
@@ -27417,7 +27456,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
27417
27456
|
instanceIdMap
|
|
27418
27457
|
});
|
|
27419
27458
|
const agentStreamManager = new DaemonAgentStreamManager(
|
|
27420
|
-
|
|
27459
|
+
LOG5.forComponent("AgentStream").asLogFn(),
|
|
27421
27460
|
providerLoader
|
|
27422
27461
|
);
|
|
27423
27462
|
commandHandler.setAgentStreamManager(agentStreamManager);
|
|
@@ -27437,7 +27476,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
27437
27476
|
onIdeConnected: () => poller?.start(),
|
|
27438
27477
|
onStatusChange: config2.onStatusChange,
|
|
27439
27478
|
onPostChatCommand: config2.onPostChatCommand,
|
|
27440
|
-
getCdpLogFn: config2.getCdpLogFn || ((ideType) =>
|
|
27479
|
+
getCdpLogFn: config2.getCdpLogFn || ((ideType) => LOG5.forComponent(`CDP:${ideType}`).asLogFn())
|
|
27441
27480
|
});
|
|
27442
27481
|
poller = new AgentStreamPoller({
|
|
27443
27482
|
agentStreamManager,
|
|
@@ -27479,7 +27518,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
27479
27518
|
await agentStreamManager.dispose(anyCdp);
|
|
27480
27519
|
}
|
|
27481
27520
|
} catch (e) {
|
|
27482
|
-
|
|
27521
|
+
LOG5.warn("Shutdown", `AgentStream dispose: ${e?.message}`);
|
|
27483
27522
|
}
|
|
27484
27523
|
try {
|
|
27485
27524
|
await cliManager.shutdownAll();
|
|
@@ -28461,6 +28500,161 @@ var init_daemon_p2p = __esm({
|
|
|
28461
28500
|
}
|
|
28462
28501
|
});
|
|
28463
28502
|
|
|
28503
|
+
// src/screenshot-controller.ts
|
|
28504
|
+
var import_daemon_core3, ScreenshotController;
|
|
28505
|
+
var init_screenshot_controller = __esm({
|
|
28506
|
+
"src/screenshot-controller.ts"() {
|
|
28507
|
+
"use strict";
|
|
28508
|
+
import_daemon_core3 = __toESM(require_dist());
|
|
28509
|
+
ScreenshotController = class _ScreenshotController {
|
|
28510
|
+
deps;
|
|
28511
|
+
timer = null;
|
|
28512
|
+
// Delta detection state
|
|
28513
|
+
debugCount = 0;
|
|
28514
|
+
lastSize = 0;
|
|
28515
|
+
lastHash = 0;
|
|
28516
|
+
staticFrameCount = 0;
|
|
28517
|
+
currentInterval;
|
|
28518
|
+
// Quality profiles
|
|
28519
|
+
profileDirect;
|
|
28520
|
+
profileRelay;
|
|
28521
|
+
STATIC_THRESHOLD = 3;
|
|
28522
|
+
// Daily budget state
|
|
28523
|
+
dailyBudgetMinutes;
|
|
28524
|
+
dailyBudgetMs;
|
|
28525
|
+
dailyUsedMs = 0;
|
|
28526
|
+
lastActiveTimestamp = 0;
|
|
28527
|
+
budgetDate;
|
|
28528
|
+
budgetExhausted = false;
|
|
28529
|
+
constructor(deps, planLimits) {
|
|
28530
|
+
this.deps = deps;
|
|
28531
|
+
const planMinIntervalMs = (planLimits?.screenshotIntervalSeconds ?? 0) * 1e3;
|
|
28532
|
+
this.profileDirect = {
|
|
28533
|
+
minInterval: Math.max(300, planMinIntervalMs),
|
|
28534
|
+
maxInterval: Math.max(2e3, planMinIntervalMs),
|
|
28535
|
+
quality: 25
|
|
28536
|
+
};
|
|
28537
|
+
this.profileRelay = {
|
|
28538
|
+
minInterval: Math.max(700, planMinIntervalMs),
|
|
28539
|
+
maxInterval: Math.max(3e3, planMinIntervalMs),
|
|
28540
|
+
quality: 12
|
|
28541
|
+
};
|
|
28542
|
+
this.currentInterval = this.profileDirect.maxInterval;
|
|
28543
|
+
this.dailyBudgetMinutes = planLimits?.dailyScreenshotMinutes ?? -1;
|
|
28544
|
+
this.dailyBudgetMs = this.dailyBudgetMinutes > 0 ? this.dailyBudgetMinutes * 6e4 : -1;
|
|
28545
|
+
this.budgetDate = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
28546
|
+
if (planMinIntervalMs > 0) {
|
|
28547
|
+
import_daemon_core3.LOG.info("Screenshot", `Plan limit: min interval ${planMinIntervalMs}ms (${planLimits?.screenshotIntervalSeconds}s)`);
|
|
28548
|
+
}
|
|
28549
|
+
if (this.dailyBudgetMs > 0) {
|
|
28550
|
+
import_daemon_core3.LOG.info("Screenshot", `Daily budget: ${this.dailyBudgetMinutes}min/day`);
|
|
28551
|
+
}
|
|
28552
|
+
}
|
|
28553
|
+
// ─── Lifecycle ────────────────────────────────
|
|
28554
|
+
start() {
|
|
28555
|
+
if (this.timer) return;
|
|
28556
|
+
this.timer = setTimeout(() => this.tick(), 1e3);
|
|
28557
|
+
}
|
|
28558
|
+
stop() {
|
|
28559
|
+
if (this.timer) {
|
|
28560
|
+
clearTimeout(this.timer);
|
|
28561
|
+
this.timer = null;
|
|
28562
|
+
}
|
|
28563
|
+
}
|
|
28564
|
+
// ─── Core loop ────────────────────────────────
|
|
28565
|
+
async tick() {
|
|
28566
|
+
if (!this.deps.isRunning()) return;
|
|
28567
|
+
const active = this.deps.isScreenshotActive();
|
|
28568
|
+
const ssIdeType = this.deps.getScreenshotIdeType();
|
|
28569
|
+
const cdp2 = this.deps.getCdp(ssIdeType);
|
|
28570
|
+
const isRelay = this.deps.isUsingRelay();
|
|
28571
|
+
const profile = isRelay ? this.profileRelay : this.profileDirect;
|
|
28572
|
+
this.checkBudgetReset();
|
|
28573
|
+
if (this.dailyBudgetMs > 0) {
|
|
28574
|
+
const now = Date.now();
|
|
28575
|
+
if (active && this.lastActiveTimestamp > 0) {
|
|
28576
|
+
this.dailyUsedMs += now - this.lastActiveTimestamp;
|
|
28577
|
+
}
|
|
28578
|
+
this.lastActiveTimestamp = active ? now : 0;
|
|
28579
|
+
if (this.dailyUsedMs >= this.dailyBudgetMs && !this.budgetExhausted) {
|
|
28580
|
+
this.budgetExhausted = true;
|
|
28581
|
+
const usedMin = Math.round(this.dailyUsedMs / 6e4);
|
|
28582
|
+
import_daemon_core3.LOG.info("Screenshot", `Daily budget exhausted: ${usedMin}/${this.dailyBudgetMinutes}min \u2014 pausing until midnight UTC`);
|
|
28583
|
+
}
|
|
28584
|
+
}
|
|
28585
|
+
if (!active || !cdp2 || this.budgetExhausted) {
|
|
28586
|
+
this.staticFrameCount = 0;
|
|
28587
|
+
this.currentInterval = profile.maxInterval;
|
|
28588
|
+
if (!active) this.lastActiveTimestamp = 0;
|
|
28589
|
+
this.timer = setTimeout(() => this.tick(), this.budgetExhausted ? 3e4 : this.currentInterval);
|
|
28590
|
+
return;
|
|
28591
|
+
}
|
|
28592
|
+
this.debugCount++;
|
|
28593
|
+
try {
|
|
28594
|
+
const buf = await cdp2.captureScreenshot({ quality: profile.quality });
|
|
28595
|
+
if (buf) {
|
|
28596
|
+
const hash2 = _ScreenshotController.fnvHash(buf);
|
|
28597
|
+
const sizeMatch = buf.length === this.lastSize;
|
|
28598
|
+
const hashMatch = hash2 === this.lastHash;
|
|
28599
|
+
const anyNeedsFirstFrame = this.deps.hasAnyNeedingFirstFrame();
|
|
28600
|
+
if (sizeMatch && hashMatch && !anyNeedsFirstFrame) {
|
|
28601
|
+
this.staticFrameCount++;
|
|
28602
|
+
if (this.staticFrameCount >= this.STATIC_THRESHOLD) {
|
|
28603
|
+
this.currentInterval = Math.min(this.currentInterval + 200, profile.maxInterval);
|
|
28604
|
+
}
|
|
28605
|
+
if (this.debugCount <= 5 || this.debugCount % 50 === 0) {
|
|
28606
|
+
import_daemon_core3.LOG.debug("Screenshot", `skip (unchanged, static=${this.staticFrameCount}, interval=${this.currentInterval}ms, ${isRelay ? "RELAY" : "DIRECT"})`);
|
|
28607
|
+
}
|
|
28608
|
+
} else {
|
|
28609
|
+
this.lastSize = buf.length;
|
|
28610
|
+
this.lastHash = hash2;
|
|
28611
|
+
this.staticFrameCount = 0;
|
|
28612
|
+
this.currentInterval = profile.minInterval;
|
|
28613
|
+
const sent = this.deps.sendScreenshotBuffer(buf);
|
|
28614
|
+
if (this.debugCount <= 3 || anyNeedsFirstFrame) {
|
|
28615
|
+
import_daemon_core3.LOG.debug("Screenshot", `sent: ${buf.length} bytes, delivered=${sent}, interval=${this.currentInterval}ms, ${isRelay ? "RELAY" : "DIRECT"}${anyNeedsFirstFrame ? " (first-frame)" : ""}`);
|
|
28616
|
+
}
|
|
28617
|
+
}
|
|
28618
|
+
} else {
|
|
28619
|
+
if (this.debugCount <= 5) import_daemon_core3.LOG.debug("Screenshot", "captureScreenshot returned null");
|
|
28620
|
+
}
|
|
28621
|
+
} catch (e) {
|
|
28622
|
+
if (this.debugCount <= 5) import_daemon_core3.LOG.warn("Screenshot", `error: ${e?.message}`);
|
|
28623
|
+
}
|
|
28624
|
+
this.timer = setTimeout(() => this.tick(), this.currentInterval);
|
|
28625
|
+
}
|
|
28626
|
+
// ─── Budget ───────────────────────────────────
|
|
28627
|
+
checkBudgetReset() {
|
|
28628
|
+
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
28629
|
+
if (today !== this.budgetDate) {
|
|
28630
|
+
this.dailyUsedMs = 0;
|
|
28631
|
+
this.budgetDate = today;
|
|
28632
|
+
this.budgetExhausted = false;
|
|
28633
|
+
import_daemon_core3.LOG.info("Screenshot", `Daily budget reset (${this.dailyBudgetMinutes}min for today)`);
|
|
28634
|
+
}
|
|
28635
|
+
}
|
|
28636
|
+
// ─── Hash ─────────────────────────────────────
|
|
28637
|
+
/** FNV-1a hash of first 1KB + last 1KB for fast delta detection */
|
|
28638
|
+
static fnvHash(buf) {
|
|
28639
|
+
let h = 2166136261;
|
|
28640
|
+
const sampleEnd = Math.min(1024, buf.length);
|
|
28641
|
+
for (let i = 0; i < sampleEnd; i++) {
|
|
28642
|
+
h ^= buf[i];
|
|
28643
|
+
h = h * 16777619 >>> 0;
|
|
28644
|
+
}
|
|
28645
|
+
if (buf.length > 1024) {
|
|
28646
|
+
const start = Math.max(0, buf.length - 1024);
|
|
28647
|
+
for (let i = start; i < buf.length; i++) {
|
|
28648
|
+
h ^= buf[i];
|
|
28649
|
+
h = h * 16777619 >>> 0;
|
|
28650
|
+
}
|
|
28651
|
+
}
|
|
28652
|
+
return h;
|
|
28653
|
+
}
|
|
28654
|
+
};
|
|
28655
|
+
}
|
|
28656
|
+
});
|
|
28657
|
+
|
|
28464
28658
|
// src/adhdev-daemon.ts
|
|
28465
28659
|
var adhdev_daemon_exports = {};
|
|
28466
28660
|
__export(adhdev_daemon_exports, {
|
|
@@ -28507,13 +28701,14 @@ function stopDaemon() {
|
|
|
28507
28701
|
return false;
|
|
28508
28702
|
}
|
|
28509
28703
|
}
|
|
28510
|
-
var
|
|
28704
|
+
var import_daemon_core4, os2, fs2, path2, crypto2, import_chalk, pkgVersion, DANGEROUS_PATTERNS, AdhdevDaemon;
|
|
28511
28705
|
var init_adhdev_daemon = __esm({
|
|
28512
28706
|
"src/adhdev-daemon.ts"() {
|
|
28513
28707
|
"use strict";
|
|
28514
28708
|
init_server_connection();
|
|
28515
|
-
|
|
28709
|
+
import_daemon_core4 = __toESM(require_dist());
|
|
28516
28710
|
init_daemon_p2p();
|
|
28711
|
+
init_screenshot_controller();
|
|
28517
28712
|
os2 = __toESM(require("os"));
|
|
28518
28713
|
fs2 = __toESM(require("fs"));
|
|
28519
28714
|
path2 = __toESM(require("path"));
|
|
@@ -28552,7 +28747,7 @@ var init_adhdev_daemon = __esm({
|
|
|
28552
28747
|
AdhdevDaemon = class {
|
|
28553
28748
|
serverConn = null;
|
|
28554
28749
|
p2p = null;
|
|
28555
|
-
|
|
28750
|
+
screenshotController = null;
|
|
28556
28751
|
statusReporter = null;
|
|
28557
28752
|
components = null;
|
|
28558
28753
|
running = false;
|
|
@@ -28567,7 +28762,7 @@ var init_adhdev_daemon = __esm({
|
|
|
28567
28762
|
installGlobalInterceptor();
|
|
28568
28763
|
} catch {
|
|
28569
28764
|
}
|
|
28570
|
-
this.localPort = options.localPort ||
|
|
28765
|
+
this.localPort = options.localPort || import_daemon_core4.DEFAULT_DAEMON_PORT;
|
|
28571
28766
|
const workingDir = options.workingDir || process.cwd();
|
|
28572
28767
|
if (isDaemonRunning()) {
|
|
28573
28768
|
console.log(import_chalk.default.yellow("\n\u26A0 ADHDev Daemon is already running."));
|
|
@@ -28576,14 +28771,14 @@ var init_adhdev_daemon = __esm({
|
|
|
28576
28771
|
return;
|
|
28577
28772
|
}
|
|
28578
28773
|
writeDaemonPid(process.pid);
|
|
28579
|
-
const config2 = (0,
|
|
28774
|
+
const config2 = (0, import_daemon_core4.loadConfig)();
|
|
28580
28775
|
if (!config2.connectionToken) {
|
|
28581
28776
|
console.log(import_chalk.default.red("\n\u2717 No connection token found."));
|
|
28582
28777
|
console.log(import_chalk.default.gray(" Run `adhdev setup` first.\n"));
|
|
28583
28778
|
process.exit(1);
|
|
28584
28779
|
}
|
|
28585
|
-
this.components = await (0,
|
|
28586
|
-
providerLogFn:
|
|
28780
|
+
this.components = await (0, import_daemon_core4.initDaemonComponents)({
|
|
28781
|
+
providerLogFn: import_daemon_core4.LOG.forComponent("Provider").asLogFn(),
|
|
28587
28782
|
cliManagerDeps: {
|
|
28588
28783
|
getServerConn: () => this.serverConn,
|
|
28589
28784
|
getP2p: () => this.p2p,
|
|
@@ -28596,7 +28791,7 @@ var init_adhdev_daemon = __esm({
|
|
|
28596
28791
|
setTimeout(() => this.statusReporter?.throttledReport(), 1e3);
|
|
28597
28792
|
setTimeout(() => this.statusReporter?.throttledReport(), 3e3);
|
|
28598
28793
|
},
|
|
28599
|
-
getCdpLogFn: (ideType) =>
|
|
28794
|
+
getCdpLogFn: (ideType) => import_daemon_core4.LOG.forComponent(`CDP:${ideType}`).asLogFn(),
|
|
28600
28795
|
onCdpManagerSetup: (ideType) => {
|
|
28601
28796
|
if (this.ideType === "unknown") this.ideType = ideType;
|
|
28602
28797
|
},
|
|
@@ -28604,11 +28799,11 @@ var init_adhdev_daemon = __esm({
|
|
|
28604
28799
|
this.statusReporter?.updateAgentStreams(ideType, streams);
|
|
28605
28800
|
}
|
|
28606
28801
|
});
|
|
28607
|
-
const versionArchive = new
|
|
28608
|
-
(0,
|
|
28802
|
+
const versionArchive = new import_daemon_core4.VersionArchive();
|
|
28803
|
+
(0, import_daemon_core4.detectAllVersions)(this.components.providerLoader, versionArchive).then((results) => {
|
|
28609
28804
|
this.components.providerLoader.setVersionArchive(versionArchive);
|
|
28610
28805
|
for (const info of results) {
|
|
28611
|
-
if (info.warning)
|
|
28806
|
+
if (info.warning) import_daemon_core4.LOG.warn("Provider", `\u26A0 [${info.name}] ${info.warning}`);
|
|
28612
28807
|
}
|
|
28613
28808
|
}).catch(() => {
|
|
28614
28809
|
});
|
|
@@ -28616,7 +28811,7 @@ var init_adhdev_daemon = __esm({
|
|
|
28616
28811
|
if (updated) {
|
|
28617
28812
|
this.components.providerLoader.reload();
|
|
28618
28813
|
this.components.providerLoader.registerToDetector();
|
|
28619
|
-
|
|
28814
|
+
import_daemon_core4.LOG.info("Provider", "Providers auto-updated from upstream");
|
|
28620
28815
|
}
|
|
28621
28816
|
}).catch(() => {
|
|
28622
28817
|
});
|
|
@@ -28669,99 +28864,25 @@ var init_adhdev_daemon = __esm({
|
|
|
28669
28864
|
});
|
|
28670
28865
|
this.p2p.onStateChange((state) => {
|
|
28671
28866
|
if (state === "connected") {
|
|
28672
|
-
|
|
28673
|
-
this.statusReporter?.sendUnifiedStatusReport().catch((e) =>
|
|
28867
|
+
import_daemon_core4.LOG.info("P2P", "Peer connected \u2192 sending immediate full status report");
|
|
28868
|
+
this.statusReporter?.sendUnifiedStatusReport().catch((e) => import_daemon_core4.LOG.warn("P2P", `Immediate status report failed: ${e?.message}`));
|
|
28674
28869
|
setTimeout(() => {
|
|
28675
28870
|
this.statusReporter?.sendUnifiedStatusReport().catch(() => {
|
|
28676
28871
|
});
|
|
28677
28872
|
}, 2e3);
|
|
28678
28873
|
}
|
|
28679
28874
|
});
|
|
28680
|
-
let ssDebugCount = 0;
|
|
28681
|
-
let lastScreenshotSize = 0;
|
|
28682
|
-
let lastScreenshotHash = 0;
|
|
28683
|
-
let staticFrameCount = 0;
|
|
28684
28875
|
const planLimits = this.serverConn.getPlanLimits();
|
|
28685
|
-
|
|
28686
|
-
|
|
28687
|
-
|
|
28688
|
-
|
|
28689
|
-
|
|
28690
|
-
|
|
28691
|
-
|
|
28692
|
-
|
|
28693
|
-
|
|
28694
|
-
|
|
28695
|
-
};
|
|
28696
|
-
let currentInterval = PROFILE_DIRECT.maxInterval;
|
|
28697
|
-
const STATIC_THRESHOLD = 3;
|
|
28698
|
-
if (planMinIntervalMs > 0) {
|
|
28699
|
-
import_daemon_core3.LOG.info("Screenshot", `Plan limit: min interval ${planMinIntervalMs}ms (${planLimits?.screenshotIntervalSeconds}s)`);
|
|
28700
|
-
}
|
|
28701
|
-
const fnvHash = (buf) => {
|
|
28702
|
-
let h = 2166136261;
|
|
28703
|
-
const sampleEnd = Math.min(1024, buf.length);
|
|
28704
|
-
for (let i = 0; i < sampleEnd; i++) {
|
|
28705
|
-
h ^= buf[i];
|
|
28706
|
-
h = h * 16777619 >>> 0;
|
|
28707
|
-
}
|
|
28708
|
-
if (buf.length > 1024) {
|
|
28709
|
-
const start = Math.max(0, buf.length - 1024);
|
|
28710
|
-
for (let i = start; i < buf.length; i++) {
|
|
28711
|
-
h ^= buf[i];
|
|
28712
|
-
h = h * 16777619 >>> 0;
|
|
28713
|
-
}
|
|
28714
|
-
}
|
|
28715
|
-
return h;
|
|
28716
|
-
};
|
|
28717
|
-
const screenshotTick = async () => {
|
|
28718
|
-
if (!this.running) return;
|
|
28719
|
-
const active = this.p2p?.screenshotActive;
|
|
28720
|
-
const ssIdeType = this.p2p?.screenshotIdeType;
|
|
28721
|
-
const cdp2 = (ssIdeType ? this.getCdpFor(ssIdeType) : null) || this.getAnyCdp();
|
|
28722
|
-
const isRelay = this.p2p?.isUsingRelay ?? false;
|
|
28723
|
-
const profile = isRelay ? PROFILE_RELAY : PROFILE_DIRECT;
|
|
28724
|
-
if (!active || !cdp2) {
|
|
28725
|
-
staticFrameCount = 0;
|
|
28726
|
-
currentInterval = profile.maxInterval;
|
|
28727
|
-
this.screenshotTimer = setTimeout(screenshotTick, currentInterval);
|
|
28728
|
-
return;
|
|
28729
|
-
}
|
|
28730
|
-
ssDebugCount++;
|
|
28731
|
-
try {
|
|
28732
|
-
const buf = await cdp2.captureScreenshot({ quality: profile.quality });
|
|
28733
|
-
if (buf) {
|
|
28734
|
-
const hash2 = fnvHash(buf);
|
|
28735
|
-
const sizeMatch = buf.length === lastScreenshotSize;
|
|
28736
|
-
const hashMatch = hash2 === lastScreenshotHash;
|
|
28737
|
-
const anyNeedsFirstFrame = this.p2p.hasAnyNeedingFirstFrame();
|
|
28738
|
-
if (sizeMatch && hashMatch && !anyNeedsFirstFrame) {
|
|
28739
|
-
staticFrameCount++;
|
|
28740
|
-
if (staticFrameCount >= STATIC_THRESHOLD) {
|
|
28741
|
-
currentInterval = Math.min(currentInterval + 200, profile.maxInterval);
|
|
28742
|
-
}
|
|
28743
|
-
if (ssDebugCount <= 5 || ssDebugCount % 50 === 0) {
|
|
28744
|
-
import_daemon_core3.LOG.debug("Screenshot", `skip (unchanged, static=${staticFrameCount}, interval=${currentInterval}ms, ${isRelay ? "RELAY" : "DIRECT"})`);
|
|
28745
|
-
}
|
|
28746
|
-
} else {
|
|
28747
|
-
lastScreenshotSize = buf.length;
|
|
28748
|
-
lastScreenshotHash = hash2;
|
|
28749
|
-
staticFrameCount = 0;
|
|
28750
|
-
currentInterval = profile.minInterval;
|
|
28751
|
-
const sent = this.p2p.sendScreenshotBuffer(buf);
|
|
28752
|
-
if (ssDebugCount <= 3 || anyNeedsFirstFrame) {
|
|
28753
|
-
import_daemon_core3.LOG.debug("Screenshot", `sent: ${buf.length} bytes, delivered=${sent}, interval=${currentInterval}ms, ${isRelay ? "RELAY" : "DIRECT"}${anyNeedsFirstFrame ? " (first-frame)" : ""}`);
|
|
28754
|
-
}
|
|
28755
|
-
}
|
|
28756
|
-
} else {
|
|
28757
|
-
if (ssDebugCount <= 5) import_daemon_core3.LOG.debug("Screenshot", "captureScreenshot returned null");
|
|
28758
|
-
}
|
|
28759
|
-
} catch (e) {
|
|
28760
|
-
if (ssDebugCount <= 5) import_daemon_core3.LOG.warn("Screenshot", `error: ${e?.message}`);
|
|
28761
|
-
}
|
|
28762
|
-
this.screenshotTimer = setTimeout(screenshotTick, currentInterval);
|
|
28763
|
-
};
|
|
28764
|
-
this.screenshotTimer = setTimeout(screenshotTick, 1e3);
|
|
28876
|
+
this.screenshotController = new ScreenshotController({
|
|
28877
|
+
isRunning: () => this.running,
|
|
28878
|
+
isScreenshotActive: () => this.p2p?.screenshotActive ?? false,
|
|
28879
|
+
getScreenshotIdeType: () => this.p2p?.screenshotIdeType,
|
|
28880
|
+
isUsingRelay: () => this.p2p?.isUsingRelay ?? false,
|
|
28881
|
+
hasAnyNeedingFirstFrame: () => this.p2p?.hasAnyNeedingFirstFrame() ?? false,
|
|
28882
|
+
getCdp: (ideType) => (ideType ? this.getCdpFor(ideType) : null) || this.getAnyCdp(),
|
|
28883
|
+
sendScreenshotBuffer: (buf) => this.p2p.sendScreenshotBuffer(buf)
|
|
28884
|
+
}, planLimits ?? void 0);
|
|
28885
|
+
this.screenshotController.start();
|
|
28765
28886
|
} else {
|
|
28766
28887
|
console.log(import_chalk.default.gray(" \u26A0 P2P unavailable \u2014 using server relay"));
|
|
28767
28888
|
}
|
|
@@ -28775,7 +28896,7 @@ var init_adhdev_daemon = __esm({
|
|
|
28775
28896
|
}
|
|
28776
28897
|
});
|
|
28777
28898
|
await this.serverConn.connect();
|
|
28778
|
-
this.statusReporter = new
|
|
28899
|
+
this.statusReporter = new import_daemon_core4.DaemonStatusReporter({
|
|
28779
28900
|
serverConn: this.serverConn,
|
|
28780
28901
|
cdpManagers: this.components.cdpManagers,
|
|
28781
28902
|
p2p: this.p2p,
|
|
@@ -28793,7 +28914,7 @@ var init_adhdev_daemon = __esm({
|
|
|
28793
28914
|
process.on("SIGINT", () => this.stop());
|
|
28794
28915
|
process.on("SIGTERM", () => this.stop());
|
|
28795
28916
|
if (options.dev) {
|
|
28796
|
-
const devServer = new
|
|
28917
|
+
const devServer = new import_daemon_core4.DevServer({ providerLoader: this.components.providerLoader, cdpManagers: this.components.cdpManagers });
|
|
28797
28918
|
await devServer.start();
|
|
28798
28919
|
}
|
|
28799
28920
|
this.printBanner(options, config2.serverUrl);
|
|
@@ -28906,7 +29027,7 @@ var init_adhdev_daemon = __esm({
|
|
|
28906
29027
|
}
|
|
28907
29028
|
}
|
|
28908
29029
|
async handleCommand(msg, cmd, args) {
|
|
28909
|
-
|
|
29030
|
+
import_daemon_core4.LOG.info("Command", `${cmd}${args?._targetInstance ? ` \u2192 ${args._targetType}:${args._targetInstance.split("_")[0]}` : ""}`);
|
|
28910
29031
|
const cmdStart = Date.now();
|
|
28911
29032
|
const source = msg.ipcWs ? "ext" : "ws";
|
|
28912
29033
|
try {
|
|
@@ -28914,7 +29035,7 @@ var init_adhdev_daemon = __esm({
|
|
|
28914
29035
|
const cmdStr = args?.command;
|
|
28915
29036
|
if (!cmdStr) throw new Error("Command string required");
|
|
28916
29037
|
if (DANGEROUS_PATTERNS.some((p) => p.test(cmdStr))) {
|
|
28917
|
-
(0,
|
|
29038
|
+
(0, import_daemon_core4.logCommand)({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source, args, success: false, error: "Blocked", durationMs: Date.now() - cmdStart });
|
|
28918
29039
|
this.sendResult(msg, false, { error: `Blocked: "${cmdStr}"` });
|
|
28919
29040
|
return;
|
|
28920
29041
|
}
|
|
@@ -28928,7 +29049,7 @@ var init_adhdev_daemon = __esm({
|
|
|
28928
29049
|
if (stderr) this.serverConn.sendMessage("log", { message: stderr.slice(0, 5e3), level: "warn" });
|
|
28929
29050
|
}
|
|
28930
29051
|
});
|
|
28931
|
-
(0,
|
|
29052
|
+
(0, import_daemon_core4.logCommand)({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd, source, args, success: true, durationMs: Date.now() - cmdStart });
|
|
28932
29053
|
this.sendResult(msg, true, { started: true });
|
|
28933
29054
|
return;
|
|
28934
29055
|
}
|
|
@@ -28945,16 +29066,16 @@ var init_adhdev_daemon = __esm({
|
|
|
28945
29066
|
try {
|
|
28946
29067
|
switch (cmdType) {
|
|
28947
29068
|
case "get_cli_history": {
|
|
28948
|
-
const config2 = (0,
|
|
28949
|
-
(0,
|
|
29069
|
+
const config2 = (0, import_daemon_core4.loadConfig)();
|
|
29070
|
+
(0, import_daemon_core4.logCommand)({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd: cmdType, source: "p2p", success: true, durationMs: Date.now() - cmdStart });
|
|
28950
29071
|
return { success: true, history: config2.cliHistory || [] };
|
|
28951
29072
|
}
|
|
28952
29073
|
case "set_machine_nickname": {
|
|
28953
29074
|
const nickname = data.nickname?.trim() || null;
|
|
28954
|
-
const config2 = (0,
|
|
29075
|
+
const config2 = (0, import_daemon_core4.loadConfig)();
|
|
28955
29076
|
config2.machineNickname = nickname;
|
|
28956
|
-
(0,
|
|
28957
|
-
(0,
|
|
29077
|
+
(0, import_daemon_core4.saveConfig)(config2);
|
|
29078
|
+
(0, import_daemon_core4.logCommand)({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd: cmdType, source: "p2p", args: { nickname }, success: true, durationMs: Date.now() - cmdStart });
|
|
28958
29079
|
return { success: true, nickname };
|
|
28959
29080
|
}
|
|
28960
29081
|
case "get_command_history": {
|
|
@@ -28966,7 +29087,7 @@ var init_adhdev_daemon = __esm({
|
|
|
28966
29087
|
}
|
|
28967
29088
|
return await this.components.router.execute(cmdType, data, "p2p");
|
|
28968
29089
|
} catch (e) {
|
|
28969
|
-
(0,
|
|
29090
|
+
(0, import_daemon_core4.logCommand)({ ts: (/* @__PURE__ */ new Date()).toISOString(), cmd: cmdType, source: "p2p", success: false, error: e.message, durationMs: Date.now() - cmdStart });
|
|
28970
29091
|
return { success: false, error: e.message };
|
|
28971
29092
|
}
|
|
28972
29093
|
}
|
|
@@ -28991,16 +29112,16 @@ var init_adhdev_daemon = __esm({
|
|
|
28991
29112
|
if (!this.running) return;
|
|
28992
29113
|
this.running = false;
|
|
28993
29114
|
console.log(import_chalk.default.yellow("\n Shutting down ADHDev Daemon..."));
|
|
28994
|
-
if (this.
|
|
28995
|
-
|
|
28996
|
-
this.
|
|
29115
|
+
if (this.screenshotController) {
|
|
29116
|
+
this.screenshotController.stop();
|
|
29117
|
+
this.screenshotController = null;
|
|
28997
29118
|
}
|
|
28998
29119
|
if (this.statusReporter) {
|
|
28999
29120
|
this.statusReporter.stopReporting();
|
|
29000
29121
|
this.statusReporter = null;
|
|
29001
29122
|
}
|
|
29002
29123
|
if (this.components) {
|
|
29003
|
-
await (0,
|
|
29124
|
+
await (0, import_daemon_core4.shutdownDaemonComponents)(this.components);
|
|
29004
29125
|
}
|
|
29005
29126
|
try {
|
|
29006
29127
|
this.p2p?.disconnect();
|
|
@@ -29042,7 +29163,7 @@ var import_chalk2 = __toESM(require("chalk"));
|
|
|
29042
29163
|
var import_inquirer = __toESM(require("inquirer"));
|
|
29043
29164
|
var import_ora = __toESM(require("ora"));
|
|
29044
29165
|
var import_open = __toESM(require("open"));
|
|
29045
|
-
var
|
|
29166
|
+
var import_daemon_core5 = __toESM(require_dist());
|
|
29046
29167
|
var SERVER_URL = process.env.ADHDEV_SERVER_URL || "https://api.adhf.dev";
|
|
29047
29168
|
var LOGO = `
|
|
29048
29169
|
${import_chalk2.default.cyan("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")}
|
|
@@ -29052,13 +29173,13 @@ ${import_chalk2.default.cyan("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u
|
|
|
29052
29173
|
`;
|
|
29053
29174
|
var DIVIDER = import_chalk2.default.gray("\u2500".repeat(44));
|
|
29054
29175
|
async function runWizard(options = {}) {
|
|
29055
|
-
const loader = new
|
|
29176
|
+
const loader = new import_daemon_core5.ProviderLoader({ logFn: () => {
|
|
29056
29177
|
} });
|
|
29057
29178
|
loader.loadAll();
|
|
29058
29179
|
loader.registerToDetector();
|
|
29059
29180
|
console.log(LOGO);
|
|
29060
|
-
if ((0,
|
|
29061
|
-
const config2 = (0,
|
|
29181
|
+
if ((0, import_daemon_core5.isSetupComplete)() && !options.force) {
|
|
29182
|
+
const config2 = (0, import_daemon_core5.loadConfig)();
|
|
29062
29183
|
console.log(import_chalk2.default.green("\u2713") + " ADHDev is already set up!");
|
|
29063
29184
|
const ides = config2.configuredIdes?.length ? config2.configuredIdes.join(", ") : config2.selectedIde || "none";
|
|
29064
29185
|
console.log(import_chalk2.default.gray(` IDEs: ${ides}`));
|
|
@@ -29087,7 +29208,7 @@ async function runWizard(options = {}) {
|
|
|
29087
29208
|
if (action === "relogin") {
|
|
29088
29209
|
const loginResult = await loginFlow();
|
|
29089
29210
|
if (loginResult) {
|
|
29090
|
-
(0,
|
|
29211
|
+
(0, import_daemon_core5.updateConfig)({
|
|
29091
29212
|
connectionToken: loginResult.connectionToken,
|
|
29092
29213
|
userEmail: loginResult.email,
|
|
29093
29214
|
userName: loginResult.name
|
|
@@ -29124,7 +29245,7 @@ async function runWizard(options = {}) {
|
|
|
29124
29245
|
async function quickSetup() {
|
|
29125
29246
|
console.log(import_chalk2.default.bold("\n\u{1F680} Quick Setup\n"));
|
|
29126
29247
|
const spinner = (0, import_ora.default)("Detecting installed IDEs...").start();
|
|
29127
|
-
const ides = await (0,
|
|
29248
|
+
const ides = await (0, import_daemon_core5.detectIDEs)();
|
|
29128
29249
|
const installedIDEs = ides.filter((i) => i.installed && i.cliCommand);
|
|
29129
29250
|
spinner.stop();
|
|
29130
29251
|
if (installedIDEs.length === 0) {
|
|
@@ -29172,9 +29293,9 @@ async function quickSetup() {
|
|
|
29172
29293
|
}
|
|
29173
29294
|
}
|
|
29174
29295
|
const ideIds = selectedIDEs.map((i) => i.id);
|
|
29175
|
-
(0,
|
|
29296
|
+
(0, import_daemon_core5.markSetupComplete)(ideIds, ["adhdev"]);
|
|
29176
29297
|
if (loginResult) {
|
|
29177
|
-
(0,
|
|
29298
|
+
(0, import_daemon_core5.updateConfig)({
|
|
29178
29299
|
connectionToken: loginResult.connectionToken,
|
|
29179
29300
|
userEmail: loginResult.email,
|
|
29180
29301
|
userName: loginResult.name
|
|
@@ -29204,7 +29325,7 @@ async function quickSetup() {
|
|
|
29204
29325
|
async function customSetup() {
|
|
29205
29326
|
console.log(import_chalk2.default.bold("\n\u{1F4CD} Step 1/4 \u2014 Detecting installed IDEs...\n"));
|
|
29206
29327
|
const spinner = (0, import_ora.default)("Scanning your system...").start();
|
|
29207
|
-
const ides = await (0,
|
|
29328
|
+
const ides = await (0, import_daemon_core5.detectIDEs)();
|
|
29208
29329
|
const installedIDEs = ides.filter((i) => i.installed);
|
|
29209
29330
|
spinner.stop();
|
|
29210
29331
|
if (installedIDEs.length === 0) {
|
|
@@ -29235,7 +29356,7 @@ async function customSetup() {
|
|
|
29235
29356
|
const selectedIDE = installedIDEs.find((i) => i.id === selectedIdeId);
|
|
29236
29357
|
console.log(DIVIDER);
|
|
29237
29358
|
console.log(import_chalk2.default.bold("\n\u{1F4CD} Step 3/4 \u2014 Choose AI extensions\n"));
|
|
29238
|
-
const aiExtensions = (0,
|
|
29359
|
+
const aiExtensions = (0, import_daemon_core5.getAIExtensions)();
|
|
29239
29360
|
const { selectedExtIds } = await import_inquirer.default.prompt([
|
|
29240
29361
|
{
|
|
29241
29362
|
type: "checkbox",
|
|
@@ -29252,7 +29373,7 @@ async function customSetup() {
|
|
|
29252
29373
|
const allExtensions = selectedAIExts;
|
|
29253
29374
|
console.log(import_chalk2.default.bold("\n\u{1F4CD} Step 4/4 \u2014 Installing extensions\n"));
|
|
29254
29375
|
if (selectedIDE.cliCommand) {
|
|
29255
|
-
await (0,
|
|
29376
|
+
await (0, import_daemon_core5.installExtensions)(
|
|
29256
29377
|
selectedIDE,
|
|
29257
29378
|
allExtensions,
|
|
29258
29379
|
(current, total, ext, result) => {
|
|
@@ -29271,9 +29392,9 @@ async function customSetup() {
|
|
|
29271
29392
|
if (loginResult?.connectionToken) {
|
|
29272
29393
|
await injectTokenToIDE(selectedIDE, loginResult.connectionToken);
|
|
29273
29394
|
}
|
|
29274
|
-
(0,
|
|
29395
|
+
(0, import_daemon_core5.markSetupComplete)(selectedIdeId, allExtensions.map((e) => e.id));
|
|
29275
29396
|
if (loginResult) {
|
|
29276
|
-
(0,
|
|
29397
|
+
(0, import_daemon_core5.updateConfig)({
|
|
29277
29398
|
connectionToken: loginResult.connectionToken,
|
|
29278
29399
|
userEmail: loginResult.email,
|
|
29279
29400
|
userName: loginResult.name
|
|
@@ -29379,7 +29500,7 @@ async function injectTokenToIDE(ide, connectionToken) {
|
|
|
29379
29500
|
return path3.join(home, ".config", appName2, "User", "settings.json");
|
|
29380
29501
|
}
|
|
29381
29502
|
};
|
|
29382
|
-
const loader = new
|
|
29503
|
+
const loader = new import_daemon_core5.ProviderLoader({ logFn: () => {
|
|
29383
29504
|
} });
|
|
29384
29505
|
loader.loadAll();
|
|
29385
29506
|
const appNameMap = loader.getMacAppIdentifiers();
|
|
@@ -29542,7 +29663,7 @@ async function installCliOnly() {
|
|
|
29542
29663
|
}
|
|
29543
29664
|
|
|
29544
29665
|
// src/cli-entrypoint.ts
|
|
29545
|
-
var
|
|
29666
|
+
var import_daemon_core6 = __toESM(require_dist());
|
|
29546
29667
|
var import_fs = require("fs");
|
|
29547
29668
|
var import_path = require("path");
|
|
29548
29669
|
var pkgVersion2 = "unknown";
|
|
@@ -29563,7 +29684,7 @@ try {
|
|
|
29563
29684
|
}
|
|
29564
29685
|
} catch {
|
|
29565
29686
|
}
|
|
29566
|
-
var _cliProviderLoader = new
|
|
29687
|
+
var _cliProviderLoader = new import_daemon_core6.ProviderLoader({ logFn: () => {
|
|
29567
29688
|
} });
|
|
29568
29689
|
_cliProviderLoader.loadAll();
|
|
29569
29690
|
_cliProviderLoader.registerToDetector();
|
|
@@ -29639,7 +29760,7 @@ program.command("launch [target]").description("Launch IDE with CDP or start CLI
|
|
|
29639
29760
|
}
|
|
29640
29761
|
let targetIdeId = targetArg;
|
|
29641
29762
|
if (!targetIdeId) {
|
|
29642
|
-
const ides = await (0,
|
|
29763
|
+
const ides = await (0, import_daemon_core6.detectIDEs)();
|
|
29643
29764
|
const installed = ides.filter((i) => i.installed && i.cliCommand);
|
|
29644
29765
|
if (installed.length === 0) {
|
|
29645
29766
|
console.log(import_chalk3.default.red("\n\u2717 No supported IDE found.\n"));
|
|
@@ -29666,7 +29787,7 @@ program.command("launch [target]").description("Launch IDE with CDP or start CLI
|
|
|
29666
29787
|
const ora2 = await import("ora");
|
|
29667
29788
|
const spinner = ora2.default("Detecting IDE...").start();
|
|
29668
29789
|
try {
|
|
29669
|
-
const result = await (0,
|
|
29790
|
+
const result = await (0, import_daemon_core6.launchWithCdp)({
|
|
29670
29791
|
ideId: targetIdeId,
|
|
29671
29792
|
workspace: options.workspace,
|
|
29672
29793
|
newWindow: options.newWindow
|
|
@@ -29677,14 +29798,14 @@ program.command("launch [target]").description("Launch IDE with CDP or start CLI
|
|
|
29677
29798
|
\u2717 ${result.error}
|
|
29678
29799
|
`));
|
|
29679
29800
|
console.log(import_chalk3.default.gray(" Available IDEs:"));
|
|
29680
|
-
const ides = await (0,
|
|
29801
|
+
const ides = await (0, import_daemon_core6.detectIDEs)();
|
|
29681
29802
|
ides.forEach((ide) => {
|
|
29682
29803
|
if (ide.installed) {
|
|
29683
29804
|
console.log(` ${import_chalk3.default.green("\u2713")} ${ide.icon} ${import_chalk3.default.bold(ide.id)} \u2014 ${ide.displayName}`);
|
|
29684
29805
|
}
|
|
29685
29806
|
});
|
|
29686
29807
|
console.log(import_chalk3.default.gray("\n Available CLI Agents:"));
|
|
29687
|
-
const clis = await (0,
|
|
29808
|
+
const clis = await (0, import_daemon_core6.detectCLIs)(_cliProviderLoader);
|
|
29688
29809
|
clis.forEach((cli) => {
|
|
29689
29810
|
if (cli.installed) {
|
|
29690
29811
|
console.log(` ${import_chalk3.default.green("\u2713")} ${cli.icon} ${import_chalk3.default.bold(cli.id)} \u2014 ${cli.displayName}`);
|
|
@@ -29723,7 +29844,7 @@ program.command("launch [target]").description("Launch IDE with CDP or start CLI
|
|
|
29723
29844
|
}
|
|
29724
29845
|
});
|
|
29725
29846
|
program.command("status").description("Show current ADHDev setup status").action(async () => {
|
|
29726
|
-
const config2 = (0,
|
|
29847
|
+
const config2 = (0, import_daemon_core6.loadConfig)();
|
|
29727
29848
|
console.log(import_chalk3.default.bold("\n\u{1F9A6} ADHDev Status\n"));
|
|
29728
29849
|
if (!config2.setupCompleted) {
|
|
29729
29850
|
console.log(import_chalk3.default.yellow(" Status: Not configured"));
|
|
@@ -29733,7 +29854,7 @@ program.command("status").description("Show current ADHDev setup status").action
|
|
|
29733
29854
|
const ideList = config2.configuredIdes?.length ? config2.configuredIdes : config2.selectedIde ? [config2.selectedIde] : [];
|
|
29734
29855
|
console.log(` ${import_chalk3.default.bold("Status:")} ${import_chalk3.default.green("\u2713 Configured")}`);
|
|
29735
29856
|
if (ideList.length > 0) {
|
|
29736
|
-
const ides = await (0,
|
|
29857
|
+
const ides = await (0, import_daemon_core6.detectIDEs)();
|
|
29737
29858
|
console.log(` ${import_chalk3.default.bold("IDEs:")}`);
|
|
29738
29859
|
for (const ideId of ideList) {
|
|
29739
29860
|
const ide = ides.find((i) => i.id === ideId);
|
|
@@ -29745,7 +29866,7 @@ program.command("status").description("Show current ADHDev setup status").action
|
|
|
29745
29866
|
}
|
|
29746
29867
|
}
|
|
29747
29868
|
}
|
|
29748
|
-
const clis = await (0,
|
|
29869
|
+
const clis = await (0, import_daemon_core6.detectCLIs)(_cliProviderLoader);
|
|
29749
29870
|
const installedClis = clis.filter((c) => c.installed);
|
|
29750
29871
|
if (installedClis.length > 0) {
|
|
29751
29872
|
console.log(` ${import_chalk3.default.bold("CLI Agents:")}`);
|
|
@@ -29766,7 +29887,7 @@ program.command("status").description("Show current ADHDev setup status").action
|
|
|
29766
29887
|
});
|
|
29767
29888
|
program.command("detect").description("Detect installed IDEs, CLI agents, and ACP agents").action(async () => {
|
|
29768
29889
|
console.log(import_chalk3.default.bold("\n\u{1F50D} Detecting installed IDEs...\n"));
|
|
29769
|
-
const ides = await (0,
|
|
29890
|
+
const ides = await (0, import_daemon_core6.detectIDEs)();
|
|
29770
29891
|
ides.forEach((ide) => {
|
|
29771
29892
|
if (ide.installed) {
|
|
29772
29893
|
const version2 = ide.version ? import_chalk3.default.gray(` v${ide.version}`) : "";
|
|
@@ -29782,7 +29903,7 @@ program.command("detect").description("Detect installed IDEs, CLI agents, and AC
|
|
|
29782
29903
|
}
|
|
29783
29904
|
});
|
|
29784
29905
|
console.log(import_chalk3.default.bold("\n\u{1F50D} Detecting CLI & ACP Agents...\n"));
|
|
29785
|
-
const clis = await (0,
|
|
29906
|
+
const clis = await (0, import_daemon_core6.detectCLIs)(_cliProviderLoader);
|
|
29786
29907
|
const cliAgents = clis.filter((c) => c.category === "cli");
|
|
29787
29908
|
const acpAgents = clis.filter((c) => c.category === "acp");
|
|
29788
29909
|
const installedCli = cliAgents.filter((c) => c.installed);
|
|
@@ -29825,7 +29946,7 @@ program.command("reset").description("Reset ADHDev configuration").action(async
|
|
|
29825
29946
|
}
|
|
29826
29947
|
]);
|
|
29827
29948
|
if (confirm) {
|
|
29828
|
-
(0,
|
|
29949
|
+
(0, import_daemon_core6.resetConfig)();
|
|
29829
29950
|
console.log(import_chalk3.default.green("\n\u2713 Configuration reset successfully."));
|
|
29830
29951
|
console.log(import_chalk3.default.gray(" Run `adhdev setup` to reconfigure.\n"));
|
|
29831
29952
|
}
|