@adhdev/daemon-standalone 0.9.82-rc.116 → 0.9.82-rc.118

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.js CHANGED
@@ -36903,6 +36903,10 @@ ${effect.notification.body || ""}`.trim();
36903
36903
  function normalizeApprovalLabel(value) {
36904
36904
  return String(value || "").toLowerCase().replace(/^[\s\[(<{]*\d+(?:\s*[.)\]}>:-]|\s)+/, "").replace(/[^\p{L}\p{N}]+/gu, " ").trim();
36905
36905
  }
36906
+ function isNegativeApprovalLabel(value) {
36907
+ const label = normalizeApprovalLabel(value);
36908
+ return /^(no|deny|reject|cancel|skip|exit|stop)\b/.test(label) || /\bwithout\b/.test(label) || /\bdo not\b/.test(label);
36909
+ }
36906
36910
  function getApprovalPositiveHints(provider) {
36907
36911
  const customHints = Array.isArray(provider?.approvalPositiveHints) ? provider.approvalPositiveHints.map((hint) => normalizeApprovalLabel(String(hint || ""))).filter(Boolean) : [];
36908
36912
  return customHints.length > 0 ? customHints : DEFAULT_APPROVAL_POSITIVE_HINTS;
@@ -36910,19 +36914,19 @@ ${effect.notification.body || ""}`.trim();
36910
36914
  function pickApprovalButton(buttons, provider) {
36911
36915
  const labels = (buttons || []).map((button) => String(button || "").trim()).filter(Boolean);
36912
36916
  if (labels.length === 0) {
36913
- return { index: 0, label: "Approve" };
36917
+ return { index: -1, label: "" };
36914
36918
  }
36915
36919
  const normalizedButtons = labels.map((label) => normalizeApprovalLabel(label));
36916
36920
  const hints = getApprovalPositiveHints(provider);
36917
36921
  for (const hint of hints) {
36918
- const exactIndex = normalizedButtons.findIndex((label) => label === hint);
36922
+ const exactIndex = normalizedButtons.findIndex((label, index) => label === hint && !isNegativeApprovalLabel(labels[index]));
36919
36923
  if (exactIndex >= 0) return { index: exactIndex, label: labels[exactIndex] };
36920
- const prefixIndex = normalizedButtons.findIndex((label) => label.startsWith(hint));
36924
+ const prefixIndex = normalizedButtons.findIndex((label, index) => label.startsWith(hint) && !isNegativeApprovalLabel(labels[index]));
36921
36925
  if (prefixIndex >= 0) return { index: prefixIndex, label: labels[prefixIndex] };
36922
- const includeIndex = normalizedButtons.findIndex((label) => label.includes(hint));
36926
+ const includeIndex = normalizedButtons.findIndex((label, index) => label.includes(hint) && !isNegativeApprovalLabel(labels[index]));
36923
36927
  if (includeIndex >= 0) return { index: includeIndex, label: labels[includeIndex] };
36924
36928
  }
36925
- return { index: 0, label: labels[0] };
36929
+ return { index: -1, label: "" };
36926
36930
  }
36927
36931
  function formatAutoApprovalMessage(modalMessage, buttonLabel) {
36928
36932
  const lines = [`Auto-approved${buttonLabel ? `: ${buttonLabel}` : ""}`];
@@ -38942,6 +38946,7 @@ ${effect.notification.body || ""}`.trim();
38942
38946
  }
38943
38947
  function buildNativeHistoryFallbackReason(args) {
38944
38948
  if (!supportsCliNativeTranscript(args.providerType, args.provider)) return "provider_native_transcript_not_supported";
38949
+ if (args.unavailableReason) return `native_history_unavailable:${args.unavailableReason}`;
38945
38950
  if (args.nativeSource === "native-unavailable") return "native_history_unavailable";
38946
38951
  if (args.nativeHistoryCoverage === "partial") return "native_history_partial";
38947
38952
  if (args.nativeHistoryCoverage === "unavailable") return "native_history_unavailable";
@@ -39016,6 +39021,15 @@ ${effect.notification.body || ""}`.trim();
39016
39021
  return hasOverlappingVisibleConversationText(args.nativeMessages, args.ptyMessages || []);
39017
39022
  }
