@adhdev/daemon-standalone 0.9.82-rc.223 → 0.9.82-rc.224

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
@@ -54748,7 +54748,9 @@ ${effect.notification.body || ""}`.trim();
54748
54748
  const historyLimit = normalizeReadChatTailLimit(args);
54749
54749
  try {
54750
54750
  const agentStr = provider?.type || args?.agentType || getCurrentProviderType(h);
54751
- const workspace = typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : void 0;
54751
+ const targetSid = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
54752
+ const registrySessionWorkspace = targetSid ? h.ctx?.sessionRegistry?.get?.(targetSid)?.workspace : void 0;
54753
+ const workspace = typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : typeof registrySessionWorkspace === "string" ? registrySessionWorkspace : void 0;
54752
54754
  const intendedWorkspace = typeof args?.workspace === "string" ? args.workspace : void 0;
54753
54755
  const supportsNative = supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.nativeHistory);
54754
54756
  const history = supportsNative ? readCliProviderNativeHistory(agentStr, {
@@ -69215,7 +69217,12 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
69215
69217
  }
69216
69218
  }
69217
69219
  function summarizeInlineMeshBranchConvergence(nodes) {
69218
- const followUps = nodes.filter((node) => readObjectRecord(node.branchConvergence).needsConvergence === true).map((node) => {
69220
+ const followUps = nodes.filter((node) => {
69221
+ if (readObjectRecord(node.branchConvergence).needsConvergence !== true) return false;
69222
+ const workspace = typeof node.workspace === "string" ? node.workspace : "";
69223
+ if (workspace && !fs23.existsSync(workspace)) return false;
69224
+ return true;
69225
+ }).map((node) => {
69219
69226
  const convergence = readObjectRecord(node.branchConvergence);
69220
69227
  return {
69221
69228
  nodeId: node.nodeId,
@@ -70726,7 +70733,66 @@ ${e?.stderr || ""}`
70726
70733
  } catch (e) {
70727
70734
  const message = String(e?.message || e || "worktree cleanup failed");
70728
70735
  const dirty = message.includes("dirty worktree") || message.includes("local changes");
70729
- const submoduleForceBlocked = /working trees containing submodules cannot be moved or removed/i.test(message) && !forceFallbackConvergence.allow;
70736
+ const isSubmoduleGuard = /working trees containing submodules cannot be moved or removed/i.test(message);
70737
+ const submoduleForceBlocked = isSubmoduleGuard && !forceFallbackConvergence.allow;
70738
+ if (isSubmoduleGuard && forceFallbackConvergence.allow) {
70739
+ const { execFile: execFile4 } = await import("child_process");
70740
+ const { promisify: promisify7 } = await import("util");
70741
+ const execFileAsync3 = promisify7(execFile4);
70742
+ const GIT_TIMEOUT_CLEANUP = 3e4;
70743
+ const GIT_MAX_BUFFER_CLEANUP = 4 * 1024 * 1024;
70744
+ try {
70745
+ await execFileAsync3("git", ["-C", workspace, "submodule", "deinit", "--all", "-f"], {
70746
+ encoding: "utf8",
70747
+ timeout: GIT_TIMEOUT_CLEANUP,
70748
+ maxBuffer: GIT_MAX_BUFFER_CLEANUP,
70749
+ windowsHide: true
70750
+ });
70751
+ await execFileAsync3("git", ["worktree", "remove", "--force", workspace], {
70752
+ cwd: repoRoot,
70753
+ encoding: "utf8",
70754
+ timeout: GIT_TIMEOUT_CLEANUP,
70755
+ maxBuffer: GIT_MAX_BUFFER_CLEANUP,
70756
+ windowsHide: true
70757
+ });
70758
+ return {
70759
+ success: true,
70760
+ removedPath: workspace,
70761
+ repoRoot,
70762
+ fallback: "git_worktree_remove_submodule_deinit",
70763
+ forced: true,
70764
+ reason: "working_trees_containing_submodules",
70765
+ convergence: forceFallbackConvergence
70766
+ };
70767
+ } catch (deinitError) {
70768
+ try {
70769
+ fs23.rmSync(workspace, { recursive: true, force: true });
70770
+ await execFileAsync3("git", ["worktree", "prune"], {
70771
+ cwd: repoRoot,
70772
+ encoding: "utf8",
70773
+ timeout: GIT_TIMEOUT_CLEANUP,
70774
+ maxBuffer: GIT_MAX_BUFFER_CLEANUP,
70775
+ windowsHide: true
70776
+ });
70777
+ return {
70778
+ success: true,
70779
+ removedPath: workspace,
70780
+ repoRoot,
70781
+ fallback: "fs_rm_worktree_prune",
70782
+ forced: true,
70783
+ reason: "working_trees_containing_submodules",
70784
+ convergence: forceFallbackConvergence
70785
+ };
70786
+ } catch (rmError) {
70787
+ return {
70788
+ success: false,
70789
+ code: "mesh_worktree_cleanup_failed",
70790
+ error: `All removal fallbacks exhausted. deinit+remove: ${deinitError?.message || deinitError}; rmSync+prune: ${rmError?.message || rmError}`,
70791
+ recoveryHint: "Manually remove the worktree directory and run git worktree prune from the source repo."
70792
+ };
70793
+ }
70794
+ }
70795
+ }
70730
70796
  return {
70731
70797
  success: false,
70732
70798
  code: dirty ? "mesh_worktree_cleanup_dirty" : submoduleForceBlocked ? "mesh_worktree_cleanup_force_fallback_blocked" : "mesh_worktree_cleanup_failed",
@@ -70738,9 +70804,13 @@ ${e?.stderr || ""}`
70738
70804
  }
70739
70805
  async getWorktreeForceCleanupConvergence(args) {
70740
70806
  const metadataStatus = typeof args.node?.branchConvergence?.status === "string" ? args.node.branchConvergence.status : "";
70741
- if (metadataStatus === "merged_to_main" || metadataStatus === "cleanup_candidate") {
70807
+ if (metadataStatus === "merged_to_main" || metadataStatus === "cleanup_candidate" || metadataStatus === "merged_pushed") {
70742
70808
  return { allow: true, status: metadataStatus, source: "node_branch_convergence" };
70743
70809
  }
70810
+ const refinedConvergence = typeof args.node?.refineState?.finalBranchConvergenceState?.status === "string" ? args.node.refineState.finalBranchConvergenceState.status : typeof args.node?.lastRefineResult?.finalBranchConvergenceState?.status === "string" ? args.node.lastRefineResult.finalBranchConvergenceState.status : "";
70811
+ if (refinedConvergence === "merged_pushed" || refinedConvergence === "merged_to_main") {
70812
+ return { allow: true, status: refinedConvergence, source: "node_refine_state" };
70813
+ }
70744
70814
  const { execFile: execFile4 } = await import("child_process");
70745
70815
  const { promisify: promisify7 } = await import("util");
70746
70816
  const execFileAsync3 = promisify7(execFile4);
@@ -71226,11 +71296,24 @@ ${e?.stderr || ""}`
71226
71296
  if (!branch) return { success: false, error: "Could not determine branch of the worktree node", refineStages };
71227
71297
  const { stdout: baseBranchStdout } = await execFileAsync3("git", ["branch", "--show-current"], { cwd: repoRoot, encoding: "utf8" });
71228
71298
  const baseBranch = baseBranchStdout.trim();
71229
- const { stdout: baseHeadStdout } = await execFileAsync3("git", ["rev-parse", "HEAD"], { cwd: repoRoot, encoding: "utf8" });
71299
+ let fetchWarning;
71300
+ try {
71301
+ await execFileAsync3("git", ["fetch", "origin", baseBranch], { cwd: repoRoot, encoding: "utf8" });
71302
+ } catch (e) {
71303
+ fetchWarning = `git fetch origin ${baseBranch} failed (proceeding with local HEAD): ${e?.message}`;
71304
+ }
71305
+ let baseHeadRaw;
71306
+ try {
71307
+ const { stdout } = await execFileAsync3("git", ["rev-parse", `origin/${baseBranch}`], { cwd: repoRoot, encoding: "utf8" });
71308
+ baseHeadRaw = stdout.trim();
71309
+ } catch {
71310
+ const { stdout: localHead } = await execFileAsync3("git", ["rev-parse", "HEAD"], { cwd: repoRoot, encoding: "utf8" });
71311
+ baseHeadRaw = localHead.trim();
71312
+ }
71230
71313
  const { stdout: branchHeadStdout } = await execFileAsync3("git", ["rev-parse", branch], { cwd: node.workspace, encoding: "utf8" });
71231
- const baseHead = baseHeadStdout.trim();
71314
+ const baseHead = baseHeadRaw;
71232
71315
  let branchHead = branchHeadStdout.trim();
71233
- recordMeshRefineStage(refineStages, "resolve_refs", "passed", resolveStarted, { branch, baseBranch, baseHead, branchHead });
71316
+ recordMeshRefineStage(refineStages, "resolve_refs", "passed", resolveStarted, { branch, baseBranch, baseHead, branchHead, ...fetchWarning ? { fetchWarning } : {} });
71234
71317
  const validationStarted = Date.now();
71235
71318
  const validationSummary = await runMeshRefineValidationGate(mesh, node.workspace, {
71236
71319
  // M2-2: consume the node's persisted bootstrap state; persist re-runs.
@@ -71249,11 +71332,25 @@ ${e?.stderr || ""}`
71249
71332
  { validationStatus: validationSummary.status, commandsRun: validationSummary.commandsRun.length }
71250
71333
  );
71251
71334
  if (validationSummary.status === "failed") {
71335
+ const firstFailedCmd = Array.isArray(validationSummary.commandsRun) ? validationSummary.commandsRun.find((c) => c.success === false) : void 0;
71336
+ const buildValidationFailedError = () => {
71337
+ const base = validationSummary.failureCode === "missing_dependencies" ? "Refinery validation dependencies are missing; merge/refine was not attempted. Configure validation.bootstrapCommands if Refinery should bootstrap dependencies before validation." : validationSummary.failureCode === "dependency_bootstrap_failed" ? "Refinery dependency/bootstrap command failed; merge/refine was not attempted." : "Refinery validation gate failed; merge/refine was not attempted.";
71338
+ if (!firstFailedCmd) return base;
71339
+ const cmdName = typeof firstFailedCmd.displayCommand === "string" ? firstFailedCmd.displayCommand : typeof firstFailedCmd.command === "string" ? [firstFailedCmd.command, ...Array.isArray(firstFailedCmd.args) ? firstFailedCmd.args : []].join(" ").trim() : typeof firstFailedCmd.cmd === "string" ? firstFailedCmd.cmd : "";
71340
+ const rawOutput = [firstFailedCmd.stdout, firstFailedCmd.stderr, firstFailedCmd.output].filter((s) => typeof s === "string" && s.length > 0).join("\n");
71341
+ const tail = rawOutput.length > 800 ? rawOutput.slice(-800) : rawOutput;
71342
+ return [
71343
+ base,
71344
+ cmdName ? `First failing command: ${cmdName}` : "",
71345
+ tail ? `Output (tail):
71346
+ ${tail}` : ""
71347
+ ].filter(Boolean).join("\n");
71348
+ };
71252
71349
  return {
71253
71350
  success: false,
71254
71351
  code: validationSummary.failureCode || "validation_failed",
71255
71352
  convergenceStatus: "blocked_review",
71256
- error: validationSummary.failureCode === "missing_dependencies" ? "Refinery validation dependencies are missing; merge/refine was not attempted. Configure validation.bootstrapCommands if Refinery should bootstrap dependencies before validation." : validationSummary.failureCode === "dependency_bootstrap_failed" ? "Refinery dependency/bootstrap command failed; merge/refine was not attempted." : "Refinery validation gate failed; merge/refine was not attempted.",
71353
+ error: buildValidationFailedError(),
71257
71354
  branch,
71258
71355
  into: baseBranch,
71259
71356
  validationSummary,
@@ -71855,13 +71952,54 @@ ${e?.stderr || ""}`
71855
71952
  this.deps.instanceManager.sendEvent(sessionId, "interactive_prompt_response", response);
71856
71953
  return { success: true };
71857
71954
  }
71858
- case "launch_cli":
71955
+ case "launch_cli": {
71956
+ const launchResult = await this.deps.cliManager.handleCliCommand(cmd, args);
71957
+ const meshNodeId = readStringValue(args?.settings?.meshNodeId);
71958
+ const meshId = readStringValue(args?.settings?.meshNodeFor);
71959
+ if (meshNodeId && meshId && launchResult?.success !== false) {
71960
+ try {
71961
+ const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
71962
+ const meshObj = getMesh2(meshId) ?? this.getCachedInlineMesh(meshId);
71963
+ const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => n.id === meshNodeId || n.nodeId === meshNodeId) : void 0;
71964
+ const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
71965
+ if (bootstrapStatus === "running") {
71966
+ return { success: true, ...launchResult, bootstrapPending: true };
71967
+ }
71968
+ } catch {
71969
+ }
71970
+ }
71971
+ return launchResult;
71972
+ }
71859
71973
  case "stop_cli":
71860
71974
  case "set_cli_view_mode":
71861
- case "record_provider_pty":
71862
- case "agent_command": {
71975
+ case "record_provider_pty": {
71863
71976
  return this.deps.cliManager.handleCliCommand(cmd, args);
71864
71977
  }
71978
+ case "agent_command": {
71979
+ const agentResult = await this.deps.cliManager.handleCliCommand(cmd, args);
71980
+ const meshCtx = args?.meshContext;
71981
+ const dispatchNodeId = readStringValue(meshCtx?.nodeId);
71982
+ const dispatchMeshId = readStringValue(meshCtx?.meshId);
71983
+ if (dispatchNodeId && dispatchMeshId && agentResult?.success !== false) {
71984
+ try {
71985
+ const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
71986
+ const meshObj = getMesh2(dispatchMeshId) ?? this.getCachedInlineMesh(dispatchMeshId);
71987
+ const nodeObj = Array.isArray(meshObj?.nodes) ? meshObj.nodes.find((n) => n.id === dispatchNodeId || n.nodeId === dispatchNodeId) : void 0;
71988
+ const bootstrapStatus = readStringValue(nodeObj?.worktreeBootstrap?.status);
71989
+ if (bootstrapStatus === "running") {
71990
+ return {
71991
+ success: true,
71992
+ ...agentResult,
71993
+ dispatchAcknowledgementRisk: true,
71994
+ dispatchAcknowledgementRiskReason: "bootstrap_still_running",
71995
+ nextAction: "Wait for worktree_bootstrap_complete event before dispatching work to this node."
71996
+ };
71997
+ }
71998
+ } catch {
71999
+ }
72000
+ }
72001
+ return agentResult;
72002
+ }
71865
72003
  // ─── Logs ───
71866
72004
  case "get_logs": {
71867
72005
  const count = parseInt(args?.count) || parseInt(args?.lines) || 100;
@@ -73246,9 +73384,11 @@ ${e?.stderr || ""}`
73246
73384
  if (meshRecord?.inline) {
73247
73385
  removed = this.removeInlineMeshNode(meshId, mesh, nodeId);
73248
73386
  if (removed) this.invalidateAggregateMeshStatus(meshId);
73387
+ if (!removed && !node) removed = true;
73249
73388
  } else {
73250
73389
  const { removeNode: removeNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
73251
73390
  removed = removeNode2(meshId, nodeId);
73391
+ if (!removed && !node) removed = true;
73252
73392
  if (removed) this.invalidateAggregateMeshStatus(meshId);
73253
73393
  }
73254
73394
  if (removed) {
@@ -73432,8 +73572,37 @@ ${e?.stderr || ""}`
73432
73572
  setupPromise.then((value) => ({ completed: true, value })),
73433
73573
  new Promise((resolve23) => setTimeout(() => resolve23({ completed: false }), setupWaitMs))
73434
73574
  ]);
73575
+ const emitBootstrapEvent = (eventStatus2, bootstrapState2, startedAtMs, extraPayload) => {
73576
+ try {
73577
+ const durationMs = Date.now() - startedAtMs;
73578
+ const eventPayload = {
73579
+ event: `worktree_${eventStatus2}`,
73580
+ meshId,
73581
+ nodeLabel: node.id,
73582
+ nodeId: node.id,
73583
+ workspace: result.worktreePath,
73584
+ metadataEvent: {
73585
+ source: "clone_mesh_node_bootstrap",
73586
+ nodeId: node.id,
73587
+ status: eventStatus2,
73588
+ worktreePath: result.worktreePath,
73589
+ durationMs,
73590
+ bootstrapStatus: bootstrapState2.status,
73591
+ ...bootstrapState2.error ? { error: bootstrapState2.error } : {},
73592
+ ...bootstrapState2.exitCode !== void 0 ? { exitCode: bootstrapState2.exitCode } : {},
73593
+ ...extraPayload || {}
73594
+ },
73595
+ queuedAt: Date.now()
73596
+ };
73597
+ queuePendingMeshCoordinatorEvent(eventPayload);
73598
+ } catch {
73599
+ }
73600
+ };
73601
+ const bootstrapStartedMs = Date.now();
73435
73602
  if (!setupResult.completed) {
73436
- setupPromise.catch((error48) => {
73603
+ setupPromise.then(({ bootstrapState: bootstrapState2 }) => {
73604
+ emitBootstrapEvent("bootstrap_complete", bootstrapState2, bootstrapStartedMs);
73605
+ }).catch((error48) => {
73437
73606
  const failedState = {
73438
73607
  ...runningBootstrapState,
73439
73608
  status: "failed",
@@ -73442,6 +73611,7 @@ ${e?.stderr || ""}`
73442
73611
  };
73443
73612
  void persistWorktreeSetupState(failedState);
73444
73613
  void appendCloneLedger(false, failedState);
73614
+ emitBootstrapEvent("bootstrap_failed", failedState, bootstrapStartedMs, { error: error48?.message || String(error48) });
73445
73615
  });
73446
73616
  return {
73447
73617
  success: true,
@@ -73459,6 +73629,7 @@ ${e?.stderr || ""}`
73459
73629
  };
73460
73630
  }
73461
73631
  const { submodulesInitialized, bootstrapState } = setupResult.value;
73632
+ emitBootstrapEvent("bootstrap_complete", bootstrapState, bootstrapStartedMs);
73462
73633
  return {
73463
73634
  success: true,
73464
73635
  node,
@@ -73526,7 +73697,34 @@ ${e?.stderr || ""}`
73526
73697
  const ownerFailure = await this.requireMeshHostMutationOwner(meshId, args?.inlineMesh, "queue trigger");
73527
73698
  if (ownerFailure) return ownerFailure;
73528
73699
  try {
73529
- const { triggerMeshQueue: triggerMeshQueue2 } = await Promise.resolve().then(() => (init_mesh_events(), mesh_events_exports));
73700
+ const { triggerMeshQueue: triggerMeshQueue2, tryAssignQueueTask: tryAssignQueueTask2 } = await Promise.resolve().then(() => (init_mesh_events(), mesh_events_exports));
73701
+ const preferredNodeId = typeof args?.preferredNodeId === "string" ? args.preferredNodeId.trim() : "";
73702
+ if (preferredNodeId) {
73703
+ const cliInstances = this.deps.instanceManager.getByCategory("cli");
73704
+ const sorted = [...cliInstances].sort((a, b) => {
73705
+ const aSettings = a.getState().settings || {};
73706
+ const bSettings = b.getState().settings || {};
73707
+ const aNode = readStringValue(aSettings.meshNodeId, aSettings.nodeId);
73708
+ const bNode = readStringValue(bSettings.meshNodeId, bSettings.nodeId);
73709
+ return (aNode === preferredNodeId ? -1 : 0) - (bNode === preferredNodeId ? -1 : 0);
73710
+ });
73711
+ for (const inst of sorted) {
73712
+ const state = inst.getState();
73713
+ const settings = state.settings || {};
73714
+ const nodeId = readStringValue(settings.meshNodeId, settings.nodeId);
73715
+ if (!nodeId || nodeId !== preferredNodeId) continue;
73716
+ const meshNodeFor = readStringValue(settings.meshNodeFor);
73717
+ if (meshNodeFor !== meshId) continue;
73718
+ const status = (readStringValue(state.status) || "").toLowerCase();
73719
+ if (status !== "idle") continue;
73720
+ const sessionId = typeof state.instanceId === "string" ? state.instanceId : "";
73721
+ const providerType = readStringValue(state.type, settings.providerType) || "";
73722
+ if (sessionId && providerType) {
73723
+ tryAssignQueueTask2(this.deps, meshId, nodeId, sessionId, providerType);
73724
+ break;
73725
+ }
73726
+ }
73727
+ }
73530
73728
  const trigger = await triggerMeshQueue2(this.deps, meshId);
73531
73729
  return { success: true, trigger };
73532
73730
  } catch (e) {