@adhdev/daemon-core 0.9.76-rc.19 → 0.9.76-rc.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adhdev/daemon-core",
3
- "version": "0.9.76-rc.19",
3
+ "version": "0.9.76-rc.20",
4
4
  "description": "ADHDev daemon core — CDP, IDE detection, providers, command execution",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -34,6 +34,7 @@ export type MeshCoordinatorSetup =
34
34
 
35
35
  export interface ResolveMeshCoordinatorSetupOptions {
36
36
  provider?: ProviderModule | null
37
+ cliType?: string
37
38
  meshId: string
38
39
  workspace: string
39
40
  adhdevMcpCommand?: string
@@ -43,6 +44,58 @@ export interface ResolveMeshCoordinatorSetupOptions {
43
44
 
44
45
  const DEFAULT_SERVER_NAME = 'adhdev-mesh'
45
46
  const DEFAULT_ADHDEV_MCP_COMMAND = 'adhdev-mcp'
47
+ const HERMES_CLI_TYPE = 'hermes-cli'
48
+ const HERMES_MCP_CONFIG_PATH = '~/.hermes/config.yaml'
49
+
50
+ function isHermesProvider(provider: ProviderModule | null | undefined, cliType?: string): boolean {
51
+ const type = cliType?.trim() || provider?.type?.trim() || ''
52
+ return type === HERMES_CLI_TYPE
53
+ }
54
+
55
+ function resolveHermesMeshCoordinatorSetup(options: ResolveMeshCoordinatorSetupOptions): MeshCoordinatorSetup {
56
+ const mcpServer = resolveAdhdevMcpServerLaunch({
57
+ meshId: options.meshId,
58
+ nodeExecutable: options.nodeExecutable,
59
+ adhdevMcpEntryPath: options.adhdevMcpEntryPath,
60
+ })
61
+ if (!mcpServer) {
62
+ return {
63
+ kind: 'unsupported',
64
+ reason: 'Could not resolve the ADHDev MCP server entrypoint and a Node runtime with WebSocket support for daemon IPC mode',
65
+ }
66
+ }
67
+ const configPath = resolveMcpConfigPath(HERMES_MCP_CONFIG_PATH, options.workspace)
68
+ if (!configPath.trim()) {
69
+ return createHermesManualMeshCoordinatorSetup(options.meshId, options.workspace)
70
+ }
71
+ return {
72
+ kind: 'auto_import',
73
+ serverName: DEFAULT_SERVER_NAME,
74
+ configPath,
75
+ configFormat: 'hermes_config_yaml',
76
+ mcpServer,
77
+ }
78
+ }
79
+
80
+ export function createHermesManualMeshCoordinatorSetup(meshId: string, workspace: string): MeshCoordinatorSetup {
81
+ return {
82
+ kind: 'manual',
83
+ serverName: DEFAULT_SERVER_NAME,
84
+ configFormat: 'hermes_config_yaml',
85
+ configPathCommand: HERMES_MCP_CONFIG_PATH,
86
+ requiresRestart: true,
87
+ instructions: 'Hermes CLI does not auto-import repo-local .mcp.json. Add this MCP server to Hermes config under mcp_servers, then start a fresh Hermes session.',
88
+ template: renderMeshCoordinatorTemplate(
89
+ 'mcp_servers:\n {{serverName}}:\n command: {{adhdevMcpCommand}}\n args:\n - --repo-mesh\n - {{meshId}}\n enabled: true\n',
90
+ {
91
+ meshId,
92
+ workspace,
93
+ serverName: DEFAULT_SERVER_NAME,
94
+ adhdevMcpCommand: DEFAULT_ADHDEV_MCP_COMMAND,
95
+ },
96
+ ),
97
+ }
98
+ }
46
99
 
47
100
  export function resolveMeshCoordinatorSetup(options: ResolveMeshCoordinatorSetupOptions): MeshCoordinatorSetup {
48
101
  const { provider, meshId, workspace } = options
@@ -54,6 +107,10 @@ export function resolveMeshCoordinatorSetup(options: ResolveMeshCoordinatorSetup
54
107
  }
55
108
  }
56
109
 
110
+ if (isHermesProvider(provider, options.cliType)) {
111
+ return resolveHermesMeshCoordinatorSetup(options)
112
+ }
113
+
57
114
  const mcpConfig = config.mcpConfig
58
115
  if (!mcpConfig || mcpConfig.mode === 'none') {
59
116
  return {
@@ -34,7 +34,7 @@ import * as yaml from 'js-yaml';
34
34
  import { getRecentLogs, LOG_PATH } from '../logging/logger.js';
35
35
  import { createInteractionId, getRecentDebugTrace, recordDebugTrace } from '../logging/debug-trace.js';
36
36
  import { getSessionHostSurfaceKind, partitionSessionHostRecords } from '../session-host/runtime-surface.js';
37
- import { resolveMeshCoordinatorSetup } from './mesh-coordinator.js';
37
+ import { createHermesManualMeshCoordinatorSetup, resolveMeshCoordinatorSetup } from './mesh-coordinator.js';
38
38
  import { buildSessionEntries } from '../status/builders.js';
39
39
  import { buildMachineInfo, buildStatusSnapshot } from '../status/snapshot.js';
40
40
  import { getSessionCompletionMarker } from '../status/snapshot.js';
@@ -1227,6 +1227,7 @@ export class DaemonCommandRouter {
1227
1227
  const providerMeta = this.deps.providerLoader.resolve?.(cliType) || this.deps.providerLoader.getMeta(cliType);
1228
1228
  const coordinatorSetup = resolveMeshCoordinatorSetup({
1229
1229
  provider: providerMeta,
1230
+ cliType,
1230
1231
  meshId,
1231
1232
  workspace,
1232
1233
  });
@@ -1289,7 +1290,41 @@ export class DaemonCommandRouter {
1289
1290
  const { existsSync, readFileSync, writeFileSync, copyFileSync, mkdirSync } = await import('fs');
1290
1291
  const { dirname } = await import('path');
1291
1292
  const mcpConfigPath = coordinatorSetup.configPath;
1292
- mkdirSync(dirname(mcpConfigPath), { recursive: true });
1293
+ const hermesManualFallback = cliType === 'hermes-cli' && configFormat === 'hermes_config_yaml'
1294
+ ? createHermesManualMeshCoordinatorSetup(meshId, workspace)
1295
+ : null;
1296
+ const returnManualFallback = (message: string) => ({
1297
+ success: false,
1298
+ code: 'mesh_coordinator_manual_mcp_setup_required',
1299
+ error: message,
1300
+ meshId,
1301
+ cliType,
1302
+ workspace,
1303
+ meshCoordinatorSetup: hermesManualFallback,
1304
+ });
1305
+
1306
+ // Merge ADHDev mesh server into existing config.
1307
+ // Pass full mesh data as env var so the MCP server can bootstrap
1308
+ // without depending on meshes.json or a running daemon.
1309
+ const mcpServerEntry: Record<string, any> = {
1310
+ command: coordinatorSetup.mcpServer.command,
1311
+ args: coordinatorSetup.mcpServer.args,
1312
+ };
1313
+ if (args?.inlineMesh) {
1314
+ mcpServerEntry.env = {
1315
+ ADHDEV_INLINE_MESH: JSON.stringify(mesh),
1316
+ ADHDEV_MCP_TRANSPORT: 'ipc',
1317
+ };
1318
+ }
1319
+
1320
+ try {
1321
+ mkdirSync(dirname(mcpConfigPath), { recursive: true });
1322
+ } catch (error: any) {
1323
+ const message = `Could not prepare MCP config path for automatic setup: ${error?.message || error}`;
1324
+ LOG.error('MeshCoordinator', message);
1325
+ if (hermesManualFallback) return returnManualFallback(message);
1326
+ return { success: false, code: 'mesh_coordinator_config_write_failed', error: message, meshId, cliType, workspace };
1327
+ }
1293
1328
 
1294
1329
  // Backup existing MCP config if present.
1295
1330
  const hadExistingMcpConfig = existsSync(mcpConfigPath);
@@ -1308,19 +1343,6 @@ export class DaemonCommandRouter {
1308
1343
  }
1309
1344
  }
1310
1345
 
1311
- // Merge ADHDev mesh server into existing config.
1312
- // Pass full mesh data as env var so the MCP server can bootstrap
1313
- // without depending on meshes.json or a running daemon.
1314
- const mcpServerEntry: Record<string, any> = {
1315
- command: coordinatorSetup.mcpServer.command,
1316
- args: coordinatorSetup.mcpServer.args,
1317
- };
1318
- if (args?.inlineMesh) {
1319
- mcpServerEntry.env = {
1320
- ADHDEV_INLINE_MESH: JSON.stringify(mesh),
1321
- ADHDEV_MCP_TRANSPORT: 'ipc',
1322
- };
1323
- }
1324
1346
  const mcpServersKey = getMcpServersKey(configFormat);
1325
1347
  const existingServers = existingMcpConfig[mcpServersKey];
1326
1348
  const mcpConfig = {
@@ -1330,7 +1352,14 @@ export class DaemonCommandRouter {
1330
1352
  [coordinatorSetup.serverName]: mcpServerEntry,
1331
1353
  },
1332
1354
  };
1333
- writeFileSync(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), 'utf-8');
1355
+ try {
1356
+ writeFileSync(mcpConfigPath, serializeMeshCoordinatorMcpConfig(mcpConfig, configFormat), 'utf-8');
1357
+ } catch (error: any) {
1358
+ const message = `Could not write MCP config for automatic setup: ${error?.message || error}`;
1359
+ LOG.error('MeshCoordinator', message);
1360
+ if (hermesManualFallback) return returnManualFallback(message);
1361
+ return { success: false, code: 'mesh_coordinator_config_write_failed', error: message, meshId, cliType, workspace };
1362
+ }
1334
1363
  LOG.info('MeshCoordinator', `Wrote ${mcpConfigPath} with ${coordinatorSetup.serverName} server`);
1335
1364
 
1336
1365
  const cliArgs: string[] = [];