@adhdev/daemon-core 0.9.76-rc.30 → 0.9.76-rc.31

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.30",
3
+ "version": "0.9.76-rc.31",
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",
@@ -1,52 +1,75 @@
1
1
  import type { DaemonComponents } from '../boot/daemon-lifecycle.js';
2
- import { getMeshByRepo } from '../config/mesh-config.js';
2
+ import { getMesh, getMeshByRepo } from '../config/mesh-config.js';
3
3
  import { LOG } from '../logging/logger.js';
4
4
 
5
+ function readNonEmptyString(value: unknown): string {
6
+ return typeof value === 'string' && value.trim() ? value.trim() : '';
7
+ }
8
+
9
+ function formatCompletionMetadata(event: Record<string, unknown>): string {
10
+ const parts = [
11
+ readNonEmptyString(event.targetSessionId) ? `session_id=${readNonEmptyString(event.targetSessionId)}` : '',
12
+ readNonEmptyString(event.providerType) ? `provider=${readNonEmptyString(event.providerType)}` : '',
13
+ readNonEmptyString(event.providerSessionId) ? `provider_session_id=${readNonEmptyString(event.providerSessionId)}` : '',
14
+ ].filter(Boolean);
15
+ return parts.length > 0 ? ` (${parts.join('; ')})` : '';
16
+ }
17
+
5
18
  export function setupMeshEventForwarding(components: DaemonComponents) {
6
19
  components.instanceManager.onEvent((event) => {
7
20
  // We only care about agent sub-session completion or waiting approval
8
21
  if (event.event !== 'agent:generating_completed' && event.event !== 'agent:waiting_approval') return;
9
-
10
- const instanceId = event.instanceId as string;
22
+
23
+ const instanceId = readNonEmptyString(event.instanceId);
11
24
  if (!instanceId) return;
12
25
 
13
- // Try to find the workspace of the sub-agent
26
+ // Try to find the workspace and mesh metadata of the sub-agent.
14
27
  const sourceInstance = components.instanceManager.getInstance(instanceId);
15
28
  if (!sourceInstance || sourceInstance.category !== 'cli') return;
16
29
  const state = sourceInstance.getState();
17
- const workspace = state.workspace;
30
+ const workspace = readNonEmptyString(state.workspace);
18
31
  if (!workspace) return;
32
+ const settings = state.settings && typeof state.settings === 'object' ? state.settings as Record<string, unknown> : {};
33
+ const meshIdFromRuntime = readNonEmptyString(settings.meshNodeFor);
19
34
 
20
- // Find the mesh that this workspace belongs to
21
- const mesh = getMeshByRepo(workspace);
22
- if (!mesh) return;
35
+ // Prefer runtime mesh metadata: delegated mesh-node agents can come from inline/cloud meshes
36
+ // that are not present in local meshes.json. Fall back to persisted mesh lookup for legacy sessions.
37
+ const mesh = meshIdFromRuntime ? getMesh(meshIdFromRuntime) : getMeshByRepo(workspace);
38
+ const meshId = meshIdFromRuntime || readNonEmptyString(mesh?.id);
39
+ if (!meshId) return;
23
40
 
24
41
  // Find the coordinator session(s)
25
42
  const allInstances = components.instanceManager.getByCategory('cli');
26
43
  const coordinatorInstances = allInstances.filter((inst) => {
27
44
  const instState = inst.getState();
28
-
45
+
29
46
  // The coordinator session was launched with meshCoordinatorFor setting
30
- if (instState.settings?.meshCoordinatorFor !== mesh.id) return false;
31
-
47
+ if (instState.settings?.meshCoordinatorFor !== meshId) return false;
48
+
32
49
  // Exclude the source instance itself (just in case)
33
50
  if (instState.instanceId === instanceId) return false;
34
-
51
+
35
52
  return true;
36
53
  });
37
54
 
38
55
  if (coordinatorInstances.length === 0) return;
39
56
 
40
- // Determine node label
41
- const targetNode = mesh.nodes.find((n) => n.workspace === workspace);
42
- const nodeLabel = targetNode ? `Node '${targetNode.id}'` : `Agent at ${workspace}`;
57
+ // Determine node label. Inline/cloud meshes may be unavailable here, so preserve runtime node id.
58
+ const targetNode = mesh?.nodes?.find((n: any) => n.workspace === workspace);
59
+ const runtimeNodeId = readNonEmptyString(settings.meshNodeId);
60
+ const nodeLabel = targetNode
61
+ ? `Node '${targetNode.id}'`
62
+ : runtimeNodeId
63
+ ? `Node '${runtimeNodeId}'`
64
+ : `Agent at ${workspace}`;
65
+ const metadata = formatCompletionMetadata(event);
43
66
 
44
67
  // Construct a system message in English
45
68
  let messageText = '';
46
69
  if (event.event === 'agent:generating_completed') {
47
- messageText = `[System] ${nodeLabel} has completed its task and is now idle. You may use mesh_read_chat to review its progress.`;
70
+ messageText = `[System] ${nodeLabel} has completed its task and is now idle${metadata}. You may use mesh_read_chat to review its progress.`;
48
71
  } else if (event.event === 'agent:waiting_approval') {
49
- messageText = `[System] ${nodeLabel} is waiting for approval to proceed. You may use mesh_read_chat and mesh_approve to handle it.`;
72
+ messageText = `[System] ${nodeLabel} is waiting for approval to proceed${metadata}. You may use mesh_read_chat and mesh_approve to handle it.`;
50
73
  }
51
74
 
52
75
  if (!messageText) return;