@adhdev/daemon-standalone 0.9.82-rc.263 → 0.9.82-rc.265

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-C5W61nZC.js"></script>
10
+ <script type="module" crossorigin src="/assets/index-BF7lyi-_.js"></script>
11
11
  <link rel="modulepreload" crossorigin href="/assets/vendor-BHUMCOj6.js">
12
- <link rel="stylesheet" crossorigin href="/assets/index-DW-XJSIP.css">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-CbR_x7-3.css">
13
13
  </head>
14
14
  <body>
15
15
  <!-- Apply theme immediately to prevent FOIT (Flash of Incorrect Theme) -->
@@ -1599,6 +1599,45 @@ function isGitStatusDirty(status) {
1599
1599
  if (Array.isArray(status?.submodules) && status.submodules.some((submodule) => submodule?.dirty || submodule?.outOfSync || submodule?.error)) return true;
1600
1600
  return countUncommittedChanges(status) > 0;
1601
1601
  }
1602
+ var LARGE_LEDGER_FIELD_KEYS = /* @__PURE__ */ new Set(["plan", "validationPlan", "suggestedConfig", "payload"]);
1603
+ var LARGE_LEDGER_OBJECT_THRESHOLD = 800;
1604
+ var LARGE_LEDGER_NESTED_BYTES_THRESHOLD = 2e3;
1605
+ function summarizeLargeLedgerField(key, value) {
1606
+ if (typeof value === "string") {
1607
+ return value.length > 500 ? value.slice(0, 500) + "\u2026" : value;
1608
+ }
1609
+ if (Array.isArray(value)) {
1610
+ const serialized = JSON.stringify(value);
1611
+ if (serialized && serialized.length > LARGE_LEDGER_OBJECT_THRESHOLD) {
1612
+ return `[${key} summarized: ${value.length} items \u2014 use verbose=true or mesh_reconcile_ledger]`;
1613
+ }
1614
+ return value;
1615
+ }
1616
+ if (value && typeof value === "object") {
1617
+ const serialized = JSON.stringify(value);
1618
+ if (serialized && serialized.length > LARGE_LEDGER_OBJECT_THRESHOLD) {
1619
+ return `[${key} summarized: ${Object.keys(value).length} keys \u2014 use verbose=true or mesh_reconcile_ledger]`;
1620
+ }
1621
+ return value;
1622
+ }
1623
+ return value;
1624
+ }
1625
+ function elideLargeNestedValue(key, value) {
1626
+ if (value === null || value === void 0) return value;
1627
+ if (typeof value === "string") {
1628
+ return value.length > 1e3 ? value.slice(0, 1e3) + "\u2026" : value;
1629
+ }
1630
+ if (typeof value !== "object") return value;
1631
+ const serialized = JSON.stringify(value);
1632
+ const bytes = serialized ? serialized.length : 0;
1633
+ if (bytes <= LARGE_LEDGER_NESTED_BYTES_THRESHOLD) return value;
1634
+ return {
1635
+ _elided: true,
1636
+ _kind: key,
1637
+ _bytes: bytes,
1638
+ _hint: "full evidence via mesh_reconcile_ledger"
1639
+ };
1640
+ }
1602
1641
  function slimLedgerPayload(payload) {
1603
1642
  const slim = {};
1604
1643
  for (const [k, v] of Object.entries(payload)) {
@@ -1607,8 +1646,10 @@ function slimLedgerPayload(payload) {
1607
1646
  } else if (k === "evidence" || k === "workerResult" || k === "gitStatus" || k === "validationResults") {
1608
1647
  } else if (k === "finalSummary") {
1609
1648
  slim[k] = typeof v === "string" && v.length > 300 ? v.slice(0, 300) + "\u2026" : v;
1649
+ } else if (LARGE_LEDGER_FIELD_KEYS.has(k)) {
1650
+ slim[k] = summarizeLargeLedgerField(k, v);
1610
1651
  } else {
1611
- slim[k] = v;
1652
+ slim[k] = elideLargeNestedValue(k, v);
1612
1653
  }
1613
1654
  }
1614
1655
  return slim;
@@ -2279,7 +2320,7 @@ var MESH_TASK_HISTORY_TOOL = {
2279
2320
  properties: {
2280
2321
  tail: { type: "number", description: "Number of recent entries to return (default: 20; clamped to 40 in compact mode, 200 in verbose)." },
2281
2322
  kind: { type: "string", description: "Filter by entry kind: task_dispatched, task_completed, task_failed, task_stalled, session_launched, checkpoint_created, node_cloned, node_removed, direct_fast_forward." },
2282
- compact: { type: "boolean", description: "Slim payload for LLM callers. Default true. Truncates long payload strings (message/taskSummary \u2264200, finalSummary \u2264300) and drops large nested evidence blobs (accessible via mesh_reconcile_ledger). Set false (or verbose=true) for full untruncated payloads." },
2323
+ compact: { type: "boolean", description: "Slim payload for LLM callers. Default true. Truncates long payload strings (message/taskSummary \u2264200, finalSummary \u2264300) and elides any large nested evidence blob (>2KB serialized \u2014 e.g. validationSummary/result/patchEquivalence/submoduleReachability) to a {_elided,_kind,_bytes,_hint} placeholder; full evidence stays accessible via mesh_reconcile_ledger. Set false (or verbose=true) for full untruncated payloads." },
2283
2324
  verbose: { type: "boolean", description: "Force the full untruncated payload; overrides compact." }
2284
2325
  }
2285
2326
  }
@@ -2312,11 +2353,13 @@ var MESH_PRUNE_STALE_DIRECT_TOOL = {
2312
2353
  };
2313
2354
  var MESH_REFINE_NODE_TOOL = {
2314
2355
  name: "mesh_refine_node",
2315
- description: "The Refinery: Accept an async validation/merge/cleanup job for a completed worktree node. The immediate response includes async:true, status:'accepted', jobId, interactionId, target node, and startedAt; completion/failure evidence is delivered through pending mesh events and the mesh task ledger.",
2356
+ description: "The Refinery: validate \u2192 merge \u2192 push \u2192 clean up a completed worktree node onto the base branch. Defaults to dry-run (plan only): returns the validation plan with mergeWillRun:false/cleanupWillRun:false and performs NO merge/push/cleanup. Pass execute=true to actually converge the node. execute=true is async: the immediate response includes async:true, status:'accepted', jobId, interactionId, target node, and startedAt; completion/failure evidence is delivered through pending mesh events and the mesh task ledger. dry_run=true overrides execute. Matches the mesh_refine_batch / mesh_fast_forward_node dry_run/execute contract.",
2316
2357
  inputSchema: {
2317
2358
  type: "object",
2318
2359
  properties: {
2319
- node_id: { type: "string", description: "Node ID of the completed worktree node to refine and merge." }
2360
+ node_id: { type: "string", description: "Node ID of the completed worktree node to refine and merge." },
2361
+ execute: { type: "boolean", description: "When true, run validation/merge/push/cleanup for this node. Defaults false/dry-run." },
2362
+ dry_run: { type: "boolean", description: "Preview the validation plan without merging. Defaults true unless execute=true; dry_run=true overrides execute." }
2320
2363
  },
2321
2364
  required: ["node_id"]
2322
2365
  }
@@ -2599,6 +2642,7 @@ async function meshStatus(ctx, args = {}) {
2599
2642
  const key = `${daemonId}::${behind.scope ?? ""}::${behind.buildCommit ?? ""}::${behind.head ?? ""}`;
2600
2643
  if (seenStale.has(key)) continue;
2601
2644
  seenStale.add(key);
2645
+ const isDaemonAffecting = behind.isDaemonAffecting !== false;
2602
2646
  staleDaemonBuilds.push({
2603
2647
  daemonId,
2604
2648
  nodeId: entry.nodeId,
@@ -2606,9 +2650,13 @@ async function meshStatus(ctx, args = {}) {
2606
2650
  liveBuildCommit: behind.buildCommit,
2607
2651
  liveBuildCommitShort: behind.buildCommitShort,
2608
2652
  head: behind.head,
2653
+ isDaemonAffecting,
2654
+ ...Array.isArray(behind.affectedPackages) && behind.affectedPackages.length > 0 ? { affectedPackages: behind.affectedPackages } : {},
2609
2655
  warning: behind.warning
2610
2656
  });
2611
2657
  }
2658
+ const daemonAffectingStaleBuilds = staleDaemonBuilds.filter((b) => b.isDaemonAffecting !== false);
2659
+ const webOnlyStaleBuilds = staleDaemonBuilds.filter((b) => b.isDaemonAffecting === false);
2612
2660
  const nodesForResponse = compact ? results.map((entry) => {
2613
2661
  if (!entry || typeof entry !== "object") return entry;
2614
2662
  const next = { ...entry };
@@ -2639,9 +2687,12 @@ async function meshStatus(ctx, args = {}) {
2639
2687
  nodes: nodesForResponse,
2640
2688
  ...compact && Object.keys(daemonSessions).length > 0 ? { daemonSessions } : {},
2641
2689
  ...Object.keys(daemonBuilds).length > 0 ? { daemonBuilds } : {},
2642
- ...staleDaemonBuilds.length > 0 ? {
2643
- staleDaemonBuilds,
2644
- staleDaemonBuildWarning: "One or more live daemons were built from a commit behind the workspace HEAD. Merged refinery/mesh-tool fixes are NOT live on those daemons until they are rebuilt/redeployed and restarted \u2014 a local daemon-core dist rebuild does not update a cloud daemon. Do not assume a just-merged fix is active."
2690
+ ...staleDaemonBuilds.length > 0 ? { staleDaemonBuilds } : {},
2691
+ ...daemonAffectingStaleBuilds.length > 0 ? {
2692
+ staleDaemonBuildWarning: "One or more live daemons were built from a commit behind the workspace HEAD with daemon-runtime package changes. Merged refinery/mesh-tool fixes are NOT live on those daemons until they are rebuilt/redeployed and restarted \u2014 a local daemon-core dist rebuild does not update a cloud daemon. Do not assume a just-merged fix is active."
2693
+ } : {},
2694
+ ...webOnlyStaleBuilds.length > 0 ? {
2695
+ webOnlyStaleBuildNote: 'One or more live daemons are behind workspace HEAD, but only web packages changed in that range. The daemon does NOT need a rebuild/restart \u2014 redeploy the web app to reflect those changes. This is informational, not a "fix not live" condition.'
2645
2696
  } : {},
2646
2697
  activeWork: activeWorkEvidence.activeWork,
2647
2698
  staleDirectWorkSummary,
@@ -2710,7 +2761,8 @@ async function meshTaskHistory(ctx, args) {
2710
2761
  const compact = args.verbose === true ? false : args.compact ?? true;
2711
2762
  const pendingEvents = await drainCoordinatorPendingEvents(ctx);
2712
2763
  const requestedTail = typeof args.tail === "number" && args.tail > 0 ? Math.floor(args.tail) : 20;
2713
- const tail = compact ? Math.min(requestedTail, 40) : Math.min(requestedTail, 200);
2764
+ const compactCap = requestedTail > 50 ? 20 : 30;
2765
+ const tail = compact ? Math.min(requestedTail, compactCap) : Math.min(requestedTail, 200);
2714
2766
  const kind = typeof args.kind === "string" && args.kind.trim() ? [args.kind.trim()] : void 0;
2715
2767
  const rawEntries = (0, import_daemon_core.readLedgerEntries)(mesh.id, { tail, kind });
2716
2768
  const entries = compact ? rawEntries.map((e) => ({
@@ -3934,6 +3986,8 @@ async function meshRefineNode(ctx, args) {
3934
3986
  const result = await commandForNode(ctx, node, "refine_mesh_node", {
3935
3987
  meshId: ctx.mesh.id,
3936
3988
  nodeId: args.node_id,
3989
+ ...args.execute !== void 0 ? { execute: args.execute } : {},
3990
+ ...args.dry_run !== void 0 ? { dryRun: args.dry_run } : {},
3937
3991
  inlineMesh: ctx.mesh
3938
3992
  });
3939
3993
  if (result?.success && result.async !== true && result.removeResult?.removed !== false) {