@adhdev/daemon-core 0.6.66 → 0.6.68

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
@@ -178,6 +178,7 @@ interface ADHDevConfig {
178
178
  }>;
179
179
  }>;
180
180
  disableUpstream?: boolean;
181
+ providerDir?: string;
181
182
  }
182
183
  interface CliHistoryEntry {
183
184
  category?: 'ide' | 'cli' | 'acp';
@@ -238,14 +239,13 @@ declare function getWorkspaceState(config: ADHDevConfig): {
238
239
  /**
239
240
  * ADHDev Shared Types — Cross-package type definitions
240
241
  *
241
- * Types used across daemon-core, web-core, web-cloud, server, etc.
242
+ * Types used across daemon-core, web-core, and downstream consumers.
242
243
  * Import via: import type { ... } from '@adhdev/daemon-core/types'
243
244
  *
244
245
  * IMPORTANT: This file must remain runtime-free (types only).
245
- * Cloudflare Workers (server) can import type-only modules safely.
246
246
  */
247
247
 
248
- /** IDE entry as reported by daemon to server/dashboard */
248
+ /** IDE entry as reported by daemon to dashboard */
249
249
  interface ManagedIdeEntry {
250
250
  ideType: string;
251
251
  ideVersion: string;
@@ -261,7 +261,7 @@ interface ManagedIdeEntry {
261
261
  currentPlan?: string;
262
262
  currentAutoApprove?: string;
263
263
  }
264
- /** CLI entry as reported by daemon to server/dashboard */
264
+ /** CLI entry as reported by daemon to dashboard */
265
265
  interface ManagedCliEntry {
266
266
  id: string;
267
267
  instanceId: string;
@@ -272,7 +272,7 @@ interface ManagedCliEntry {
272
272
  workspace: string;
273
273
  activeChat: ActiveChatData | null;
274
274
  }
275
- /** ACP entry as reported by daemon to server/dashboard */
275
+ /** ACP entry as reported by daemon to dashboard */
276
276
  interface ManagedAcpEntry {
277
277
  id: string;
278
278
  acpType: string;
@@ -705,7 +705,7 @@ interface ProviderSettingSchema extends ProviderSettingDef {
705
705
  /**
706
706
  * ADHDev Daemon Core — Shared Types
707
707
  *
708
- * Shared types referenced by daemon-core, daemon-standalone, daemon-cloud, web-core.
708
+ * Shared types referenced by daemon-core, daemon-standalone, and web-core.
709
709
  * When modifying this file, also update interface contracts in AGENT_PROTOCOL.md.
710
710
  */
711
711
 
@@ -833,7 +833,7 @@ interface AgentEntry {
833
833
  /**
834
834
  * DaemonCore — Core daemon orchestrator interface
835
835
  *
836
- * Both daemon-standalone and daemon-cloud use this interface via daemon-core.
836
+ * Provides the core daemon orchestrator interface consumed by daemon-standalone.
837
837
  * Actual implementation extracted from launcher and placed in this package.
838
838
  */
839
839
 
@@ -1337,6 +1337,8 @@ declare class DaemonCdpManager {
1337
1337
  private isMainPageUrl;
1338
1338
  /** Connected page title (includes workspace name) */
1339
1339
  get pageTitle(): string;
1340
+ /** Connected target ID */
1341
+ get targetId(): string | null;
1340
1342
  /**
1341
1343
  * Query all workbench pages on port (static)
1342
1344
  * Returns multiple entries if multiple IDE windows are open on same port
@@ -1595,8 +1597,7 @@ declare class DaemonAgentStreamManager {
1595
1597
  /**
1596
1598
  * AgentStreamPoller — Periodic agent stream polling + extension dynamic management
1597
1599
  *
1598
- * Extracted from cloud daemon's startAgentStreamPolling() logic.
1599
- * Used by both daemon-cloud and daemon-standalone.
1600
+ * Handles periodic agent stream polling and extension dynamic management.
1600
1601
  *
1601
1602
  * Responsibilities:
1602
1603
  * 1. Refresh extension providers in CDP managers (config changes take effect immediately)
@@ -1936,11 +1937,8 @@ declare class IdeProviderInstance implements ProviderInstance {
1936
1937
  /**
1937
1938
  * DaemonCdpSetup — Shared CDP initialization helpers
1938
1939
  *
1939
- * Extracted from daemon-cloud/adhdev-daemon.ts setupCdpManager()
1940
- * and daemon-standalone/index.ts inline CDP setup logic.
1941
- *
1942
- * Used by both daemon-cloud and daemon-standalone to ensure
1943
- * consistent CDP → ProviderInstance registration.
1940
+ * Common CDP setup logic for consistent
1941
+ * CDP ProviderInstance registration.
1944
1942
  */
1945
1943
 
1946
1944
  interface CdpSetupContext {
@@ -1949,7 +1947,7 @@ interface CdpSetupContext {
1949
1947
  cdpManagers: Map<string, DaemonCdpManager>;
1950
1948
  /** UUID instanceId → CDP manager key mapping */
1951
1949
  instanceIdMap: Map<string, string>;
1952
- /** Server connection (optional, cloud-only) */
1950
+ /** Server connection (optional) */
1953
1951
  serverConn?: any;
1954
1952
  }
1955
1953
  interface SetupIdeInstanceOptions {
@@ -1995,7 +1993,7 @@ declare function probeCdpPort(port: number, timeoutMs?: number): Promise<boolean
1995
1993
  /**
1996
1994
  * DaemonCdpScanner — Periodic CDP port scanning & auto-connect
1997
1995
  *
1998
- * Extracted from daemon-cloud initCdp() and daemon-standalone initCdp().
1996
+ * Periodic CDP port scanning and auto-connect for IDE discovery.
1999
1997
  * Provides a unified approach to:
2000
1998
  * 1. Initial CDP port discovery
2001
1999
  * 2. Periodic scanning for newly launched IDEs
@@ -2044,7 +2042,7 @@ declare class DaemonCdpScanner {
2044
2042
  */
2045
2043
  private connectSingleWindow;
2046
2044
  /**
2047
- * Multi-window connection (cloud mode).
2045
+ * Multi-window connection.
2048
2046
  * Multiple CDP managers per IDE — one per workbench page.
2049
2047
  */
2050
2048
  private connectMultiWindow;
@@ -2053,7 +2051,7 @@ declare class DaemonCdpScanner {
2053
2051
  /**
2054
2052
  * DaemonCdpInitializer — Unified CDP initialization + periodic scanning
2055
2053
  *
2056
- * Replaces initCdp() in both cloud and standalone daemons.
2054
+ * Unified CDP initialization + periodic scanning.
2057
2055
  *
2058
2056
  * Features:
2059
2057
  * 1. Initial connection: connectAll() — multi-window aware
@@ -2175,8 +2173,7 @@ declare class DaemonCliManager {
2175
2173
  /**
2176
2174
  * DaemonCommandRouter — Unified command routing for daemon-level commands
2177
2175
  *
2178
- * Extracted from cloud daemon's executeDaemonCommand() logic.
2179
- * Used by both daemon-cloud and daemon-standalone.
2176
+ * Unified command routing for daemon-level commands.
2180
2177
  *
2181
2178
  * Routing flow:
2182
2179
  * 1. Daemon-level commands (launch_ide, stop_ide, restart_ide, etc.) → handled here
@@ -2196,13 +2193,13 @@ interface CommandRouterDeps {
2196
2193
  };
2197
2194
  /** UUID instanceId → CDP manager key mapping */
2198
2195
  instanceIdMap: Map<string, string>;
2199
- /** Callback for CDP manager creation after launch_ide (cloud: setupCdpManager, standalone: no-op) */
2196
+ /** Callback for CDP manager creation after launch_ide */
2200
2197
  onCdpManagerCreated?: (ideType: string, manager: DaemonCdpManager) => void;
2201
2198
  /** Callback after IDE connected (e.g., startAgentStreamPolling) */
2202
2199
  onIdeConnected?: () => void;
2203
2200
  /** Callback after status change (stop_ide, restart) */
2204
2201
  onStatusChange?: () => void;
2205
- /** Callback after chat-related commands (cloud: throttled report) */
2202
+ /** Callback after chat-related commands */
2206
2203
  onPostChatCommand?: () => void;
2207
2204
  /** Get a connected CDP manager (for agent stream reset check) */
2208
2205
  getCdpLogFn?: (ideType: string) => (msg: string) => void;
@@ -2320,11 +2317,10 @@ declare class DaemonStatusReporter {
2320
2317
  * Status Builders — shared conversion functions for ProviderState → ManagedEntry
2321
2318
  *
2322
2319
  * Used by:
2323
- * - daemon-cloud (DaemonStatusReporter)
2324
2320
  * - daemon-standalone (StandaloneServer.getStatus)
2321
+ * - DaemonStatusReporter
2325
2322
  *
2326
- * Consolidates duplicated ProviderState→ManagedEntry mapping that was
2327
- * previously copy-pasted between cloud and standalone codebases.
2323
+ * Consolidates ProviderState→ManagedEntry mapping logic.
2328
2324
  */
2329
2325
 
2330
2326
  /**
@@ -3051,7 +3047,7 @@ declare function getAIExtensions(): ExtensionInfo[];
3051
3047
  declare function launchIDE(ide: IDEInfo, workspacePath?: string): boolean;
3052
3048
 
3053
3049
  /**
3054
- * Daemon Lifecycle — Shared init + shutdown for cloud/standalone
3050
+ * Daemon Lifecycle — Shared init + shutdown logic
3055
3051
  *
3056
3052
  * initDaemonComponents(): Creates all core daemon components in correct order.
3057
3053
  * shutdownDaemonComponents(): Graceful shutdown of all components.
@@ -3101,7 +3097,6 @@ interface DaemonComponents {
3101
3097
  }
3102
3098
  /**
3103
3099
  * Initialize all daemon core components.
3104
- * Shared by both cloud and standalone daemons.
3105
3100
  *
3106
3101
  * Order:
3107
3102
  * 1. Global log interceptor
@@ -3116,7 +3111,6 @@ interface DaemonComponents {
3116
3111
  declare function initDaemonComponents(config: DaemonInitConfig): Promise<DaemonComponents>;
3117
3112
  /**
3118
3113
  * Graceful shutdown of all daemon components.
3119
- * Shared by both cloud and standalone daemons.
3120
3114
  *
3121
3115
  * Order:
3122
3116
  * 1. Stop timers (poller, cdpInitializer)
package/dist/index.js CHANGED
@@ -2008,6 +2008,10 @@ var DaemonCdpManager = class {
2008
2008
  get pageTitle() {
2009
2009
  return this._pageTitle;
2010
2010
  }
2011
+ /** Connected target ID */
2012
+ get targetId() {
2013
+ return this._targetId;
2014
+ }
2011
2015
  /**
2012
2016
  * Query all workbench pages on port (static)
2013
2017
  * Returns multiple entries if multiple IDE windows are open on same port
@@ -4118,7 +4122,7 @@ var DaemonCdpScanner = class {
4118
4122
  this.opts.onConnected?.(ide, ide, manager);
4119
4123
  }
4120
4124
  /**
4121
- * Multi-window connection (cloud mode).
4125
+ * Multi-window connection.
4122
4126
  * Multiple CDP managers per IDE — one per workbench page.
4123
4127
  */
4124
4128
  async connectMultiWindow(port, ide) {
@@ -4205,6 +4209,7 @@ var DaemonCdpInitializer = class {
4205
4209
  const { providerLoader, cdpManagers } = this.config;
4206
4210
  const targets = await DaemonCdpManager.listAllTargets(port);
4207
4211
  if (targets.length === 0) {
4212
+ if (cdpManagers.has(ide)) return;
4208
4213
  if (!await probeCdpPort(port)) return;
4209
4214
  const provider = providerLoader.getMeta(ide);
4210
4215
  const manager = new DaemonCdpManager(
@@ -4224,12 +4229,19 @@ var DaemonCdpInitializer = class {
4224
4229
  }
4225
4230
  for (let i = 0; i < targets.length; i++) {
4226
4231
  const target = targets[i];
4232
+ let alreadyTracked = false;
4233
+ for (const [key, m] of cdpManagers.entries()) {
4234
+ if ((key === ide || key.startsWith(`${ide}_`)) && m.targetId === target.id) {
4235
+ alreadyTracked = true;
4236
+ break;
4237
+ }
4238
+ }
4239
+ if (alreadyTracked) continue;
4227
4240
  let managerKey;
4228
- if (targets.length === 1) {
4241
+ if (targets.length === 1 && !cdpManagers.has(ide)) {
4229
4242
  managerKey = ide;
4230
4243
  } else {
4231
- const workspaceName = (target.title || "").split(" \u2014 ")[0].trim() || `window_${i}`;
4232
- managerKey = `${ide}_${workspaceName}`;
4244
+ managerKey = `${ide}_${target.id}`;
4233
4245
  }
4234
4246
  if (cdpManagers.has(managerKey)) continue;
4235
4247
  const provider = providerLoader.getMeta(ide);
@@ -4260,10 +4272,6 @@ var DaemonCdpInitializer = class {
4260
4272
  const portMap = providerLoader.getCdpPortMap();
4261
4273
  for (const [ide, ports] of Object.entries(portMap)) {
4262
4274
  const primaryPort = ports[0];
4263
- const alreadyConnected = [...cdpManagers.entries()].some(
4264
- ([key, m]) => m.isConnected && (key === ide || key.startsWith(ide + "_"))
4265
- );
4266
- if (alreadyConnected) continue;
4267
4275
  await this.connectIdePort(primaryPort, ide);
4268
4276
  }
4269
4277
  }, intervalMs);
@@ -6290,8 +6298,9 @@ var ProviderLoader = class _ProviderLoader {
6290
6298
  } else {
6291
6299
  this.builtinDirs = [];
6292
6300
  }
6293
- this.userDir = options?.userDir || path6.join(os7.homedir(), ".adhdev", "providers");
6294
- this.upstreamDir = path6.join(this.userDir, ".upstream");
6301
+ const defaultProvidersDir = path6.join(os7.homedir(), ".adhdev", "providers");
6302
+ this.userDir = options?.userDir || defaultProvidersDir;
6303
+ this.upstreamDir = path6.join(defaultProvidersDir, ".upstream");
6295
6304
  this.disableUpstream = options?.disableUpstream ?? false;
6296
6305
  this.logFn = options?.logFn || LOG.forComponent("Provider").asLogFn();
6297
6306
  }
@@ -6498,7 +6507,8 @@ var ProviderLoader = class _ProviderLoader {
6498
6507
  try {
6499
6508
  const { loadConfig: loadConfig2 } = (init_config(), __toCommonJS(config_exports));
6500
6509
  const config = loadConfig2();
6501
- const val = config.ideSettings?.[ideType]?.extensions?.[type]?.enabled;
6510
+ const baseIdeType = ideType.split("_")[0];
6511
+ const val = config.ideSettings?.[baseIdeType]?.extensions?.[type]?.enabled;
6502
6512
  return val === true;
6503
6513
  } catch {
6504
6514
  return false;
@@ -6511,10 +6521,11 @@ var ProviderLoader = class _ProviderLoader {
6511
6521
  try {
6512
6522
  const { loadConfig: loadConfig2, saveConfig: saveConfig2 } = (init_config(), __toCommonJS(config_exports));
6513
6523
  const config = loadConfig2();
6524
+ const baseIdeType = ideType.split("_")[0];
6514
6525
  if (!config.ideSettings) config.ideSettings = {};
6515
- if (!config.ideSettings[ideType]) config.ideSettings[ideType] = {};
6516
- if (!config.ideSettings[ideType].extensions) config.ideSettings[ideType].extensions = {};
6517
- config.ideSettings[ideType].extensions[extensionType] = { enabled };
6526
+ if (!config.ideSettings[baseIdeType]) config.ideSettings[baseIdeType] = {};
6527
+ if (!config.ideSettings[baseIdeType].extensions) config.ideSettings[baseIdeType].extensions = {};
6528
+ config.ideSettings[baseIdeType].extensions[extensionType] = { enabled };
6518
6529
  saveConfig2(config);
6519
6530
  this.log(`IDE extension setting: ${ideType}.${extensionType}.enabled = ${enabled}`);
6520
6531
  return true;
@@ -13029,7 +13040,7 @@ var DevServer = class _DevServer {
13029
13040
  const cleanData = chunk.replace(/\x1B\[\d*[A-HJKSTfG]/g, " ").replace(/\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g, "").replace(/\x1B\][^\x07]*\x07/g, "").replace(/\x1B\][^\x1B]*\x1B\\/g, "").replace(/ +/g, " ");
13030
13041
  approvalBuffer = (approvalBuffer + cleanData).slice(-1500);
13031
13042
  const elapsed = Date.now() - spawnedAt;
13032
- if (elapsed > 15e3 && approvalBuffer.includes("_PIPELINE_COMPLETE_SIGNAL_")) {
13043
+ if (elapsed > 15e3 && cleanData.includes("_PIPELINE_COMPLETE_SIGNAL_")) {
13033
13044
  this.log(`Agent finished task after ${Math.round(elapsed / 1e3)}s. Terminating interactive CLI session to unblock pipeline.`);
13034
13045
  this.sendAutoImplSSE({ event: "output", data: { chunk: `
13035
13046
  [\u{1F916} ADHDev Pipeline] Completion token detected. Proceeding...
@@ -13219,6 +13230,31 @@ var DevServer = class _DevServer {
13219
13230
  lines.push("");
13220
13231
  }
13221
13232
  }
13233
+ const docsDir = path12.join(providerDir, "../../docs");
13234
+ const loadGuide = (name) => {
13235
+ try {
13236
+ const p = path12.join(docsDir, name);
13237
+ if (fs9.existsSync(p)) return fs9.readFileSync(p, "utf-8");
13238
+ } catch {
13239
+ }
13240
+ return null;
13241
+ };
13242
+ const providerGuide = loadGuide("PROVIDER_GUIDE.md");
13243
+ if (providerGuide) {
13244
+ lines.push("## Documentation: PROVIDER_GUIDE.md");
13245
+ lines.push("```markdown");
13246
+ lines.push(providerGuide);
13247
+ lines.push("```");
13248
+ lines.push("");
13249
+ }
13250
+ const cdpGuide = loadGuide("CDP_SELECTOR_GUIDE.md");
13251
+ if (cdpGuide) {
13252
+ lines.push("## Documentation: CDP_SELECTOR_GUIDE.md");
13253
+ lines.push("```markdown");
13254
+ lines.push(cdpGuide);
13255
+ lines.push("```");
13256
+ lines.push("");
13257
+ }
13222
13258
  lines.push("## Task");
13223
13259
  lines.push(`Edit files in \`${providerDir}\` to implement: **${functions.join(", ")}**`);
13224
13260
  lines.push("");
@@ -13415,6 +13451,23 @@ var DevServer = class _DevServer {
13415
13451
  lines.push("");
13416
13452
  }
13417
13453
  }
13454
+ const docsDir = path12.join(providerDir, "../../docs");
13455
+ const loadGuide = (name) => {
13456
+ try {
13457
+ const p = path12.join(docsDir, name);
13458
+ if (fs9.existsSync(p)) return fs9.readFileSync(p, "utf-8");
13459
+ } catch {
13460
+ }
13461
+ return null;
13462
+ };
13463
+ const providerGuide = loadGuide("PROVIDER_GUIDE.md");
13464
+ if (providerGuide) {
13465
+ lines.push("## Documentation: PROVIDER_GUIDE.md");
13466
+ lines.push("```markdown");
13467
+ lines.push(providerGuide);
13468
+ lines.push("```");
13469
+ lines.push("");
13470
+ }
13418
13471
  lines.push("## Runtime Contract");
13419
13472
  lines.push("The daemon runtime is already implemented in `packages/daemon-core/src/cli-adapters/provider-cli-adapter.ts`.");
13420
13473
  lines.push("Your scripts receive PTY-derived input and must return plain JS objects.");
@@ -14039,7 +14092,8 @@ async function initDaemonComponents(config) {
14039
14092
  const disableUpstream = appConfig.disableUpstream ?? false;
14040
14093
  const providerLoader = new ProviderLoader({
14041
14094
  logFn: config.providerLogFn,
14042
- disableUpstream
14095
+ disableUpstream,
14096
+ userDir: appConfig.providerDir
14043
14097
  });
14044
14098
  if (!disableUpstream && !providerLoader.hasUpstream()) {
14045
14099
  LOG.info("Provider", "No upstream providers found \u2014 downloading from GitHub...");