@adhdev/daemon-core 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/index.d.ts +2662 -0
- package/dist/index.js +11341 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
- package/providers/_builtin/.github/workflows/generate-registry.yml +57 -0
- package/providers/_builtin/COMPATIBILITY.md +217 -0
- package/providers/_builtin/CONTRIBUTING.md +200 -0
- package/providers/_builtin/README.md +119 -0
- package/providers/_builtin/_helpers/index.js +188 -0
- package/providers/_builtin/acp/agentpool/provider.json +54 -0
- package/providers/_builtin/acp/amp/provider.json +52 -0
- package/providers/_builtin/acp/auggie/provider.json +57 -0
- package/providers/_builtin/acp/autodev/provider.json +54 -0
- package/providers/_builtin/acp/autohand/provider.json +52 -0
- package/providers/_builtin/acp/blackbox-ai/provider.json +54 -0
- package/providers/_builtin/acp/claude-agent/provider.json +57 -0
- package/providers/_builtin/acp/cline-acp/provider.json +54 -0
- package/providers/_builtin/acp/codebuddy/provider.json +54 -0
- package/providers/_builtin/acp/codex-cli/provider.json +57 -0
- package/providers/_builtin/acp/corust-agent/provider.json +52 -0
- package/providers/_builtin/acp/crow-cli/provider.json +54 -0
- package/providers/_builtin/acp/cursor-acp/provider.json +54 -0
- package/providers/_builtin/acp/deepagents/provider.json +52 -0
- package/providers/_builtin/acp/dimcode/provider.json +54 -0
- package/providers/_builtin/acp/docker-cagent/provider.json +57 -0
- package/providers/_builtin/acp/factory-droid/provider.json +60 -0
- package/providers/_builtin/acp/fast-agent/provider.json +52 -0
- package/providers/_builtin/acp/gemini-cli/provider.json +114 -0
- package/providers/_builtin/acp/github-copilot/provider.json +54 -0
- package/providers/_builtin/acp/goose/provider.json +57 -0
- package/providers/_builtin/acp/junie/provider.json +52 -0
- package/providers/_builtin/acp/kilo/provider.json +54 -0
- package/providers/_builtin/acp/kimi-cli/provider.json +57 -0
- package/providers/_builtin/acp/minion-code/provider.json +52 -0
- package/providers/_builtin/acp/mistral-vibe/provider.json +57 -0
- package/providers/_builtin/acp/nova/provider.json +54 -0
- package/providers/_builtin/acp/openclaw/provider.json +54 -0
- package/providers/_builtin/acp/opencode/provider.json +52 -0
- package/providers/_builtin/acp/openhands/provider.json +54 -0
- package/providers/_builtin/acp/pi-acp/provider.json +52 -0
- package/providers/_builtin/acp/qoder/provider.json +54 -0
- package/providers/_builtin/acp/qwen-code/provider.json +60 -0
- package/providers/_builtin/acp/stakpak/provider.json +54 -0
- package/providers/_builtin/acp/vtcode/provider.json +54 -0
- package/providers/_builtin/cli/claude-cli/provider.json +100 -0
- package/providers/_builtin/cli/codex-cli/provider.json +89 -0
- package/providers/_builtin/cli/gemini-cli/provider.json +93 -0
- package/providers/_builtin/docs/CDP_SELECTOR_GUIDE.md +370 -0
- package/providers/_builtin/docs/PROVIDER_GUIDE.md +916 -0
- package/providers/_builtin/extension/cline/provider.json +35 -0
- package/providers/_builtin/extension/cline/scripts/focus_editor.js +48 -0
- package/providers/_builtin/extension/cline/scripts/list_chats.js +100 -0
- package/providers/_builtin/extension/cline/scripts/list_models.js +43 -0
- package/providers/_builtin/extension/cline/scripts/list_modes.js +35 -0
- package/providers/_builtin/extension/cline/scripts/new_session.js +85 -0
- package/providers/_builtin/extension/cline/scripts/open_panel.js +25 -0
- package/providers/_builtin/extension/cline/scripts/read_chat.js +257 -0
- package/providers/_builtin/extension/cline/scripts/resolve_action.js +83 -0
- package/providers/_builtin/extension/cline/scripts/send_message.js +95 -0
- package/providers/_builtin/extension/cline/scripts/set_mode.js +36 -0
- package/providers/_builtin/extension/cline/scripts/set_model.js +36 -0
- package/providers/_builtin/extension/cline/scripts/switch_session.js +206 -0
- package/providers/_builtin/extension/cline/scripts.js +73 -0
- package/providers/_builtin/extension/roo-code/provider.json +35 -0
- package/providers/_builtin/extension/roo-code/scripts.js +659 -0
- package/providers/_builtin/ide/antigravity/provider.json +68 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/focus_editor.js +20 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/list_chats.js +137 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/list_models.js +38 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/list_modes.js +48 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/new_session.js +75 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/read_chat.js +262 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/resolve_action.js +68 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/scripts.js +57 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/send_message.js +56 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/set_mode.js +34 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/set_model.js +47 -0
- package/providers/_builtin/ide/antigravity/scripts/1.106/switch_session.js +114 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/focus_editor.js +20 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/list_chats.js +137 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/list_models.js +61 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/list_modes.js +72 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/new_session.js +75 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/read_chat.js +262 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/resolve_action.js +68 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/scripts.js +67 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/send_message.js +56 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/set_mode.js +67 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/set_model.js +72 -0
- package/providers/_builtin/ide/antigravity/scripts/1.107/switch_session.js +114 -0
- package/providers/_builtin/ide/cursor/provider.json +70 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/dismiss_notification.js +30 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/focus_editor.js +13 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/list_models.js +78 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/list_modes.js +40 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/list_notifications.js +23 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/list_sessions.js +42 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/new_session.js +20 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/open_panel.js +23 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/read_chat.js +75 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/resolve_action.js +19 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/scripts.js +78 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/send_message.js +23 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/set_mode.js +38 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/set_model.js +81 -0
- package/providers/_builtin/ide/cursor/scripts/0.49/switch_session.js +28 -0
- package/providers/_builtin/ide/kiro/provider.json +67 -0
- package/providers/_builtin/ide/kiro/scripts/focus_editor.js +20 -0
- package/providers/_builtin/ide/kiro/scripts/open_panel.js +47 -0
- package/providers/_builtin/ide/kiro/scripts/resolve_action.js +54 -0
- package/providers/_builtin/ide/kiro/scripts/send_message.js +29 -0
- package/providers/_builtin/ide/kiro/scripts/webview_list_models.js +39 -0
- package/providers/_builtin/ide/kiro/scripts/webview_list_modes.js +39 -0
- package/providers/_builtin/ide/kiro/scripts/webview_list_sessions.js +21 -0
- package/providers/_builtin/ide/kiro/scripts/webview_new_session.js +34 -0
- package/providers/_builtin/ide/kiro/scripts/webview_read_chat.js +68 -0
- package/providers/_builtin/ide/kiro/scripts/webview_send_message.js +72 -0
- package/providers/_builtin/ide/kiro/scripts/webview_set_mode.js +15 -0
- package/providers/_builtin/ide/kiro/scripts/webview_set_model.js +15 -0
- package/providers/_builtin/ide/kiro/scripts/webview_switch_session.js +26 -0
- package/providers/_builtin/ide/kiro/scripts.js +62 -0
- package/providers/_builtin/ide/pearai/provider.json +67 -0
- package/providers/_builtin/ide/pearai/scripts/focus_editor.js +20 -0
- package/providers/_builtin/ide/pearai/scripts/list_sessions.js +38 -0
- package/providers/_builtin/ide/pearai/scripts/new_session.js +55 -0
- package/providers/_builtin/ide/pearai/scripts/open_panel.js +46 -0
- package/providers/_builtin/ide/pearai/scripts/resolve_action.js +54 -0
- package/providers/_builtin/ide/pearai/scripts/send_message.js +29 -0
- package/providers/_builtin/ide/pearai/scripts/webview_list_models.js +43 -0
- package/providers/_builtin/ide/pearai/scripts/webview_list_modes.js +35 -0
- package/providers/_builtin/ide/pearai/scripts/webview_list_sessions.js +62 -0
- package/providers/_builtin/ide/pearai/scripts/webview_new_session.js +49 -0
- package/providers/_builtin/ide/pearai/scripts/webview_read_chat.js +92 -0
- package/providers/_builtin/ide/pearai/scripts/webview_resolve_action.js +59 -0
- package/providers/_builtin/ide/pearai/scripts/webview_send_message.js +72 -0
- package/providers/_builtin/ide/pearai/scripts/webview_set_mode.js +36 -0
- package/providers/_builtin/ide/pearai/scripts/webview_set_model.js +36 -0
- package/providers/_builtin/ide/pearai/scripts/webview_switch_session.js +34 -0
- package/providers/_builtin/ide/pearai/scripts.js +74 -0
- package/providers/_builtin/ide/trae/provider.json +66 -0
- package/providers/_builtin/ide/trae/scripts/focus_editor.js +20 -0
- package/providers/_builtin/ide/trae/scripts/list_chats.js +24 -0
- package/providers/_builtin/ide/trae/scripts/list_models.js +39 -0
- package/providers/_builtin/ide/trae/scripts/list_modes.js +39 -0
- package/providers/_builtin/ide/trae/scripts/new_session.js +30 -0
- package/providers/_builtin/ide/trae/scripts/open_panel.js +44 -0
- package/providers/_builtin/ide/trae/scripts/read_chat.js +113 -0
- package/providers/_builtin/ide/trae/scripts/resolve_action.js +54 -0
- package/providers/_builtin/ide/trae/scripts/send_message.js +69 -0
- package/providers/_builtin/ide/trae/scripts/set_mode.js +15 -0
- package/providers/_builtin/ide/trae/scripts/set_model.js +15 -0
- package/providers/_builtin/ide/trae/scripts/switch_session.js +23 -0
- package/providers/_builtin/ide/trae/scripts.js +57 -0
- package/providers/_builtin/ide/vscode/provider.json +64 -0
- package/providers/_builtin/ide/vscode-insiders/provider.json +62 -0
- package/providers/_builtin/ide/vscodium/provider.json +63 -0
- package/providers/_builtin/ide/windsurf/provider.json +53 -0
- package/providers/_builtin/ide/windsurf/scripts/focus_editor.js +30 -0
- package/providers/_builtin/ide/windsurf/scripts/list_chats.js +117 -0
- package/providers/_builtin/ide/windsurf/scripts/list_models.js +39 -0
- package/providers/_builtin/ide/windsurf/scripts/list_modes.js +39 -0
- package/providers/_builtin/ide/windsurf/scripts/new_session.js +69 -0
- package/providers/_builtin/ide/windsurf/scripts/open_panel.js +58 -0
- package/providers/_builtin/ide/windsurf/scripts/read_chat.js +297 -0
- package/providers/_builtin/ide/windsurf/scripts/resolve_action.js +68 -0
- package/providers/_builtin/ide/windsurf/scripts/send_message.js +87 -0
- package/providers/_builtin/ide/windsurf/scripts/set_mode.js +15 -0
- package/providers/_builtin/ide/windsurf/scripts/set_model.js +15 -0
- package/providers/_builtin/ide/windsurf/scripts/switch_session.js +58 -0
- package/providers/_builtin/ide/windsurf/scripts.js +57 -0
- package/providers/_builtin/registry.json +266 -0
- package/providers/_builtin/validate.js +156 -0
- package/src/agent-stream/index.ts +6 -0
- package/src/agent-stream/manager.ts +286 -0
- package/src/agent-stream/poller.ts +154 -0
- package/src/agent-stream/provider-adapter.ts +138 -0
- package/src/agent-stream/types.ts +61 -0
- package/src/boot/daemon-lifecycle.ts +252 -0
- package/src/cdp/devtools.ts +335 -0
- package/src/cdp/initializer.ts +191 -0
- package/src/cdp/manager.ts +897 -0
- package/src/cdp/scanner.ts +185 -0
- package/src/cdp/setup.ts +150 -0
- package/src/cli-adapter-types.ts +25 -0
- package/src/cli-adapters/provider-cli-adapter.ts +448 -0
- package/src/commands/cdp-commands.ts +208 -0
- package/src/commands/chat-commands.ts +675 -0
- package/src/commands/cli-manager.ts +353 -0
- package/src/commands/handler.ts +328 -0
- package/src/commands/router.ts +258 -0
- package/src/commands/stream-commands.ts +325 -0
- package/src/config/chat-history.ts +211 -0
- package/src/config/config.ts +219 -0
- package/src/daemon/dev-server.ts +2378 -0
- package/src/daemon/scaffold-template.ts +394 -0
- package/src/daemon-core.ts +50 -0
- package/src/detection/cli-detector.ts +89 -0
- package/src/detection/ide-detector.ts +157 -0
- package/src/index.ts +103 -0
- package/src/installer.ts +263 -0
- package/src/ipc-protocol.ts +133 -0
- package/src/launch.ts +433 -0
- package/src/logging/command-log.ts +180 -0
- package/src/logging/logger.ts +316 -0
- package/src/providers/acp-provider-instance.ts +1140 -0
- package/src/providers/cli-provider-instance.ts +207 -0
- package/src/providers/contracts.ts +524 -0
- package/src/providers/extension-provider-instance.ts +156 -0
- package/src/providers/ide-provider-instance.ts +377 -0
- package/src/providers/index.ts +18 -0
- package/src/providers/provider-instance-manager.ts +182 -0
- package/src/providers/provider-instance.ts +112 -0
- package/src/providers/provider-loader.ts +1031 -0
- package/src/providers/status-monitor.ts +125 -0
- package/src/providers/version-archive.ts +266 -0
- package/src/status/reporter.ts +294 -0
- package/src/types.ts +206 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DaemonCliManager — CLI session creation, management, and command handling
|
|
3
|
+
*
|
|
4
|
+
* Separated from adhdev-daemon.ts.
|
|
5
|
+
* CLI cases of createAdapter, startCliSession, stopCliSession, executeDaemonCommand extracted to independent module extract.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import * as os from 'os';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import * as crypto from 'crypto';
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
import { ProviderCliAdapter } from '../cli-adapters/provider-cli-adapter.js';
|
|
13
|
+
import { detectCLI } from '../detection/cli-detector.js';
|
|
14
|
+
import { loadConfig, saveConfig, addCliHistory } from '../config/config.js';
|
|
15
|
+
import { CliProviderInstance } from '../providers/cli-provider-instance.js';
|
|
16
|
+
import { AcpProviderInstance } from '../providers/acp-provider-instance.js';
|
|
17
|
+
import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
|
|
18
|
+
import { ProviderLoader } from '../providers/provider-loader.js';
|
|
19
|
+
import type { CliAdapter } from '../cli-adapter-types.js';
|
|
20
|
+
import { LOG } from '../logging/logger.js';
|
|
21
|
+
|
|
22
|
+
// ─── external dependency interface ──────────────────────────
|
|
23
|
+
|
|
24
|
+
export interface CliManagerDeps {
|
|
25
|
+
/** Server connection — injected into adapter */
|
|
26
|
+
getServerConn(): any | null;
|
|
27
|
+
/** P2P — PTY output transmit */
|
|
28
|
+
getP2p(): { broadcastPtyOutput(key: string, data: string): void } | null;
|
|
29
|
+
/** StatusReporter callback */
|
|
30
|
+
onStatusChange(): void;
|
|
31
|
+
removeAgentTracking(key: string): void;
|
|
32
|
+
/** InstanceManager — register in CLI unified status */
|
|
33
|
+
getInstanceManager(): ProviderInstanceManager | null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type CommandResult = { success: boolean;[key: string]: unknown };
|
|
37
|
+
|
|
38
|
+
// ─── DaemonCliManager ────────────────────────────
|
|
39
|
+
|
|
40
|
+
export class DaemonCliManager {
|
|
41
|
+
readonly adapters = new Map<string, CliAdapter>();
|
|
42
|
+
private deps: CliManagerDeps;
|
|
43
|
+
private providerLoader: ProviderLoader;
|
|
44
|
+
|
|
45
|
+
constructor(deps: CliManagerDeps, providerLoader: ProviderLoader) {
|
|
46
|
+
this.deps = deps;
|
|
47
|
+
this.providerLoader = providerLoader;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// ─── Key create ─────────────────────────────────
|
|
51
|
+
|
|
52
|
+
getCliKey(cliType: string, dir: string): string {
|
|
53
|
+
const hash = require('crypto').createHash('md5').update(require('path').resolve(dir)).digest('hex').slice(0, 8);
|
|
54
|
+
return `${cliType}_${hash}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private createAdapter(cliType: string, workingDir: string, cliArgs?: string[]): CliAdapter {
|
|
58
|
+
// cliType normalize (Resolve alias)
|
|
59
|
+
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
60
|
+
|
|
61
|
+
// Load CLI config from provider.js
|
|
62
|
+
const provider = this.providerLoader.getMeta(normalizedType);
|
|
63
|
+
if (provider && provider.category === 'cli' && provider.patterns && provider.spawn) {
|
|
64
|
+
console.log(chalk.cyan(` 📦 Using provider: ${provider.name} (${provider.type})`));
|
|
65
|
+
return new ProviderCliAdapter(provider as any, workingDir, cliArgs);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
throw new Error(`No CLI provider found for '${cliType}'. Create a provider.js in providers/cli/${cliType}/`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// ─── Session start/management ──────────────────────────────
|
|
72
|
+
|
|
73
|
+
async startSession(cliType: string, workingDir: string, cliArgs?: string[], initialModel?: string): Promise<void> {
|
|
74
|
+
const trimmed = (workingDir || os.homedir()).trim();
|
|
75
|
+
const resolvedDir = trimmed.startsWith('~')
|
|
76
|
+
? trimmed.replace(/^~/, os.homedir())
|
|
77
|
+
: path.resolve(trimmed);
|
|
78
|
+
|
|
79
|
+
// cliType normalize (Resolve alias)
|
|
80
|
+
const normalizedType = this.providerLoader.resolveAlias(cliType);
|
|
81
|
+
const provider = this.providerLoader.getByAlias(cliType);
|
|
82
|
+
|
|
83
|
+
// Create UUID-based key (allows separate instances even for same type+dir)
|
|
84
|
+
const key = crypto.randomUUID();
|
|
85
|
+
|
|
86
|
+
// ─── ACP category handle ───
|
|
87
|
+
if (provider && provider.category === 'acp') {
|
|
88
|
+
const instanceManager = this.deps.getInstanceManager();
|
|
89
|
+
if (!instanceManager) throw new Error('InstanceManager not available');
|
|
90
|
+
|
|
91
|
+
// Check if command is installed
|
|
92
|
+
const spawnCmd = provider.spawn?.command;
|
|
93
|
+
if (spawnCmd) {
|
|
94
|
+
try {
|
|
95
|
+
const { execSync } = require('child_process');
|
|
96
|
+
execSync(`which ${spawnCmd}`, { stdio: 'ignore' });
|
|
97
|
+
} catch {
|
|
98
|
+
const installInfo = provider.install || `Install: check ${provider.displayName || provider.name} documentation`;
|
|
99
|
+
throw new Error(
|
|
100
|
+
`${provider.displayName || provider.name} is not installed.\n` +
|
|
101
|
+
`Command '${spawnCmd}' not found in PATH.\n\n` +
|
|
102
|
+
`${installInfo}`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
console.log(chalk.cyan(` 🔌 Starting ACP agent: ${provider.name} (${provider.type}) in ${resolvedDir}`));
|
|
108
|
+
|
|
109
|
+
const acpInstance = new AcpProviderInstance(provider, resolvedDir, cliArgs);
|
|
110
|
+
await instanceManager.addInstance(key, acpInstance, {
|
|
111
|
+
settings: this.providerLoader.getSettings(normalizedType),
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Register ACP entry in adapter map (getStatus queries from acpInstance in real-time)
|
|
115
|
+
this.adapters.set(key, {
|
|
116
|
+
cliType: normalizedType,
|
|
117
|
+
workingDir: resolvedDir,
|
|
118
|
+
_acpInstance: acpInstance,
|
|
119
|
+
spawn: async () => {},
|
|
120
|
+
shutdown: () => { instanceManager.removeInstance(key); },
|
|
121
|
+
sendMessage: async (text: string) => { acpInstance.onEvent('send_message', { text }); },
|
|
122
|
+
getStatus: () => {
|
|
123
|
+
const state = acpInstance.getState();
|
|
124
|
+
return {
|
|
125
|
+
status: state.status,
|
|
126
|
+
messages: state.activeChat?.messages || [],
|
|
127
|
+
activeModal: state.activeChat?.activeModal || null,
|
|
128
|
+
};
|
|
129
|
+
},
|
|
130
|
+
setOnStatusChange: () => {},
|
|
131
|
+
setOnPtyData: () => {},
|
|
132
|
+
} as any);
|
|
133
|
+
|
|
134
|
+
console.log(chalk.green(` ✓ ACP agent started: ${provider.name} in ${resolvedDir}`));
|
|
135
|
+
|
|
136
|
+
// If initialModel exists, change model after session start
|
|
137
|
+
if (initialModel) {
|
|
138
|
+
try {
|
|
139
|
+
await acpInstance.setConfigOption('model', initialModel);
|
|
140
|
+
console.log(chalk.green(` 🤖 Initial model set: ${initialModel}`));
|
|
141
|
+
} catch (e: any) {
|
|
142
|
+
LOG.warn('CLI', `[ACP] Initial model set failed: ${e?.message}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
try { addCliHistory({ cliType: normalizedType, dir: resolvedDir, cliArgs }); } catch (e) { LOG.warn('CLI', `ACP history save failed: ${(e as Error)?.message}`); }
|
|
147
|
+
this.deps.onStatusChange();
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ─── CLI category handling (existing) ───
|
|
152
|
+
const cliInfo = await detectCLI(cliType, this.providerLoader);
|
|
153
|
+
if (!cliInfo) throw new Error(`${cliType} not found`);
|
|
154
|
+
|
|
155
|
+
console.log(chalk.yellow(` ⚡ Starting CLI ${cliType} in ${resolvedDir}...`));
|
|
156
|
+
if (provider) {
|
|
157
|
+
console.log(chalk.cyan(` 📦 Using provider: ${provider.name} (${provider.type})`));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// If InstanceManager exists, manage as CliProviderInstance unified
|
|
161
|
+
const instanceManager = this.deps.getInstanceManager();
|
|
162
|
+
if (provider && instanceManager) {
|
|
163
|
+
const cliInstance = new CliProviderInstance(provider, resolvedDir, cliArgs, key);
|
|
164
|
+
await instanceManager.addInstance(key, cliInstance, {
|
|
165
|
+
serverConn: this.deps.getServerConn(),
|
|
166
|
+
settings: {},
|
|
167
|
+
onPtyData: (data: string) => {
|
|
168
|
+
this.deps.getP2p()?.broadcastPtyOutput(key, data);
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Keep adapter ref too (backward compat — write, resize etc)
|
|
173
|
+
this.adapters.set(key, cliInstance.getAdapter() as any);
|
|
174
|
+
console.log(chalk.green(` ✓ CLI started: ${cliInfo.displayName} v${cliInfo.version || 'unknown'} in ${resolvedDir}`));
|
|
175
|
+
} else {
|
|
176
|
+
// Fallback: InstanceManager without directly adapter manage
|
|
177
|
+
const adapter = this.createAdapter(cliType, resolvedDir, cliArgs);
|
|
178
|
+
await adapter.spawn();
|
|
179
|
+
|
|
180
|
+
const serverConn = this.deps.getServerConn();
|
|
181
|
+
if (serverConn && typeof adapter.setServerConn === 'function') {
|
|
182
|
+
adapter.setServerConn(serverConn);
|
|
183
|
+
}
|
|
184
|
+
adapter.setOnStatusChange(() => {
|
|
185
|
+
this.deps.onStatusChange();
|
|
186
|
+
const status = adapter.getStatus?.();
|
|
187
|
+
if (status?.status === 'stopped') {
|
|
188
|
+
setTimeout(() => {
|
|
189
|
+
if (this.adapters.get(key) === adapter) {
|
|
190
|
+
this.adapters.delete(key);
|
|
191
|
+
this.deps.removeAgentTracking(key);
|
|
192
|
+
console.log(chalk.yellow(` 🧹 Auto-cleaned stopped CLI: ${adapter.cliType}`));
|
|
193
|
+
this.deps.onStatusChange();
|
|
194
|
+
}
|
|
195
|
+
}, 3000);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
if (typeof adapter.setOnPtyData === 'function') {
|
|
200
|
+
adapter.setOnPtyData((data: string) => {
|
|
201
|
+
this.deps.getP2p()?.broadcastPtyOutput(key, data);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
this.adapters.set(key, adapter);
|
|
206
|
+
console.log(chalk.green(` ✓ CLI started: ${cliInfo.displayName} v${cliInfo.version || 'unknown'} in ${resolvedDir}`));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
try { addCliHistory({ cliType, dir: resolvedDir, cliArgs }); } catch (e) { LOG.warn('CLI', `CLI history save failed: ${(e as Error)?.message}`); }
|
|
210
|
+
|
|
211
|
+
this.deps.onStatusChange();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async stopSession(key: string): Promise<void> {
|
|
215
|
+
const adapter = this.adapters.get(key);
|
|
216
|
+
if (adapter) {
|
|
217
|
+
adapter.shutdown();
|
|
218
|
+
this.adapters.delete(key);
|
|
219
|
+
this.deps.removeAgentTracking(key);
|
|
220
|
+
// Also remove from InstanceManager
|
|
221
|
+
this.deps.getInstanceManager()?.removeInstance(key);
|
|
222
|
+
console.log(chalk.yellow(` 🛑 CLI Agent stopped: ${adapter.cliType} in ${adapter.workingDir}`));
|
|
223
|
+
this.deps.onStatusChange();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
shutdownAll(): void {
|
|
228
|
+
for (const adapter of this.adapters.values()) adapter.shutdown();
|
|
229
|
+
this.adapters.clear();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// ─── Adapter search ─────────────────────────────
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Search for CLI adapter. Priority order:
|
|
236
|
+
* 0. instanceKey (UUID direct match) — extracted from _targetInstance / composite ID
|
|
237
|
+
* 1. agentType + dir (iteration match)
|
|
238
|
+
* 2. agentType fuzzy match (⚠ returns first match when multiple sessions exist)
|
|
239
|
+
*/
|
|
240
|
+
findAdapter(agentType: string, opts?: { dir?: string; instanceKey?: string }): { adapter: CliAdapter; key: string } | null {
|
|
241
|
+
// 0. UUID direct match (most accurate)
|
|
242
|
+
if (opts?.instanceKey) {
|
|
243
|
+
let ik = opts.instanceKey;
|
|
244
|
+
// Strip composite prefix: 'doId:cli:uuid' → 'uuid' or 'doId:uuid' → 'uuid'
|
|
245
|
+
const colonIdx = ik.lastIndexOf(':');
|
|
246
|
+
if (colonIdx >= 0) ik = ik.substring(colonIdx + 1);
|
|
247
|
+
const adapter = this.adapters.get(ik);
|
|
248
|
+
if (adapter) return { adapter, key: ik };
|
|
249
|
+
}
|
|
250
|
+
// 1. agentType + dir match
|
|
251
|
+
if (opts?.dir) {
|
|
252
|
+
for (const [k, a] of this.adapters) {
|
|
253
|
+
if (a.cliType === agentType && a.workingDir === opts.dir) {
|
|
254
|
+
return { adapter: a, key: k };
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
// 2. Fuzzy match (returns first of multiple sessions — may be inaccurate)
|
|
259
|
+
for (const [k, a] of this.adapters) {
|
|
260
|
+
if (a.cliType === agentType) {
|
|
261
|
+
return { adapter: a, key: k };
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// ─── CLI command handling ────────────────────────────
|
|
268
|
+
|
|
269
|
+
async handleCliCommand(cmd: string, args: any): Promise<CommandResult | null> {
|
|
270
|
+
switch (cmd) {
|
|
271
|
+
case 'launch_cli': {
|
|
272
|
+
const cliType = args?.cliType;
|
|
273
|
+
const defaultedToHome = !args?.dir;
|
|
274
|
+
const dir = args?.dir || os.homedir();
|
|
275
|
+
if (!cliType) throw new Error('cliType required');
|
|
276
|
+
|
|
277
|
+
await this.startSession(cliType, dir, args?.cliArgs, args?.initialModel);
|
|
278
|
+
|
|
279
|
+
// On startSession success, new UUID key exists in adapters (last added item)
|
|
280
|
+
let newKey: string | null = null;
|
|
281
|
+
for (const [k, adapter] of this.adapters) {
|
|
282
|
+
if (adapter.cliType === cliType && adapter.workingDir === dir) {
|
|
283
|
+
newKey = k; // Last match = just added item
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
try {
|
|
288
|
+
const config = loadConfig();
|
|
289
|
+
console.log(chalk.cyan(` 📂 Saving recent workspace: ${dir}`));
|
|
290
|
+
const recent = config.recentCliWorkspaces || [];
|
|
291
|
+
if (!recent.includes(dir)) {
|
|
292
|
+
const updated = [dir, ...recent].slice(0, 10);
|
|
293
|
+
saveConfig({ ...config, recentCliWorkspaces: updated });
|
|
294
|
+
console.log(chalk.green(` ✓ Recent workspace saved: ${dir}`));
|
|
295
|
+
}
|
|
296
|
+
} catch (e) {
|
|
297
|
+
console.error(chalk.red(` ✗ Failed to save recent workspace: ${e}`));
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return { success: true, cliType, dir, id: newKey, defaultedToHome };
|
|
301
|
+
}
|
|
302
|
+
case 'stop_cli': {
|
|
303
|
+
const cliType = args?.cliType;
|
|
304
|
+
const dir = args?.dir || '';
|
|
305
|
+
if (!cliType) throw new Error('cliType required');
|
|
306
|
+
// UUID (_targetInstance) based search priority
|
|
307
|
+
const found = this.findAdapter(cliType, { instanceKey: args?._targetInstance, dir });
|
|
308
|
+
if (found) {
|
|
309
|
+
await this.stopSession(found.key);
|
|
310
|
+
} else {
|
|
311
|
+
console.log(chalk.yellow(` ⚠ No adapter found for ${cliType}`));
|
|
312
|
+
}
|
|
313
|
+
return { success: true, cliType, dir, stopped: true };
|
|
314
|
+
}
|
|
315
|
+
case 'restart_session': {
|
|
316
|
+
const cliType = args?.cliType || args?.agentType || args?.ideType;
|
|
317
|
+
const dir = args?.dir || process.cwd();
|
|
318
|
+
if (!cliType) throw new Error('cliType required');
|
|
319
|
+
const found = this.findAdapter(cliType, { instanceKey: args?._targetInstance, dir });
|
|
320
|
+
if (found) await this.stopSession(found.key);
|
|
321
|
+
await this.startSession(cliType, dir);
|
|
322
|
+
return { success: true, restarted: true };
|
|
323
|
+
}
|
|
324
|
+
case 'agent_command': {
|
|
325
|
+
const agentType = args?.agentType || args?.cliType;
|
|
326
|
+
const action = args?.action;
|
|
327
|
+
if (!agentType || !action) throw new Error('agentType and action required');
|
|
328
|
+
|
|
329
|
+
const found = this.findAdapter(agentType, {
|
|
330
|
+
dir: args?.dir,
|
|
331
|
+
instanceKey: args?._targetInstance,
|
|
332
|
+
});
|
|
333
|
+
if (!found) throw new Error(`CLI agent not running: ${agentType}`);
|
|
334
|
+
const { adapter, key } = found;
|
|
335
|
+
|
|
336
|
+
if (action === 'send_chat') {
|
|
337
|
+
const message = args.message || args.text;
|
|
338
|
+
if (!message) throw new Error('message required for send_chat');
|
|
339
|
+
await adapter.sendMessage(message);
|
|
340
|
+
return { success: true, status: 'generating' };
|
|
341
|
+
} else if (action === 'clear_history') {
|
|
342
|
+
if (typeof (adapter as any).clearHistory === 'function') (adapter as any).clearHistory();
|
|
343
|
+
return { success: true, cleared: true };
|
|
344
|
+
} else if (action === 'stop') {
|
|
345
|
+
await this.stopSession(key);
|
|
346
|
+
return { success: true, stopped: true };
|
|
347
|
+
}
|
|
348
|
+
throw new Error(`Unknown action: ${action}`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return null; // Not a CLI command
|
|
352
|
+
}
|
|
353
|
+
}
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daemon Commands — unified command handler
|
|
3
|
+
*
|
|
4
|
+
* Routes all functionality from legacy Extension commands.ts to Daemon.
|
|
5
|
+
*
|
|
6
|
+
* Command implementations are split into sub-modules:
|
|
7
|
+
* - chat-commands.ts — Chat I/O, session management, mode/model control
|
|
8
|
+
* - cdp-commands.ts — CDP eval, screenshot, batch, remote actions, file ops
|
|
9
|
+
* - stream-commands.ts — Agent stream, PTY I/O, provider settings, extension scripts
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { DaemonCdpManager } from '../cdp/manager.js';
|
|
13
|
+
import { CdpDomHandlers } from '../cdp/devtools.js';
|
|
14
|
+
import { ProviderLoader } from '../providers/provider-loader.js';
|
|
15
|
+
import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
|
|
16
|
+
import type { ProviderModule } from '../providers/contracts.js';
|
|
17
|
+
import type { DaemonAgentStreamManager } from '../agent-stream/index.js';
|
|
18
|
+
import { loadConfig } from '../config/config.js';
|
|
19
|
+
import { ChatHistoryWriter } from '../config/chat-history.js';
|
|
20
|
+
import { LOG } from '../logging/logger.js';
|
|
21
|
+
|
|
22
|
+
// Sub-module imports
|
|
23
|
+
import * as Chat from './chat-commands.js';
|
|
24
|
+
import * as Cdp from './cdp-commands.js';
|
|
25
|
+
import * as Stream from './stream-commands.js';
|
|
26
|
+
|
|
27
|
+
export interface CommandResult {
|
|
28
|
+
success: boolean;
|
|
29
|
+
[key: string]: unknown;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface CommandContext {
|
|
33
|
+
cdpManagers: Map<string, DaemonCdpManager>;
|
|
34
|
+
ideType: string;
|
|
35
|
+
adapters: Map<string, any>;
|
|
36
|
+
providerLoader?: ProviderLoader;
|
|
37
|
+
/** ProviderInstanceManager — for runtime settings propagation */
|
|
38
|
+
instanceManager?: ProviderInstanceManager;
|
|
39
|
+
/** UUID instanceId → CDP manager key (ideType) mapping */
|
|
40
|
+
instanceIdMap?: Map<string, string>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Shared helpers interface — passed to sub-module command functions
|
|
45
|
+
* for accessing CDP, providers, agent streams, and other handler-owned state.
|
|
46
|
+
*/
|
|
47
|
+
export interface CommandHelpers {
|
|
48
|
+
getCdp(ideType?: string): DaemonCdpManager | null;
|
|
49
|
+
getProvider(overrideType?: string): ProviderModule | undefined;
|
|
50
|
+
getProviderScript(scriptName: string, params?: Record<string, string>, ideType?: string): string | null;
|
|
51
|
+
evaluateProviderScript(scriptName: string, params?: Record<string, string>, timeout?: number): Promise<{ result: any; category: string } | null>;
|
|
52
|
+
getCliAdapter(type?: string): any | null;
|
|
53
|
+
readonly currentIdeType: string | undefined;
|
|
54
|
+
readonly currentProviderType: string | undefined;
|
|
55
|
+
readonly agentStream: DaemonAgentStreamManager | null;
|
|
56
|
+
readonly ctx: CommandContext;
|
|
57
|
+
readonly historyWriter: ChatHistoryWriter;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export class DaemonCommandHandler implements CommandHelpers {
|
|
61
|
+
private _ctx: CommandContext;
|
|
62
|
+
private _agentStream: DaemonAgentStreamManager | null = null;
|
|
63
|
+
private domHandlers: CdpDomHandlers;
|
|
64
|
+
private _historyWriter: ChatHistoryWriter;
|
|
65
|
+
|
|
66
|
+
/** Current IDE type extracted from command args (per-request) */
|
|
67
|
+
private _currentIdeType: string | undefined;
|
|
68
|
+
/** Current provider type — agentType priority, ideType use */
|
|
69
|
+
private _currentProviderType: string | undefined;
|
|
70
|
+
|
|
71
|
+
constructor(ctx: CommandContext) {
|
|
72
|
+
this._ctx = ctx;
|
|
73
|
+
this.domHandlers = new CdpDomHandlers((ideType?) => this.getCdp(ideType));
|
|
74
|
+
this._historyWriter = new ChatHistoryWriter();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ─── CommandHelpers implementation ─────────────────
|
|
78
|
+
|
|
79
|
+
get ctx(): CommandContext { return this._ctx; }
|
|
80
|
+
get agentStream(): DaemonAgentStreamManager | null { return this._agentStream; }
|
|
81
|
+
get historyWriter(): ChatHistoryWriter { return this._historyWriter; }
|
|
82
|
+
get currentIdeType(): string | undefined { return this._currentIdeType; }
|
|
83
|
+
get currentProviderType(): string | undefined { return this._currentProviderType; }
|
|
84
|
+
|
|
85
|
+
/** Get CDP manager for a specific ideType.
|
|
86
|
+
* Returns null if no match — never falls back to another IDE. */
|
|
87
|
+
getCdp(ideType?: string): DaemonCdpManager | null {
|
|
88
|
+
const key = ideType || this._currentIdeType;
|
|
89
|
+
if (!key) return null;
|
|
90
|
+
const m = this._ctx.cdpManagers.get(key.toLowerCase());
|
|
91
|
+
if (m?.isConnected) return m;
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Get provider module — _currentProviderType (agentType priority) use.
|
|
97
|
+
*/
|
|
98
|
+
getProvider(overrideType?: string): ProviderModule | undefined {
|
|
99
|
+
const key = overrideType || this._currentProviderType || this._currentIdeType;
|
|
100
|
+
if (!key || !this._ctx.providerLoader) return undefined;
|
|
101
|
+
const result = this._ctx.providerLoader.resolve(key);
|
|
102
|
+
if (result) return result;
|
|
103
|
+
const baseType = key.split('_')[0];
|
|
104
|
+
if (baseType !== key) return this._ctx.providerLoader.resolve(baseType);
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** Get a provider script by name from ProviderLoader. */
|
|
109
|
+
getProviderScript(scriptName: string, params?: Record<string, string>, ideType?: string): string | null {
|
|
110
|
+
const provider = this.getProvider(ideType);
|
|
111
|
+
if (provider?.scripts) {
|
|
112
|
+
const fn = (provider.scripts as any)[scriptName];
|
|
113
|
+
if (typeof fn === 'function') {
|
|
114
|
+
const firstVal = params ? Object.values(params)[0] : undefined;
|
|
115
|
+
const script = firstVal ? fn(firstVal) : fn();
|
|
116
|
+
if (script) return script;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* per-category CDP script execute:
|
|
124
|
+
* IDE → cdp.evaluate(script) (main window)
|
|
125
|
+
* Extension → cdp.evaluateInSession(sessionId, script) (webview)
|
|
126
|
+
*/
|
|
127
|
+
async evaluateProviderScript(
|
|
128
|
+
scriptName: string,
|
|
129
|
+
params?: Record<string, string>,
|
|
130
|
+
timeout = 30000,
|
|
131
|
+
): Promise<{ result: any; category: string } | null> {
|
|
132
|
+
const provider = this.getProvider();
|
|
133
|
+
const script = this.getProviderScript(scriptName, params);
|
|
134
|
+
if (!script) return null;
|
|
135
|
+
|
|
136
|
+
const cdp = this.getCdp();
|
|
137
|
+
if (!cdp?.isConnected) return null;
|
|
138
|
+
|
|
139
|
+
// Extension: evaluateInSession
|
|
140
|
+
if (provider?.category === 'extension') {
|
|
141
|
+
let sessionId = this.getExtensionSessionId(provider);
|
|
142
|
+
if (!sessionId && this._agentStream) {
|
|
143
|
+
await this._agentStream.switchActiveAgent(cdp, provider.type);
|
|
144
|
+
await this._agentStream.syncAgentSessions(cdp);
|
|
145
|
+
sessionId = this.getExtensionSessionId(provider);
|
|
146
|
+
}
|
|
147
|
+
if (!sessionId) return null;
|
|
148
|
+
const result = await cdp.evaluateInSession(sessionId, script, timeout);
|
|
149
|
+
return { result, category: 'extension' };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// IDE (default): evaluate in main window
|
|
153
|
+
const result = await cdp.evaluate(script, timeout);
|
|
154
|
+
return { result, category: provider?.category || 'ide' };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** CLI adapter search */
|
|
158
|
+
getCliAdapter(type?: string): any | null {
|
|
159
|
+
const target = type || this._currentIdeType;
|
|
160
|
+
if (!target || !this._ctx.adapters) return null;
|
|
161
|
+
for (const [key, adapter] of this._ctx.adapters.entries()) {
|
|
162
|
+
if ((adapter as any).cliType === target || key.startsWith(target)) {
|
|
163
|
+
return adapter;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ─── Private helpers ──────────────────────────────
|
|
170
|
+
|
|
171
|
+
private getExtensionSessionId(provider: ProviderModule): string | null {
|
|
172
|
+
if (provider.category !== 'extension' || !this._agentStream) return null;
|
|
173
|
+
const managed = this._agentStream.getManagedAgent(provider.type);
|
|
174
|
+
return managed?.sessionId || null;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Extract ideType from _targetInstance */
|
|
178
|
+
private extractIdeType(args: any): string | undefined {
|
|
179
|
+
if (args?._targetInstance) {
|
|
180
|
+
let raw = args._targetInstance as string;
|
|
181
|
+
const ideMatch = raw.match(/:ide:(.+)$/);
|
|
182
|
+
const cliMatch = raw.match(/:cli:(.+)$/);
|
|
183
|
+
const acpMatch = raw.match(/:acp:(.+)$/);
|
|
184
|
+
if (ideMatch) raw = ideMatch[1];
|
|
185
|
+
else if (cliMatch) raw = cliMatch[1];
|
|
186
|
+
else if (acpMatch) raw = acpMatch[1];
|
|
187
|
+
|
|
188
|
+
if (this._ctx.instanceIdMap?.has(raw)) {
|
|
189
|
+
return this._ctx.instanceIdMap.get(raw)!;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const lastUnderscore = raw.lastIndexOf('_');
|
|
193
|
+
if (lastUnderscore > 0) return raw.substring(0, lastUnderscore);
|
|
194
|
+
return raw;
|
|
195
|
+
}
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
setAgentStreamManager(manager: DaemonAgentStreamManager): void {
|
|
200
|
+
this._agentStream = manager;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ─── Command Dispatcher ──────────────────────────
|
|
204
|
+
|
|
205
|
+
async handle(cmd: string, args: any): Promise<CommandResult> {
|
|
206
|
+
// Per-request: extract target IDE/provider type from args
|
|
207
|
+
this._currentIdeType = this.extractIdeType(args);
|
|
208
|
+
this._currentProviderType = args?.agentType || args?.providerType || this._currentIdeType;
|
|
209
|
+
|
|
210
|
+
// Commands without ideType CDP silently fail (prevent P2P retry spam)
|
|
211
|
+
if (!this._currentIdeType && !this._currentProviderType) {
|
|
212
|
+
const cdpCommands = ['send_chat', 'read_chat', 'list_chats', 'new_chat', 'switch_chat', 'set_mode', 'change_model', 'set_thought_level', 'resolve_action'];
|
|
213
|
+
if (cdpCommands.includes(cmd)) {
|
|
214
|
+
return { success: false, error: 'No ideType specified — cannot route command' };
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
try {
|
|
219
|
+
return await this.dispatch(cmd, args);
|
|
220
|
+
} catch (e: any) {
|
|
221
|
+
LOG.error('Command', `[${cmd}] Unhandled error: ${e?.message || e}`);
|
|
222
|
+
return { success: false, error: `Internal error: ${e?.message || 'unknown'}` };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
private async dispatch(cmd: string, args: any): Promise<CommandResult> {
|
|
227
|
+
switch (cmd) {
|
|
228
|
+
// ─── Chat commands (chat-commands.ts) ───────────────
|
|
229
|
+
case 'read_chat': return Chat.handleReadChat(this, args);
|
|
230
|
+
case 'chat_history': return Chat.handleChatHistory(this, args);
|
|
231
|
+
case 'send_chat': return Chat.handleSendChat(this, args);
|
|
232
|
+
case 'list_chats': return Chat.handleListChats(this, args);
|
|
233
|
+
case 'new_chat': return Chat.handleNewChat(this, args);
|
|
234
|
+
case 'switch_chat': return Chat.handleSwitchChat(this, args);
|
|
235
|
+
case 'set_mode': return Chat.handleSetMode(this, args);
|
|
236
|
+
case 'change_model': return Chat.handleChangeModel(this, args);
|
|
237
|
+
case 'set_thought_level': return Chat.handleSetThoughtLevel(this, args);
|
|
238
|
+
case 'resolve_action': return Chat.handleResolveAction(this, args);
|
|
239
|
+
|
|
240
|
+
// ─── CDP commands (cdp-commands.ts) ───────────────
|
|
241
|
+
case 'cdp_eval': return Cdp.handleCdpEval(this, args);
|
|
242
|
+
case 'cdp_screenshot':
|
|
243
|
+
case 'screenshot': return Cdp.handleScreenshot(this, args);
|
|
244
|
+
case 'cdp_command_exec': return Cdp.handleCdpCommand(this, args);
|
|
245
|
+
case 'cdp_batch': return Cdp.handleCdpBatch(this, args);
|
|
246
|
+
case 'cdp_remote_action': return Cdp.handleCdpRemoteAction(this, args);
|
|
247
|
+
case 'cdp_discover_agents': return Cdp.handleDiscoverAgents(this, args);
|
|
248
|
+
case 'cdp_dom_dump': return this.domHandlers.handleDomDump(args);
|
|
249
|
+
case 'cdp_dom_query': return this.domHandlers.handleDomQuery(args);
|
|
250
|
+
case 'cdp_dom_debug': return this.domHandlers.handleDomDebug(args);
|
|
251
|
+
|
|
252
|
+
// ─── File commands (cdp-commands.ts) ──────────────
|
|
253
|
+
case 'file_read': return Cdp.handleFileRead(this, args);
|
|
254
|
+
case 'file_write': return Cdp.handleFileWrite(this, args);
|
|
255
|
+
case 'file_list': return Cdp.handleFileList(this, args);
|
|
256
|
+
case 'file_list_browse': return Cdp.handleFileListBrowse(this, args);
|
|
257
|
+
|
|
258
|
+
// ─── VSCode API commands (not available) ────
|
|
259
|
+
case 'vscode_command_exec':
|
|
260
|
+
case 'execute_vscode_command': {
|
|
261
|
+
const resolvedCmd = args?.commandId || args?.command;
|
|
262
|
+
if (resolvedCmd === 'adhdev.captureCdpScreenshot') {
|
|
263
|
+
return Cdp.handleScreenshot(this, args);
|
|
264
|
+
}
|
|
265
|
+
return { success: false, error: `VSCode command not available: ${resolvedCmd || cmd}` };
|
|
266
|
+
}
|
|
267
|
+
case 'get_open_editors':
|
|
268
|
+
case 'open_tab':
|
|
269
|
+
case 'close_tab':
|
|
270
|
+
case 'open_folder':
|
|
271
|
+
case 'open_folder_picker':
|
|
272
|
+
case 'open_recent':
|
|
273
|
+
case 'get_commands':
|
|
274
|
+
return { success: false, error: `${cmd} requires bridge-extension (removed)` };
|
|
275
|
+
case 'get_recent_workspaces': return this.handleGetRecentWorkspaces(args);
|
|
276
|
+
|
|
277
|
+
// ─── Script manage ───────────────────
|
|
278
|
+
case 'refresh_scripts': return this.handleRefreshScripts(args);
|
|
279
|
+
|
|
280
|
+
// ─── Stream commands (stream-commands.ts) ───────────
|
|
281
|
+
case 'agent_stream_switch': return Stream.handleAgentStreamSwitch(this, args);
|
|
282
|
+
case 'agent_stream_read': return Stream.handleAgentStreamRead(this, args);
|
|
283
|
+
case 'agent_stream_send': return Stream.handleAgentStreamSend(this, args);
|
|
284
|
+
case 'agent_stream_resolve': return Stream.handleAgentStreamResolve(this, args);
|
|
285
|
+
case 'agent_stream_new': return Stream.handleAgentStreamNew(this, args);
|
|
286
|
+
case 'agent_stream_list_chats': return Stream.handleAgentStreamListChats(this, args);
|
|
287
|
+
case 'agent_stream_switch_session': return Stream.handleAgentStreamSwitchSession(this, args);
|
|
288
|
+
case 'agent_stream_focus': return Stream.handleAgentStreamFocus(this, args);
|
|
289
|
+
|
|
290
|
+
// ─── PTY Raw I/O (stream-commands.ts) ─────────
|
|
291
|
+
case 'pty_input': return Stream.handlePtyInput(this, args);
|
|
292
|
+
case 'pty_resize': return Stream.handlePtyResize(this, args);
|
|
293
|
+
|
|
294
|
+
// ─── Provider Settings (stream-commands.ts) ──────────
|
|
295
|
+
case 'get_provider_settings': return Stream.handleGetProviderSettings(this, args);
|
|
296
|
+
case 'set_provider_setting': return Stream.handleSetProviderSetting(this, args);
|
|
297
|
+
|
|
298
|
+
// ─── IDE Extension Settings (stream-commands.ts) ──────────
|
|
299
|
+
case 'get_ide_extensions': return Stream.handleGetIdeExtensions(this, args);
|
|
300
|
+
case 'set_ide_extension': return Stream.handleSetIdeExtension(this, args);
|
|
301
|
+
|
|
302
|
+
// ─── Extension Model / Mode Control (stream-commands.ts) ──────────
|
|
303
|
+
case 'list_extension_models': return Stream.handleExtensionScript(this, args, 'listModels');
|
|
304
|
+
case 'set_extension_model': return Stream.handleExtensionScript(this, args, 'setModel');
|
|
305
|
+
case 'list_extension_modes': return Stream.handleExtensionScript(this, args, 'listModes');
|
|
306
|
+
case 'set_extension_mode': return Stream.handleExtensionScript(this, args, 'setMode');
|
|
307
|
+
|
|
308
|
+
default:
|
|
309
|
+
return { success: false, error: `Unknown command: ${cmd}` };
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// ─── Misc (kept in handler — too small to extract) ───────
|
|
314
|
+
|
|
315
|
+
private async handleGetRecentWorkspaces(args: any): Promise<CommandResult> {
|
|
316
|
+
const config = loadConfig();
|
|
317
|
+
const cliRecent = config.recentCliWorkspaces || [];
|
|
318
|
+
return { success: true, result: cliRecent };
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
private async handleRefreshScripts(_args: any): Promise<CommandResult> {
|
|
322
|
+
if (this._ctx.providerLoader) {
|
|
323
|
+
this._ctx.providerLoader.reload();
|
|
324
|
+
return { success: true };
|
|
325
|
+
}
|
|
326
|
+
return { success: false, error: 'ProviderLoader not initialized' };
|
|
327
|
+
}
|
|
328
|
+
}
|