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

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.mjs CHANGED
@@ -3270,9 +3270,8 @@ ${lastSnapshot}`;
3270
3270
  };
3271
3271
  this.recordTrace("submit_echo_missing", diagnostic);
3272
3272
  if (this.requirePromptEchoBeforeSubmit) {
3273
- const message = `${this.cliName} prompt echo was not observed on the PTY screen before submit`;
3274
- LOG.warn("CLI", `[${this.cliType}] ${message} elapsed=${elapsed}ms maxEchoWaitMs=${state.maxEchoWaitMs} screen=${JSON.stringify(diagnostic.screenText).slice(0, 240)}`);
3275
- completion.rejectOnce(new Error(message));
3273
+ LOG.warn("CLI", `[${this.cliType}] prompt echo was not observed before submit; sending guarded submit key anyway elapsed=${elapsed}ms maxEchoWaitMs=${state.maxEchoWaitMs} screen=${JSON.stringify(diagnostic.screenText).slice(0, 240)}`);
3274
+ this.submitSendKey(state, completion);
3276
3275
  return;
3277
3276
  }
3278
3277
  LOG.warn("CLI", `[${this.cliType}] prompt echo was not observed before submit; sending submit key anyway elapsed=${elapsed}ms maxEchoWaitMs=${state.maxEchoWaitMs}`);
@@ -20334,6 +20333,100 @@ function normalizeExistingPath(filePath) {
20334
20333
  }
20335
20334
  }
20336
20335
 
20336
+ // src/mesh/mesh-events.ts
20337
+ init_mesh_config();
20338
+ init_logger();
20339
+ function readNonEmptyString(value) {
20340
+ return typeof value === "string" && value.trim() ? value.trim() : "";
20341
+ }
20342
+ function formatCompletionMetadata(event) {
20343
+ const parts = [
20344
+ readNonEmptyString(event.targetSessionId) ? `session_id=${readNonEmptyString(event.targetSessionId)}` : "",
20345
+ readNonEmptyString(event.providerType) ? `provider=${readNonEmptyString(event.providerType)}` : "",
20346
+ readNonEmptyString(event.providerSessionId) ? `provider_session_id=${readNonEmptyString(event.providerSessionId)}` : ""
20347
+ ].filter(Boolean);
20348
+ return parts.length > 0 ? ` (${parts.join("; ")})` : "";
20349
+ }
20350
+ function buildMeshSystemMessage(args) {
20351
+ const metadata = formatCompletionMetadata(args.metadataEvent);
20352
+ if (args.event === "agent:generating_completed") {
20353
+ return `[System] ${args.nodeLabel} has completed its task and is now idle${metadata}. You may use mesh_read_chat to review its progress.`;
20354
+ }
20355
+ if (args.event === "agent:waiting_approval") {
20356
+ return `[System] ${args.nodeLabel} is waiting for approval to proceed${metadata}. You may use mesh_read_chat and mesh_approve to handle it.`;
20357
+ }
20358
+ return "";
20359
+ }
20360
+ function injectMeshSystemMessage(components, args) {
20361
+ const coordinatorInstances = components.instanceManager.getByCategory("cli").filter((inst) => {
20362
+ const instState = inst.getState();
20363
+ if (instState.settings?.meshCoordinatorFor !== args.meshId) return false;
20364
+ if (args.sourceInstanceId && instState.instanceId === args.sourceInstanceId) return false;
20365
+ return true;
20366
+ });
20367
+ if (coordinatorInstances.length === 0) return { success: true, forwarded: 0 };
20368
+ const messageText = buildMeshSystemMessage({
20369
+ event: args.event,
20370
+ nodeLabel: args.nodeLabel,
20371
+ metadataEvent: args.metadataEvent
20372
+ });
20373
+ if (!messageText) return { success: false, error: "unsupported mesh event" };
20374
+ for (const coord of coordinatorInstances) {
20375
+ const coordState = coord.getState();
20376
+ LOG.info("MeshEvents", `Forwarding mesh event to coordinator ${coordState.instanceId}`);
20377
+ coord.onEvent("send_message", { input: { text: messageText, textFallback: messageText } });
20378
+ }
20379
+ return { success: true, forwarded: coordinatorInstances.length };
20380
+ }
20381
+ function handleMeshForwardEvent(components, payload) {
20382
+ const eventName = readNonEmptyString(payload.event);
20383
+ if (eventName !== "agent:generating_completed" && eventName !== "agent:waiting_approval") {
20384
+ return { success: false, error: "unsupported mesh event" };
20385
+ }
20386
+ const meshId = readNonEmptyString(payload.meshId);
20387
+ if (!meshId) return { success: false, error: "meshId required" };
20388
+ const nodeId = readNonEmptyString(payload.nodeId);
20389
+ const workspace = readNonEmptyString(payload.workspace);
20390
+ const nodeLabel = nodeId ? `Node '${nodeId}'` : workspace ? `Agent at ${workspace}` : "Remote agent";
20391
+ return injectMeshSystemMessage(components, {
20392
+ meshId,
20393
+ nodeLabel,
20394
+ event: eventName,
20395
+ metadataEvent: {
20396
+ targetSessionId: readNonEmptyString(payload.targetSessionId) || readNonEmptyString(payload.sessionId),
20397
+ providerType: readNonEmptyString(payload.providerType),
20398
+ providerSessionId: readNonEmptyString(payload.providerSessionId)
20399
+ }
20400
+ });
20401
+ }
20402
+ function setupMeshEventForwarding(components) {
20403
+ components.instanceManager.onEvent((event) => {
20404
+ if (event.event !== "agent:generating_completed" && event.event !== "agent:waiting_approval") return;
20405
+ const instanceId = readNonEmptyString(event.instanceId);
20406
+ if (!instanceId) return;
20407
+ const sourceInstance = components.instanceManager.getInstance(instanceId);
20408
+ if (!sourceInstance || sourceInstance.category !== "cli") return;
20409
+ const state = sourceInstance.getState();
20410
+ const workspace = readNonEmptyString(state.workspace);
20411
+ if (!workspace) return;
20412
+ const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
20413
+ const meshIdFromRuntime = readNonEmptyString(settings.meshNodeFor);
20414
+ const mesh = meshIdFromRuntime ? getMesh(meshIdFromRuntime) : getMeshByRepo(workspace);
20415
+ const meshId = meshIdFromRuntime || readNonEmptyString(mesh?.id);
20416
+ if (!meshId) return;
20417
+ const targetNode = mesh?.nodes?.find((n) => n.workspace === workspace);
20418
+ const runtimeNodeId = readNonEmptyString(settings.meshNodeId);
20419
+ const nodeLabel = targetNode ? `Node '${targetNode.id}'` : runtimeNodeId ? `Node '${runtimeNodeId}'` : `Agent at ${workspace}`;
20420
+ injectMeshSystemMessage(components, {
20421
+ meshId,
20422
+ sourceInstanceId: instanceId,
20423
+ nodeLabel,
20424
+ event: event.event,
20425
+ metadataEvent: event
20426
+ });
20427
+ });
20428
+ }
20429
+
20337
20430
  // src/status/snapshot.ts
20338
20431
  init_config();
20339
20432
  import * as os18 from "os";
@@ -21303,6 +21396,9 @@ var DaemonCommandRouter = class {
21303
21396
  async executeDaemonCommand(cmd, args) {
21304
21397
  switch (cmd) {
21305
21398
  // ─── CLI / ACP commands ───
21399
+ case "mesh_forward_event": {
21400
+ return handleMeshForwardEvent({ instanceManager: this.deps.instanceManager }, args);
21401
+ }
21306
21402
  case "launch_cli":
21307
21403
  case "stop_cli":
21308
21404
  case "set_cli_view_mode":
@@ -29930,64 +30026,6 @@ var SessionRegistry = class {
29930
30026
  // src/boot/daemon-lifecycle.ts
29931
30027
  init_logger();
29932
30028
  init_config();
29933
-
29934
- // src/mesh/mesh-events.ts
29935
- init_mesh_config();
29936
- init_logger();
29937
- function readNonEmptyString(value) {
29938
- return typeof value === "string" && value.trim() ? value.trim() : "";
29939
- }
29940
- function formatCompletionMetadata(event) {
29941
- const parts = [
29942
- readNonEmptyString(event.targetSessionId) ? `session_id=${readNonEmptyString(event.targetSessionId)}` : "",
29943
- readNonEmptyString(event.providerType) ? `provider=${readNonEmptyString(event.providerType)}` : "",
29944
- readNonEmptyString(event.providerSessionId) ? `provider_session_id=${readNonEmptyString(event.providerSessionId)}` : ""
29945
- ].filter(Boolean);
29946
- return parts.length > 0 ? ` (${parts.join("; ")})` : "";
29947
- }
29948
- function setupMeshEventForwarding(components) {
29949
- components.instanceManager.onEvent((event) => {
29950
- if (event.event !== "agent:generating_completed" && event.event !== "agent:waiting_approval") return;
29951
- const instanceId = readNonEmptyString(event.instanceId);
29952
- if (!instanceId) return;
29953
- const sourceInstance = components.instanceManager.getInstance(instanceId);
29954
- if (!sourceInstance || sourceInstance.category !== "cli") return;
29955
- const state = sourceInstance.getState();
29956
- const workspace = readNonEmptyString(state.workspace);
29957
- if (!workspace) return;
29958
- const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
29959
- const meshIdFromRuntime = readNonEmptyString(settings.meshNodeFor);
29960
- const mesh = meshIdFromRuntime ? getMesh(meshIdFromRuntime) : getMeshByRepo(workspace);
29961
- const meshId = meshIdFromRuntime || readNonEmptyString(mesh?.id);
29962
- if (!meshId) return;
29963
- const allInstances = components.instanceManager.getByCategory("cli");
29964
- const coordinatorInstances = allInstances.filter((inst) => {
29965
- const instState = inst.getState();
29966
- if (instState.settings?.meshCoordinatorFor !== meshId) return false;
29967
- if (instState.instanceId === instanceId) return false;
29968
- return true;
29969
- });
29970
- if (coordinatorInstances.length === 0) return;
29971
- const targetNode = mesh?.nodes?.find((n) => n.workspace === workspace);
29972
- const runtimeNodeId = readNonEmptyString(settings.meshNodeId);
29973
- const nodeLabel = targetNode ? `Node '${targetNode.id}'` : runtimeNodeId ? `Node '${runtimeNodeId}'` : `Agent at ${workspace}`;
29974
- const metadata = formatCompletionMetadata(event);
29975
- let messageText = "";
29976
- if (event.event === "agent:generating_completed") {
29977
- messageText = `[System] ${nodeLabel} has completed its task and is now idle${metadata}. You may use mesh_read_chat to review its progress.`;
29978
- } else if (event.event === "agent:waiting_approval") {
29979
- messageText = `[System] ${nodeLabel} is waiting for approval to proceed${metadata}. You may use mesh_read_chat and mesh_approve to handle it.`;
29980
- }
29981
- if (!messageText) return;
29982
- for (const coord of coordinatorInstances) {
29983
- const coordState = coord.getState();
29984
- LOG.info("MeshEvents", `Forwarding event from ${workspace} to coordinator ${coordState.instanceId}`);
29985
- coord.onEvent("send_message", { input: { text: messageText, textFallback: messageText } });
29986
- }
29987
- });
29988
- }
29989
-
29990
- // src/boot/daemon-lifecycle.ts
29991
30029
  async function initDaemonComponents(config) {
29992
30030
  installGlobalInterceptor();
29993
30031
  const appConfig = loadConfig();