@adhdev/daemon-standalone 1.0.40 → 1.0.41-rc.10

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-DUQvQURE.js"></script>
10
+ <script type="module" crossorigin src="/assets/index-DY_eF9Hd.js"></script>
11
11
  <link rel="modulepreload" crossorigin href="/assets/vendor-DgFmqOGd.js">
12
- <link rel="stylesheet" crossorigin href="/assets/index-BRvsAKU_.css">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-DcvJsnpp.css">
13
13
  </head>
14
14
  <body>
15
15
  <!-- Apply theme immediately to prevent FOIT (Flash of Incorrect Theme) -->
@@ -986,7 +986,7 @@ var MESH_ENQUEUE_TASK_TOOL = {
986
986
  priority: { type: "string", enum: ["low", "normal", "high"], description: "G6 (task-level scheduling priority). Within the claim tier a high task is pulled ahead of an older normal/low task (created_at is the tie-break); low is pulled last. Defaults to normal. This is the TASK priority (which task a node pulls first) \u2014 distinct from a node's schedulingPriority (which node work goes to). Use high to jump an urgent fix ahead of a backlog without cancelling the queue." },
987
987
  model: { type: "string", description: "Optional model override for the agent that runs this task, e.g. opus, sonnet, haiku. Best-effort: applied at launch for providers that support a model flag (claude-cli --model, ACP setConfigOption); ignored by providers that cannot honor it. Use a cheaper model for simple tasks to save tokens, a stronger one for hard work. Blank = the provider default." },
988
988
  thinkingLevel: { type: "string", enum: ["low", "medium", "high"], description: "Optional reasoning-effort level for this task. Best-effort: applied at launch for providers that support it (claude-cli --effort, codex-cli reasoning effort, ACP thought_level); ignored otherwise. Use low for simple tasks (fewer tokens), high for hard reasoning." },
989
- difficulty: { type: "string", enum: ["easy", "medium", "difficult", "freeform"], description: "Optional task execution difficulty. When set, the mesh per-difficulty brain preset fills in the model + thinkingLevel you did not pass explicitly (easy \u2192 cheap model / low effort to save tokens; difficult \u2192 strong model / high effort). Classify each task you enqueue so simple work runs cheaply. An explicit model/thinkingLevel above always wins over the preset." },
989
+ difficulty: { type: "string", enum: ["easy", "medium", "difficult", "freeform"], description: "Optional task execution difficulty \u2014 a ROUTING HINT, not a model selector. It is matched against each node's capability slots so the task lands on a slot configured for that difficulty, and THAT SLOT's own model + thinkingLevel are what launch. It does not by itself mean a cheaper or stronger model: to change what a difficulty runs on, edit the node's slots (mesh_node_slots_set) rather than picking a different difficulty. Classify each task by how hard the work actually is. An explicit model/thinkingLevel above always wins." },
990
990
  notBefore: { type: "number", description: "CamelCase alias for not_before. Also accepts an ISO-8601 timestamp string." },
991
991
  max_retries: { type: "number", description: "P3 (retry cap). Max automatic requeue attempts before the task auto-fails instead of returning to pending. When requeueCount reaches this, mesh_queue_requeue auto-fails the task unless force=true. Omit to use the mesh policy default (maxTaskRetries, typically 1)." },
992
992
  maxRetries: { type: "number", description: "CamelCase alias for max_retries." },
@@ -4472,6 +4472,16 @@ function findInFlightDuplicate(ctx, message, targetNodeId) {
4472
4472
  }
4473
4473
  return null;
4474
4474
  }
