@adhdev/daemon-core 0.9.76-rc.63 → 0.9.76-rc.65

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
@@ -15146,8 +15146,32 @@ function materializeImageDataPart(part, index, dir) {
15146
15146
  fs6.mkdirSync(dir, { recursive: true });
15147
15147
  const filePath = path16.join(dir, safeInputImageBasename(index, part.mimeType));
15148
15148
  fs6.writeFileSync(filePath, Buffer.from(rawData, "base64"));
15149
+ cleanupStaleMaterializedImages(dir);
15149
15150
  return filePath;
15150
15151
  }
15152
+ var MATERIALIZED_IMAGE_MAX_AGE_MS = 60 * 60 * 1e3;
15153
+ var MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS = 5 * 60 * 1e3;
15154
+ var lastMaterializedImageCleanupAt = 0;
15155
+ function cleanupStaleMaterializedImages(dir) {
15156
+ const now = Date.now();
15157
+ if (now - lastMaterializedImageCleanupAt < MATERIALIZED_IMAGE_CLEANUP_INTERVAL_MS) return;
15158
+ lastMaterializedImageCleanupAt = now;
15159
+ try {
15160
+ const entries = fs6.readdirSync(dir);
15161
+ for (const entry of entries) {
15162
+ if (!entry.startsWith("adhdev-input-image-")) continue;
15163
+ const fullPath = path16.join(dir, entry);
15164
+ try {
15165
+ const stat2 = fs6.statSync(fullPath);
15166
+ if (now - stat2.mtimeMs > MATERIALIZED_IMAGE_MAX_AGE_MS) {
15167
+ fs6.unlinkSync(fullPath);
15168
+ }
15169
+ } catch {
15170
+ }
15171
+ }
15172
+ } catch {
15173
+ }
15174
+ }
15151
15175
  function buildCliStructuredInputPrompt(input, options = {}) {
15152
15176
  const promptParts = [];
15153
15177
  const imageRefs = [];
@@ -15174,7 +15198,10 @@ function buildCliStructuredInputPrompt(input, options = {}) {
15174
15198
  resourceRefs.push([part.name, part.text, part.uri].filter(Boolean).join("\n"));
15175
15199
  }
15176
15200
  });
