@adhdev/daemon-standalone 0.9.76-rc.24 → 0.9.76-rc.26

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,7 +7,7 @@
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-DEm3mt0C.js"></script>
10
+ <script type="module" crossorigin src="/assets/index-BJXopvr8.js"></script>
11
11
  <link rel="modulepreload" crossorigin href="/assets/vendor-CLec0455.js">
12
12
  <link rel="stylesheet" crossorigin href="/assets/index-DHNzD5nE.css">
13
13
  </head>
@@ -31370,7 +31370,7 @@ async function handleChatHistory(h, args) {
31370
31370
  }
31371
31371
  }
31372
31372
  async function handleReadChat(h, args) {
31373
- const provider = h.getProvider(args?.agentType);
31373
+ const provider = h.getProvider(args?.agentType || args?.providerType);
31374
31374
  const transport = getTargetTransport(h, provider);
31375
31375
  const historySessionId = getHistorySessionId(h, args);
31376
31376
  const _log = (msg) => LOG.debug("Command", `[read_chat] ${msg}`);
@@ -35223,6 +35223,40 @@ function normalizeReleaseChannel(value) {
35223
35223
  function resolveUpgradeChannel(args) {
35224
35224
  return normalizeReleaseChannel(args?.channel) || normalizeReleaseChannel(args?.updatePolicy?.channel) || normalizeReleaseChannel(args?.npmTag) || normalizeReleaseChannel(loadConfig().updateChannel) || "stable";
35225
35225
  }
35226
+ function readProviderPriorityFromPolicy(policy) {
35227
+ const record2 = policy && typeof policy === "object" && !Array.isArray(policy) ? policy : {};
35228
+ const raw = record2.providerPriority;
35229
+ if (!Array.isArray(raw)) return [];
35230
+ const seen = /* @__PURE__ */ new Set();
35231
+ return raw.map((type2) => typeof type2 === "string" ? type2.trim() : "").filter(Boolean).filter((type2) => {
35232
+ if (seen.has(type2)) return false;
35233
+ seen.add(type2);
35234
+ return true;
35235
+ });
35236
+ }
35237
+ async function resolveProviderTypeFromPriority(args) {
35238
+ if (!args.providerPriority.length) {
35239
+ return { error: `Node '${args.nodeId}' has no providerPriority policy; pass cliType explicitly or configure node.policy.providerPriority` };
35240
+ }
35241
+ const failed = [];
35242
+ for (const requestedType of args.providerPriority) {
35243
+ const normalizedType = args.providerLoader.resolveAlias(requestedType);
35244
+ if (!args.providerLoader.isMachineProviderEnabled(normalizedType)) {
35245
+ failed.push(`${requestedType}: disabled`);
35246
+ continue;
35247
+ }
35248
+ const detected = await detectCLI(normalizedType, args.providerLoader, { includeVersion: false });
35249
+ args.providerLoader.setCliDetectionResults([{
35250
+ id: normalizedType,
35251
+ installed: !!detected,
35252
+ path: detected?.path
35253
+ }], false);
35254
+ args.onStatusChange?.();
35255
+ if (detected) return { providerType: normalizedType };
35256
+ failed.push(`${requestedType}: not detected`);
35257
+ }
35258
+ return { error: `No usable provider detected for node '${args.nodeId}' from providerPriority: ${failed.join("; ")}` };
35259
+ }
35226
35260
  function loadYamlModule() {
35227
35261
  return js_yaml_exports;
35228
35262
  }
@@ -46834,7 +46868,19 @@ ${effect.notification.body || ""}`.trim();
46834
46868
  }
46835
46869
  }
46836
46870
  pushEvent(event) {
46837
- this.events.push(event);
46871
+ const enrichedEvent = {
46872
+ ...event,
46873
+ instanceId: typeof event.instanceId === "string" && event.instanceId.trim() ? event.instanceId : this.instanceId,
46874
+ targetSessionId: typeof event.targetSessionId === "string" && event.targetSessionId.trim() ? event.targetSessionId : this.instanceId,
46875
+ providerType: typeof event.providerType === "string" && event.providerType.trim() ? event.providerType : this.type,
46876
+ workspaceName: typeof event.workspaceName === "string" && event.workspaceName.trim() ? event.workspaceName : this.workingDir,
46877
+ providerSessionId: typeof event.providerSessionId === "string" && event.providerSessionId.trim() ? event.providerSessionId : this.providerSessionId
46878
+ };
46879
+ if (this.context?.emitProviderEvent) {
46880
+ this.context.emitProviderEvent(enrichedEvent);
46881
+ return;
46882
+ }
46883
+ this.events.push(enrichedEvent);
46838
46884
  }
46839
46885
  flushEvents() {
46840
46886
  const events = [...this.events];
@@ -51309,7 +51355,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
51309
51355
  if (!workspace) return { success: false, error: "workspace required" };
51310
51356
  try {
51311
51357
  const { addNode: addNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51312
- const node = addNode3(meshId, { workspace });
51358
+ const providerPriority = Array.isArray(args?.providerPriority) ? args.providerPriority.map((type2) => typeof type2 === "string" ? type2.trim() : "").filter(Boolean) : [];
51359
+ const readOnly = args?.readOnly === true;
51360
+ const policy = {
51361
+ ...readOnly ? { readOnly: true } : {},
51362
+ ...providerPriority.length ? { providerPriority } : {}
51363
+ };
51364
+ const node = addNode3(meshId, { workspace, ...policy ? { policy } : {} });
51313
51365
  if (!node) return { success: false, error: "Mesh not found" };
51314
51366
  return { success: true, node };
51315
51367
  } catch (e) {
@@ -51412,7 +51464,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
51412
51464
  // ─── Mesh Coordinator Launch ───
51413
51465
  case "launch_mesh_coordinator": {
51414
51466
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51415
- const cliType = typeof args?.cliType === "string" ? args.cliType.trim() : "claude-cli";
51467
+ let cliType = typeof args?.cliType === "string" ? args.cliType.trim() : "";
51416
51468
  if (!meshId) return { success: false, error: "meshId required" };
51417
51469
  try {
51418
51470
  const { buildCoordinatorSystemPrompt: buildCoordinatorSystemPrompt2 } = await Promise.resolve().then(() => (init_coordinator_prompt(), coordinator_prompt_exports));
@@ -51440,6 +51492,25 @@ Run 'adhdev doctor' for detailed diagnostics.`
51440
51492
  }
51441
51493
  const workspace = typeof coordinatorNode.workspace === "string" ? coordinatorNode.workspace.trim() : "";
51442
51494
  if (!workspace) return { success: false, error: "Coordinator node workspace required", meshId, cliType };
51495
+ if (!cliType) {
51496
+ const resolved = await resolveProviderTypeFromPriority({
51497
+ nodeId: String(coordinatorNode.id || coordinatorNode.nodeId || preferredCoordinatorNodeId || "coordinator"),
51498
+ providerPriority: readProviderPriorityFromPolicy(coordinatorNode.policy),
51499
+ providerLoader: this.deps.providerLoader,
51500
+ onStatusChange: this.deps.onStatusChange
51501
+ });
51502
+ if (!resolved.providerType) {
51503
+ return {
51504
+ success: false,
51505
+ code: "mesh_coordinator_provider_priority_unusable",
51506
+ error: resolved.error || "No usable provider found from node providerPriority",
51507
+ meshId,
51508
+ cliType,
51509
+ workspace
51510
+ };
51511
+ }
51512
+ cliType = resolved.providerType;
51513
+ }
51443
51514
  const providerMeta = this.deps.providerLoader.resolve?.(cliType) || this.deps.providerLoader.getMeta(cliType);
51444
51515
  const coordinatorSetup = resolveMeshCoordinatorSetup({
51445
51516
  provider: providerMeta,
@@ -51752,6 +51823,12 @@ Run 'adhdev doctor' for detailed diagnostics.`
51752
51823
  if (providerType) {
51753
51824
  payload.providerType = providerType;
51754
51825
  }
51826
+ if (typeof event.providerSessionId === "string" && event.providerSessionId.trim()) {
51827
+ payload.providerSessionId = event.providerSessionId.trim();
51828
+ }
51829
+ if (typeof event.workspaceName === "string" && event.workspaceName.trim()) {
51830
+ payload.workspaceName = event.workspaceName.trim();
51831
+ }
51755
51832
  if (typeof event.duration === "number" && Number.isFinite(event.duration)) {
51756
51833
  payload.duration = event.duration;
51757
51834
  }
@@ -52799,7 +52876,10 @@ Run 'adhdev doctor' for detailed diagnostics.`
52799
52876
  this.instances.get(id).dispose();
52800
52877
  }
52801
52878
  this.instances.set(id, instance);
52802
- await instance.init(context);
52879
+ await instance.init({
52880
+ ...context,
52881
+ emitProviderEvent: (event) => this.emitProviderEvent(instance.type, id, event)
52882
+ });
52803
52883
  }
52804
52884
  /**
52805
52885
  * Instance remove
@@ -52961,6 +53041,17 @@ Run 'adhdev doctor' for detailed diagnostics.`
52961
53041
  onEvent(listener) {
52962
53042
  this.eventListeners.push(listener);
52963
53043
  }
53044
+ emitProviderEvent(providerType, instanceId, event) {
53045
+ const payload = {
53046
+ ...event,
53047
+ providerType,
53048
+ instanceId: typeof event.instanceId === "string" && event.instanceId.trim() ? event.instanceId : instanceId,
53049
+ targetSessionId: typeof event.targetSessionId === "string" && event.targetSessionId.trim() ? event.targetSessionId : instanceId
53050
+ };
53051
+ for (const listener of this.eventListeners) {
53052
+ listener(payload);
53053
+ }
53054
+ }
52964
53055
  emitPendingEvents(providerType, state, extra = {}) {
52965
53056
  for (const event of state.pendingEvents) {
52966
53057
  for (const listener of this.eventListeners) {
@@ -56459,6 +56550,7 @@ ${lines.join("\n\n")}`;
56459
56550
  }
56460
56551
 
56461
56552
  // src/tools/mesh-tools.ts
56553
+ var meshSessionProviderMetadata = /* @__PURE__ */ new Map();
56462
56554
  async function refreshMeshFromDaemon(ctx) {
56463
56555
  if (!(ctx.transport instanceof IpcTransport)) return;
56464
56556
  try {
@@ -56507,6 +56599,12 @@ function extractGitDiff(value) {
56507
56599
  const payload = unwrapCommandPayload(value);
56508
56600
  return payload?.diffSummary ?? payload?.diff ?? value?.diffSummary ?? value?.diff ?? payload;
56509
56601
  }
56602
+ function extractLaunchPayload(value) {
56603
+ return findNestedPayload(value, (payload) => Boolean(payload?.sessionId || payload?.id || payload?.runtimeSessionId));
56604
+ }
56605
+ function meshSessionCacheKey(nodeId, runtimeSessionId) {
56606
+ return `${nodeId}:${runtimeSessionId}`;
56607
+ }
56510
56608
  function countUncommittedChanges(status) {
56511
56609
  if (typeof status?.uncommittedChanges === "number") return status.uncommittedChanges;
56512
56610
  const keys = ["staged", "modified", "untracked", "deleted", "renamed"];
@@ -56559,12 +56657,13 @@ var MESH_SEND_TASK_TOOL = {
56559
56657
  };
56560
56658
  var MESH_READ_CHAT_TOOL = {
56561
56659
  name: "mesh_read_chat",
56562
- description: "Read recent chat messages from a delegated agent session on a mesh node. Use this to check progress.",
56660
+ description: "Read recent chat messages from a delegated agent session on a mesh node. Use this to check progress. If the runtime session has completed, provider_session_id can explicitly target provider transcript history.",
56563
56661
  inputSchema: {
56564
56662
  type: "object",
56565
56663
  properties: {
56566
56664
  node_id: { type: "string", description: "Target node ID." },
56567
56665
  session_id: { type: "string", description: "Agent session ID to read from." },
56666
+ provider_session_id: { type: "string", description: "Optional provider transcript/session ID for completed sessions." },
56568
56667
  tail: { type: "number", description: "Number of recent messages to return (default: 10)." }
56569
56668
  },
56570
56669
  required: ["node_id", "session_id"]
@@ -56572,14 +56671,14 @@ var MESH_READ_CHAT_TOOL = {
56572
56671
  };
56573
56672
  var MESH_LAUNCH_SESSION_TOOL = {
56574
56673
  name: "mesh_launch_session",
56575
- description: "Launch a new agent session on a mesh node. Returns the session ID for subsequent send_task/read_chat calls. If the user names a provider, preserve it exactly: Hermes = hermes-cli, Claude Code/Claude = claude-cli, Codex = codex-cli, Gemini = gemini-cli. Do not default to claude-cli unless the user requested Claude Code or no provider was specified.",
56674
+ description: "Launch a new agent session on a mesh node. Returns the session ID for subsequent send_task/read_chat calls. If the user names a provider, preserve it exactly: Hermes = hermes-cli, Claude Code/Claude = claude-cli, Codex = codex-cli, Gemini = gemini-cli. If type is omitted, resolve strictly from the node policy providerPriority and provider detection; fail closed when no configured provider is usable. Do not default to claude-cli.",
56576
56675
  inputSchema: {
56577
56676
  type: "object",
56578
56677
  properties: {
56579
56678
  node_id: { type: "string", description: "Target node ID." },
56580
- type: { type: "string", description: "Provider type to launch. Use hermes-cli for Hermes, claude-cli for Claude Code, codex-cli for Codex, gemini-cli for Gemini." }
56679
+ type: { type: "string", description: "Optional provider type to launch. Use hermes-cli for Hermes, claude-cli for Claude Code, codex-cli for Codex, gemini-cli for Gemini. When omitted, node.policy.providerPriority is probed in order." }
56581
56680
  },
56582
- required: ["node_id", "type"]
56681
+ required: ["node_id"]
56583
56682
  }
56584
56683
  };
56585
56684
  var MESH_GIT_STATUS_TOOL = {
@@ -56736,9 +56835,13 @@ async function meshSendTask(ctx, args) {
56736
56835
  async function meshReadChat(ctx, args) {
56737
56836
  const node = await findNodeWithRefresh(ctx, args.node_id);
56738
56837
  if (isLocalTransport(ctx.transport)) {
56838
+ const cached2 = meshSessionProviderMetadata.get(meshSessionCacheKey(args.node_id, args.session_id));
56839
+ const providerSessionId = typeof args.provider_session_id === "string" && args.provider_session_id.trim() ? args.provider_session_id.trim() : cached2?.providerSessionId;
56739
56840
  const result = await commandForNode(ctx, node, "read_chat", {
56740
56841
  sessionId: args.session_id,
56741
56842
  targetSessionId: args.session_id,
56843
+ ...cached2?.providerType ? { agentType: cached2.providerType, providerType: cached2.providerType } : {},
56844
+ ...providerSessionId ? { providerSessionId } : {},
56742
56845
  tailLimit: args.tail ?? 10
56743
56846
  });
56744
56847
  return JSON.stringify(result, null, 2);
@@ -56749,15 +56852,49 @@ async function meshReadChat(ctx, args) {
56749
56852
  async function meshLaunchSession(ctx, args) {
56750
56853
  const node = await findNodeWithRefresh(ctx, args.node_id);
56751
56854
  if (isLocalTransport(ctx.transport)) {
56855
+ let resolvedProviderType = typeof args.type === "string" && args.type.trim() ? args.type : "";
56856
+ if (!resolvedProviderType) {
56857
+ const rawProviderPriority = node.policy?.providerPriority;
56858
+ const providerPriority = Array.isArray(rawProviderPriority) ? rawProviderPriority.map((type2) => typeof type2 === "string" ? type2.trim() : "").filter(Boolean) : [];
56859
+ if (!providerPriority.length) {
56860
+ return JSON.stringify({ error: `Node '${args.node_id}' has no providerPriority policy; pass type explicitly or configure node.policy.providerPriority` });
56861
+ }
56862
+ const failed = [];
56863
+ for (const providerType of providerPriority) {
56864
+ const detectedResult = await commandForNode(ctx, node, "detect_provider", { providerType });
56865
+ const detectedPayload = unwrapCommandPayload(detectedResult);
56866
+ if (detectedPayload?.success && detectedPayload?.detected) {
56867
+ resolvedProviderType = providerType;
56868
+ break;
56869
+ }
56870
+ failed.push(`${providerType}: ${detectedPayload?.error || "not detected"}`);
56871
+ }
56872
+ if (!resolvedProviderType) {
56873
+ return JSON.stringify({ error: `No usable provider detected for node '${args.node_id}' from providerPriority: ${failed.join("; ")}` });
56874
+ }
56875
+ }
56752
56876
  const result = await commandForNode(ctx, node, "launch_cli", {
56753
- cliType: args.type,
56877
+ cliType: resolvedProviderType,
56754
56878
  dir: node.workspace,
56755
56879
  settings: {
56756
56880
  meshNodeFor: ctx.mesh.id,
56757
56881
  launchedByCoordinator: true
56758
56882
  }
56759
56883
  });
56760
- return JSON.stringify(result, null, 2);
56884
+ const launchPayload = extractLaunchPayload(result);
56885
+ const runtimeSessionId = typeof launchPayload?.sessionId === "string" ? launchPayload.sessionId : typeof launchPayload?.id === "string" ? launchPayload.id : typeof launchPayload?.runtimeSessionId === "string" ? launchPayload.runtimeSessionId : "";
56886
+ const providerSessionId = typeof launchPayload?.providerSessionId === "string" && launchPayload.providerSessionId.trim() ? launchPayload.providerSessionId.trim() : void 0;
56887
+ if (runtimeSessionId) {
56888
+ meshSessionProviderMetadata.set(meshSessionCacheKey(args.node_id, runtimeSessionId), {
56889
+ providerType: resolvedProviderType,
56890
+ ...providerSessionId ? { providerSessionId } : {}
56891
+ });
56892
+ }
56893
+ return JSON.stringify({
56894
+ ...launchPayload,
56895
+ resolvedProviderType,
56896
+ ...providerSessionId ? { providerSessionId } : {}
56897
+ }, null, 2);
56761
56898
  } else {
56762
56899
  return JSON.stringify({ error: "Cloud mesh launch_session not yet implemented" });
56763
56900
  }