4475
+ function buildUntargetedCodeChangeWorktreeAdvisory(input) {
4476
+ if (input.taskMode !== "code_change") return null;
4477
+ if (input.readonly) return null;
4478
+ if (input.targetNodeId) return null;
4479
+ if (input.preferWorktree) return null;
4480
+ if (Array.isArray(input.requiredTags) && input.requiredTags.length > 0) return null;
4481
+ return {
4482
+ worktreeRoutingAdvisory: 'This untargeted `code_change` will be claimed by whichever node polls first \u2014 usually the BASE node, which gives it no branch isolation. Base nodes are for environment-specific testing (win32 PATH/registry, clean install on one OS, that machine\'s package state, OS-dependent runtime behavior). If this task only changes code, cancel it (mesh_queue_cancel), call mesh_clone_node (~10s, auto-launch starts the session), and re-enqueue with target_node_id set to the returned worktree node id \u2014 or pass prefer_worktree: true to route to the most recent worktree. If it DOES need a specific machine, pin it with required_tags (e.g. ["os=win32"]) or target_node_id and this advisory will not appear.'
4483
+ };
4484
+ }
4475
4485
  async function meshEnqueueTask(ctx, args) {
4476
4486
  const message = readString(args.message);
4477
4487
  if (!message) {
@@ -4541,6 +4551,13 @@ async function meshEnqueueTask(ctx, args) {
4541
4551
  });
4542
4552
  const duplicateWarning = duplicateSuspect ? { duplicateSuspect: { taskId: duplicateSuspect.id, status: duplicateSuspect.status, assignedNodeId: duplicateSuspect.assignedNodeId, targetNodeId: duplicateSuspect.targetNodeId }, duplicateSuspectHint: "An in-flight task with the same message+target already exists. This new task was enqueued anyway (warn-only). Cancel one via mesh_queue_cancel if it is an accidental re-enqueue, or pass allow_duplicate=true to silence this, or block_duplicate=true to refuse next time." } : {};
4543
4553
  const missionWarning = buildMissionInactiveWarning(ctx, missionId) ?? {};
4554
+ const worktreeAdvisory = buildUntargetedCodeChangeWorktreeAdvisory({
4555
+ taskMode,
4556
+ readonly,
4557
+ requiredTags,
4558
+ targetNodeId,
4559
+ preferWorktree
4560
+ }) ?? {};
4544
4561
  const enqueueEcho = {
4545
4562
  ...task.priority ? { priority: task.priority } : {},
4546
4563
  ...task.notBefore ? { notBefore: task.notBefore } : {},
@@ -4560,6 +4577,7 @@ async function meshEnqueueTask(ctx, args) {
4560
4577
  ...preferWorktree && !explicitTargetRaw && !targetNodeId ? { preferWorktreeNoOp: true } : {},
4561
4578
  ...duplicateWarning,
4562
4579
  ...missionWarning,
4580
+ ...worktreeAdvisory,
4563
4581
  queueTrigger,
4564
4582
  ...buildQueueTriggerGuidance(queueTrigger)
4565
4583
  });
@@ -4645,6 +4663,7 @@ async function meshEnqueueTask(ctx, args) {
4645
4663
  ...eagerPushDeferred ? { eagerPushDeferred: true, eagerPushDeferredReason: "dependencies_unsatisfied" } : {},
4646
4664
  ...duplicateWarning,
4647
4665
  ...missionWarning,
4666
+ ...worktreeAdvisory,
4648
4667
  queueTrigger,
4649
4668
  ...buildQueueTriggerGuidance(queueTrigger)
4650
4669
  });
@@ -8086,6 +8105,10 @@ async function meshCloneNode(ctx, args) {
8086
8105
  ctx.mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
8087
8106
  await syncCoordinatorDaemonMeshCache(ctx);
8088
8107
  }
8108
+ const planWarnings = Array.isArray(planned?.warnings) ? planned.warnings : [];
8109
+ if (planWarnings.length && result && typeof result === "object") {
8110
+ return JSON.stringify({ ...result, warnings: planWarnings }, null, 2);
8111
+ }
8089
8112
  return JSON.stringify(result, null, 2);
8090
8113
  }
8091
8114
  async function meshRemoveNode(ctx, args) {