adhdev 0.9.82-rc.436 → 0.9.82-rc.437

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.
@@ -1293,10 +1293,10 @@ function readInjected(value) {
1293
1293
  }
1294
1294
  function getDaemonBuildInfo() {
1295
1295
  if (cached) return cached;
1296
- const commit = readInjected(true ? "db891cf6efe138b52b7a1c4aa5b4f874b5309ed3" : void 0) ?? "unknown";
1297
- const commitShort = readInjected(true ? "db891cf6" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
1298
- const version2 = readInjected(true ? "0.9.82-rc.436" : void 0) ?? readInjected(typeof process !== "undefined" ? "0.9.82-rc.436" : void 0) ?? "unknown";
1299
- const builtAt = readInjected(true ? "2026-06-30T16:41:30.130Z" : void 0);
1296
+ const commit = readInjected(true ? "07c5209009300611151cd8363b63b4b066b6ecec" : void 0) ?? "unknown";
1297
+ const commitShort = readInjected(true ? "07c52090" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
1298
+ const version2 = readInjected(true ? "0.9.82-rc.437" : void 0) ?? readInjected(typeof process !== "undefined" ? "0.9.82-rc.437" : void 0) ?? "unknown";
1299
+ const builtAt = readInjected(true ? "2026-07-01T00:49:56.746Z" : void 0);
1300
1300
  cached = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
1301
1301
  return cached;
1302
1302
  }
@@ -137520,7 +137520,7 @@ var init_adhdev_daemon = __esm({
137520
137520
  init_version();
137521
137521
  init_src();
137522
137522
  init_runtime_defaults();
137523
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.436" });
137523
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.437" });
137524
137524
  LOCAL_DAEMON_HEALTH_TIMEOUT_MS = 8e3;
137525
137525
  AdhdevDaemon = class _AdhdevDaemon {
137526
137526
  localHttpServer = null;
package/dist/cli/index.js CHANGED
@@ -1293,10 +1293,10 @@ function readInjected(value) {
1293
1293
  }
1294
1294
  function getDaemonBuildInfo() {
1295
1295
  if (cached) return cached;
1296
- const commit = readInjected(true ? "db891cf6efe138b52b7a1c4aa5b4f874b5309ed3" : void 0) ?? "unknown";
1297
- const commitShort = readInjected(true ? "db891cf6" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
1298
- const version2 = readInjected(true ? "0.9.82-rc.436" : void 0) ?? readInjected(typeof process !== "undefined" ? "0.9.82-rc.436" : void 0) ?? "unknown";
1299
- const builtAt = readInjected(true ? "2026-06-30T16:41:30.130Z" : void 0);
1296
+ const commit = readInjected(true ? "07c5209009300611151cd8363b63b4b066b6ecec" : void 0) ?? "unknown";
1297
+ const commitShort = readInjected(true ? "07c52090" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
1298
+ const version2 = readInjected(true ? "0.9.82-rc.437" : void 0) ?? readInjected(typeof process !== "undefined" ? "0.9.82-rc.437" : void 0) ?? "unknown";
1299
+ const builtAt = readInjected(true ? "2026-07-01T00:49:56.746Z" : void 0);
1300
1300
  cached = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
1301
1301
  return cached;
1302
1302
  }
@@ -137490,7 +137490,7 @@ var init_adhdev_daemon = __esm({
137490
137490
  init_version();
137491
137491
  init_src();
137492
137492
  init_runtime_defaults();
137493
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.436" });
137493
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.437" });
137494
137494
  LOCAL_DAEMON_HEALTH_TIMEOUT_MS = 8e3;
137495
137495
  AdhdevDaemon = class _AdhdevDaemon {
137496
137496
  localHttpServer = null;
package/dist/index.js CHANGED
@@ -773,10 +773,10 @@ function readInjected(value) {
773
773
  }
774
774
  function getDaemonBuildInfo() {
775
775
  if (cached) return cached;
776
- const commit = readInjected(true ? "db891cf6efe138b52b7a1c4aa5b4f874b5309ed3" : void 0) ?? "unknown";
777
- const commitShort = readInjected(true ? "db891cf6" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
778
- const version2 = readInjected(true ? "0.9.82-rc.436" : void 0) ?? readInjected(typeof process !== "undefined" ? "0.9.82-rc.436" : void 0) ?? "unknown";
779
- const builtAt = readInjected(true ? "2026-06-30T16:41:30.130Z" : void 0);
776
+ const commit = readInjected(true ? "07c5209009300611151cd8363b63b4b066b6ecec" : void 0) ?? "unknown";
777
+ const commitShort = readInjected(true ? "07c52090" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
778
+ const version2 = readInjected(true ? "0.9.82-rc.437" : void 0) ?? readInjected(typeof process !== "undefined" ? "0.9.82-rc.437" : void 0) ?? "unknown";
779
+ const builtAt = readInjected(true ? "2026-07-01T00:49:56.746Z" : void 0);
780
780
  cached = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
781
781
  return cached;
782
782
  }
@@ -106312,7 +106312,7 @@ var init_adhdev_daemon = __esm({
106312
106312
  init_version();
106313
106313
  init_src();
106314
106314
  init_runtime_defaults();
106315
- pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.436" });
106315
+ pkgVersion = resolvePackageVersion({ injectedVersion: "0.9.82-rc.437" });
106316
106316
  LOCAL_DAEMON_HEALTH_TIMEOUT_MS = 8e3;
106317
106317
  AdhdevDaemon = class _AdhdevDaemon {
106318
106318
  localHttpServer = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adhdev",
3
- "version": "0.9.82-rc.436",
3
+ "version": "0.9.82-rc.437",
4
4
  "description": "ADHDev — Agent Dashboard Hub for Dev. The control hub for your AI coding agents (Claude Code, Codex, Hermes, …).",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -49,9 +49,9 @@
49
49
  "node": ">=18"
50
50
  },
51
51
  "dependencies": {
52
- "@adhdev/daemon-core": "0.9.82-rc.436",
52
+ "@adhdev/daemon-core": "0.9.82-rc.437",
53
53
  "@adhdev/ghostty-vt-node": "*",
54
- "@adhdev/mesh-shared": "0.9.82-rc.436",
54
+ "@adhdev/mesh-shared": "0.9.82-rc.437",
55
55
  "@modelcontextprotocol/sdk": "^1.0.0",
56
56
  "@xterm/addon-serialize": "^0.14.0",
57
57
  "@xterm/xterm": "^6.0.0",
@@ -1150,14 +1150,14 @@ var MESH_REVIEW_INBOX_TOOL = {
1150
1150
  };
1151
1151
  var MESH_MAGI_REVIEW_TOOL = {
1152
1152
  name: "mesh_magi_review",
1153
- description: 'Cross-verify a read-only investigation across a standing panel of independent mesh agents (different machines/providers), instead of sending a SINGLE read-only worker. Drop-in for any read-only investigation \u2014 bug RCA, defect/regression measurement, "why does this code do X?", or doc/design/API review. Fans the SAME question out to N independent (node \xD7 provider) replicas, then synthesizes consensus/disagreement/unique evidence into a needs_verification list \u2014 NOT a majority vote (high agreement among coupled agents \u2260 correct). Read-only is FORCED (no execute/write flag exists). COST: multiplies token spend by the total replica count (the call is the opt-in). Requires a configured panel (mesh_magi_panel_set) resolving to \u22652 (node, provider) targets; never silently degrades to N=1.',
1153
+ description: "Cross-verify a read-only investigation across a standing panel of independent mesh agents (different machines/providers), instead of sending a SINGLE read-only worker. Drop-in for any read-only investigation \u2014 bug RCA, defect/regression measurement, \"why does this code do X?\", or doc/design/API review. Fans the SAME question out to N independent (node \xD7 provider) replicas, then synthesizes consensus/disagreement/unique evidence into a needs_verification list \u2014 NOT a majority vote (high agreement among coupled agents \u2260 correct). Read-only is FORCED (no execute/write flag exists). COST: multiplies token spend by the total replica count (the call is the opt-in). NO pre-authored panel is required: omit `panel` and `members` and pass only `task_kind` (plus the question) to auto-synthesize a maximally-diverse cross-provider PRESET panel from the LIVE mesh \u2014 the resolver enumerates every routable (node \xD7 provider) pair (seeing a node's 2nd+ priority providers, matching the queue's per-provider claim check) and greedily picks the most independent set for that kind. Still resolves to \u22652 (node, provider) targets; never silently degrades to N=1 (errors magi_insufficient_providers if the live mesh cannot supply them).",
1154
1154
  inputSchema: {
1155
1155
  type: "object",
1156
1156
  properties: {
1157
1157
  question: { type: "string", description: 'The single investigation question every agent answers \u2014 e.g. "What is the root cause of this defect?", "Refute this RCA.", "Why does this code do X?". Not only "review this".' },
1158
1158
  target: { type: "string", description: "What to investigate \u2014 file path(s), a bug symptom / error / stack trace, a code area / symbol, or omitted when the question is self-contained." },
1159
1159
  artifacts: { type: "array", items: { type: "string" }, description: "Inline content when not file-backed: a doc/diff, a log/error dump, or a prior single-worker RCA to refute." },
1160
- panel: { type: "string", description: 'Named panel from meshes.json (mesh_magi_panel_set). Falls back to a panel named "default" if omitted; errors clearly if none exists. Ignored when inline members are provided.' },
1160
+ panel: { type: "string", description: 'Named panel from meshes.json (mesh_magi_panel_set). When omitted: if task_kind is given (and no inline members), a maximally-diverse cross-provider preset panel is auto-synthesized from the live mesh; otherwise falls back to a panel named "default" and errors clearly if none exists. Ignored when inline members are provided.' },
1161
1161
  members: {
1162
1162
  type: "array",
1163
1163
  description: "Inline ad-hoc panel override (NOT persisted): same member shape as a configured panel. When present, the named panel is ignored. Maximize distinct providers AND machines for real independence.",
@@ -1173,7 +1173,7 @@ var MESH_MAGI_REVIEW_TOOL = {
1173
1173
  }
1174
1174
  },
1175
1175
  n: { type: "number", description: "Global replica override per member (clamped by the total-replica guard cap, default 12)." },
1176
- task_kind: { type: "string", enum: ["claim_audit", "rca", "design", "freeform"], description: "Selects the SINGLE output schema injected into each replica prompt and the strict parser used at collection (no schema-on-schema conflict). claim_audit (DEFAULT, backward-compatible): {claims[],top_findings[],open_questions[]}. rca: {rootCause,failsAt,mechanism,evidence[],fixDirection,confidence}. design: {recommendation,rationale,alternatives[],tradeoffs[],risks[],evidence[],confidence}. freeform: no schema \u2014 natural-language answer, parsing/evidence checks waived, cross-verification is weak. Every kind except freeform requires non-empty evidence[]; an empty-evidence or schema-invalid answer triggers ONE delta re-request before being dropped as unparseable. Do NOT also embed an output-format schema in the question \u2014 it collides with this contract (a warning is surfaced if detected)." },
1176
+ task_kind: { type: "string", enum: ["claim_audit", "rca", "design", "freeform"], description: "Selects the SINGLE output schema injected into each replica prompt and the strict parser used at collection (no schema-on-schema conflict). claim_audit (DEFAULT, backward-compatible): {claims[],top_findings[],open_questions[]}. rca: {rootCause,failsAt,mechanism,evidence[],fixDirection,confidence}. design: {recommendation,rationale,alternatives[],tradeoffs[],risks[],evidence[],confidence}. freeform: no schema \u2014 natural-language answer, parsing/evidence checks waived, cross-verification is weak. When `panel` and `members` are both omitted, task_kind ALSO drives auto-synthesis of a maximally-diverse cross-provider preset panel from the live mesh (design fans out widest, claim_audit/rca a triad, freeform the minimum pair). Every kind except freeform requires non-empty evidence[]; an empty-evidence or schema-invalid answer triggers ONE delta re-request before being dropped as unparseable. Do NOT also embed an output-format schema in the question \u2014 it collides with this contract (a warning is surfaced if detected)." },
1177
1177
  mode: { type: "string", enum: ["rca", "investigation", "claim_audit", "design_review", "code_audit"], description: "Synthesis emphasis hint \u2014 affects labels only, never the agent count or schema. Distinct from task_kind (which selects the output schema)." },
1178
1178
  use_judge: { type: "boolean", description: "Default false (clustering synthesis). STUB: judge synthesis is not yet implemented \u2014 passing true currently falls back to clustering with a warning. Reserved interface only." },
1179
1179
  require_independent_evidence: { type: "boolean", description: "Default true \u2014 high-impact claims with no file:line/source evidence are routed to needs_verification." },
@@ -4089,6 +4089,12 @@ var MAGI_MAX_WAIT_MS = 6e5;
4089
4089
  var MAGI_POLL_INTERVAL_MS = 5e3;
4090
4090
  var VALID_TASK_KINDS = ["claim_audit", "rca", "design", "freeform"];
4091
4091
  var DEFAULT_TASK_KIND = "claim_audit";
4092
+ var MAGI_KIND_PRESETS = {
4093
+ claim_audit: { targetK: 3, minK: 2, providerPreference: ["claude-cli", "codex-cli", "gemini-cli", "hermes-cli"], avoidConcurrentProviders: ["antigravity-cli"] },
4094
+ rca: { targetK: 3, minK: 2, providerPreference: ["claude-cli", "codex-cli", "gemini-cli", "hermes-cli"], avoidConcurrentProviders: ["antigravity-cli"] },
4095
+ design: { targetK: 4, minK: 2, providerPreference: ["claude-cli", "codex-cli", "gemini-cli", "hermes-cli"], avoidConcurrentProviders: ["antigravity-cli"] },
4096
+ freeform: { targetK: 2, minK: 2, providerPreference: ["claude-cli", "codex-cli", "gemini-cli", "hermes-cli"], avoidConcurrentProviders: ["antigravity-cli"] }
4097
+ };
4092
4098
  function normalizeMagiTaskKind(raw) {
4093
4099
  const s = typeof raw === "string" ? raw.trim().toLowerCase() : "";
4094
4100
  return VALID_TASK_KINDS.includes(s) ? s : DEFAULT_TASK_KIND;
@@ -4811,6 +4817,77 @@ function buildInlineMagiPanel(members, opts = {}) {
4811
4817
  description: opts.description ?? "inline ad-hoc panel"
4812
4818
  });
4813
4819
  }
4820
+ function enumerateLivePresetCandidates(nodes) {
4821
+ const out = [];
4822
+ const seen = /* @__PURE__ */ new Set();
4823
+ for (const node of Array.isArray(nodes) ? nodes : []) {
4824
+ const nodeId = node?.id;
4825
+ if (typeof nodeId !== "string" || !nodeId.trim()) continue;
4826
+ for (const provider of readProviderPriority(node?.policy)) {
4827
+ const tags = (0, import_daemon_core4.buildMeshNodeCapabilityTags)(node, provider);
4828
+ if (!(0, import_daemon_core4.nodeSatisfiesRequiredTags)([`provider=${provider}`], tags)) continue;
4829
+ const key = `${nodeId}|${provider}`;
4830
+ if (seen.has(key)) continue;
4831
+ seen.add(key);
4832
+ out.push({ nodeId, provider });
4833
+ }
4834
+ }
4835
+ return out;
4836
+ }
4837
+ function selectDiversePresetPairs(candidates, preset) {
4838
+ const prefRank = /* @__PURE__ */ new Map();
4839
+ (preset.providerPreference ?? []).forEach((p, i) => prefRank.set(p, i));
4840
+ const prefOf = (provider) => prefRank.has(provider) ? prefRank.get(provider) : Number.MAX_SAFE_INTEGER;
4841
+ const fragile = new Set(preset.avoidConcurrentProviders ?? []);
4842
+ const scarcity = /* @__PURE__ */ new Map();
4843
+ for (const c of candidates) scarcity.set(c.provider, (scarcity.get(c.provider) ?? 0) + 1);
4844
+ const sorted = [...candidates].sort(
4845
+ (a, b) => prefOf(a.provider) - prefOf(b.provider) || (scarcity.get(a.provider) ?? 0) - (scarcity.get(b.provider) ?? 0) || (a.nodeId < b.nodeId ? -1 : a.nodeId > b.nodeId ? 1 : 0) || (a.provider < b.provider ? -1 : a.provider > b.provider ? 1 : 0)
4846
+ );
4847
+ const picked = [];
4848
+ const usedNodes = /* @__PURE__ */ new Set();
4849
+ const usedProviders = /* @__PURE__ */ new Set();
4850
+ const fragileNodes = /* @__PURE__ */ new Set();
4851
+ const tryPick = (c) => {
4852
+ if (picked.length >= preset.targetK) return;
4853
+ if (fragile.has(c.provider) && fragileNodes.has(c.nodeId)) return;
4854
+ picked.push(c);
4855
+ usedNodes.add(c.nodeId);
4856
+ usedProviders.add(c.provider);
4857
+ if (fragile.has(c.provider)) fragileNodes.add(c.nodeId);
4858
+ };
4859
+ const isPicked = (c) => picked.some((p) => p.nodeId === c.nodeId && p.provider === c.provider);
4860
+ for (const c of sorted) {
4861
+ if (picked.length >= preset.targetK) break;
4862
+ if (isPicked(c)) continue;
4863
+ if (!usedProviders.has(c.provider) && !usedNodes.has(c.nodeId)) tryPick(c);
4864
+ }
4865
+ for (const c of sorted) {
4866
+ if (picked.length >= preset.targetK) break;
4867
+ if (isPicked(c)) continue;
4868
+ if (!usedProviders.has(c.provider) || !usedNodes.has(c.nodeId)) tryPick(c);
4869
+ }
4870
+ for (const c of sorted) {
4871
+ if (picked.length >= preset.targetK) break;
4872
+ if (isPicked(c)) continue;
4873
+ tryPick(c);
4874
+ }
4875
+ return picked;
4876
+ }
4877
+ function buildPresetMagiPanelForKind(kind, nodes, opts = {}) {
4878
+ const preset = MAGI_KIND_PRESETS[kind] ?? MAGI_KIND_PRESETS[DEFAULT_TASK_KIND];
4879
+ const candidates = enumerateLivePresetCandidates(nodes);
4880
+ const pairs = selectDiversePresetPairs(candidates, preset);
4881
+ const members = pairs.map((p) => ({
4882
+ provider: p.provider,
4883
+ nodeId: p.nodeId,
4884
+ ...opts.n !== void 0 ? { n: Math.max(1, Math.floor(opts.n)) } : { n: 1 }
4885
+ }));
4886
+ if (members.length === 0) {
4887
+ return { members: [], description: `preset:${kind}` };
4888
+ }
4889
+ return buildInlineMagiPanel(members, { defaultN: opts.n, description: `preset:${kind}` });
4890
+ }
4814
4891
  async function meshMagiPanelList(ctx, args = {}) {
4815
4892
  await refreshMeshFromDaemon(ctx);
4816
4893
  const all = (0, import_daemon_core4.listMagiPanels)();
@@ -4862,9 +4939,13 @@ async function meshMagiReview(ctx, args) {
4862
4939
  const useJudge = (args.use_judge ?? args.useJudge) === true;
4863
4940
  const judgeWarning = useJudge ? "use_judge=true requested, but judge synthesis is not yet implemented \u2014 falling back to clustering synthesis." : null;
4864
4941
  await refreshMeshFromDaemon(ctx);
4942
+ const referenceCommit = resolveMagiReferenceCommit(ctx);
4865
4943
  const hasInlineMembers = Array.isArray(args.members) && args.members.length > 0;
4944
+ const explicitPanelName = readString(args.panel);
4945
+ const usePresetPath = !hasInlineMembers && !explicitPanelName && typeof explicitTaskKind === "string" && VALID_TASK_KINDS.includes(explicitTaskKind.trim().toLowerCase());
4866
4946
  let panel;
4867
4947
  let panelName;
4948
+ let presetKind;
4868
4949
  if (hasInlineMembers) {
4869
4950
  panelName = "(inline)";
4870
4951
  try {
@@ -4877,8 +4958,23 @@ async function meshMagiReview(ctx, args) {
4877
4958
  hint: "Inline members use the same shape as a configured panel: [{ provider (REQUIRED), nodeId?, capabilityTags?, n? }]."
4878
4959
  });
4879
4960
  }
4961
+ } else if (usePresetPath) {
4962
+ presetKind = normalizeMagiTaskKind(explicitTaskKind);
4963
+ panelName = `(preset:${presetKind})`;
4964
+ const preset = MAGI_KIND_PRESETS[presetKind];
4965
+ const maxReplicas = Math.max(1, Math.floor(Number(args.n) > 0 ? Number(args.n) : MAGI_MAX_REPLICAS));
4966
+ panel = buildPresetMagiPanelForKind(presetKind, ctx.mesh.nodes, { n: args.n, referenceCommit, maxReplicas });
4967
+ if (panel.members.length < preset.minK) {
4968
+ return JSON.stringify({
4969
+ success: false,
4970
+ code: "magi_insufficient_providers",
4971
+ error: `task_kind '${presetKind}' auto-synthesis found only ${panel.members.length} independent (node, provider) target(s) in the live mesh; MAGI requires \u2265${preset.minK} and never silently degrades to N=1.`,
4972
+ resolvedMembers: panel.members,
4973
+ hint: "Bring a second provider or a second node online (mesh_status to inspect), or pass explicit inline members to mesh_magi_review."
4974
+ }, null, 2);
4975
+ }
4880
4976
  } else {
4881
- panelName = readString(args.panel) || "default";
4977
+ panelName = explicitPanelName || "default";
4882
4978
  panel = (0, import_daemon_core4.getMagiPanel)(panelName);
4883
4979
  }
4884
4980
  if (!panel) {
@@ -4891,7 +4987,6 @@ async function meshMagiReview(ctx, args) {
4891
4987
  }
4892
4988
  const taskKind = normalizeMagiTaskKind(explicitTaskKind ?? panel.defaultKind);
4893
4989
  const includeStale = (args.include_stale ?? args.includeStale) === true;
4894
- const referenceCommit = resolveMagiReferenceCommit(ctx);
4895
4990
  const plan = buildMagiFanoutPlan(panel, ctx.mesh.nodes, { n: args.n, referenceCommit, includeStale });
4896
4991
  if (!plan.enoughTargets) {
4897
4992
  const droppedByStale = plan.staleMembers.length > 0;