@adhdev/daemon-standalone 0.9.76-rc.36 → 0.9.76-rc.38

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-WChRdqEF.js"></script>
10
+ <script type="module" crossorigin src="/assets/index-BV2Xx1Dg.js"></script>
11
11
  <link rel="modulepreload" crossorigin href="/assets/vendor-CLec0455.js">
12
- <link rel="stylesheet" crossorigin href="/assets/index-DHNzD5nE.css">
12
+ <link rel="stylesheet" crossorigin href="/assets/index-B2g6OjTL.css">
13
13
  </head>
14
14
  <body>
15
15
  <!-- Apply theme immediately to prevent FOIT (Flash of Incorrect Theme) -->
@@ -25604,6 +25604,18 @@ function normalizeRepoIdentity(remoteUrl) {
25604
25604
  if (sshMatch) return `${sshMatch[1]}/${sshMatch[2]}`;
25605
25605
  return identity;
25606
25606
  }
25607
+ function mergeMeshPolicy(base, patch) {
25608
+ const policy = { ...DEFAULT_MESH_POLICY, ...base || {}, ...patch || {} };
25609
+ if (!["block", "warn", "checkpoint_then_continue"].includes(policy.dirtyWorkspaceBehavior)) {
25610
+ policy.dirtyWorkspaceBehavior = "warn";
25611
+ }
25612
+ const maxParallelTasks = Number(policy.maxParallelTasks);
25613
+ policy.maxParallelTasks = Number.isFinite(maxParallelTasks) ? Math.max(1, Math.min(8, Math.floor(maxParallelTasks))) : 2;
25614
+ if (!SESSION_CLEANUP_MODES.has(String(policy.sessionCleanupOnNodeRemove))) {
25615
+ policy.sessionCleanupOnNodeRemove = "preserve";
25616
+ }
25617
+ return policy;
25618
+ }
25607
25619
  function listMeshes() {
25608
25620
  return loadMeshConfig().meshes;
25609
25621
  }
