@adhdev/daemon-core 0.9.82-rc.115 → 0.9.82-rc.117

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/dist/index.mjs CHANGED
@@ -14577,6 +14577,10 @@ var DEFAULT_APPROVAL_POSITIVE_HINTS = [
14577
14577
  function normalizeApprovalLabel(value) {
14578
14578
  return String(value || "").toLowerCase().replace(/^[\s\[(<{]*\d+(?:\s*[.)\]}>:-]|\s)+/, "").replace(/[^\p{L}\p{N}]+/gu, " ").trim();
14579
14579
  }
14580
+ function isNegativeApprovalLabel(value) {
14581
+ const label = normalizeApprovalLabel(value);
14582
+ return /^(no|deny|reject|cancel|skip|exit|stop)\b/.test(label) || /\bwithout\b/.test(label) || /\bdo not\b/.test(label);
14583
+ }
14580
14584
  function getApprovalPositiveHints(provider) {
14581
14585
  const customHints = Array.isArray(provider?.approvalPositiveHints) ? provider.approvalPositiveHints.map((hint) => normalizeApprovalLabel(String(hint || ""))).filter(Boolean) : [];
14582
14586
  return customHints.length > 0 ? customHints : DEFAULT_APPROVAL_POSITIVE_HINTS;
@@ -14584,19 +14588,19 @@ function getApprovalPositiveHints(provider) {
14584
14588
  function pickApprovalButton(buttons, provider) {
14585
14589
  const labels = (buttons || []).map((button) => String(button || "").trim()).filter(Boolean);
14586
14590
  if (labels.length === 0) {
14587
- return { index: 0, label: "Approve" };
14591
+ return { index: -1, label: "" };
14588
14592
  }
14589
14593
  const normalizedButtons = labels.map((label) => normalizeApprovalLabel(label));
14590
14594
  const hints = getApprovalPositiveHints(provider);
14591
14595
  for (const hint of hints) {
14592
- const exactIndex = normalizedButtons.findIndex((label) => label === hint);
14596
+ const exactIndex = normalizedButtons.findIndex((label, index) => label === hint && !isNegativeApprovalLabel(labels[index]));
14593
14597
  if (exactIndex >= 0) return { index: exactIndex, label: labels[exactIndex] };
14594
- const prefixIndex = normalizedButtons.findIndex((label) => label.startsWith(hint));
14598
+ const prefixIndex = normalizedButtons.findIndex((label, index) => label.startsWith(hint) && !isNegativeApprovalLabel(labels[index]));
14595
14599
  if (prefixIndex >= 0) return { index: prefixIndex, label: labels[prefixIndex] };
14596
- const includeIndex = normalizedButtons.findIndex((label) => label.includes(hint));
14600
+ const includeIndex = normalizedButtons.findIndex((label, index) => label.includes(hint) && !isNegativeApprovalLabel(labels[index]));
14597
14601
  if (includeIndex >= 0) return { index: includeIndex, label: labels[includeIndex] };
14598
14602
  }
14599
- return { index: 0, label: labels[0] };
14603
+ return { index: -1, label: "" };
14600
14604
  }
14601
14605
  function formatAutoApprovalMessage(modalMessage, buttonLabel) {
14602
14606
  const lines = [`Auto-approved${buttonLabel ? `: ${buttonLabel}` : ""}`];
@@ -16687,16 +16691,39 @@ function hasOverlappingVisibleConversationText(nativeMessages, ptyMessages) {
16687
16691
  return false;
16688
16692
  }
16689
16693
  function hasSafeNativeHistoryMapping(args) {
16694
+ const isCoordinatorTranscript = args.nativeMessages.some((m) => {
16695
+ const text = typeof m?.content === "string" ? m.content : JSON.stringify(m?.content || "");
16696
+ return text.includes("mesh_send_task") || text.includes("mesh_status") || text.includes("mesh_read_chat") || text.includes("mesh_launch_session");
16697
+ });
16690
16698
  const explicitSessionId = String(args.historySessionId || args.providerSessionId || "").trim();
16691
16699
  if (explicitSessionId) {
16692
16700
  const messageSessionIds = args.nativeMessages.map((message) => typeof message?.historySessionId === "string" ? message.historySessionId.trim() : "").filter(Boolean);
16693
- if (messageSessionIds.length === 0) return true;
16694
- return messageSessionIds.some((id) => id === explicitSessionId);
16701
+ if (messageSessionIds.length > 0) {
16702
+ return messageSessionIds.some((id) => id === explicitSessionId);
16703
+ }
16704
+ if (isCoordinatorTranscript && args.ptyMessages && args.ptyMessages.length > 0) {
16705
+ const ptyHasCoordinator = args.ptyMessages.some((m) => {
16706
+ const text = typeof m?.content === "string" ? m.content : JSON.stringify(m?.content || "");
16707
+ return text.includes("mesh_send_task") || text.includes("mesh_status") || text.includes("mesh_read_chat");
16708
+ });
16709
+ if (!ptyHasCoordinator) {
16710
+ return false;
16711
+ }
16712
+ }
16695
16713
  }
16696
16714
  const workspace = String(args.workspace || "").trim();
16697
16715
  if (!workspace) return false;
16698
16716
  const workspaceMatches = args.nativeMessages.some((message) => String(message?.workspace || "").trim() === workspace);
16699
16717
  if (!workspaceMatches) return false;
16718
+ if (isCoordinatorTranscript && args.ptyMessages && args.ptyMessages.length > 0) {
16719
+ const ptyHasCoordinator = args.ptyMessages.some((m) => {
16720
+ const text = typeof m?.content === "string" ? m.content : JSON.stringify(m?.content || "");
16721
+ return text.includes("mesh_send_task") || text.includes("mesh_status") || text.includes("mesh_read_chat");
16722
+ });
16723
+ if (!ptyHasCoordinator) {
16724
+ return false;
16725
+ }
16726
+ }
16700
16727
  if (!args.requireWorkspaceContentOverlap) return true;
16701
16728
  return hasOverlappingVisibleConversationText(args.nativeMessages, args.ptyMessages || []);
16702
16729
  }
@@ -27581,6 +27608,12 @@ function finalizeMeshNodeStatus(args) {
27581
27608
  status.launchBlockedMessage = readStringValue(bootstrap.error) || "Required worktree bootstrap failed; resolve it before launching an agent into this node.";
27582
27609
  return;
27583
27610
  }
27611
+ if (bootstrap.status === "running" && bootstrap.required !== false) {
27612
+ status.launchReady = false;
27613
+ status.launchBlockedReason = "worktree_bootstrap_running";
27614
+ status.launchBlockedMessage = "Required worktree bootstrap is still running; wait for it to finish before launching an agent into this node.";
27615
+ return;
27616
+ }
27584
27617
  }
27585
27618
  const connectionState = readStringValue(readObjectRecord(status.connection).state);
27586
27619
  status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || connectionState === "connected" || isSelfNode);
@@ -30930,56 +30963,113 @@ var DaemonCommandRouter = class {
30930
30963
  if (!node) return { success: false, error: "Failed to register worktree node" };
30931
30964
  this.invalidateAggregateMeshStatus(meshId);
30932
30965
  }
30933
- const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
30934
- if (initSubmodules) {
30935
- try {
30936
- const { runGit: runGit3 } = await Promise.resolve().then(() => (init_git_executor(), git_executor_exports));
30937
- await runGit3(
30938
- { workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true },
30939
- ["submodule", "update", "--init", "--recursive"],
30940
- { timeoutMs: 12e4 }
30941
- );
30942
- } catch (subErr) {
30943
- console.warn("[mesh] Submodule init failed for worktree:", subErr.message);
30966
+ const persistWorktreeSetupState = async (bootstrapState2) => {
30967
+ node.worktreeBootstrap = bootstrapState2;
30968
+ if (meshRecord.inline) {
30969
+ this.updateInlineMeshNode(meshId, mesh, node);
30970
+ return;
30944
30971
  }
30945
- }
30946
- const bootstrapState = await runMeshWorktreeBootstrap(mesh, result.worktreePath);
30947
- node.worktreeBootstrap = bootstrapState;
30948
- if (!meshRecord.inline) {
30949
30972
  try {
30950
30973
  const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
30951
- updateNode2(meshId, node.id, { worktreeBootstrap: bootstrapState });
30974
+ updateNode2(meshId, node.id, { worktreeBootstrap: bootstrapState2 });
30952
30975
  this.invalidateAggregateMeshStatus(meshId);
30953
30976
  } catch {
30954
30977
  }
30955
- }
30956
- try {
30957
- const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
30958
- appendLedgerEntry2(meshId, {
30959
- kind: "node_cloned",
30960
- nodeId: node.id,
30961
- payload: {
30962
- sourceNodeId,
30963
- branch: result.branch,
30964
- worktreePath: result.worktreePath,
30965
- submodulesInitialized: initSubmodules,
30966
- worktreeBootstrap: {
30967
- status: bootstrapState.status,
30968
- required: bootstrapState.required,
30969
- configSource: bootstrapState.configSource,
30970
- configSourceType: bootstrapState.configSourceType,
30971
- lastCommand: bootstrapState.lastCommand,
30972
- exitCode: bootstrapState.exitCode
30978
+ };
30979
+ const appendCloneLedger = async (initSubmodules2, bootstrapState2) => {
30980
+ try {
30981
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
30982
+ appendLedgerEntry2(meshId, {
30983
+ kind: "node_cloned",
30984
+ nodeId: node.id,
30985
+ payload: {
30986
+ sourceNodeId,
30987
+ branch: result.branch,
30988
+ worktreePath: result.worktreePath,
30989
+ submodulesInitialized: initSubmodules2,
30990
+ worktreeBootstrap: {
30991
+ status: bootstrapState2.status,
30992
+ required: bootstrapState2.required,
30993
+ configSource: bootstrapState2.configSource,
30994
+ configSourceType: bootstrapState2.configSourceType,
30995
+ lastCommand: bootstrapState2.lastCommand,
30996
+ exitCode: bootstrapState2.exitCode
30997
+ }
30973
30998
  }
30999
+ });
31000
+ } catch {
31001
+ }
31002
+ };
31003
+ const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
31004
+ const loadedBootstrap = loadMeshWorktreeBootstrapConfig(mesh, result.worktreePath);
31005
+ const runningBootstrapState = {
31006
+ status: "running",
31007
+ required: loadedBootstrap.config?.required !== false,
31008
+ configSource: loadedBootstrap.path || loadedBootstrap.source,
31009
+ configSourceType: loadedBootstrap.sourceType,
31010
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
31011
+ };
31012
+ await persistWorktreeSetupState(runningBootstrapState);
31013
+ const finishWorktreeSetup = async () => {
31014
+ let submodulesInitialized2 = false;
31015
+ if (initSubmodules) {
31016
+ try {
31017
+ const { runGit: runGit3 } = await Promise.resolve().then(() => (init_git_executor(), git_executor_exports));
31018
+ await runGit3(
31019
+ { workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true },
31020
+ ["submodule", "update", "--init", "--recursive"],
31021
+ { timeoutMs: 12e4 }
31022
+ );
31023
+ submodulesInitialized2 = true;
31024
+ } catch (subErr) {
31025
+ console.warn("[mesh] Submodule init failed for worktree:", subErr.message);
30974
31026
  }
31027
+ }
31028
+ const bootstrapState2 = await runMeshWorktreeBootstrap(mesh, result.worktreePath);
31029
+ await persistWorktreeSetupState(bootstrapState2);
31030
+ await appendCloneLedger(submodulesInitialized2, bootstrapState2);
31031
+ return { submodulesInitialized: submodulesInitialized2, bootstrapState: bootstrapState2 };
31032
+ };
31033
+ const requestedSetupWaitMs = Number(args?.setupWaitMs ?? args?.bootstrapWaitMs ?? 8e3);
31034
+ const setupWaitMs = Number.isFinite(requestedSetupWaitMs) ? Math.min(Math.max(requestedSetupWaitMs, 0), 14e3) : 8e3;
31035
+ const setupPromise = finishWorktreeSetup();
31036
+ const setupResult = await Promise.race([
31037
+ setupPromise.then((value) => ({ completed: true, value })),
31038
+ new Promise((resolve17) => setTimeout(() => resolve17({ completed: false }), setupWaitMs))
31039
+ ]);
31040
+ if (!setupResult.completed) {
31041
+ setupPromise.catch((error) => {
31042
+ const failedState = {
31043
+ ...runningBootstrapState,
31044
+ status: "failed",
31045
+ completedAt: (/* @__PURE__ */ new Date()).toISOString(),
31046
+ error: error?.message || String(error)
31047
+ };
31048
+ void persistWorktreeSetupState(failedState);
31049
+ void appendCloneLedger(false, failedState);
30975
31050
  });
30976
- } catch {
31051
+ return {
31052
+ success: true,
31053
+ async: true,
31054
+ status: "accepted",
31055
+ node,
31056
+ worktreePath: result.worktreePath,
31057
+ branch: result.branch,
31058
+ worktreeBootstrap: runningBootstrapState,
31059
+ worktreeSetup: {
31060
+ status: "running",
31061
+ setupWaitMs,
31062
+ message: "Worktree node is registered; submodule/bootstrap setup is continuing in the background."
31063
+ }
31064
+ };
30977
31065
  }
31066
+ const { submodulesInitialized, bootstrapState } = setupResult.value;
30978
31067
  return {
30979
31068
  success: true,
30980
31069
  node,
30981
31070
  worktreePath: result.worktreePath,
30982
31071
  branch: result.branch,
31072
+ submodulesInitialized,
30983
31073
  worktreeBootstrap: bootstrapState
30984
31074
  };
30985
31075
  } catch (e) {