@adhdev/daemon-core 0.5.18 → 0.5.20

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 CHANGED
@@ -1611,14 +1611,16 @@ declare function readChatHistory(agentType: string, offset?: number, limit?: num
1611
1611
  };
1612
1612
 
1613
1613
  /**
1614
- * Daemon Commands — unified command handler
1614
+ * DaemonCommandHandler — unified command routing for CDP & CLI
1615
1615
  *
1616
- * Routes all functionality from legacy Extension commands.ts to Daemon.
1616
+ * Routes incoming commands (from server WS, P2P, or local WS) to
1617
+ * the correct CDP manager or CLI adapter.
1617
1618
  *
1618
- * Command implementations are split into sub-modules:
1619
- * - chat-commands.ts — Chat I/O, session management, mode/model control
1620
- * - cdp-commands.ts — CDP eval, screenshot, batch, remote actions, file ops
1621
- * - stream-commands.ts — Agent stream, PTY I/O, provider settings, extension scripts
1619
+ * Key concepts:
1620
+ * - extractIdeType(): determines target IDE from _targetInstance
1621
+ * - getCdp(): returns the DaemonCdpManager for current command
1622
+ * - getProvider(): returns the ProviderModule for current command
1623
+ * - handle(): main entry point, sets context then dispatches
1622
1624
  */
1623
1625
 