39018
39023
  function readCliProviderNativeHistory(agentStr, args) {
39024
+ if (!args.historySessionId) {
39025
+ return {
39026
+ messages: [],
39027
+ hasMore: false,
39028
+ source: "native-unavailable",
39029
+ unavailableReason: "native_history_workspace_only_lookup_unsafe",
39030
+ lookup: "session"
39031
+ };
39032
+ }
39019
39033
  const sessionHistory = readProviderChatHistory(agentStr, {
39020
39034
  canonicalHistory: args.canonicalHistory,
39021
39035
  historySessionId: args.historySessionId,
@@ -39026,20 +39040,7 @@ ${effect.notification.body || ""}`.trim();
39026
39040
  historyBehavior: args.historyBehavior,
39027
39041
  scripts: args.scripts
39028
39042
  });
39029
- if (sessionHistory.source !== "native-unavailable" || args.exactSessionScoped || !args.historySessionId || !args.workspace) {
39030
- return { ...sessionHistory, lookup: args.historySessionId ? "session" : "workspace" };
39031
- }
39032
- const workspaceHistory = readProviderChatHistory(agentStr, {
39033
- canonicalHistory: args.canonicalHistory,
39034
- historySessionId: void 0,
39035
- workspace: args.workspace,
39036
- offset: args.offset,
39037
- limit: args.limit,
39038
- excludeRecentCount: args.excludeRecentCount,
39039
- historyBehavior: args.historyBehavior,
39040
- scripts: args.scripts
39041
- });
39042
- return { ...workspaceHistory, lookup: "workspace" };
39043
+ return { ...sessionHistory, lookup: "session" };
39043
39044
  }
39044
39045
  function isNativeHistoryFreshEnough(args) {
39045
39046
  const nativeNewest = getMessageNewestReceivedAt(args.nativeMessages);
@@ -39782,6 +39783,7 @@ ${effect.notification.body || ""}`.trim();
39782
39783
  provider,
39783
39784
  nativeSource: nativeHistory.source,
39784
39785
  nativeHistoryCoverage,
39786
+ unavailableReason,
39785
39787
  nativeMessageCount: nativeMessages.length,
39786
39788
  safeMapping,
39787
39789
  freshEnough
@@ -39881,6 +39883,7 @@ ${effect.notification.body || ""}`.trim();
39881
39883
  provider,
39882
39884
  nativeSource: history.source,
39883
39885
  nativeHistoryCoverage,
39886
+ unavailableReason,
39884
39887
  nativeMessageCount: historyMessages.length,
39885
39888
  safeMapping,
39886
39889
  freshEnough: true
@@ -49831,6 +49834,12 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
49831
49834
  status.launchBlockedMessage = readStringValue(bootstrap.error) || "Required worktree bootstrap failed; resolve it before launching an agent into this node.";
49832
49835
  return;
49833
49836
  }
49837
+ if (bootstrap.status === "running" && bootstrap.required !== false) {
49838
+ status.launchReady = false;
49839
+ status.launchBlockedReason = "worktree_bootstrap_running";
49840
+ status.launchBlockedMessage = "Required worktree bootstrap is still running; wait for it to finish before launching an agent into this node.";
49841
+ return;
49842
+ }
49834
49843
  }
49835
49844
  const connectionState = readStringValue(readObjectRecord(status.connection).state);
49836
49845
  status.launchReady = !!daemonId && (readStringValue(status.machineStatus) === "online" || connectionState === "connected" || isSelfNode);
@@ -49931,9 +49940,12 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
49931
49940
  isCached: false
49932
49941
  };
49933
49942
  }
49934
- function liveSessionRecordMatchesMeshNode(record2, meshId, nodeId) {
49943
+ function liveSessionRecordMatchesMeshNode(record2, meshId, nodeId, nodeWorkspace = "", nodeIsMissingLocalWorktree = false) {
49935
49944
  const recordNodeId = readStringValue(record2?.meta?.meshNodeId);
49936
49945
  if (!recordNodeId || recordNodeId !== nodeId) return false;
49946
+ if (nodeIsMissingLocalWorktree) return false;
49947
+ const recordWorkspace = readStringValue(record2?.workspace);
49948
+ if (nodeWorkspace && recordWorkspace && recordWorkspace !== nodeWorkspace) return false;
49937
49949
  const recordMeshId = readStringValue(record2?.meta?.meshNodeFor);
49938
49950
  return !recordMeshId || recordMeshId === meshId;
49939
49951
  }
@@ -49958,9 +49970,13 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
49958
49970
  return "";
49959
49971
  }
49960
49972
  function collectLiveMeshSessionRecords(args) {
49973
+ const nodeWorkspace = readStringValue(args.node?.workspace);
49974
+ const nodeIsMissingLocalWorktree = args.node?.isLocalWorktree === true && !!nodeWorkspace && !fs11.existsSync(nodeWorkspace);
49961
49975
  const matches = args.liveSessionRecords.filter((record2) => {
49962
- const nodeWorkspace = readStringValue(args.node?.workspace);
49963
- if (liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId)) return true;
49976
+ const recordNodeId = readStringValue(record2?.meta?.meshNodeId);
49977
+ if (recordNodeId && recordNodeId !== args.nodeId) return false;
49978
+ if (liveSessionRecordMatchesMeshNode(record2, args.meshId, args.nodeId, nodeWorkspace || "", nodeIsMissingLocalWorktree)) return true;
49979
+ if (nodeIsMissingLocalWorktree) return false;
49964
49980
  return !!nodeWorkspace && liveSessionRecordMatchesMeshWorkspace(record2, args.meshId, nodeWorkspace);
49965
49981
  });
49966
49982
  if (args.allowCoordinatorSession) {
@@ -49976,11 +49992,15 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
49976
49992
  function buildHistoricalMeshSessions(args) {
49977
49993
  const liveNodeIds = /* @__PURE__ */ new Set();
49978
49994
  const liveWorkspaces = /* @__PURE__ */ new Set();
49995
+ const missingLocalWorktreeNodeIds = /* @__PURE__ */ new Set();
49979
49996
  for (const node of args.nodes || []) {
49980
49997
  const nodeId = readStringValue(node?.id, node?.nodeId);
49981
49998
  const workspace = readStringValue(node?.workspace);
49982
49999
  if (nodeId) liveNodeIds.add(nodeId);
49983
50000
  if (workspace) liveWorkspaces.add(workspace);
50001
+ if (nodeId && node?.isLocalWorktree === true && workspace && !fs11.existsSync(workspace)) {
50002
+ missingLocalWorktreeNodeIds.add(nodeId);
50003
+ }
49984
50004
  }
49985
50005
  const sessions = [];
49986
50006
  for (const record2 of args.liveSessionRecords || []) {
@@ -49989,7 +50009,7 @@ ${(0, import_node_path.resolve)(workspace || os17.tmpdir())}`;
49989
50009
  if (recordMeshId !== args.meshId) continue;
49990
50010
  const recordNodeId = readStringValue(meta3.meshNodeId);
49991
50011
  const workspace = readStringValue(record2?.workspace);
49992
- const removedNode = !!recordNodeId && !liveNodeIds.has(recordNodeId);
50012
+ const removedNode = !!recordNodeId && (!liveNodeIds.has(recordNodeId) || missingLocalWorktreeNodeIds.has(recordNodeId));
49993
50013
  const orphanedWorkspace = !!workspace && !liveWorkspaces.has(workspace) && meta3.meshCoordinatorFor !== args.meshId;
49994
50014
  if (!removedNode && !orphanedWorkspace) continue;
49995
50015
  sessions.push({
@@ -53180,56 +53200,113 @@ ${e?.stderr || ""}`
53180
53200
  if (!node) return { success: false, error: "Failed to register worktree node" };
53181
53201
  this.invalidateAggregateMeshStatus(meshId);
53182
53202
  }
53183
- const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
53184
- if (initSubmodules) {
53185
- try {
53186
- const { runGit: runGit3 } = await Promise.resolve().then(() => (init_git_executor(), git_executor_exports));
53187
- await runGit3(
53188
- { workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true },
53189
- ["submodule", "update", "--init", "--recursive"],
53190
- { timeoutMs: 12e4 }
53191
- );
53192
- } catch (subErr) {
53193
- console.warn("[mesh] Submodule init failed for worktree:", subErr.message);
53203
+ const persistWorktreeSetupState = async (bootstrapState2) => {
53204
+ node.worktreeBootstrap = bootstrapState2;
53205
+ if (meshRecord.inline) {
53206
+ this.updateInlineMeshNode(meshId, mesh, node);
53207
+ return;
53194
53208
  }
53195
- }
53196
- const bootstrapState = await runMeshWorktreeBootstrap(mesh, result.worktreePath);
53197
- node.worktreeBootstrap = bootstrapState;
53198
- if (!meshRecord.inline) {
53199
53209
  try {
53200
53210
  const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
53201
- updateNode2(meshId, node.id, { worktreeBootstrap: bootstrapState });
53211
+ updateNode2(meshId, node.id, { worktreeBootstrap: bootstrapState2 });
53202
53212
  this.invalidateAggregateMeshStatus(meshId);
53203
53213
  } catch {
53204
53214
  }
53205
- }
53206
- try {
53207
- const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
53208
- appendLedgerEntry2(meshId, {
53209
- kind: "node_cloned",
53210
- nodeId: node.id,
53211
- payload: {
53212
- sourceNodeId,
53213
- branch: result.branch,
53214
- worktreePath: result.worktreePath,
53215
- submodulesInitialized: initSubmodules,
53216
- worktreeBootstrap: {
53217
- status: bootstrapState.status,
53218
- required: bootstrapState.required,
53219
- configSource: bootstrapState.configSource,
53220
- configSourceType: bootstrapState.configSourceType,
53221
- lastCommand: bootstrapState.lastCommand,
53222
- exitCode: bootstrapState.exitCode
53215
+ };
53216
+ const appendCloneLedger = async (initSubmodules2, bootstrapState2) => {
53217
+ try {
53218
+ const { appendLedgerEntry: appendLedgerEntry2 } = await Promise.resolve().then(() => (init_mesh_ledger(), mesh_ledger_exports));
53219
+ appendLedgerEntry2(meshId, {
53220
+ kind: "node_cloned",
53221
+ nodeId: node.id,
53222
+ payload: {
53223
+ sourceNodeId,
53224
+ branch: result.branch,
53225
+ worktreePath: result.worktreePath,
53226
+ submodulesInitialized: initSubmodules2,
53227
+ worktreeBootstrap: {
53228
+ status: bootstrapState2.status,
53229
+ required: bootstrapState2.required,
53230
+ configSource: bootstrapState2.configSource,
53231
+ configSourceType: bootstrapState2.configSourceType,
53232
+ lastCommand: bootstrapState2.lastCommand,
53233
+ exitCode: bootstrapState2.exitCode
53234
+ }
53223
53235
  }
53236
+ });
53237
+ } catch {
53238
+ }
53239
+ };
53240
+ const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
53241
+ const loadedBootstrap = loadMeshWorktreeBootstrapConfig(mesh, result.worktreePath);
53242
+ const runningBootstrapState = {
53243
+ status: "running",
53244
+ required: loadedBootstrap.config?.required !== false,
53245
+ configSource: loadedBootstrap.path || loadedBootstrap.source,
53246
+ configSourceType: loadedBootstrap.sourceType,
53247
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
53248
+ };
53249
+ await persistWorktreeSetupState(runningBootstrapState);
53250
+ const finishWorktreeSetup = async () => {
53251
+ let submodulesInitialized2 = false;
53252
+ if (initSubmodules) {
53253
+ try {
53254
+ const { runGit: runGit3 } = await Promise.resolve().then(() => (init_git_executor(), git_executor_exports));
53255
+ await runGit3(
53256
+ { workspace: result.worktreePath, repoRoot: result.worktreePath, isGitRepo: true },
53257
+ ["submodule", "update", "--init", "--recursive"],
53258
+ { timeoutMs: 12e4 }
53259
+ );
53260
+ submodulesInitialized2 = true;
53261
+ } catch (subErr) {
53262
+ console.warn("[mesh] Submodule init failed for worktree:", subErr.message);
53224
53263
  }
53264
+ }
53265
+ const bootstrapState2 = await runMeshWorktreeBootstrap(mesh, result.worktreePath);
53266
+ await persistWorktreeSetupState(bootstrapState2);
53267
+ await appendCloneLedger(submodulesInitialized2, bootstrapState2);
53268
+ return { submodulesInitialized: submodulesInitialized2, bootstrapState: bootstrapState2 };
53269
+ };
53270
+ const requestedSetupWaitMs = Number(args?.setupWaitMs ?? args?.bootstrapWaitMs ?? 8e3);
53271
+ const setupWaitMs = Number.isFinite(requestedSetupWaitMs) ? Math.min(Math.max(requestedSetupWaitMs, 0), 14e3) : 8e3;
53272
+ const setupPromise = finishWorktreeSetup();
53273
+ const setupResult = await Promise.race([
53274
+ setupPromise.then((value) => ({ completed: true, value })),
53275
+ new Promise((resolve17) => setTimeout(() => resolve17({ completed: false }), setupWaitMs))
53276
+ ]);
53277
+ if (!setupResult.completed) {
53278
+ setupPromise.catch((error48) => {
53279
+ const failedState = {
53280
+ ...runningBootstrapState,
53281
+ status: "failed",
53282
+ completedAt: (/* @__PURE__ */ new Date()).toISOString(),
53283
+ error: error48?.message || String(error48)
53284
+ };
53285
+ void persistWorktreeSetupState(failedState);
53286
+ void appendCloneLedger(false, failedState);
53225
53287
  });
53226
- } catch {
53288
+ return {
53289
+ success: true,
53290
+ async: true,
53291
+ status: "accepted",
53292
+ node,
53293
+ worktreePath: result.worktreePath,
53294
+ branch: result.branch,
53295
+ worktreeBootstrap: runningBootstrapState,
53296
+ worktreeSetup: {
53297
+ status: "running",
53298
+ setupWaitMs,
53299
+ message: "Worktree node is registered; submodule/bootstrap setup is continuing in the background."
53300
+ }
53301
+ };
53227
53302
  }
53303
+ const { submodulesInitialized, bootstrapState } = setupResult.value;
53228
53304
  return {
53229
53305
  success: true,
53230
53306
  node,
53231
53307
  worktreePath: result.worktreePath,
53232
53308
  branch: result.branch,
53309
+ submodulesInitialized,
53233
53310
  worktreeBootstrap: bootstrapState
53234
53311
  };
53235
53312
  } catch (e) {
@@ -53686,12 +53763,18 @@ ${block2}`);
53686
53763
  for (const [nodeIndex, node] of (mesh.nodes || []).entries()) {
53687
53764
  const nodeId = String(node.id || node.nodeId || "");
53688
53765
  const daemonId = readStringValue(node.daemonId);
53766
+ const nodeMachineId = readMeshNodeMachineId(node);
53767
+ const nodeHostname = readMeshNodeHostname(node);
53689
53768
  const providerPriority = readProviderPriorityFromPolicy(node.policy);
53769
+ const configuredCoordinatorNode = Boolean(
53770
+ nodeId && selectedCoordinatorNodeId && nodeId === selectedCoordinatorNodeId
53771
+ );
53772
+ const sparseConfiguredCoordinatorNode = configuredCoordinatorNode && !daemonId && !nodeMachineId && !nodeHostname;
53690
53773
  const isSelfNode = Boolean(
53691
53774
  nodeId && inlineCoordinatorNodeId && nodeId === inlineCoordinatorNodeId
53692
53775
  ) || Boolean(
53693
53776
  daemonId && (daemonId === localMachineId || daemonId === this.deps.statusInstanceId)
53694
- ) || Boolean(meshRecord?.inline && nodeIndex === 0);
53777
+ ) || Boolean(meshRecord?.inline && nodeIndex === 0) || sparseConfiguredCoordinatorNode;
53695
53778
  const machineIdentity = buildMeshNodeMachineIdentity(node, {
53696
53779
  localMachineId,
53697
53780
  localDaemonId: this.deps.statusInstanceId,
@@ -53708,7 +53791,7 @@ ${block2}`);
53708
53791
  worktreeBranch: node.worktreeBranch,
53709
53792
  role: normalizeMeshDaemonRole(node.role) || (meshHost.hostNodeId && nodeId === meshHost.hostNodeId ? "host" : void 0),
53710
53793
  daemonId,
53711
- machineId: readMeshNodeMachineId(node) || node.machineId,
53794
+ machineId: nodeMachineId || node.machineId,
53712
53795
  machine: machineIdentity,
53713
53796
  machineStatus: node.machineStatus,
53714
53797
  health: "unknown",