@@ -25627,7 +25639,7 @@ function createMesh(opts) {
25627
25639
  repoIdentity,
25628
25640
  repoRemoteUrl: opts.repoRemoteUrl,
25629
25641
  defaultBranch: opts.defaultBranch,
25630
- policy: { ...DEFAULT_MESH_POLICY, ...opts.policy },
25642
+ policy: mergeMeshPolicy(void 0, opts.policy),
25631
25643
  coordinator: opts.coordinator || {},
25632
25644
  nodes: [],
25633
25645
  createdAt: now,
@@ -25643,7 +25655,7 @@ function updateMesh(meshId, opts) {
25643
25655
  if (!mesh) return void 0;
25644
25656
  if (opts.name !== void 0) mesh.name = opts.name.trim().slice(0, 100);
25645
25657
  if (opts.defaultBranch !== void 0) mesh.defaultBranch = opts.defaultBranch;
25646
- if (opts.policy) mesh.policy = { ...mesh.policy, ...opts.policy };
25658
+ if (opts.policy) mesh.policy = mergeMeshPolicy(mesh.policy, opts.policy);
25647
25659
  if (opts.coordinator) mesh.coordinator = opts.coordinator;
25648
25660
  mesh.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
25649
25661
  saveMeshConfig(config2);
@@ -39837,7 +39849,7 @@ async function shutdownDaemonComponents(components) {
39837
39849
  }
39838
39850
  cdpManagers.clear();
39839
39851
  }
39840
- var path4, import_promises4, import_fs, import_child_process, import_util3, import_os, import_path, import_fs2, import_crypto2, import_fs3, import_path2, import_crypto3, fs2, path10, os4, os8, os9, path14, import_child_process2, os10, path15, os11, import_child_process3, import_fs4, import_promises5, path, import_util4, import_promises6, path22, path32, fs, os5, path5, import_crypto4, path6, path7, import_fs5, import_path3, import_child_process4, import_fs6, import_os2, path8, import_child_process5, os22, path9, import_fs7, os32, import_child_process6, http, crypto2, fs3, path11, os52, fs4, os6, path12, import_crypto5, fs5, path13, os7, os13, path17, crypto4, import_fs8, import_child_process7, os12, path16, crypto3, fs6, import_module, import_stream2, import_child_process8, import_child_process9, net2, os15, path19, fs7, path18, os14, fs8, path20, os16, import_child_process10, import_fs9, import_module2, os17, import_path4, os18, import_child_process11, import_child_process12, fs9, os19, path21, fs10, fs11, path222, os20, import_child_process13, import_os3, http2, fs15, path26, fs12, path23, fs13, path24, fs14, path25, os21, import_child_process14, __defProp2, __getOwnPropDesc2, __getOwnPropNames2, __hasOwnProp2, __require2, __esm2, __export2, __copyProps2, __toCommonJS2, DEFAULT_MESH_POLICY, init_repo_mesh_types, git_worktree_exports, execFileAsync2, WORKTREE_DIR_NAME, GIT_TIMEOUT_MS, GIT_MAX_BUFFER, init_git_worktree, config_exports, DEFAULT_CONFIG, MACHINE_ID_PREFIX, init_config, mesh_config_exports, init_mesh_config, coordinator_prompt_exports, TOOLS_SECTION, WORKFLOW_SECTION, init_coordinator_prompt, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, init_logger, NORMAL_TRACE_BUFFER_SIZE, DEV_TRACE_BUFFER_SIZE, DEFAULT_CONFIG2, currentConfig, init_debug_config, DEFAULT_BINDING_CANDIDATES, cachedBinding, cachedBindingError, GhosttyVtTerminalBackend, init_ghostty_vt_backend, TerminalCtor, XtermTerminalBackend, init_xterm_backend, DEFAULT_SCROLLBACK, loggedTerminalBackends, TerminalScreen, init_terminal_screen, init_spawn_env, cachedPty, NodePtyRuntimeTransport, NodePtyTransportFactory, init_pty_transport, buildCliSpawnEnv, init_provider_cli_shared, init_provider_cli_parse, init_provider_cli_config, init_provider_cli_runtime, provider_cli_adapter_exports, ProviderCliAdapter, init_provider_cli_adapter, execFileAsync, DEFAULT_TIMEOUT_MS, DEFAULT_MAX_BUFFER, GitCommandError, DEFAULT_MAX_FILES, DEFAULT_MAX_BYTES, summarizeGitStatus, InMemoryGitSnapshotStore, DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS, MIN_GIT_WORKSPACE_POLL_INTERVAL_MS, GitWorkspaceMonitor, GIT_COMMAND_NAMES, SNAPSHOT_REASONS, FAILURE_REASONS, defaultSnapshotStore, defaultGitCommandServices, BUSY_STATUSES, TERMINAL_STATUSES, TurnSnapshotTracker, MAX_WORKSPACES, MAX_ACTIVITY, MAX_SAVED_SESSIONS, DEFAULT_STATE, BUILTIN_IDE_DEFINITIONS, registeredIDEs, LIVE_LIFECYCLES, DEFAULT_ACTIVE_CHAT_POLL_STATUSES, DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS, LIVE_RUNTIME_LIFECYCLES, DaemonCdpManager, CdpDomHandlers, DEFAULT_MONITOR_CONFIG, StatusMonitor, BUILTIN_CHAT_MESSAGE_KINDS, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES, HISTORY_DIR, RETAIN_DAYS, SAVED_HISTORY_INDEX_VERSION, SAVED_HISTORY_INDEX_FILE, SAVED_HISTORY_INDEX_LOCK_SUFFIX, SAVED_HISTORY_INDEX_LOCK_WAIT_MS, SAVED_HISTORY_INDEX_LOCK_STALE_MS, SAVED_HISTORY_INDEX_LOCK_POLL_MS, SAVED_HISTORY_ROLLUP_THRESHOLD_BYTES, savedHistorySessionCache, savedHistoryFileSummaryCache, savedHistoryBackgroundRefresh, savedHistoryRollupInFlight, ChatHistoryWriter, IDE_PROVIDER_SESSION_CAPABILITIES_BASE, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE, ExtensionProviderInstance, VALID_STATUSES, VALID_ROLES, VALID_BUBBLE_STATES, VALID_TURN_STATUSES, DEFAULT_APPROVAL_POSITIVE_HINTS, IdeProviderInstance, DEFAULT_CDP_SCAN_INTERVAL_MS, DEFAULT_CDP_DISCOVERY_INTERVAL_MS, DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS, DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS, DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS, MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_READY_TIMEOUT_MS, STANDALONE_CDP_SCAN_INTERVAL_MS, DaemonCdpScanner, DaemonCdpInitializer, WORKING_STATUSES, FULL_STATUS_ACTIVE_CHAT_OPTIONS, LIVE_STATUS_ACTIVE_CHAT_OPTIONS, STATUS_MODAL_MESSAGE_LIMIT, STATUS_MODAL_BUTTON_LIMIT, IDE_SESSION_CAPABILITIES, EXTENSION_SESSION_CAPABILITIES, PTY_SESSION_CAPABILITIES, CLI_CHAT_SESSION_CAPABILITIES, ACP_SESSION_CAPABILITIES, VALID_INPUT_MEDIA_TYPES, globalStore, RECENT_SEND_WINDOW_MS, READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS, recentSendByTarget, DEFAULT_DEBUG_SANITIZE_OPTIONS, SECRET_KEY_PATTERN, KEY_TO_VK, COMMAND_DEBUG_LEVELS, DaemonCommandHandler, CachedDatabaseSync, CliProviderInstance, AcpProviderInstance, chalkModule, chalkApi, COORDINATOR_DELEGATED_ENV_UNSETS, DaemonCliManager, VALID_CAPABILITY_MEDIA_TYPES, KNOWN_PROVIDER_FIELDS, VALUE_CONTROL_TYPES, ProviderLoader, _providerLoader, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS, DEFAULT_SERVER_NAME, DEFAULT_ADHDEV_MCP_COMMAND, HERMES_CLI_TYPE, HERMES_MCP_CONFIG_PATH, READ_DEBUG_ENABLED, recentReadDebugSignatureBySession, UPGRADE_HELPER_ENV, CHANNEL_NPM_TAG, CHANNEL_SERVER_URL, CHAT_COMMANDS, READ_DEBUG_ENABLED2, DaemonCommandRouter, DaemonStatusReporter, DEFAULT_DAEMON_PORT, DAEMON_WS_PATH, ProviderStreamAdapter, DaemonAgentStreamManager, AgentStreamPoller, ProviderInstanceManager, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive, DEV_SERVER_PORT, DevServer, SessionHostRuntimeTransport, SessionHostPtyTransportFactory, DEFAULT_SESSION_HOST_APP_NAME, DEFAULT_STANDALONE_SESSION_HOST_APP_NAME, STARTUP_TIMEOUT_MS, STARTUP_POLL_MS, EXTENSION_CATALOG, SessionRegistry;
39852
+ var path4, import_promises4, import_fs, import_child_process, import_util3, import_os, import_path, import_fs2, import_crypto2, import_fs3, import_path2, import_crypto3, fs2, path10, os4, os8, os9, path14, import_child_process2, os10, path15, os11, import_child_process3, import_fs4, import_promises5, path, import_util4, import_promises6, path22, path32, fs, os5, path5, import_crypto4, path6, path7, import_fs5, import_path3, import_child_process4, import_fs6, import_os2, path8, import_child_process5, os22, path9, import_fs7, os32, import_child_process6, http, crypto2, fs3, path11, os52, fs4, os6, path12, import_crypto5, fs5, path13, os7, os13, path17, crypto4, import_fs8, import_child_process7, os12, path16, crypto3, fs6, import_module, import_stream2, import_child_process8, import_child_process9, net2, os15, path19, fs7, path18, os14, fs8, path20, os16, import_child_process10, import_fs9, import_module2, os17, import_path4, os18, import_child_process11, import_child_process12, fs9, os19, path21, fs10, fs11, path222, os20, import_child_process13, import_os3, http2, fs15, path26, fs12, path23, fs13, path24, fs14, path25, os21, import_child_process14, __defProp2, __getOwnPropDesc2, __getOwnPropNames2, __hasOwnProp2, __require2, __esm2, __export2, __copyProps2, __toCommonJS2, DEFAULT_MESH_POLICY, init_repo_mesh_types, git_worktree_exports, execFileAsync2, WORKTREE_DIR_NAME, GIT_TIMEOUT_MS, GIT_MAX_BUFFER, init_git_worktree, config_exports, DEFAULT_CONFIG, MACHINE_ID_PREFIX, init_config, mesh_config_exports, SESSION_CLEANUP_MODES, init_mesh_config, coordinator_prompt_exports, TOOLS_SECTION, WORKFLOW_SECTION, init_coordinator_prompt, LEVEL_NUM, LEVEL_LABEL, currentLevel, LOG_DIR, MAX_LOG_SIZE, MAX_LOG_DAYS, currentDate, currentLogFile, writeCount, RING_BUFFER_SIZE, ringBuffer, origConsoleLog, origConsoleError, origConsoleWarn, LOG, interceptorInstalled, LOG_PATH, init_logger, NORMAL_TRACE_BUFFER_SIZE, DEV_TRACE_BUFFER_SIZE, DEFAULT_CONFIG2, currentConfig, init_debug_config, DEFAULT_BINDING_CANDIDATES, cachedBinding, cachedBindingError, GhosttyVtTerminalBackend, init_ghostty_vt_backend, TerminalCtor, XtermTerminalBackend, init_xterm_backend, DEFAULT_SCROLLBACK, loggedTerminalBackends, TerminalScreen, init_terminal_screen, init_spawn_env, cachedPty, NodePtyRuntimeTransport, NodePtyTransportFactory, init_pty_transport, buildCliSpawnEnv, init_provider_cli_shared, init_provider_cli_parse, init_provider_cli_config, init_provider_cli_runtime, provider_cli_adapter_exports, ProviderCliAdapter, init_provider_cli_adapter, execFileAsync, DEFAULT_TIMEOUT_MS, DEFAULT_MAX_BUFFER, GitCommandError, DEFAULT_MAX_FILES, DEFAULT_MAX_BYTES, summarizeGitStatus, InMemoryGitSnapshotStore, DEFAULT_GIT_WORKSPACE_POLL_INTERVAL_MS, MIN_GIT_WORKSPACE_POLL_INTERVAL_MS, GitWorkspaceMonitor, GIT_COMMAND_NAMES, SNAPSHOT_REASONS, FAILURE_REASONS, defaultSnapshotStore, defaultGitCommandServices, BUSY_STATUSES, TERMINAL_STATUSES, TurnSnapshotTracker, MAX_WORKSPACES, MAX_ACTIVITY, MAX_SAVED_SESSIONS, DEFAULT_STATE, BUILTIN_IDE_DEFINITIONS, registeredIDEs, LIVE_LIFECYCLES, DEFAULT_ACTIVE_CHAT_POLL_STATUSES, DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS, LIVE_RUNTIME_LIFECYCLES, DaemonCdpManager, CdpDomHandlers, DEFAULT_MONITOR_CONFIG, StatusMonitor, BUILTIN_CHAT_MESSAGE_KINDS, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES, HISTORY_DIR, RETAIN_DAYS, SAVED_HISTORY_INDEX_VERSION, SAVED_HISTORY_INDEX_FILE, SAVED_HISTORY_INDEX_LOCK_SUFFIX, SAVED_HISTORY_INDEX_LOCK_WAIT_MS, SAVED_HISTORY_INDEX_LOCK_STALE_MS, SAVED_HISTORY_INDEX_LOCK_POLL_MS, SAVED_HISTORY_ROLLUP_THRESHOLD_BYTES, savedHistorySessionCache, savedHistoryFileSummaryCache, savedHistoryBackgroundRefresh, savedHistoryRollupInFlight, ChatHistoryWriter, IDE_PROVIDER_SESSION_CAPABILITIES_BASE, EXTENSION_PROVIDER_SESSION_CAPABILITIES_BASE, ExtensionProviderInstance, VALID_STATUSES, VALID_ROLES, VALID_BUBBLE_STATES, VALID_TURN_STATUSES, DEFAULT_APPROVAL_POSITIVE_HINTS, IdeProviderInstance, DEFAULT_CDP_SCAN_INTERVAL_MS, DEFAULT_CDP_DISCOVERY_INTERVAL_MS, DEFAULT_STATUS_INITIAL_REPORT_DELAY_MS, DEFAULT_STATUS_SERVER_REPORT_INTERVAL_MS, DEFAULT_STATUS_P2P_REPORT_INTERVAL_MS, MIN_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, DEFAULT_MACHINE_RUNTIME_SUBSCRIPTION_INTERVAL_MS, MIN_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_DIAGNOSTICS_SUBSCRIPTION_INTERVAL_MS, DEFAULT_SESSION_HOST_READY_TIMEOUT_MS, STANDALONE_CDP_SCAN_INTERVAL_MS, DaemonCdpScanner, DaemonCdpInitializer, WORKING_STATUSES, FULL_STATUS_ACTIVE_CHAT_OPTIONS, LIVE_STATUS_ACTIVE_CHAT_OPTIONS, STATUS_MODAL_MESSAGE_LIMIT, STATUS_MODAL_BUTTON_LIMIT, IDE_SESSION_CAPABILITIES, EXTENSION_SESSION_CAPABILITIES, PTY_SESSION_CAPABILITIES, CLI_CHAT_SESSION_CAPABILITIES, ACP_SESSION_CAPABILITIES, VALID_INPUT_MEDIA_TYPES, globalStore, RECENT_SEND_WINDOW_MS, READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS, recentSendByTarget, DEFAULT_DEBUG_SANITIZE_OPTIONS, SECRET_KEY_PATTERN, KEY_TO_VK, COMMAND_DEBUG_LEVELS, DaemonCommandHandler, CachedDatabaseSync, CliProviderInstance, AcpProviderInstance, chalkModule, chalkApi, COORDINATOR_DELEGATED_ENV_UNSETS, DaemonCliManager, VALID_CAPABILITY_MEDIA_TYPES, KNOWN_PROVIDER_FIELDS, VALUE_CONTROL_TYPES, ProviderLoader, _providerLoader, LOG_DIR2, MAX_FILE_SIZE, MAX_DAYS, SENSITIVE_KEYS, currentDate2, currentFile, writeCount2, SKIP_COMMANDS, DEFAULT_SERVER_NAME, DEFAULT_ADHDEV_MCP_COMMAND, HERMES_CLI_TYPE, HERMES_MCP_CONFIG_PATH, READ_DEBUG_ENABLED, recentReadDebugSignatureBySession, UPGRADE_HELPER_ENV, CHANNEL_NPM_TAG, CHANNEL_SERVER_URL, CHAT_COMMANDS, READ_DEBUG_ENABLED2, DaemonCommandRouter, DaemonStatusReporter, DEFAULT_DAEMON_PORT, DAEMON_WS_PATH, ProviderStreamAdapter, DaemonAgentStreamManager, AgentStreamPoller, ProviderInstanceManager, ARCHIVE_PATH, MAX_ENTRIES_PER_PROVIDER, VersionArchive, DEV_SERVER_PORT, DevServer, SessionHostRuntimeTransport, SessionHostPtyTransportFactory, DEFAULT_SESSION_HOST_APP_NAME, DEFAULT_STANDALONE_SESSION_HOST_APP_NAME, STARTUP_TIMEOUT_MS, STARTUP_POLL_MS, EXTENSION_CATALOG, SessionRegistry;
39841
39853
  var init_dist2 = __esm({
39842
39854
  "../daemon-core/dist/index.mjs"() {
39843
39855
  "use strict";
@@ -39995,7 +40007,8 @@ var init_dist2 = __esm({
39995
40007
  requireApprovalForPush: true,
39996
40008
  requireApprovalForDestructiveGit: true,
39997
40009
  dirtyWorkspaceBehavior: "warn",
39998
- maxParallelTasks: 2
40010
+ maxParallelTasks: 2,
40011
+ sessionCleanupOnNodeRemove: "preserve"
39999
40012
  };
40000
40013
  }
40001
40014
  });
@@ -40077,6 +40090,7 @@ var init_dist2 = __esm({
40077
40090
  "use strict";
40078
40091
  init_config();
40079
40092
  init_repo_mesh_types();
40093
+ SESSION_CLEANUP_MODES = /* @__PURE__ */ new Set(["preserve", "stop", "delete_stopped", "stop_and_delete"]);
40080
40094
  }
40081
40095
  });
40082
40096
  coordinator_prompt_exports = {};
@@ -50748,6 +50762,75 @@ Run 'adhdev doctor' for detailed diagnostics.`
50748
50762
  this.inlineMeshCache.set(meshId, mesh);
50749
50763
  return true;
50750
50764
  }
50765
+ normalizeMeshSessionCleanupMode(value) {
50766
+ return value === "stop" || value === "delete_stopped" || value === "stop_and_delete" || value === "preserve" ? value : "preserve";
50767
+ }
50768
+ sessionMatchesMeshNode(record2, node, nodeId, sessionIds) {
50769
+ const sessionId = typeof record2?.sessionId === "string" ? record2.sessionId : "";
50770
+ if (!sessionId) return false;
50771
+ if (sessionIds?.size) return sessionIds.has(sessionId);
50772
+ const workspace = typeof node?.workspace === "string" ? node.workspace : "";
50773
+ if (workspace && record2?.workspace === workspace) return true;
50774
+ if (record2?.meta?.meshNodeId === nodeId) return true;
50775
+ return false;
50776
+ }
50777
+ isCompletedHostedSession(record2) {
50778
+ return record2?.lifecycle === "stopped" || record2?.lifecycle === "failed" || record2?.lifecycle === "interrupted";
50779
+ }
50780
+ async cleanupMeshSessions(args) {
50781
+ if (args.mode === "preserve") {
50782
+ return { success: true, mode: "preserve", matchedCount: 0, stoppedSessionIds: [], deletedSessionIds: [], skippedSessionIds: [] };
50783
+ }
50784
+ if (!this.deps.sessionHostControl) return { success: false, error: "Session host control unavailable" };
50785
+ const requestedSessionIds = Array.isArray(args.sessionIds) ? new Set(args.sessionIds.map((id) => typeof id === "string" ? id.trim() : "").filter(Boolean)) : void 0;
50786
+ const sessions = await this.deps.sessionHostControl.listSessions();
50787
+ const matched = sessions.filter((record2) => this.sessionMatchesMeshNode(record2, args.node, args.nodeId, requestedSessionIds));
50788
+ const stoppedSessionIds = [];
50789
+ const deletedSessionIds = [];
50790
+ const skippedSessionIds = [];
50791
+ const errors = [];
50792
+ for (const record2 of matched) {
50793
+ const sessionId = String(record2.sessionId);
50794
+ const completed = this.isCompletedHostedSession(record2);
50795
+ try {
50796
+ if (args.mode === "stop") {
50797
+ if (!completed) {
50798
+ if (!args.dryRun) await this.deps.sessionHostControl.stopSession(sessionId);
50799
+ stoppedSessionIds.push(sessionId);
50800
+ } else {
50801
+ skippedSessionIds.push(sessionId);
50802
+ }
50803
+ continue;
50804
+ }
50805
+ if (args.mode === "delete_stopped") {
50806
+ if (completed) {
50807
+ if (!args.dryRun) await this.deps.sessionHostControl.deleteSession(sessionId, { force: false });
50808
+ deletedSessionIds.push(sessionId);
50809
+ } else {
50810
+ skippedSessionIds.push(sessionId);
50811
+ }
50812
+ continue;
50813
+ }
50814
+ if (args.mode === "stop_and_delete") {
50815
+ if (!args.dryRun) await this.deps.sessionHostControl.deleteSession(sessionId, { force: true });
50816
+ deletedSessionIds.push(sessionId);
50817
+ continue;
50818
+ }
50819
+ } catch (e) {
50820
+ errors.push({ sessionId, error: e?.message || String(e) });
50821
+ }
50822
+ }
50823
+ return {
50824
+ success: errors.length === 0,
50825
+ mode: args.mode,
50826
+ dryRun: args.dryRun === true,
50827
+ matchedCount: matched.length,
50828
+ stoppedSessionIds,
50829
+ deletedSessionIds,
50830
+ skippedSessionIds,
50831
+ ...errors.length ? { errors } : {}
50832
+ };
50833
+ }
50751
50834
  async traceSessionHostAction(action, args, run, summarizeResult) {
50752
50835
  const interactionId = typeof args?._interactionId === "string" ? args._interactionId : void 0;
50753
50836
  const sessionId = typeof args?.sessionId === "string" ? args.sessionId : void 0;
@@ -51414,7 +51497,26 @@ Run 'adhdev doctor' for detailed diagnostics.`
51414
51497
  if (!name) return { success: false, error: "name required" };
51415
51498
  try {
51416
51499
  const { createMesh: createMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51417
- const mesh = createMesh2({ name, repoIdentity, repoRemoteUrl, defaultBranch });
51500
+ const mesh = createMesh2({ name, repoIdentity, repoRemoteUrl, defaultBranch, policy: args?.policy });
51501
+ return { success: true, mesh };
51502
+ } catch (e) {
51503
+ return { success: false, error: e.message };
51504
+ }
51505
+ }
51506
+ case "update_mesh": {
51507
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51508
+ if (!meshId) return { success: false, error: "meshId required" };
51509
+ try {
51510
+ const { updateMesh: updateMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51511
+ const patch = {};
51512
+ if (typeof args?.name === "string") patch.name = args.name;
51513
+ if (typeof args?.defaultBranch === "string") patch.defaultBranch = args.defaultBranch;
51514
+ if (args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy)) patch.policy = args.policy;
51515
+ if (args?.coordinator && typeof args.coordinator === "object" && !Array.isArray(args.coordinator)) patch.coordinator = args.coordinator;
51516
+ if (!Object.keys(patch).length) return { success: false, error: "No updates provided" };
51517
+ const mesh = updateMesh2(meshId, patch);
51518
+ if (!mesh) return { success: false, error: "Mesh not found" };
51519
+ this.inlineMeshCache.set(meshId, mesh);
51418
51520
  return { success: true, mesh };
51419
51521
  } catch (e) {
51420
51522
  return { success: false, error: e.message };
@@ -51451,6 +51553,54 @@ Run 'adhdev doctor' for detailed diagnostics.`
51451
51553
  return { success: false, error: e.message };
51452
51554
  }
51453
51555
  }
51556
+ case "update_mesh_node": {
51557
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51558
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
51559
+ if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
51560
+ try {
51561
+ const { updateNode: updateNode2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51562
+ const policy = args?.policy && typeof args.policy === "object" && !Array.isArray(args.policy) ? { ...args.policy } : {};
51563
+ if (Array.isArray(args?.providerPriority)) {
51564
+ const providerPriority = args.providerPriority.map((type2) => typeof type2 === "string" ? type2.trim() : "").filter(Boolean);
51565
+ delete policy.provider_priority;
51566
+ if (providerPriority.length) {
51567
+ policy.providerPriority = providerPriority;
51568
+ } else {
51569
+ delete policy.providerPriority;
51570
+ }
51571
+ }
51572
+ const node = updateNode2(meshId, nodeId, { policy });
51573
+ if (!node) return { success: false, error: "Mesh node not found" };
51574
+ return { success: true, node };
51575
+ } catch (e) {
51576
+ return { success: false, error: e.message };
51577
+ }
51578
+ }
51579
+ case "cleanup_mesh_sessions": {
51580
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51581
+ const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
51582
+ if (!meshId || !nodeId) return { success: false, error: "meshId and nodeId required" };
51583
+ try {
51584
+ const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
51585
+ const mesh = meshRecord?.mesh;
51586
+ if (!mesh) return { success: false, error: "Mesh not found" };
51587
+ const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
51588
+ if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
51589
+ const mode = this.normalizeMeshSessionCleanupMode(args?.mode ?? mesh?.policy?.sessionCleanupOnNodeRemove);
51590
+ const sessionIds = Array.isArray(args?.sessionIds) ? args.sessionIds.map((id) => typeof id === "string" ? id.trim() : "").filter(Boolean) : void 0;
51591
+ const result = await this.cleanupMeshSessions({
51592
+ meshId,
51593
+ nodeId,
51594
+ node,
51595
+ mode,
51596
+ sessionIds,
51597
+ dryRun: args?.dryRun === true
51598
+ });
51599
+ return result;
51600
+ } catch (e) {
51601
+ return { success: false, error: e.message };
51602
+ }
51603
+ }
51454
51604
  case "remove_mesh_node": {
51455
51605
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
51456
51606
  const nodeId = typeof args?.nodeId === "string" ? args.nodeId.trim() : "";
@@ -51459,6 +51609,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
51459
51609
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
51460
51610
  const mesh = meshRecord?.mesh;
51461
51611
  const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
51612
+ const sessionCleanupMode = this.normalizeMeshSessionCleanupMode(
51613
+ args?.sessionCleanupMode ?? args?.session_cleanup_mode ?? mesh?.policy?.sessionCleanupOnNodeRemove
51614
+ );
51615
+ let sessionCleanup;
51616
+ if (node && sessionCleanupMode !== "preserve") {
51617
+ sessionCleanup = await this.cleanupMeshSessions({ meshId, nodeId, node, mode: sessionCleanupMode });
51618
+ if (sessionCleanup.success === false) return { success: false, removed: false, sessionCleanup };
51619
+ }
51462
51620
  if (node?.isLocalWorktree && node.workspace) {
51463
51621
  try {
51464
51622
  const sourceNode = node.clonedFromNodeId ? mesh?.nodes.find((n) => n.id === node.clonedFromNodeId || n.nodeId === node.clonedFromNodeId) : mesh?.nodes.find((n) => !n.isLocalWorktree);
@@ -51478,7 +51636,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
51478
51636
  const { removeNode: removeNode3 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
51479
51637
  removed = removeNode3(meshId, nodeId);
51480
51638
  }
51481
- return { success: true, removed };
51639
+ return { success: true, removed, ...sessionCleanup ? { sessionCleanup } : {} };
51482
51640
  } catch (e) {
51483
51641
  return { success: false, error: e.message };
51484
51642
  }
@@ -56974,15 +57132,42 @@ var MESH_CLONE_NODE_TOOL = {
56974
57132
  };
56975
57133
  var MESH_REMOVE_NODE_TOOL = {
56976
57134
  name: "mesh_remove_node",
56977
- description: "Remove a node from the mesh. If the node is a worktree, also cleans up the git worktree and directory.",
57135
+ description: "Remove a node from the mesh. If the node is a worktree, also cleans up the git worktree and directory. Session cleanup is controlled by mesh policy sessionCleanupOnNodeRemove unless session_cleanup_mode overrides it for this call.",
56978
57136
  inputSchema: {
56979
57137
  type: "object",
56980
57138
  properties: {
56981
- node_id: { type: "string", description: "Node ID to remove." }
57139
+ node_id: { type: "string", description: "Node ID to remove." },
57140
+ session_cleanup_mode: {
57141
+ type: "string",
57142
+ enum: ["preserve", "stop", "delete_stopped", "stop_and_delete"],
57143
+ description: "Optional override for cleanup of delegated sessions attached to this node. preserve keeps history/processes; stop stops live runtimes only; delete_stopped removes completed transcripts only; stop_and_delete stops live runtimes and deletes records."
57144
+ }
56982
57145
  },
56983
57146
  required: ["node_id"]
56984
57147
  }
56985
57148
  };
57149
+ var MESH_CLEANUP_SESSIONS_TOOL = {
57150
+ name: "mesh_cleanup_sessions",
57151
+ description: "Manually clean up delegated session records for a mesh node without removing the node. Defaults should preserve reviewable history unless the caller chooses a mode explicitly.",
57152
+ inputSchema: {
57153
+ type: "object",
57154
+ properties: {
57155
+ node_id: { type: "string", description: "Node ID whose delegated sessions should be considered for cleanup." },
57156
+ mode: {
57157
+ type: "string",
57158
+ enum: ["preserve", "stop", "delete_stopped", "stop_and_delete"],
57159
+ description: "preserve = no-op; stop = release process occupancy by stopping live runtimes; delete_stopped = remove completed/stopped records while leaving live runtimes alone; stop_and_delete = stop live runtimes and delete records."
57160
+ },
57161
+ session_ids: {
57162
+ type: "array",
57163
+ items: { type: "string" },
57164
+ description: "Optional explicit session IDs to limit cleanup to. When omitted, sessions are matched by node/workspace metadata."
57165
+ },
57166
+ dry_run: { type: "boolean", description: "Preview matched/stopped/deleted/skipped session IDs without mutating session-host state." }
57167
+ },
57168
+ required: ["node_id", "mode"]
57169
+ }
57170
+ };
56986
57171
  var ALL_MESH_TOOLS = [
56987
57172
  MESH_STATUS_TOOL,
56988
57173
  MESH_LIST_NODES_TOOL,
@@ -56994,7 +57179,8 @@ var ALL_MESH_TOOLS = [
56994
57179
  MESH_CHECKPOINT_TOOL,
56995
57180
  MESH_APPROVE_TOOL,
56996
57181
  MESH_CLONE_NODE_TOOL,
56997
- MESH_REMOVE_NODE_TOOL
57182
+ MESH_REMOVE_NODE_TOOL,
57183
+ MESH_CLEANUP_SESSIONS_TOOL
56998
57184
  ];
56999
57185
  async function meshStatus(ctx) {
57000
57186
  await refreshMeshFromDaemon(ctx);
@@ -57256,12 +57442,29 @@ async function meshCloneNode(ctx, args) {
57256
57442
  return JSON.stringify({ error: "Cloud mesh clone_node not yet implemented" });
57257
57443
  }
57258
57444
  }
57445
+ async function meshCleanupSessions(ctx, args) {
57446
+ const node = await findNodeWithRefresh(ctx, args.node_id);
57447
+ if (isLocalTransport(ctx.transport)) {
57448
+ const result = await commandForNode(ctx, node, "cleanup_mesh_sessions", {
57449
+ meshId: ctx.mesh.id,
57450
+ nodeId: args.node_id,
57451
+ mode: args.mode,
57452
+ sessionIds: args.session_ids,
57453
+ dryRun: args.dry_run === true,
57454
+ inlineMesh: ctx.mesh
57455
+ });
57456
+ return JSON.stringify(result, null, 2);
57457
+ } else {
57458
+ return JSON.stringify({ error: "Cloud mesh cleanup_sessions not yet implemented" });
57459
+ }
57460
+ }
57259
57461
  async function meshRemoveNode(ctx, args) {
57260
57462
  const node = await findNodeWithRefresh(ctx, args.node_id);
57261
57463
  if (isLocalTransport(ctx.transport)) {
57262
57464
  const result = await commandForNode(ctx, node, "remove_mesh_node", {
57263
57465
  meshId: ctx.mesh.id,
57264
57466
  nodeId: args.node_id,
57467
+ ...args.session_cleanup_mode ? { sessionCleanupMode: args.session_cleanup_mode } : {},
57265
57468
  inlineMesh: ctx.mesh
57266
57469
  });
57267
57470
  if (result?.success && result.removed !== false) {
@@ -57461,6 +57664,9 @@ async function startMcpServer(opts) {
57461
57664
  case "mesh_remove_node":
57462
57665
  text = await meshRemoveNode(meshCtx, a);
57463
57666
  break;
57667
+ case "mesh_cleanup_sessions":
57668
+ text = await meshCleanupSessions(meshCtx, a);
57669
+ break;
57464
57670
  default:
57465
57671
  return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
57466
57672
  }