@adhdev/daemon-standalone 0.9.82-rc.196 → 0.9.82-rc.198

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-0rc1KNB7.js"></script>
10
+ <script type="module" crossorigin src="/assets/index-DrnKfl-h.js"></script>
11
11
  <link rel="modulepreload" crossorigin href="/assets/vendor-BwuWgaJI.js">
12
- <link rel="stylesheet" crossorigin href="/assets/index-DNAiYM9S.css">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-BmDLCbzV.css">
13
13
  </head>
14
14
  <body>
15
15
  <!-- Apply theme immediately to prevent FOIT (Flash of Incorrect Theme) -->
@@ -2976,6 +2976,35 @@ async function meshSendTask(ctx, args) {
2976
2976
  nextAction: `Relaunch the target session on node '${args.node_id}' or retry without session_id so Repo Mesh can pick a session with provider metadata.`
2977
2977
  });
2978
2978
  }
2979
+ if (explicitTargetSession && !isIdleSessionRecord(explicitTargetSession) && !isTerminalSessionRecord(explicitTargetSession)) {
2980
+ const sessionStatus = typeof explicitTargetSession?.status === "string" ? explicitTargetSession.status : "unknown";
2981
+ const { createSessionDelivery: createDelivery, resolveDeliveryDecision } = await import("@adhdev/daemon-core");
2982
+ const policyResult = resolveDeliveryDecision(sessionStatus, { kind: "task" });
2983
+ if (policyResult.decision === "queued") {
2984
+ const delivery = createDelivery({
2985
+ meshId: ctx.mesh.id,
2986
+ nodeId: args.node_id,
2987
+ sessionId: args.session_id,
2988
+ providerType: resolvedProviderType,
2989
+ kind: "task",
2990
+ message: args.message,
2991
+ status: "queued"
2992
+ });
2993
+ return JSON.stringify({
2994
+ success: true,
2995
+ dispatched: false,
2996
+ decision: "queued_delivery",
2997
+ deliveryId: delivery.id,
2998
+ reason: policyResult.reason,
2999
+ nodeId: args.node_id,
3000
+ sessionId: args.session_id,
3001
+ sessionStatus,
3002
+ taskMode: taskMode || void 0,
3003
+ message: policyResult.message,
3004
+ nextAction: `Use mesh_status to watch for session idle transition, or use mesh_enqueue_task for queue-based assignment. Check deliveryId '${delivery.id}' to track queued delivery.`
3005
+ });
3006
+ }
3007
+ }
2979
3008
  const sessionWasIdle = explicitTargetSession ? isIdleSessionRecord(explicitTargetSession) : false;
2980
3009
  const taskId = (0, import_node_crypto.randomUUID)();
2981
3010
  const dispatchedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -3030,11 +3059,29 @@ async function meshSendTask(ctx, args) {
3030
3059
  dispatchedToIdleSession: sessionWasIdle,
3031
3060
  dispatchedAt
3032
3061
  });
