@adhdev/daemon-standalone 0.9.82-rc.186 → 0.9.82-rc.188

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/public/index.html CHANGED
@@ -7,9 +7,9 @@
7
7
  <meta name="description" content="ADHDev self-hosted dashboard for controlling AI agents" />
8
8
  <link rel="icon" href="/otter-logo.png" />
9
9
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
10
- <script type="module" crossorigin src="/assets/index-B9KHrSa-.js"></script>
11
- <link rel="modulepreload" crossorigin href="/assets/vendor-DNk1FT1R.js">
12
- <link rel="stylesheet" crossorigin href="/assets/index-BSeeeP5M.css">
10
+ <script type="module" crossorigin src="/assets/index-Du2Maw3Y.js"></script>
11
+ <link rel="modulepreload" crossorigin href="/assets/vendor-BwuWgaJI.js">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-Bgt2DRUK.css">
13
13
  </head>
14
14
  <body>
15
15
  <!-- Apply theme immediately to prevent FOIT (Flash of Incorrect Theme) -->
@@ -778,6 +778,172 @@ function unwrapCommandPayload(value) {
778
778
  }
779
779
  return current;
780
780
  }
781
+ function isDirectDispatchLedgerEntry(entry) {
782
+ if (entry?.kind !== "task_dispatched") return false;
783
+ const payload = entry.payload || {};
784
+ const via = readString(payload.via);
785
+ return payload.source === "direct" || via === "p2p_direct" || via === "local_direct" || via === "mesh_send_task";
786
+ }
787
+ function readMessageTimestampIso(message) {
788
+ for (const value of [message?.timestamp, message?.createdAt, message?.created_at, message?.updatedAt, message?.time]) {
789
+ if (typeof value === "number" && Number.isFinite(value)) {
790
+ const ms = value > 1e10 ? value : value * 1e3;
791
+ return new Date(ms).toISOString();
792
+ }
793
+ if (typeof value === "string" && value.trim()) {
794
+ const ms = new Date(value.trim()).getTime();
795
+ if (Number.isFinite(ms)) return new Date(ms).toISOString();
796
+ }
797
+ }
798
+ return void 0;
799
+ }
800
+ function readFinalAssistantTranscriptEvidence(payload) {
801
+ const rawMessages = Array.isArray(payload?.messages) ? payload.messages : [];
802
+ const finalAssistant = [...rawMessages].reverse().filter(isCoordinatorVisibleMessage).find((message) => {
803
+ const role = String(message?.role ?? "").toLowerCase();
804
+ return (role === "assistant" || role === "agent") && messageContent(message).trim();
805
+ });
806
+ const finalSummary = messageContent(finalAssistant).trim() || (typeof payload?.summary === "string" && payload.summary.trim() ? payload.summary.trim() : void 0);
807
+ return {
808
+ finalSummary,
809
+ transcriptMessageAt: finalAssistant ? readMessageTimestampIso(finalAssistant) : void 0
810
+ };
811
+ }
812
+ function findNodeSession(nodes, nodeId, sessionId) {
813
+ if (!nodeId || !sessionId) return {};
814
+ const node = nodes.find((candidate) => readString(candidate?.id) === nodeId || readString(candidate?.nodeId) === nodeId);
815
+ if (!node) return {};
816
+ const sessions = Array.isArray(node.sessions) ? node.sessions : [];
817
+ const session = sessions.find((candidate) => readSessionRecordId(candidate) === sessionId);
818
+ return { node, session };
819
+ }
820
+ function buildDirectDispatchReconciliationCandidates(directDispatches, ledgerEntries) {
821
+ const candidates = [];
822
+ const seenTaskIds = /* @__PURE__ */ new Set();
823
+ for (const dispatch of directDispatches || []) {
824
+ const taskId = readString(dispatch?.taskId);
825
+ if (!taskId || seenTaskIds.has(taskId)) continue;
826
+ seenTaskIds.add(taskId);
827
+ candidates.push(dispatch);
828
+ }
829
+ for (const entry of ledgerEntries || []) {
830
+ if (!isDirectDispatchLedgerEntry(entry)) continue;
831
+ const taskId = readString(entry.payload?.taskId);
832
+ if (!taskId || seenTaskIds.has(taskId)) continue;
833
+ seenTaskIds.add(taskId);
834
+ candidates.push({
835
+ taskId,
836
+ nodeId: entry.nodeId,
837
+ sessionId: entry.sessionId,
838
+ providerType: entry.providerType || readString(entry.payload?.providerType),
839
+ message: readString(entry.payload?.message),
840
+ dispatchedAt: entry.timestamp,
841
+ via: readString(entry.payload?.via)
842
+ });
843
+ }
844
+ return candidates;
845
+ }
846
+ async function reconcileDirectDispatchesFromTranscriptEvidence(ctx, liveNodes, directDispatches, ledgerEntries) {
847
+ let attempted = 0;
848
+ let reconciled = 0;
849
+ let skipped = 0;
850
+ const candidates = buildDirectDispatchReconciliationCandidates(directDispatches, ledgerEntries);
851
+ for (const dispatch of candidates) {
852
+ const taskId = readString(dispatch?.taskId);
853
+ const nodeId = readString(dispatch?.nodeId);
854
+ const sessionId = readString(dispatch?.sessionId);
855
+ if (!taskId || !nodeId || !sessionId) {
856
+ skipped += 1;
857
+ continue;
858
+ }
859
+ const { session } = findNodeSession(liveNodes, nodeId, sessionId);
860
+ if (!session || !isIdleSessionRecord(session)) {
861
+ skipped += 1;
862
+ continue;
863
+ }
864
+ const node = await findOptionalNodeWithRefresh(ctx, nodeId).catch(() => null);
865
+ if (!node) {
866
+ skipped += 1;
867
+ continue;
868
+ }
869
+ const providerType = readString(dispatch?.providerType) || resolveSessionProviderType(session);
870
+ const providerSessionId = readString(session?.providerSessionId) || readString(session?.activeChat?.providerSessionId) || readString(session?.settings?.providerSessionId) || resolveMeshSessionProviderMetadata(ctx, nodeId, sessionId)?.providerSessionId;
871
+ attempted += 1;
872
+ try {
873
+ const readResult = await commandForNode(ctx, node, "read_chat", {
874
+ sessionId,
875
+ targetSessionId: sessionId,
876
+ workspace: node.workspace,
877
+ ...providerType ? { agentType: providerType, providerType } : {},
878
+ ...providerSessionId ? { providerSessionId } : {},
879
+ tailLimit: 10
880
+ });
881
+ const payload = unwrapCommandPayload(readResult);
882
+ if (payload?.success === false) continue;
883
+ const evidence = readFinalAssistantTranscriptEvidence(payload);
884
+ if (!evidence.finalSummary) continue;
885
+ const result = (0, import_daemon_core.reconcileDirectDispatchCompletionFromTranscript)({
886
+ meshId: ctx.mesh.id,
887
+ nodeId,
888
+ sessionId,
889
+ providerType,
890
+ providerSessionId: readString(payload?.providerSessionId) || providerSessionId,
891
+ taskId,
892
+ finalSummary: evidence.finalSummary,
893
+ transcriptMessageAt: evidence.transcriptMessageAt,
894
+ targetCoordinatorDaemonId: ctx.localDaemonId,
895
+ source: "mcp_mesh_status_transcript_reconciliation"
896
+ });
897
+ if (result.reconciled) reconciled += 1;
898
+ } catch {
899
+ skipped += 1;
900
+ }
901
+ }
902
+ return { attempted, reconciled, skipped };
903
+ }
904
+ async function triggerMeshQueueAndReport(ctx, node, opts) {
905
+ if (!(isLocalTransport(ctx.transport) || ctx.transport instanceof IpcTransport)) return void 0;
906
+ try {
907
+ let raw;
908
+ if (ctx.transport instanceof IpcTransport && node?.daemonId && opts?.localNode === false) {
909
+ raw = await ctx.transport.meshCommand(node.daemonId, "trigger_mesh_queue", { meshId: ctx.mesh.id });
910
+ } else if (isLocalTransport(ctx.transport)) {
911
+ raw = await ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id });
912
+ } else {
913
+ return void 0;
914
+ }
915
+ const payload = unwrapCommandPayload(raw);
916
+ const trigger = payload?.trigger && typeof payload.trigger === "object" ? payload.trigger : payload;
917
+ return trigger && typeof trigger === "object" ? trigger : { success: true };
918
+ } catch (e) {
919
+ return {
920
+ success: false,
921
+ error: e?.message || String(e)
922
+ };
923
+ }
924
+ }
925
+ function buildQueueTriggerGuidance(queueTrigger) {
926
+ if (!queueTrigger || queueTrigger.claimed === true) return void 0;
927
+ if (queueTrigger.success === false) {
928
+ return {
929
+ queueClaimed: false,
930
+ queueDispatchState: "trigger_failed",
931
+ nextAction: "Do not assume the queued task is running. Check mesh_view_queue and daemon connectivity before redispatching."
932
+ };
933
+ }
934
+ if (queueTrigger.noIdleMeshSessionAvailable === true) {
935
+ return {
936
+ queueClaimed: false,
937
+ queueDispatchState: "pending_no_idle_mesh_session",
938
+ nextAction: "The task is queued but not running. Launch a managed worker with mesh_launch_session, or wait for a delegated session to become ready and trigger the queue again."
939
+ };
940
+ }
941
+ return {
942
+ queueClaimed: false,
943
+ queueDispatchState: "pending_or_waiting_for_ready",
944
+ nextAction: "The task is queued but this trigger did not claim it. Use mesh_view_queue for the current active-work source of truth before retrying."
945
+ };
946
+ }
781
947
  function isTerminalSessionRecord(session) {
782
948
  const status = typeof session?.status === "string" ? session.status.toLowerCase() : "";
783
949
  const lifecycle = typeof session?.lifecycle === "string" ? session.lifecycle.toLowerCase() : "";
@@ -797,11 +963,19 @@ function isMeshOwnedDelegateSession(session, meshId, nodeId) {
797
963
  if (sessionMeshId !== meshId) return false;
798
964
  return !sessionNodeId || sessionNodeId === nodeId;
799
965
  }
966
+ function hasRemoteRelayMetadata(session) {
967
+ return Boolean(
968
+ readString(session?.settings?.meshCoordinatorDaemonId) || readString(session?.meta?.meshCoordinatorDaemonId) || readString(session?.metadata?.meshCoordinatorDaemonId) || readString(session?.meshCoordinatorDaemonId)
969
+ );
970
+ }
971
+ function isRelaySafeRemoteDelegateSession(session, meshId, nodeId) {
972
+ return isMeshOwnedDelegateSession(session, meshId, nodeId) && hasRemoteRelayMetadata(session);
973
+ }
800
974
  function chooseDispatchableSession(sessions, providerType, meshId, nodeId) {
801
975
  const live = sessions.filter((session) => !isTerminalSessionRecord(session));
802
976
  const matchingProvider = (session) => !providerType || session?.providerType === providerType || session?.cliType === providerType;
803
977
  const meshSessions = live.filter(
804
- (session) => isMeshOwnedDelegateSession(session, meshId, nodeId)
978
+ (session) => isRelaySafeRemoteDelegateSession(session, meshId, nodeId)
805
979
  );
806
980
  return meshSessions.find((session) => isIdleSessionRecord(session) && matchingProvider(session)) || meshSessions.find(matchingProvider) || void 0;
807
981
  }
@@ -1006,7 +1180,7 @@ async function ipcDispatchToRemoteAgent(ctx, node, args) {
1006
1180
  let resolvedProviderType = args.providerType?.trim() || providerPriorityList[0] || "";
1007
1181
  if (sessionId && args.verifiedSession) {
1008
1182
  const explicitSession = args.verifiedSession;
1009
- if (!isMeshOwnedDelegateSession(explicitSession, ctx.mesh.id, node.id)) {
1183
+ if (!isRelaySafeRemoteDelegateSession(explicitSession, ctx.mesh.id, node.id)) {
1010
1184
  return buildRelayUnsafeRemoteSessionFailure(
1011
1185
  ctx,
1012
1186
  node,
@@ -1041,7 +1215,7 @@ async function ipcDispatchToRemoteAgent(ctx, node, args) {
1041
1215
  nextAction: `Launch a fresh session with mesh_launch_session(node_id: '${node.id}'${resolvedProviderType ? `, type: '${resolvedProviderType}'` : ""}) or retry without session_id so Repo Mesh can target a live delegate session.`
1042
1216
  };
1043
1217
  }
1044
- if (!isMeshOwnedDelegateSession(explicitSession, ctx.mesh.id, node.id)) {
1218
+ if (!isRelaySafeRemoteDelegateSession(explicitSession, ctx.mesh.id, node.id)) {
1045
1219
  return buildRelayUnsafeRemoteSessionFailure(
1046
1220
  ctx,
1047
1221
  node,
@@ -1198,8 +1372,6 @@ function buildNodeMachineIdentity(ctx, node) {
1198
1372
  function nodeHasLocalDaemonEvidence(ctx, node) {
1199
1373
  const isLocal = (session) => {
1200
1374
  if (!session || typeof session !== "object") return false;
1201
- if (ctx.localDaemonId && session.settings?.meshCoordinatorDaemonId === ctx.localDaemonId) return true;
1202
- if (session.launchedByCoordinator === true) return true;
1203
1375
  if (ctx.localDaemonId && session.runtime?.owner === ctx.localDaemonId) return true;
1204
1376
  if (ctx.localDaemonId && session.daemonClient?.daemonId === ctx.localDaemonId) return true;
1205
1377
  return false;
@@ -1337,6 +1509,7 @@ function countUncommittedChanges(status) {
1337
1509
  function isGitStatusDirty(status) {
1338
1510
  if (typeof status?.isDirty === "boolean") return status.isDirty;
1339
1511
  if (typeof status?.dirty === "boolean") return status.dirty;
1512
+ if (Array.isArray(status?.submodules) && status.submodules.some((submodule) => submodule?.dirty || submodule?.outOfSync || submodule?.error)) return true;
1340
1513
  return countUncommittedChanges(status) > 0;
1341
1514
  }
1342
1515
  function slimLedgerPayload(payload) {
@@ -1638,9 +1811,14 @@ async function drainCoordinatorPendingEvents(ctx, opts) {
1638
1811
  const matchesCurrentMesh = (event) => readString(event?.meshId) === ctx.mesh.id;
1639
1812
  if (ctx.transport instanceof IpcTransport) {
1640
1813
  const surfacedEvents = [];
1814
+ const coordinatorDaemonId = readString(ctx.localDaemonId);
1815
+ const pendingEventArgs = {
1816
+ meshId: ctx.mesh.id,
1817
+ ...coordinatorDaemonId ? { coordinatorDaemonId } : {}
1818
+ };
1641
1819
  try {
1642
1820
  surfacedEvents.push(
1643
- ...normalizePendingMeshCoordinatorEvents(await ctx.transport.command("get_pending_mesh_events", { meshId: ctx.mesh.id })).filter(matchesCurrentMesh)
1821
+ ...normalizePendingMeshCoordinatorEvents(await ctx.transport.command("get_pending_mesh_events", pendingEventArgs)).filter(matchesCurrentMesh)
1644
1822
  );
1645
1823
  surfacedEvents.forEach(rememberMeshSessionProviderMetadataFromEvent);
1646
1824
  } catch {
@@ -1650,7 +1828,7 @@ async function drainCoordinatorPendingEvents(ctx, opts) {
1650
1828
  if (requestedNodeIds && !requestedNodeIds.has(node.id)) continue;
1651
1829
  try {
1652
1830
  const remoteEvents = normalizePendingMeshCoordinatorEvents(
1653
- await ctx.transport.meshCommand(node.daemonId, "get_pending_mesh_events", { meshId: ctx.mesh.id })
1831
+ await ctx.transport.meshCommand(node.daemonId, "get_pending_mesh_events", pendingEventArgs)
1654
1832
  ).filter(matchesCurrentMesh);
1655
1833
  if (remoteEvents.length === 0) continue;
1656
1834
  for (const event of remoteEvents) {
@@ -1664,7 +1842,7 @@ async function drainCoordinatorPendingEvents(ctx, opts) {
1664
1842
  }
1665
1843
  try {
1666
1844
  surfacedEvents.push(
1667
- ...normalizePendingMeshCoordinatorEvents(await ctx.transport.command("get_pending_mesh_events", { meshId: ctx.mesh.id })).filter(matchesCurrentMesh)
1845
+ ...normalizePendingMeshCoordinatorEvents(await ctx.transport.command("get_pending_mesh_events", pendingEventArgs)).filter(matchesCurrentMesh)
1668
1846
  );
1669
1847
  surfacedEvents.forEach(rememberMeshSessionProviderMetadataFromEvent);
1670
1848
  } catch {
@@ -2033,7 +2211,7 @@ var ALL_MESH_TOOLS = [
2033
2211
  async function meshStatus(ctx, args = {}) {
2034
2212
  await refreshMeshFromDaemon(ctx);
2035
2213
  const { mesh, transport } = ctx;
2036
- const ledgerSummary = (0, import_daemon_core.getLedgerSummary)(mesh.id);
2214
+ let ledgerSummary = (0, import_daemon_core.getLedgerSummary)(mesh.id);
2037
2215
  const results = await Promise.all(mesh.nodes.map(async (node) => {
2038
2216
  const entry = {
2039
2217
  nodeId: node.id,
@@ -2164,11 +2342,19 @@ async function meshStatus(ctx, args = {}) {
2164
2342
  }
2165
2343
  return entry;
2166
2344
  }));
2167
- const ledgerEntries = (0, import_daemon_core.readLedgerEntries)(mesh.id, { tail: 200 });
2345
+ let ledgerEntries = (0, import_daemon_core.readLedgerEntries)(mesh.id, { tail: 200 });
2346
+ let directDispatches = (0, import_daemon_core.getActiveDirectDispatches)(mesh.id);
2347
+ const directReconciliation = await reconcileDirectDispatchesFromTranscriptEvidence(ctx, results, directDispatches, ledgerEntries);
2348
+ if (directReconciliation.reconciled > 0) {
2349
+ ledgerEntries = (0, import_daemon_core.readLedgerEntries)(mesh.id, { tail: 200 });
2350
+ directDispatches = (0, import_daemon_core.getActiveDirectDispatches)(mesh.id);
2351
+ ledgerSummary = (0, import_daemon_core.getLedgerSummary)(mesh.id);
2352
+ }
2168
2353
  const activeWorkEvidence = (0, import_daemon_core.buildMeshActiveWork)({
2169
2354
  meshId: mesh.id,
2170
2355
  queue: (0, import_daemon_core.getQueue)(mesh.id),
2171
2356
  ledgerEntries,
2357
+ directDispatches,
2172
2358
  nodes: results
2173
2359
  });
2174
2360
  const pollingGuidance = buildActiveWorkPollingGuidance(activeWorkEvidence.summary);
@@ -2364,13 +2550,20 @@ async function meshEnqueueTask(ctx, args) {
2364
2550
  try {
2365
2551
  const task = (0, import_daemon_core.enqueueTask)(ctx.mesh.id, args.message, { taskMode, requiredTags });
2366
2552
  if (isLocalTransport(ctx.transport) && !(ctx.transport instanceof IpcTransport)) {
2367
- ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
2553
+ const queueTrigger = await triggerMeshQueueAndReport(ctx);
2554
+ return JSON.stringify({
2555
+ success: true,
2556
+ source: "queue",
2557
+ taskId: task.id,
2558
+ status: task.status,
2559
+ taskMode: task.taskMode,
2560
+ requiredTags: task.requiredTags,
2561
+ queueTrigger,
2562
+ ...buildQueueTriggerGuidance(queueTrigger)
2368
2563
  });
2369
- return JSON.stringify({ success: true, source: "queue", taskId: task.id, status: task.status, taskMode: task.taskMode, requiredTags: task.requiredTags });
2370
2564
  }
2371
2565
  if (ctx.transport instanceof IpcTransport) {
2372
- ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
2373
- });
2566
+ const queueTrigger = await triggerMeshQueueAndReport(ctx);
2374
2567
  const dispatchPromises = [];
2375
2568
  for (const node of ctx.mesh.nodes) {
2376
2569
  const isLocalNode = isLocalControlPlaneNode(ctx, node);
@@ -2422,7 +2615,16 @@ async function meshEnqueueTask(ctx, args) {
2422
2615
  }
2423
2616
  Promise.all(dispatchPromises).catch(() => {
2424
2617
  });
2425
- return JSON.stringify({ success: true, source: "queue", taskId: task.id, status: task.status, taskMode: task.taskMode, requiredTags: task.requiredTags });
2618
+ return JSON.stringify({
2619
+ success: true,
2620
+ source: "queue",
2621
+ taskId: task.id,
2622
+ status: task.status,
2623
+ taskMode: task.taskMode,
2624
+ requiredTags: task.requiredTags,
2625
+ queueTrigger,
2626
+ ...buildQueueTriggerGuidance(queueTrigger)
2627
+ });
2426
2628
  }
2427
2629
  return JSON.stringify({ success: true, source: "queue", taskId: task.id, status: task.status, taskMode: task.taskMode, requiredTags: task.requiredTags });
2428
2630
  } catch (e) {
@@ -2444,9 +2646,15 @@ async function meshViewQueue(ctx, args) {
2444
2646
  const visibleSummary = buildQueueStatusSummary(queue);
2445
2647
  const maintenance = buildQueueMaintenanceReport(fullQueue);
2446
2648
  const liveNodes = await collectMeshViewQueueNodesWithLiveSessions(ctx);
2649
+ let ledgerEntries = (0, import_daemon_core.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
2650
+ let directDispatches = (0, import_daemon_core.getActiveDirectDispatches)(ctx.mesh.id);
2651
+ const directReconciliation = await reconcileDirectDispatchesFromTranscriptEvidence(ctx, liveNodes, directDispatches, ledgerEntries);
2652
+ if (directReconciliation.reconciled > 0) {
2653
+ ledgerEntries = (0, import_daemon_core.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
2654
+ directDispatches = (0, import_daemon_core.getActiveDirectDispatches)(ctx.mesh.id);
2655
+ }
2447
2656
  (0, import_daemon_core.markStaleDirectDispatches)(ctx.mesh.id);
2448
- const ledgerEntries = (0, import_daemon_core.readLedgerEntries)(ctx.mesh.id, { tail: 200 });
2449
- const directDispatches = (0, import_daemon_core.getActiveDirectDispatches)(ctx.mesh.id);
2657
+ directDispatches = (0, import_daemon_core.getActiveDirectDispatches)(ctx.mesh.id);
2450
2658
  const activeWorkEvidence = (0, import_daemon_core.buildMeshActiveWork)({
2451
2659
  meshId: ctx.mesh.id,
2452
2660
  queue: fullQueue,
@@ -2485,6 +2693,15 @@ async function meshViewQueue(ctx, args) {
2485
2693
  activeWorkSummary: activeWorkEvidence.summary,
2486
2694
  ...pollingGuidance ? { pollingGuidance } : {},
2487
2695
  summary,
2696
+ visibleSummary,
2697
+ activeCounts: summary.activeCounts,
2698
+ historicalCounts: summary.historicalCounts,
2699
+ visibleActiveCounts: visibleSummary.activeCounts,
2700
+ visibleHistoricalCounts: visibleSummary.historicalCounts,
2701
+ activeCount: summary.activeCount,
2702
+ historicalCount: summary.historicalCount,
2703
+ visibleActiveCount: visibleSummary.activeCount,
2704
+ visibleHistoricalCount: visibleSummary.historicalCount,
2488
2705
  staleAssignedTasks,
2489
2706
  staleAssignedCount: maintenance.staleAssignedCount,
2490
2707
  queueMaintenance: maintenance,
@@ -2834,12 +3051,18 @@ async function meshSendTask(ctx, args) {
2834
3051
  targetSessionId: args.session_id,
2835
3052
  taskMode
2836
3053
  });
2837
- if (isLocalTransport(ctx.transport) || ctx.transport instanceof IpcTransport) {
2838
- ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
2839
- });
2840
- }
3054
+ const queueTrigger = isLocalTransport(ctx.transport) || ctx.transport instanceof IpcTransport ? await triggerMeshQueueAndReport(ctx) : void 0;
2841
3055
  const pendingEvents = isLocalTransport(ctx.transport) ? (0, import_daemon_core.drainPendingMeshCoordinatorEvents)(ctx.mesh.id, ctx.localDaemonId) : [];
2842
- const result = { success: true, source: "queue", nodeId: args.node_id, taskId: task.id, status: task.status, taskMode: task.taskMode };
3056
+ const result = {
3057
+ success: true,
3058
+ source: "queue",
3059
+ nodeId: args.node_id,
3060
+ taskId: task.id,
3061
+ status: task.status,
3062
+ taskMode: task.taskMode,
3063
+ queueTrigger,
3064
+ ...buildQueueTriggerGuidance(queueTrigger)
3065
+ };
2843
3066
  if (pendingEvents.length > 0) {
2844
3067
  result.pendingCoordinatorEvents = pendingEvents;
2845
3068
  }
@@ -3012,17 +3235,13 @@ async function meshLaunchSession(ctx, args) {
3012
3235
  });
3013
3236
  } catch {
3014
3237
  }
3015
- if (ctx.transport instanceof IpcTransport && node.daemonId && !isLocalNode) {
3016
- ctx.transport.meshCommand(node.daemonId, "trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
3017
- });
3018
- } else if (isLocalTransport(ctx.transport)) {
3019
- ctx.transport.command("trigger_mesh_queue", { meshId: ctx.mesh.id }).catch(() => {
3020
- });
3021
- }
3238
+ const queueTrigger = await triggerMeshQueueAndReport(ctx, node, { localNode: isLocalNode });
3022
3239
  return JSON.stringify({
3023
3240
  ...launchPayload,
3024
3241
  resolvedProviderType,
3025
- ...providerSessionId ? { providerSessionId } : {}
3242
+ ...providerSessionId ? { providerSessionId } : {},
3243
+ queueTrigger,
3244
+ ...buildQueueTriggerGuidance(queueTrigger)
3026
3245
  }, null, 2);
3027
3246
  } else if (!isLocalTransport(ctx.transport) && node.daemonId) {
3028
3247
  let resolvedProviderType = typeof args.type === "string" && args.type.trim() ? args.type : "";