@adhdev/daemon-core 0.9.67 → 0.9.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.js +506 -328
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +506 -327
- package/dist/index.mjs.map +1 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/commands/router.ts +156 -0
package/package.json
CHANGED
package/src/commands/router.ts
CHANGED
|
@@ -920,6 +920,162 @@ export class DaemonCommandRouter {
|
|
|
920
920
|
return { success: true };
|
|
921
921
|
}
|
|
922
922
|
|
|
923
|
+
// ─── Mesh CRUD (local meshes.json) ───
|
|
924
|
+
case 'list_meshes': {
|
|
925
|
+
try {
|
|
926
|
+
const { listMeshes } = await import('../config/mesh-config.js');
|
|
927
|
+
return { success: true, meshes: listMeshes() };
|
|
928
|
+
} catch (e: any) {
|
|
929
|
+
return { success: false, error: e.message };
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
case 'get_mesh': {
|
|
934
|
+
const meshId = typeof args?.meshId === 'string' ? args.meshId.trim() : '';
|
|
935
|
+
if (!meshId) return { success: false, error: 'meshId required' };
|
|
936
|
+
try {
|
|
937
|
+
const { getMesh } = await import('../config/mesh-config.js');
|
|
938
|
+
const mesh = getMesh(meshId);
|
|
939
|
+
if (!mesh) return { success: false, error: 'Mesh not found' };
|
|
940
|
+
return { success: true, mesh };
|
|
941
|
+
} catch (e: any) {
|
|
942
|
+
return { success: false, error: e.message };
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
case 'create_mesh': {
|
|
947
|
+
const name = typeof args?.name === 'string' ? args.name.trim() : '';
|
|
948
|
+
const repoIdentity = typeof args?.repoIdentity === 'string' ? args.repoIdentity.trim() : '';
|
|
949
|
+
const repoRemoteUrl = typeof args?.repoRemoteUrl === 'string' ? args.repoRemoteUrl.trim() : undefined;
|
|
950
|
+
const defaultBranch = typeof args?.defaultBranch === 'string' ? args.defaultBranch.trim() : undefined;
|
|
951
|
+
if (!name) return { success: false, error: 'name required' };
|
|
952
|
+
try {
|
|
953
|
+
const { createMesh } = await import('../config/mesh-config.js');
|
|
954
|
+
const mesh = createMesh({ name, repoIdentity, repoRemoteUrl, defaultBranch });
|
|
955
|
+
return { success: true, mesh };
|
|
956
|
+
} catch (e: any) {
|
|
957
|
+
return { success: false, error: e.message };
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
case 'delete_mesh': {
|
|
962
|
+
const meshId = typeof args?.meshId === 'string' ? args.meshId.trim() : '';
|
|
963
|
+
if (!meshId) return { success: false, error: 'meshId required' };
|
|
964
|
+
try {
|
|
965
|
+
const { deleteMesh } = await import('../config/mesh-config.js');
|
|
966
|
+
const deleted = deleteMesh(meshId);
|
|
967
|
+
return { success: true, deleted };
|
|
968
|
+
} catch (e: any) {
|
|
969
|
+
return { success: false, error: e.message };
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
case 'add_mesh_node': {
|
|
974
|
+
const meshId = typeof args?.meshId === 'string' ? args.meshId.trim() : '';
|
|
975
|
+
const workspace = typeof args?.workspace === 'string' ? args.workspace.trim() : '';
|
|
976
|
+
if (!meshId) return { success: false, error: 'meshId required' };
|
|
977
|
+
if (!workspace) return { success: false, error: 'workspace required' };
|
|
978
|
+
try {
|
|
979
|
+
const { addNode } = await import('../config/mesh-config.js');
|
|
980
|
+
const node = addNode(meshId, { workspace });
|
|
981
|
+
if (!node) return { success: false, error: 'Mesh not found' };
|
|
982
|
+
return { success: true, node };
|
|
983
|
+
} catch (e: any) {
|
|
984
|
+
return { success: false, error: e.message };
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
case 'remove_mesh_node': {
|
|
989
|
+
const meshId = typeof args?.meshId === 'string' ? args.meshId.trim() : '';
|
|
990
|
+
const nodeId = typeof args?.nodeId === 'string' ? args.nodeId.trim() : '';
|
|
991
|
+
if (!meshId || !nodeId) return { success: false, error: 'meshId and nodeId required' };
|
|
992
|
+
try {
|
|
993
|
+
const { removeNode } = await import('../config/mesh-config.js');
|
|
994
|
+
const removed = removeNode(meshId, nodeId);
|
|
995
|
+
return { success: true, removed };
|
|
996
|
+
} catch (e: any) {
|
|
997
|
+
return { success: false, error: e.message };
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
// ─── Mesh Coordinator Launch ───
|
|
1002
|
+
case 'launch_mesh_coordinator': {
|
|
1003
|
+
const meshId = typeof args?.meshId === 'string' ? args.meshId.trim() : '';
|
|
1004
|
+
const cliType = typeof args?.cliType === 'string' ? args.cliType.trim() : 'claude-cli';
|
|
1005
|
+
if (!meshId) return { success: false, error: 'meshId required' };
|
|
1006
|
+
|
|
1007
|
+
try {
|
|
1008
|
+
const { getMesh } = await import('../config/mesh-config.js');
|
|
1009
|
+
const { buildCoordinatorSystemPrompt } = await import('../mesh/coordinator-prompt.js');
|
|
1010
|
+
const mesh = getMesh(meshId);
|
|
1011
|
+
if (!mesh) return { success: false, error: 'Mesh not found' };
|
|
1012
|
+
if (mesh.nodes.length === 0) return { success: false, error: 'No nodes in mesh' };
|
|
1013
|
+
|
|
1014
|
+
const workspace = mesh.nodes[0].workspace;
|
|
1015
|
+
|
|
1016
|
+
// 1. Write .mcp.json to workspace so Claude CLI auto-discovers mesh tools
|
|
1017
|
+
const { existsSync, readFileSync, writeFileSync, copyFileSync } = await import('fs');
|
|
1018
|
+
const { join } = await import('path');
|
|
1019
|
+
const mcpConfigPath = join(workspace, '.mcp.json');
|
|
1020
|
+
|
|
1021
|
+
// Backup existing .mcp.json if present
|
|
1022
|
+
const hadExistingMcpConfig = existsSync(mcpConfigPath);
|
|
1023
|
+
let existingMcpConfig: any = {};
|
|
1024
|
+
if (hadExistingMcpConfig) {
|
|
1025
|
+
try {
|
|
1026
|
+
existingMcpConfig = JSON.parse(readFileSync(mcpConfigPath, 'utf-8'));
|
|
1027
|
+
copyFileSync(mcpConfigPath, mcpConfigPath + '.backup');
|
|
1028
|
+
} catch { /* empty */ }
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// Merge adhdev-mesh server into existing config
|
|
1032
|
+
const mcpConfig = {
|
|
1033
|
+
...existingMcpConfig,
|
|
1034
|
+
mcpServers: {
|
|
1035
|
+
...(existingMcpConfig.mcpServers || {}),
|
|
1036
|
+
'adhdev-mesh': {
|
|
1037
|
+
command: 'adhdev-mcp',
|
|
1038
|
+
args: ['--repo-mesh', meshId],
|
|
1039
|
+
},
|
|
1040
|
+
},
|
|
1041
|
+
};
|
|
1042
|
+
writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2), 'utf-8');
|
|
1043
|
+
LOG.info('MeshCoordinator', `Wrote .mcp.json to ${workspace} with adhdev-mesh server`);
|
|
1044
|
+
|
|
1045
|
+
// 2. Build coordinator system prompt
|
|
1046
|
+
let systemPrompt = '';
|
|
1047
|
+
try {
|
|
1048
|
+
systemPrompt = buildCoordinatorSystemPrompt({ mesh });
|
|
1049
|
+
} catch {
|
|
1050
|
+
systemPrompt = `You are a Repo Mesh Coordinator for "${mesh.name}". Use the adhdev-mesh MCP tools (mesh_status, mesh_list_nodes, mesh_send_task, mesh_read_chat, mesh_launch_session, etc.) to orchestrate work across ${mesh.nodes.length} node(s).`;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
// 3. Launch CLI session via existing cliManager
|
|
1054
|
+
const launchResult: any = await this.deps.cliManager.handleCliCommand('launch_cli', {
|
|
1055
|
+
cliType,
|
|
1056
|
+
dir: workspace,
|
|
1057
|
+
initialPrompt: systemPrompt,
|
|
1058
|
+
});
|
|
1059
|
+
|
|
1060
|
+
if (!launchResult?.success) {
|
|
1061
|
+
return { success: false, error: launchResult?.error || 'Failed to launch CLI session' };
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
LOG.info('MeshCoordinator', `Launched ${cliType} coordinator for mesh ${meshId} in ${workspace}`);
|
|
1065
|
+
return {
|
|
1066
|
+
success: true,
|
|
1067
|
+
meshId,
|
|
1068
|
+
cliType,
|
|
1069
|
+
workspace,
|
|
1070
|
+
sessionId: launchResult.sessionId || launchResult.id,
|
|
1071
|
+
mcpConfigWritten: true,
|
|
1072
|
+
};
|
|
1073
|
+
} catch (e: any) {
|
|
1074
|
+
LOG.error('MeshCoordinator', `Failed: ${e.message}`);
|
|
1075
|
+
return { success: false, error: e.message };
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
|
|
923
1079
|
default:
|
|
924
1080
|
break;
|
|
925
1081
|
}
|