1624
1626
  interface CommandResult$1 {
@@ -1669,7 +1671,8 @@ declare class DaemonCommandHandler implements CommandHelpers {
1669
1671
  get historyWriter(): ChatHistoryWriter;
1670
1672
  get currentIdeType(): string | undefined;
1671
1673
  get currentProviderType(): string | undefined;
1672
- /** Get CDP manager for a specific ideType.
1674
+ /** Get CDP manager for a specific ideType or managerKey.
1675
+ * Supports exact match, multi-window prefix match, and instanceIdMap UUID lookup.
1673
1676
  * Returns null if no match — never falls back to another IDE. */
1674
1677
  getCdp(ideType?: string): DaemonCdpManager | null;
1675
1678
  /**
@@ -1690,7 +1693,7 @@ declare class DaemonCommandHandler implements CommandHelpers {
1690
1693
  /** CLI adapter search */
1691
1694
  getCliAdapter(type?: string): any | null;
1692
1695
  private getExtensionSessionId;
1693
- /** Extract ideType from _targetInstance */
1696
+ /** Extract ideType from _targetInstance or explicit ideType */
1694
1697
  private extractIdeType;
1695
1698
  setAgentStreamManager(manager: DaemonAgentStreamManager): void;
1696
1699
  handle(cmd: string, args: any): Promise<CommandResult$1>;
@@ -2116,6 +2119,8 @@ interface CommandRouterDeps {
2116
2119
  onPostChatCommand?: () => void;
2117
2120
  /** Get a connected CDP manager (for agent stream reset check) */
2118
2121
  getCdpLogFn?: (ideType: string) => (msg: string) => void;
2122
+ /** Package name for upgrade detection ('adhdev' or '@adhdev/daemon-standalone') */
2123
+ packageName?: string;
2119
2124
  }
2120
2125
  interface CommandRouterResult {
2121
2126
  success: boolean;
@@ -2219,6 +2224,72 @@ declare class DaemonStatusReporter {
2219
2224
  private simpleHash;
2220
2225
  }
2221
2226
 
2227
+ /**
2228
+ * Status Builders — shared conversion functions for ProviderState → ManagedEntry
2229
+ *
2230
+ * Used by:
2231
+ * - daemon-cloud (DaemonStatusReporter)
2232
+ * - daemon-standalone (StandaloneServer.getStatus)
2233
+ *
2234
+ * Consolidates duplicated ProviderState→ManagedEntry mapping that was
2235
+ * previously copy-pasted between cloud and standalone codebases.
2236
+ */
2237
+
2238
+ /**
2239
+ * Find a CDP manager by key, with prefix matching for multi-window support.
2240
+ *
2241
+ * Lookup order:
2242
+ * 1. Exact match: cdpManagers.get(key)
2243
+ * 2. Prefix match: key starts with `${ideType}_` (multi-window: "cursor_remote_vs")
2244
+ * 3. null
2245
+ *
2246
+ * This replaces raw `cdpManagers.get(ideType)` calls that broke when
2247
+ * multi-window keys like "cursor_remote_vs" were used.
2248
+ */
2249
+ declare function findCdpManager(cdpManagers: Map<string, DaemonCdpManager>, key: string): DaemonCdpManager | null;
2250
+ /**
2251
+ * Check if any CDP manager matches the given key (exact or prefix).
2252
+ */
2253
+ declare function hasCdpManager(cdpManagers: Map<string, DaemonCdpManager>, key: string): boolean;
2254
+ /**
2255
+ * Check if any CDP manager matching the key is connected.
2256
+ */
2257
+ declare function isCdpConnected(cdpManagers: Map<string, DaemonCdpManager>, key: string): boolean;
2258
+ /**
2259
+ * Convert IdeProviderState[] → ManagedIdeEntry[]
2260
+ *
2261
+ * @param ideStates - from instanceManager.collectAllStates() filtered to ide
2262
+ * @param cdpManagers - for cdpConnected lookup
2263
+ * @param opts.detectedIdes - include CDPs that have no instance yet
2264
+ */
2265
+ declare function buildManagedIdes(ideStates: IdeProviderState[], cdpManagers: Map<string, DaemonCdpManager>, opts?: {
2266
+ detectedIdes?: {
2267
+ id: string;
2268
+ installed: boolean;
2269
+ }[];
2270
+ }): ManagedIdeEntry[];
2271
+ /**
2272
+ * Convert CliProviderState[] → ManagedCliEntry[]
2273
+ */
2274
+ declare function buildManagedClis(cliStates: CliProviderState[]): ManagedCliEntry[];
2275
+ /**
2276
+ * Convert AcpProviderState[] → ManagedAcpEntry[]
2277
+ */
2278
+ declare function buildManagedAcps(acpStates: AcpProviderState[]): ManagedAcpEntry[];
2279
+ /**
2280
+ * Convenience: collect & build all managed entries from instanceManager
2281
+ */
2282
+ declare function buildAllManagedEntries(allStates: ProviderState[], cdpManagers: Map<string, DaemonCdpManager>, opts?: {
2283
+ detectedIdes?: {
2284
+ id: string;
2285
+ installed: boolean;
2286
+ }[];
2287
+ }): {
2288
+ managedIdes: ManagedIdeEntry[];
2289
+ managedClis: ManagedCliEntry[];
2290
+ managedAcps: ManagedAcpEntry[];
2291
+ };
2292
+
2222
2293
  /**
2223
2294
  * ADHDev Daemon — unified logger (v2)
2224
2295
  *
@@ -2729,9 +2800,10 @@ declare class DevServer {
2729
2800
  private handleAutoImplSSE;
2730
2801
  private handleAutoImplCancel;
2731
2802
  private sendAutoImplSSE;
2732
- /** Get CDP manager — matching IDE when ideType specified, first connected one otherwise */
2803
+ /** Get CDP manager — matching IDE when ideType specified, first connected one otherwise.
2804
+ * DevServer is a debugging tool so first-connected fallback is acceptable,
2805
+ * but callers should pass ideType when possible. */
2733
2806
  private getCdp;
2734
- private getAnyCdp;
2735
2807
  private json;
2736
2808
  private readBody;
2737
2809
  /** GET /api/cli/status — list all running CLI/ACP instances with state */
@@ -2875,4 +2947,4 @@ declare function initDaemonComponents(config: DaemonInitConfig): Promise<DaemonC
2875
2947
  */
2876
2948
  declare function shutdownDaemonComponents(components: DaemonComponents): Promise<void>;
2877
2949
 
2878
- export { type AcpConfigOption, type AcpMode, AcpProviderInstance, type AcpProviderState, type ActiveChatData, type AgentEntry, AgentStreamPoller, type AgentStreamPollerDeps, type AvailableProviderInfo, CdpDomHandlers, type CdpInitializerConfig, type CdpScannerOptions, type CdpSetupContext, type CdpTargetFilter, type ChatMessage, type CliAdapter, CliProviderInstance, type CliProviderState, type CommandContext, type CommandResult$1 as CommandResult, type CommandRouterDeps, type CommandRouterResult, type CommandResult$2 as CoreCommandResult, DAEMON_WS_PATH, DEFAULT_DAEMON_PORT, DaemonAgentStreamManager, DaemonCdpInitializer, DaemonCdpManager, DaemonCdpScanner, DaemonCliManager, DaemonCommandHandler, DaemonCommandRouter, type DaemonComponents, type DaemonCoreOptions, type DaemonEvent, type DaemonInitConfig, DaemonStatusReporter, type DetectedIde, type DetectedIdeInfo, DevServer, type ExtensionInfo$1 as ExtensionInfo, type ExtensionProviderState, type HostMemorySnapshot, type IDEInfo, type IDaemonCore, IdeProviderInstance, type IdeProviderState, type ExtensionInfo as InstallerExtensionInfo, LOG, type LogEntry, type LogLevel, type MachineInfo, type ManagedAcpEntry, type ManagedAgentStream, type ManagedCliEntry, type ManagedIdeEntry, ProviderCliAdapter, type ProviderConfig, type ProviderErrorReason, type ProviderInfo, ProviderInstanceManager, ProviderLoader, type ProviderModule, type ProviderStatus, type ProviderVersionInfo, type ScopedLogger, type SetupIdeInstanceOptions, type StatusReportPayload, type StatusResponse, type SystemInfo, VersionArchive, type VersionHistory, type WorkspaceActivity, type WorkspaceEntry, addCliHistory, connectCdpManager, detectAllVersions, detectCLIs, detectIDEs, getAIExtensions, getAvailableIdeIds, getHostMemorySnapshot, getLogLevel, getRecentCommands, getRecentLogs, getWorkspaceActivity, getWorkspaceState, initDaemonComponents, installExtensions, installGlobalInterceptor, isExtensionInstalled, isIdeRunning, isSetupComplete, killIdeProcess, launchIDE, launchWithCdp, loadConfig, logCommand, markSetupComplete, probeCdpPort, readChatHistory, registerExtensionProviders, resetConfig, saveConfig, setLogLevel, setupIdeInstance, shutdownDaemonComponents, updateConfig };
2950
+ export { type AcpConfigOption, type AcpMode, AcpProviderInstance, type AcpProviderState, type ActiveChatData, type AgentEntry, AgentStreamPoller, type AgentStreamPollerDeps, type AvailableProviderInfo, CdpDomHandlers, type CdpInitializerConfig, type CdpScannerOptions, type CdpSetupContext, type CdpTargetFilter, type ChatMessage, type CliAdapter, CliProviderInstance, type CliProviderState, type CommandContext, type CommandResult$1 as CommandResult, type CommandRouterDeps, type CommandRouterResult, type CommandResult$2 as CoreCommandResult, DAEMON_WS_PATH, DEFAULT_DAEMON_PORT, DaemonAgentStreamManager, DaemonCdpInitializer, DaemonCdpManager, DaemonCdpScanner, DaemonCliManager, DaemonCommandHandler, DaemonCommandRouter, type DaemonComponents, type DaemonCoreOptions, type DaemonEvent, type DaemonInitConfig, DaemonStatusReporter, type DetectedIde, type DetectedIdeInfo, DevServer, type ExtensionInfo$1 as ExtensionInfo, type ExtensionProviderState, type HostMemorySnapshot, type IDEInfo, type IDaemonCore, IdeProviderInstance, type IdeProviderState, type ExtensionInfo as InstallerExtensionInfo, LOG, type LogEntry, type LogLevel, type MachineInfo, type ManagedAcpEntry, type ManagedAgentStream, type ManagedCliEntry, type ManagedIdeEntry, ProviderCliAdapter, type ProviderConfig, type ProviderErrorReason, type ProviderInfo, ProviderInstanceManager, ProviderLoader, type ProviderModule, type ProviderStatus, type ProviderVersionInfo, type ScopedLogger, type SetupIdeInstanceOptions, type StatusReportPayload, type StatusResponse, type SystemInfo, VersionArchive, type VersionHistory, type WorkspaceActivity, type WorkspaceEntry, addCliHistory, buildAllManagedEntries, buildManagedAcps, buildManagedClis, buildManagedIdes, connectCdpManager, detectAllVersions, detectCLIs, detectIDEs, findCdpManager, getAIExtensions, getAvailableIdeIds, getHostMemorySnapshot, getLogLevel, getRecentCommands, getRecentLogs, getWorkspaceActivity, getWorkspaceState, hasCdpManager, initDaemonComponents, installExtensions, installGlobalInterceptor, isCdpConnected, isExtensionInstalled, isIdeRunning, isSetupComplete, killIdeProcess, launchIDE, launchWithCdp, loadConfig, logCommand, markSetupComplete, probeCdpPort, readChatHistory, registerExtensionProviders, resetConfig, saveConfig, setLogLevel, setupIdeInstance, shutdownDaemonComponents, updateConfig };
package/dist/index.js CHANGED
@@ -380,10 +380,15 @@ __export(index_exports, {
380
380
  ProviderLoader: () => ProviderLoader,
381
381
  VersionArchive: () => VersionArchive,
382
382
  addCliHistory: () => addCliHistory,
383
+ buildAllManagedEntries: () => buildAllManagedEntries,
384
+ buildManagedAcps: () => buildManagedAcps,
385
+ buildManagedClis: () => buildManagedClis,
386
+ buildManagedIdes: () => buildManagedIdes,
383
387
  connectCdpManager: () => connectCdpManager,
384
388
  detectAllVersions: () => detectAllVersions,
385
389
  detectCLIs: () => detectCLIs,
386
390
  detectIDEs: () => detectIDEs,
391
+ findCdpManager: () => findCdpManager,
387
392
  getAIExtensions: () => getAIExtensions,
388
393
  getAvailableIdeIds: () => getAvailableIdeIds,
389
394
  getHostMemorySnapshot: () => getHostMemorySnapshot,
@@ -392,9 +397,11 @@ __export(index_exports, {
392
397
  getRecentLogs: () => getRecentLogs,
393
398
  getWorkspaceActivity: () => getWorkspaceActivity,
394
399
  getWorkspaceState: () => getWorkspaceState,
400
+ hasCdpManager: () => hasCdpManager,
395
401
  initDaemonComponents: () => initDaemonComponents,
396
402
  installExtensions: () => installExtensions,
397
403
  installGlobalInterceptor: () => installGlobalInterceptor,
404
+ isCdpConnected: () => isCdpConnected,
398
405
  isExtensionInstalled: () => isExtensionInstalled,
399
406
  isIdeRunning: () => isIdeRunning,
400
407
  isSetupComplete: () => isSetupComplete,
@@ -2968,6 +2975,119 @@ var DaemonCdpInitializer = class {
2968
2975
  }
2969
2976
  };
2970
2977
 
2978
+ // src/status/builders.ts
2979
+ function findCdpManager(cdpManagers, key) {
2980
+ const exact = cdpManagers.get(key);
2981
+ if (exact) return exact;
2982
+ const prefix = key + "_";
2983
+ for (const [k, m] of cdpManagers.entries()) {
2984
+ if (k.startsWith(prefix) && m.isConnected) return m;
2985
+ }
2986
+ return null;
2987
+ }
2988
+ function hasCdpManager(cdpManagers, key) {
2989
+ if (cdpManagers.has(key)) return true;
2990
+ const prefix = key + "_";
2991
+ for (const k of cdpManagers.keys()) {
2992
+ if (k.startsWith(prefix)) return true;
2993
+ }
2994
+ return false;
2995
+ }
2996
+ function isCdpConnected(cdpManagers, key) {
2997
+ const m = findCdpManager(cdpManagers, key);
2998
+ return m?.isConnected ?? false;
2999
+ }
3000
+ function buildManagedIdes(ideStates, cdpManagers, opts) {
3001
+ const result = [];
3002
+ for (const state of ideStates) {
3003
+ const cdpConnected = state.cdpConnected ?? isCdpConnected(cdpManagers, state.type);
3004
+ result.push({
3005
+ ideType: state.type,
3006
+ ideVersion: "",
3007
+ instanceId: state.instanceId || state.type,
3008
+ workspace: state.workspace || null,
3009
+ terminals: 0,
3010
+ aiAgents: [],
3011
+ activeChat: state.activeChat,
3012
+ chats: [],
3013
+ agentStreams: state.extensions.map((ext) => ({
3014
+ agentType: ext.type,
3015
+ agentName: ext.name,
3016
+ extensionId: ext.type,
3017
+ status: ext.status || "idle",
3018
+ messages: ext.activeChat?.messages || [],
3019
+ inputContent: ext.activeChat?.inputContent || "",
3020
+ activeModal: ext.activeChat?.activeModal || null
3021
+ })),
3022
+ cdpConnected,
3023
+ currentModel: state.currentModel,
3024
+ currentPlan: state.currentPlan,
3025
+ currentAutoApprove: state.currentAutoApprove
3026
+ });
3027
+ }
3028
+ if (opts?.detectedIdes) {
3029
+ const coveredTypes = new Set(ideStates.map((s) => s.type));
3030
+ for (const ide of opts.detectedIdes) {
3031
+ if (!ide.installed || coveredTypes.has(ide.id)) continue;
3032
+ if (!isCdpConnected(cdpManagers, ide.id)) continue;
3033
+ result.push({
3034
+ ideType: ide.id,
3035
+ ideVersion: "",
3036
+ instanceId: ide.id,
3037
+ workspace: null,
3038
+ terminals: 0,
3039
+ aiAgents: [],
3040
+ activeChat: null,
3041
+ chats: [],
3042
+ agentStreams: [],
3043
+ cdpConnected: true,
3044
+ currentModel: void 0,
3045
+ currentPlan: void 0
3046
+ });
3047
+ }
3048
+ }
3049
+ return result;
3050
+ }
3051
+ function buildManagedClis(cliStates) {
3052
+ return cliStates.map((s) => ({
3053
+ id: s.instanceId,
3054
+ instanceId: s.instanceId,
3055
+ cliType: s.type,
3056
+ cliName: s.name,
3057
+ status: s.status,
3058
+ mode: s.mode,
3059
+ workspace: s.workspace || "",
3060
+ activeChat: s.activeChat
3061
+ }));
3062
+ }
3063
+ function buildManagedAcps(acpStates) {
3064
+ return acpStates.map((s) => ({
3065
+ id: s.instanceId,
3066
+ acpType: s.type,
3067
+ acpName: s.name,
3068
+ status: s.status,
3069
+ mode: "chat",
3070
+ workspace: s.workspace || "",
3071
+ activeChat: s.activeChat,
3072
+ currentModel: s.currentModel,
3073
+ currentPlan: s.currentPlan,
3074
+ acpConfigOptions: s.acpConfigOptions,
3075
+ acpModes: s.acpModes,
3076
+ errorMessage: s.errorMessage,
3077
+ errorReason: s.errorReason
3078
+ }));
3079
+ }
3080
+ function buildAllManagedEntries(allStates, cdpManagers, opts) {
3081
+ const ideStates = allStates.filter((s) => s.category === "ide");
3082
+ const cliStates = allStates.filter((s) => s.category === "cli");
3083
+ const acpStates = allStates.filter((s) => s.category === "acp");
3084
+ return {
3085
+ managedIdes: buildManagedIdes(ideStates, cdpManagers, opts),
3086
+ managedClis: buildManagedClis(cliStates),
3087
+ managedAcps: buildManagedAcps(acpStates)
3088
+ };
3089
+ }
3090
+
2971
3091
  // src/commands/handler.ts
2972
3092
  init_config();
2973
3093
 
@@ -4284,12 +4404,14 @@ var DaemonCommandHandler = class {
4284
4404
  get currentProviderType() {
4285
4405
  return this._currentProviderType;
4286
4406
  }
4287
- /** Get CDP manager for a specific ideType.
4407
+ /** Get CDP manager for a specific ideType or managerKey.
4408
+ * Supports exact match, multi-window prefix match, and instanceIdMap UUID lookup.
4288
4409
  * Returns null if no match — never falls back to another IDE. */
4289
4410
  getCdp(ideType) {
4290
4411
  const key = ideType || this._currentIdeType;
4291
4412
  if (!key) return null;
4292
- const m = this._ctx.cdpManagers.get(key.toLowerCase());
4413
+ const resolved = this._ctx.instanceIdMap?.get(key) || key;
4414
+ const m = findCdpManager(this._ctx.cdpManagers, resolved.toLowerCase());
4293
4415
  if (m?.isConnected) return m;
4294
4416
  return null;
4295
4417
  }
@@ -4360,10 +4482,18 @@ var DaemonCommandHandler = class {
4360
4482
  const managed = this._agentStream.getManagedAgent(provider.type);
4361
4483
  return managed?.sessionId || null;
4362
4484
  }
4363
- /** Extract ideType from _targetInstance */
4485
+ /** Extract ideType from _targetInstance or explicit ideType */
4364
4486
  extractIdeType(args) {
4365
- if (args?.ideType && this._ctx.cdpManagers.has(args.ideType)) {
4366
- return args.ideType;
4487
+ if (args?.ideType) {
4488
+ if (this._ctx.cdpManagers.has(args.ideType)) {
4489
+ return args.ideType;
4490
+ }
4491
+ const found = findCdpManager(this._ctx.cdpManagers, args.ideType);
4492
+ if (found) {
4493
+ for (const [k, m] of this._ctx.cdpManagers.entries()) {
4494
+ if (m === found) return k;
4495
+ }
4496
+ }
4367
4497
  }
4368
4498
  if (args?._targetInstance) {
4369
4499
  let raw = args._targetInstance;
@@ -4379,9 +4509,10 @@ var DaemonCommandHandler = class {
4379
4509
  if (this._ctx.cdpManagers.has(raw)) {
4380
4510
  return raw;
4381
4511
  }
4382
- if (!ideMatch && !cliMatch && !acpMatch) {
4383
- for (const [key, mgr] of this._ctx.cdpManagers.entries()) {
4384
- if (mgr.isConnected) return key;
4512
+ const found = findCdpManager(this._ctx.cdpManagers, raw);
4513
+ if (found) {
4514
+ for (const [k, m] of this._ctx.cdpManagers.entries()) {
4515
+ if (m === found) return k;
4385
4516
  }
4386
4517
  }
4387
4518
  const lastUnderscore = raw.lastIndexOf("_");
@@ -6113,9 +6244,11 @@ var DaemonCommandRouter = class {
6113
6244
  LOG.info("Upgrade", "Remote upgrade requested from dashboard");
6114
6245
  try {
6115
6246
  const { execSync: execSync7 } = await import("child_process");
6116
- const latest = execSync7("npm view adhdev version", { encoding: "utf-8", timeout: 1e4 }).trim();
6117
- LOG.info("Upgrade", `Latest available: v${latest}`);
6118
- execSync7("npm install -g adhdev@latest", {
6247
+ const isStandalone = this.deps.packageName === "@adhdev/daemon-standalone" || process.argv[1]?.includes("daemon-standalone");
6248
+ const pkgName = isStandalone ? "@adhdev/daemon-standalone" : "adhdev";
6249
+ const latest = execSync7(`npm view ${pkgName} version`, { encoding: "utf-8", timeout: 1e4 }).trim();
6250
+ LOG.info("Upgrade", `Latest ${pkgName}: v${latest}`);
6251
+ execSync7(`npm install -g ${pkgName}@latest`, {
6119
6252
  encoding: "utf-8",
6120
6253
  timeout: 6e4,
6121
6254
  stdio: ["pipe", "pipe", "pipe"]
@@ -6123,8 +6256,15 @@ var DaemonCommandRouter = class {
6123
6256
  LOG.info("Upgrade", `\u2705 Upgraded to v${latest}`);
6124
6257
  setTimeout(() => {
6125
6258
  LOG.info("Upgrade", "Restarting daemon with new version...");
6259
+ try {
6260
+ const path13 = require("path");
6261
+ const fs10 = require("fs");
6262
+ const pidFile = path13.join(process.env.HOME || process.env.USERPROFILE || "", ".adhdev", "daemon.pid");
6263
+ if (fs10.existsSync(pidFile)) fs10.unlinkSync(pidFile);
6264
+ } catch {
6265
+ }
6126
6266
  const { spawn: spawn3 } = require("child_process");
6127
- const child = spawn3(process.execPath, [process.argv[1], "daemon", "-p", "19222"], {
6267
+ const child = spawn3(process.execPath, process.argv.slice(1), {
6128
6268
  detached: true,
6129
6269
  stdio: "ignore",
6130
6270
  env: { ...process.env }
@@ -6332,54 +6472,10 @@ var DaemonStatusReporter = class {
6332
6472
  LOG.info("StatusReport", summary);
6333
6473
  }
6334
6474
  }
6335
- const managedIdes = ideStates.map((s) => ({
6336
- ideType: s.type,
6337
- ideVersion: "",
6338
- instanceId: s.instanceId,
6339
- workspace: s.workspace || null,
6340
- terminals: 0,
6341
- aiAgents: [],
6342
- activeChat: s.activeChat,
6343
- chats: [],
6344
- agentStreams: s.extensions.map((ext) => ({
6345
- agentType: ext.type,
6346
- agentName: ext.name,
6347
- extensionId: ext.type,
6348
- status: ext.status || "idle",
6349
- messages: ext.activeChat?.messages || [],
6350
- inputContent: ext.activeChat?.inputContent || "",
6351
- activeModal: ext.activeChat?.activeModal || null
6352
- })),
6353
- cdpConnected: s.cdpConnected,
6354
- currentModel: s.currentModel,
6355
- currentPlan: s.currentPlan,
6356
- currentAutoApprove: s.currentAutoApprove
6357
- }));
6358
- const managedClis = cliStates.map((s) => ({
6359
- id: s.instanceId,
6360
- instanceId: s.instanceId,
6361
- cliType: s.type,
6362
- cliName: s.name,
6363
- status: s.status,
6364
- mode: s.mode,
6365
- workspace: s.workspace || "",
6366
- activeChat: s.activeChat
6367
- }));
6368
- const managedAcps = acpStates.map((s) => ({
6369
- id: s.instanceId,
6370
- acpType: s.type,
6371
- acpName: s.name,
6372
- status: s.status,
6373
- mode: s.mode,
6374
- workspace: s.workspace || "",
6375
- activeChat: s.activeChat,
6376
- currentModel: s.currentModel,
6377
- currentPlan: s.currentPlan,
6378
- acpConfigOptions: s.acpConfigOptions,
6379
- acpModes: s.acpModes,
6380
- errorMessage: s.errorMessage,
6381
- errorReason: s.errorReason
6382
- }));
6475
+ const { managedIdes, managedClis, managedAcps } = buildAllManagedEntries(
6476
+ allStates,
6477
+ this.deps.cdpManagers
6478
+ );
6383
6479
  const cfg = loadConfig();
6384
6480
  const wsState = getWorkspaceState(cfg);
6385
6481
  const memSnap = getHostMemorySnapshot();
@@ -6426,37 +6522,34 @@ var DaemonStatusReporter = class {
6426
6522
  LOG.debug("P2P", `sent (${JSON.stringify(payload).length} bytes)`);
6427
6523
  }
6428
6524
  if (opts?.p2pOnly) return;
6429
- const plan = serverConn.getUserPlan();
6430
- if (plan !== "free") {
6431
- const wsPayload = {
6432
- daemonMode: true,
6433
- machineNickname: payload.machineNickname,
6434
- defaultWorkspaceId: wsState.defaultWorkspaceId,
6435
- workspaceCount: (wsState.workspaces || []).length,
6436
- // managedIdes: server only saves id, type, cdpConnected
6437
- managedIdes: managedIdes.map((ide) => ({
6438
- ideType: ide.ideType,
6439
- instanceId: ide.instanceId,
6440
- cdpConnected: ide.cdpConnected
6441
- })),
6442
- // managedClis: server only saves id, type, name
6443
- managedClis: managedClis.map((c) => ({
6444
- id: c.id,
6445
- cliType: c.cliType,
6446
- cliName: c.cliName
6447
- })),
6448
- // managedAcps: server only saves id, type, name
6449
- managedAcps: managedAcps?.map((a) => ({
6450
- id: a.id,
6451
- acpType: a.acpType,
6452
- acpName: a.acpName
6453
- })),
6454
- p2p: payload.p2p,
6455
- timestamp: now
6456
- };
6457
- serverConn.sendMessage("status_report", wsPayload);
6458
- LOG.debug("Server", `sent status_report (${JSON.stringify(wsPayload).length} bytes)`);
6459
- }
6525
+ const wsPayload = {
6526
+ daemonMode: true,
6527
+ machineNickname: payload.machineNickname,
6528
+ defaultWorkspaceId: wsState.defaultWorkspaceId,
6529
+ workspaceCount: (wsState.workspaces || []).length,
6530
+ // managedIdes: server only saves id, type, cdpConnected
6531
+ managedIdes: managedIdes.map((ide) => ({
6532
+ ideType: ide.ideType,
6533
+ instanceId: ide.instanceId,
6534
+ cdpConnected: ide.cdpConnected
6535
+ })),
6536
+ // managedClis: server only saves id, type, name
6537
+ managedClis: managedClis.map((c) => ({
6538
+ id: c.id,
6539
+ cliType: c.cliType,
6540
+ cliName: c.cliName
6541
+ })),
6542
+ // managedAcps: server only saves id, type, name
6543
+ managedAcps: managedAcps?.map((a) => ({
6544
+ id: a.id,
6545
+ acpType: a.acpType,
6546
+ acpName: a.acpName
6547
+ })),
6548
+ p2p: payload.p2p,
6549
+ timestamp: now
6550
+ };
6551
+ serverConn.sendMessage("status_report", wsPayload);
6552
+ LOG.debug("Server", `sent status_report (${JSON.stringify(wsPayload).length} bytes)`);
6460
6553
  }
6461
6554
  // ─── P2P ─────────────────────────────────────────
6462
6555
  sendP2PPayload(payload) {
@@ -9935,7 +10028,10 @@ var DevServer = class _DevServer {
9935
10028
  this.json(res, 400, { error: "expression required" });
9936
10029
  return;
9937
10030
  }
9938
- const cdp = ideType ? this.cdpManagers.get(ideType) : this.getAnyCdp();
10031
+ const cdp = this.getCdp(ideType);
10032
+ if (!cdp && !ideType) {
10033
+ LOG.warn("DevServer", "CDP evaluate without ideType \u2014 picked first connected manager");
10034
+ }
9939
10035
  if (!cdp?.isConnected) {
9940
10036
  this.json(res, 503, { error: "No CDP connection available" });
9941
10037
  return;
@@ -10175,7 +10271,7 @@ var DevServer = class _DevServer {
10175
10271
  this.sendSSE({ type: "watch_error", error: `Script '${this.watchScriptName}' not found` });
10176
10272
  return;
10177
10273
  }
10178
- const cdp = this.getAnyCdp();
10274
+ const cdp = this.getCdp();
10179
10275
  if (!cdp) {
10180
10276
  this.sendSSE({ type: "watch_error", error: "No CDP connection" });
10181
10277
  return;
@@ -11928,20 +12024,24 @@ data: ${JSON.stringify(msg.data)}
11928
12024
  }
11929
12025
  }
11930
12026
  }
11931
- /** Get CDP manager — matching IDE when ideType specified, first connected one otherwise */
12027
+ /** Get CDP manager — matching IDE when ideType specified, first connected one otherwise.
12028
+ * DevServer is a debugging tool so first-connected fallback is acceptable,
12029
+ * but callers should pass ideType when possible. */
11932
12030
  getCdp(ideType) {
11933
12031
  if (ideType) {
11934
12032
  const cdp = this.cdpManagers.get(ideType);
11935
12033
  if (cdp?.isConnected) return cdp;
12034
+ for (const [k, m] of this.cdpManagers.entries()) {
12035
+ if (k.startsWith(ideType + "_") && m.isConnected) return m;
12036
+ }
12037
+ LOG.warn("DevServer", `getCdp: no manager found for ideType '${ideType}', available: [${[...this.cdpManagers.keys()].join(", ")}]`);
12038
+ return null;
11936
12039
  }
11937
12040
  for (const cdp of this.cdpManagers.values()) {
11938
12041
  if (cdp.isConnected) return cdp;
11939
12042
  }
11940
12043
  return null;
11941
12044
  }
11942
- getAnyCdp() {
11943
- return this.getCdp();
11944
- }
11945
12045
  json(res, status, data) {
11946
12046
  res.writeHead(status, { "Content-Type": "application/json" });
11947
12047
  res.end(JSON.stringify(data, null, 2));
@@ -12537,10 +12637,15 @@ async function shutdownDaemonComponents(components) {
12537
12637
  ProviderLoader,
12538
12638
  VersionArchive,
12539
12639
  addCliHistory,
12640
+ buildAllManagedEntries,
12641
+ buildManagedAcps,
12642
+ buildManagedClis,
12643
+ buildManagedIdes,
12540
12644
  connectCdpManager,
12541
12645
  detectAllVersions,
12542
12646
  detectCLIs,
12543
12647
  detectIDEs,
12648
+ findCdpManager,
12544
12649
  getAIExtensions,
12545
12650
  getAvailableIdeIds,
12546
12651
  getHostMemorySnapshot,
@@ -12549,9 +12654,11 @@ async function shutdownDaemonComponents(components) {
12549
12654
  getRecentLogs,
12550
12655
  getWorkspaceActivity,
12551
12656
  getWorkspaceState,
12657
+ hasCdpManager,
12552
12658
  initDaemonComponents,
12553
12659
  installExtensions,
12554
12660
  installGlobalInterceptor,
12661
+ isCdpConnected,
12555
12662
  isExtensionInstalled,
12556
12663
  isIdeRunning,
12557
12664
  isSetupComplete,