3062
+ let deliveryId;
3063
+ try {
3064
+ const { createSessionDelivery: createDelivery } = await import("@adhdev/daemon-core");
3065
+ const delivery = createDelivery({
3066
+ meshId: ctx.mesh.id,
3067
+ nodeId: args.node_id,
3068
+ sessionId: args.session_id,
3069
+ providerType: resolvedProviderType || void 0,
3070
+ taskId,
3071
+ kind: "task",
3072
+ message: args.message,
3073
+ status: sessionWasIdle ? "delivered" : "delivering"
3074
+ });
3075
+ deliveryId = delivery.id;
3076
+ } catch {
3077
+ }
3033
3078
  return JSON.stringify({
3034
3079
  success: true,
3035
3080
  dispatched: true,
3081
+ decision: "immediate",
3036
3082
  source: "direct",
3037
3083
  taskId,
3084
+ deliveryId,
3038
3085
  taskMode,
3039
3086
  providerType: resolvedProviderType,
3040
3087
  nodeId: args.node_id,
@@ -4399,6 +4446,90 @@ function formatChatDebugResult(result, options) {
4399
4446
  return JSON.stringify(result, null, 2);
4400
4447
  }
4401
4448
 
4449
+ // src/tools/spec-debug.ts
4450
+ var SPEC_DEBUG_TOOL = {
4451
+ name: "spec_debug",
4452
+ description: "Get current spec state, sections, and state transition history for a spec-driven CLI session (claude-cli, antigravity-cli, etc.). Use to diagnose idle/busy detection issues, inspect section parsing, or verify idle_hold and busy_hold behavior.",
4453
+ inputSchema: {
4454
+ type: "object",
4455
+ properties: {
4456
+ session_id: {
4457
+ type: "string",
4458
+ description: "Target session ID (from list_sessions)."
4459
+ },
4460
+ daemon_id: {
4461
+ type: "string",
4462
+ description: "Daemon ID (cloud mode only). Omit for local mode."
4463
+ },
4464
+ ...FORMAT_PROP
4465
+ },
4466
+ required: ["session_id"]
4467
+ }
4468
+ };
4469
+ async function specDebug(transport, args) {
4470
+ const sessionId = typeof args.session_id === "string" ? args.session_id.trim() : "";
4471
+ if (!sessionId) throw new Error("session_id is required");
4472
+ let result;
4473
+ if (isLocalTransport(transport)) {
4474
+ result = await transport.command("get_spec_debug", { targetSessionId: sessionId });
4475
+ } else {
4476
+ if (!args.daemon_id) throw new Error("daemon_id is required in cloud mode");
4477
+ const targetId = `${args.daemon_id}:session:${sessionId}`;
4478
+ result = await transport.sendCommand(targetId, "get_spec_debug", { targetSessionId: sessionId });
4479
+ }
4480
+ return formatSpecDebugResult(result, { sessionId, format: args.format });
4481
+ }
4482
+ function formatSpecDebugResult(result, options) {
4483
+ if (!result?.success) {
4484
+ const err = result?.error || "Unknown error";
4485
+ if (options.format === "json") return JSON.stringify({ success: false, error: err }, null, 2);
4486
+ return `Error: ${err}`;
4487
+ }
4488
+ if (options.format === "json") return JSON.stringify(result, null, 2);
4489
+ const snap = result.snapshot;
4490
+ if (!snap) {
4491
+ return [
4492
+ `session_id: ${options.sessionId}`,
4493
+ `provider_type: ${String(result.providerType || "")}`,
4494
+ "is_spec_provider: false",
4495
+ "No spec debug data available (not a spec-driven provider)."
4496
+ ].join("\n");
4497
+ }
4498
+ const lines = [];
4499
+ lines.push(`session_id: ${options.sessionId}`);
4500
+ lines.push(`provider_type: ${String(result.providerType || snap.cliType || "")}`);
4501
+ lines.push(`spec_id: ${String(snap.spec_id || "")}`);
4502
+ lines.push(`spec_path: ${String(snap.specPath || "")}`);
4503
+ lines.push(`current_state: ${snap.current_state ? `${snap.current_state.id} (${snap.current_state.label})` : "none"}`);
4504
+ lines.push(`idle_hold_pending: ${String(snap.idleHoldPending ?? false)}`);
4505
+ lines.push(`last_busy_at: ${snap.lastBusyAt ? new Date(snap.lastBusyAt).toISOString() : "never"}`);
4506
+ lines.push(`exited: ${String(snap.exited ?? false)}`);
4507
+ if (snap.current_modal) {
4508
+ lines.push(`current_modal: ${JSON.stringify(snap.current_modal)}`);
4509
+ }
4510
+ if (snap.sections && typeof snap.sections === "object") {
4511
+ lines.push("");
4512
+ lines.push("\u2500\u2500 sections \u2500\u2500");
4513
+ for (const [id, text] of Object.entries(snap.sections)) {
4514
+ const preview = String(text || "").replace(/\n/g, "\u21B5").slice(0, 120);
4515
+ lines.push(` ${id}: ${preview}`);
4516
+ }
4517
+ }
4518
+ const history = Array.isArray(snap.stateHistory) ? snap.stateHistory : [];
4519
+ if (history.length > 0) {
4520
+ lines.push("");
4521
+ lines.push("\u2500\u2500 state history (newest first) \u2500\u2500");
4522
+ const now = Date.now();
4523
+ for (const entry of [...history].reverse().slice(0, 20)) {
4524
+ const agoMs = now - entry.at;
4525
+ const ago = agoMs < 2e3 ? `${agoMs}ms ago` : `${(agoMs / 1e3).toFixed(1)}s ago`;
4526
+ const dur = entry.durationMs > 0 ? ` held ${entry.durationMs}ms` : "";
4527
+ lines.push(` ${String(entry.stateId).padEnd(18)} ${ago}${dur}`);
4528
+ }
4529
+ }
4530
+ return lines.join("\n");
4531
+ }
4532
+
4402
4533
  // src/tools/send-chat.ts
4403
4534
  var SEND_CHAT_TOOL = {
4404
4535
  name: "send_chat",
@@ -5461,6 +5592,7 @@ async function startMcpServer(opts) {
5461
5592
  CHECK_PENDING_TOOL,
5462
5593
  READ_CHAT_TOOL,
5463
5594
  READ_CHAT_DEBUG_TOOL,
5595
+ SPEC_DEBUG_TOOL,
5464
5596
  SEND_CHAT_TOOL,
5465
5597
  APPROVE_TOOL,
5466
5598
  GIT_STATUS_TOOL,
@@ -5496,6 +5628,10 @@ async function startMcpServer(opts) {
5496
5628
  const text = await readChatDebug(transport, a);
5497
5629
  return { content: [{ type: "text", text }] };
5498
5630
  }
5631
+ case "spec_debug": {
5632
+ const text = await specDebug(transport, a);
5633
+ return { content: [{ type: "text", text }] };
5634
+ }
5499
5635
  case "send_chat": {
5500
5636
  const text = await sendChat(transport, { message: a.message, session_id: a.session_id, daemon_id: a.daemon_id });
5501
5637
  return { content: [{ type: "text", text }] };