15177
- if (input.textFallback.trim()) promptParts.push(input.textFallback.trim());
15201
+ const hasExplicitTextParts = input.parts.some((part) => part.type === "text" && part.text.trim());
15202
+ if (!hasExplicitTextParts && input.textFallback.trim()) {
15203
+ promptParts.push(input.textFallback.trim());
15204
+ }
15178
15205
  const ordered = [
15179
15206
  ...imageRefs,
15180
15207
  ...promptParts,
@@ -20703,7 +20730,7 @@ import * as yaml from "js-yaml";
20703
20730
  // src/commands/mesh-coordinator.ts
20704
20731
  import { execFileSync as execFileSync2 } from "child_process";
20705
20732
  import { createHash as createHash2 } from "crypto";
20706
- import { existsSync as existsSync15, readdirSync as readdirSync6, realpathSync as realpathSync2 } from "fs";
20733
+ import { existsSync as existsSync15, readdirSync as readdirSync7, realpathSync as realpathSync2 } from "fs";
20707
20734
  import { createRequire as createRequire2 } from "module";
20708
20735
  import * as os17 from "os";
20709
20736
  import { dirname as dirname4, isAbsolute as isAbsolute11, join as join18, resolve as resolve13 } from "path";
@@ -20888,7 +20915,7 @@ function addNodeCandidatesFromPath(pathValue, addCandidate) {
20888
20915
  function addNodeCandidatesFromNvm(homeDir, addCandidate) {
20889
20916
  const versionsDir = join18(homeDir, ".nvm", "versions", "node");
20890
20917
  try {
20891
- const versionDirs = readdirSync6(versionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeVersionNamesDescending);
20918
+ const versionDirs = readdirSync7(versionsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort(compareNodeVersionNamesDescending);
20892
20919
  for (const versionDir of versionDirs) {
20893
20920
  addCandidate(join18(versionsDir, versionDir, "bin", "node"));
20894
20921
  }
@@ -21035,7 +21062,10 @@ function setupMeshEventForwarding(components) {
21035
21062
  const workspace = readNonEmptyString(state.workspace);
21036
21063
  if (!workspace) return;
21037
21064
  const settings = state.settings && typeof state.settings === "object" ? state.settings : {};
21065
+ if (readNonEmptyString(settings.meshCoordinatorFor)) return;
21038
21066
  const meshIdFromRuntime = readNonEmptyString(settings.meshNodeFor);
21067
+ const isMeshDelegate = Boolean(meshIdFromRuntime || settings.launchedByCoordinator);
21068
+ if (!isMeshDelegate) return;
21039
21069
  const mesh = meshIdFromRuntime ? getMesh(meshIdFromRuntime) : getMeshByRepo(workspace);
21040
21070
  const meshId = meshIdFromRuntime || readNonEmptyString(mesh?.id);
21041
21071
  if (!meshId) return;
@@ -21704,6 +21734,8 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
21704
21734
  }
21705
21735
 
21706
21736
  // src/commands/router.ts
21737
+ import { homedir as homedir19 } from "os";
21738
+ import { join as pathJoin, resolve as pathResolve } from "path";
21707
21739
  import * as fs10 from "fs";
21708
21740
  var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
21709
21741
  var CHANNEL_SERVER_URL = {
@@ -21770,6 +21802,32 @@ function serializeMeshCoordinatorMcpConfig(config, format) {
21770
21802
  if (format === "claude_mcp_json") return JSON.stringify(config, null, 2);
21771
21803
  return loadYamlModule().dump(config, { noRefs: true, lineWidth: 120 });
21772
21804
  }
21805
+ function resolveHermesUserHome() {
21806
+ const explicitHome = process.env.HERMES_HOME?.trim();
21807
+ return explicitHome || pathJoin(homedir19(), ".hermes");
21808
+ }
21809
+ function loadHermesCoordinatorBaseConfig(targetConfigPath) {
21810
+ const sourceHome = resolveHermesUserHome();
21811
+ const sourceConfigPath = pathJoin(sourceHome, "config.yaml");
21812
+ if (!fs10.existsSync(sourceConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
21813
+ if (pathResolve(sourceConfigPath) === pathResolve(targetConfigPath)) return { config: {}, sourceHome, sourceConfigPath };
21814
+ const parsed = parseMeshCoordinatorMcpConfig(fs10.readFileSync(sourceConfigPath, "utf-8"), "hermes_config_yaml");
21815
+ const { mcp_servers: _mcpServers, ...baseConfig } = parsed;
21816
+ return { config: baseConfig, sourceHome, sourceConfigPath };
21817
+ }
21818
+ function copyHermesCoordinatorCredentialFiles(sourceHome, targetHome) {
21819
+ if (pathResolve(sourceHome) === pathResolve(targetHome)) return;
21820
+ for (const fileName of [".env", "auth.json"]) {
21821
+ const sourcePath = pathJoin(sourceHome, fileName);
21822
+ const targetPath = pathJoin(targetHome, fileName);
21823
+ if (!fs10.existsSync(sourcePath)) continue;
21824
+ try {
21825
+ fs10.copyFileSync(sourcePath, targetPath);
21826
+ } catch (error) {
21827
+ LOG.warn("MeshCoordinator", `Could not copy Hermes ${fileName} into isolated coordinator home: ${error?.message || error}`);
21828
+ }
21829
+ }
21830
+ }
21773
21831
  var CHAT_COMMANDS = [
21774
21832
  "send_chat",
21775
21833
  "new_chat",
@@ -22991,10 +23049,20 @@ var DaemonCommandRouter = class {
22991
23049
  workspace
22992
23050
  };
22993
23051
  }
22994
- const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync: writeFileSync14, copyFileSync: copyFileSync3, mkdirSync: mkdirSync16 } = await import("fs");
23052
+ const { existsSync: existsSync23, readFileSync: readFileSync15, writeFileSync: writeFileSync14, copyFileSync: copyFileSync4, mkdirSync: mkdirSync16 } = await import("fs");
22995
23053
  const { dirname: dirname9 } = await import("path");
22996
23054
  const mcpConfigPath = coordinatorSetup.configPath;
22997
23055
  const hermesManualFallback = cliType === "hermes-cli" && configFormat === "hermes_config_yaml" ? createHermesManualMeshCoordinatorSetup(meshId, workspace) : null;
23056
+ let hermesBaseConfig = null;
23057
+ if (hermesManualFallback) {
23058
+ try {
23059
+ hermesBaseConfig = loadHermesCoordinatorBaseConfig(mcpConfigPath);
23060
+ } catch (error) {
23061
+ const message = `Failed to parse Hermes base config for automatic coordinator setup: ${error?.message || error}`;
23062
+ LOG.error("MeshCoordinator", message);
23063
+ return { success: false, code: "mesh_coordinator_config_parse_failed", error: message, meshId, cliType, workspace };
23064
+ }
23065
+ }
22998
23066
  const returnManualFallback = (message) => ({
22999
23067
  success: false,
23000
23068
  code: "mesh_coordinator_manual_mcp_setup_required",
@@ -23023,11 +23091,15 @@ var DaemonCommandRouter = class {
23023
23091
  return { success: false, code: "mesh_coordinator_config_write_failed", error: message, meshId, cliType, workspace };
23024
23092
  }
23025
23093
  const hadExistingMcpConfig = existsSync23(mcpConfigPath);
23026
- let existingMcpConfig = {};
23094
+ let existingMcpConfig = hermesBaseConfig?.config || {};
23095
+ if (hermesBaseConfig) {
23096
+ copyHermesCoordinatorCredentialFiles(hermesBaseConfig.sourceHome, dirname9(mcpConfigPath));
23097
+ }
23027
23098
  if (hadExistingMcpConfig) {
23028
23099
  try {
23029
- existingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync15(mcpConfigPath, "utf-8"), configFormat);
23030
- copyFileSync3(mcpConfigPath, mcpConfigPath + ".backup");
23100
+ const parsedExistingMcpConfig = parseMeshCoordinatorMcpConfig(readFileSync15(mcpConfigPath, "utf-8"), configFormat);
23101
+ existingMcpConfig = { ...existingMcpConfig, ...parsedExistingMcpConfig };
23102
+ copyFileSync4(mcpConfigPath, mcpConfigPath + ".backup");
23031
23103
  } catch (error) {
23032
23104
  LOG.error("MeshCoordinator", `Failed to parse existing MCP config ${mcpConfigPath}: ${error?.message || error}`);
23033
23105
  return {
@@ -23483,7 +23555,7 @@ function prepareSessionChatTailUpdate(input) {
23483
23555
  };
23484
23556
  }
23485
23557
  const fullMessages = normalizeChatMessages(Array.isArray(result.messages) ? result.messages : []);
23486
- const messages = filterUserFacingChatMessages(fullMessages);
23558
+ const messages = fullMessages;
23487
23559
  const title = typeof result.title === "string" ? result.title : void 0;
23488
23560
  const activeModal = normalizeChatTailActiveModal(result.activeModal);
23489
23561
  const status = typeof result.status === "string" ? result.status : "idle";