@adhdev/daemon-core 0.9.82-rc.438 → 0.9.82-rc.439

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.d.ts CHANGED
@@ -30,7 +30,7 @@ export { getSavedProviderSessions, upsertSavedProviderSession } from './config/s
30
30
  export type { SavedProviderSessionEntry } from './config/saved-sessions.js';
31
31
  export { listMeshes, getMesh, getMeshByRepo, createMesh, updateMesh, deleteMesh, addNode, removeNode, updateNode, normalizeRepoIdentity, listMagiPanels, getMagiPanel, upsertMagiPanel, removeMagiPanel, normalizeMagiPanel, listMagiKindPanels, getMagiKindPanel, setMagiKindPanel, removeMagiKindPanel, normalizeMagiSlots, } from './config/mesh-config.js';
32
32
  export type { CreateMeshOptions, UpdateMeshOptions, AddNodeOptions } from './config/mesh-config.js';
33
- export type { MagiPanel, MagiPanelMember, MagiPanelMap, MagiMode, MagiTaskKind, MagiPanelDefaultKind, MagiClaim, MagiClaimStance, MagiAgentResponse, MagiResponseSource, MagiReplicaGitRef, MagiGitSkew, MagiSynthesizedResponse, MagiClusterCategory, MagiClusterMember, MagiClaimCluster, MagiSynthesis, } from '@adhdev/mesh-shared';
33
+ export type { MagiPanel, MagiPanelMember, MagiPanelMap, MagiMode, MagiTaskKind, MagiPanelDefaultKind, MagiSlot, MagiKindPanelMap, MagiClaim, MagiClaimStance, MagiAgentResponse, MagiResponseSource, MagiReplicaGitRef, MagiGitSkew, MagiSynthesizedResponse, MagiClusterCategory, MagiClusterMember, MagiClaimCluster, MagiSynthesis, } from '@adhdev/mesh-shared';
34
34
  export { MAGI_RAW_ANSWER_CAP } from '@adhdev/mesh-shared';
35
35
  export { expandDaemonIdForms, daemonIdsEquivalent, machineCoreFromDaemonId, canonicalDaemonId } from '@adhdev/mesh-shared';
36
36
  export { normalizeMeshNodeId, meshNodeIdMatches } from '@adhdev/mesh-shared';
package/dist/index.js CHANGED
@@ -409,10 +409,10 @@ function readInjected(value) {
409
409
  }
410
410
  function getDaemonBuildInfo() {
411
411
  if (cached) return cached;
412
- const commit = readInjected(true ? "84f8b9ff2e41b3bbf8375a9e4594c0ec33905b6e" : void 0) ?? "unknown";
413
- const commitShort = readInjected(true ? "84f8b9ff" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
414
- const version = readInjected(true ? "0.9.82-rc.438" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
415
- const builtAt = readInjected(true ? "2026-07-01T02:03:18.523Z" : void 0);
412
+ const commit = readInjected(true ? "065287032ac520cf8950f90025e1758b873723b1" : void 0) ?? "unknown";
413
+ const commitShort = readInjected(true ? "06528703" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
414
+ const version = readInjected(true ? "0.9.82-rc.439" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
415
+ const builtAt = readInjected(true ? "2026-07-01T04:55:17.522Z" : void 0);
416
416
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
417
417
  return cached;
418
418
  }
@@ -3501,6 +3501,7 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
3501
3501
  sections.push(TOOLS_SECTION);
3502
3502
  sections.push(TOOL_EXPOSURE_PREFLIGHT_SECTION);
3503
3503
  sections.push(WORKFLOW_SECTION);
3504
+ sections.push(ONBOARDING_SECTION);
3504
3505
  sections.push(buildRulesSection(coordinatorCliType));
3505
3506
  return sections.join("\n\n");
3506
3507
  }
@@ -3533,6 +3534,7 @@ function expandPromptPlaceholders(template, ctx) {
3533
3534
  policy: buildPolicySection(mergeAndNormalizePolicy(void 0, mesh.policy)),
3534
3535
  tools: TOOLS_SECTION,
3535
3536
  workflow: WORKFLOW_SECTION,
3537
+ onboarding: ONBOARDING_SECTION,
3536
3538
  rules: buildRulesSection(coordinatorCliType),
3537
3539
  toolExposurePreflight: TOOL_EXPOSURE_PREFLIGHT_SECTION
3538
3540
  };
@@ -3691,7 +3693,7 @@ function buildRulesSection(coordinatorCliType) {
3691
3693
  - **Never fabricate tool results.** Always call the actual tool.
3692
3694
  - **Keep the user informed.** One or two sentences after each delegation round.${coordinatorNote}`;
3693
3695
  }
3694
- var fs2, os2, path8, TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION;
3696
+ var fs2, os2, path8, TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION, ONBOARDING_SECTION;
3695
3697
  var init_coordinator_prompt = __esm({
3696
3698
  "src/mesh/coordinator-prompt.ts"() {
3697
3699
  "use strict";
@@ -3723,7 +3725,12 @@ var init_coordinator_prompt = __esm({
3723
3725
  | \`mesh_clone_node\` | Create a worktree node for isolated parallel branch work |
3724
3726
  | \`mesh_refine_node\` | Validate and merge a completed worktree node back into its base branch |
3725
3727
  | \`mesh_remove_node\` | Remove a node (cleans up worktree if applicable) |
3726
- | \`mesh_cleanup_sessions\` | Manually clean up delegated session records for a node |`;
3728
+ | \`mesh_cleanup_sessions\` | Manually clean up delegated session records for a node |
3729
+ | \`mesh_init\` | Guided onboarding for a fresh repo: dry-run scan \u2192 suggest \`.adhdev/*\` configs (refine/bootstrap/change-impact) + providerPriority + current-config echo; gated write on approval |
3730
+ | \`mesh_reinit\` | Re-onboard an already-configured repo: re-suggest with overwrite semantics + current-vs-suggested diff; dry-run preview first, per-section approval before write |
3731
+ | \`mesh_write_mesh_json_config\` | Gated write of \`.adhdev/mesh.json\` (repo coordinator-prompt config) from the mesh entry \u2014 dry-run/overwrite like mesh_init |
3732
+ | \`mesh_magi_kind_panel_set\` | Bind a task_kind \u2192 MAGI kind-panel slots (machine-local, wholesale replacement \u2014 approve current-vs-new first) |
3733
+ | \`mesh_magi_kind_panel_list\` | List configured task_kind \u2192 MAGI kind-panel slot bindings (machine-local, read-only) |`;
3727
3734
  TOOL_EXPOSURE_PREFLIGHT_SECTION = `## Tool Exposure Preflight
3728
3735
 
3729
3736
  Before doing any coordinator work, confirm that the actual callable tool list includes \`mesh_status\` and the other \`mesh_*\` tools from the table above. If this Repo Mesh coordinator prompt is present but the callable \`mesh_*\` tools are missing, the MCP server/tool manifest is stale or not injected yet. Do not substitute terminal/file/git tools, do not inspect or edit the repository directly, and do not continue as a non-mesh local coding agent. Stop immediately and tell the user to run \`/reload-mcp\` or start a fresh coordinator session so ADHDev can reconnect \`adhdev-mesh\`.`;
@@ -3756,6 +3763,28 @@ Follow these recovery rules:
3756
3763
  2. **If "Max retries exceeded"**: Do NOT retry on the same node. Either reassign the task to a different node, or inform the user that the task requires manual intervention.
3757
3764
  3. **If no recovery context**: The stop may be intentional (normal completion). Use \`mesh_read_chat\` once to verify, then move on.
3758
3765
  4. **Always record what happened**: After handling a failure, briefly note the outcome in your report to the user.`;
3766
+ ONBOARDING_SECTION = `## Onboarding / Reinit
3767
+
3768
+ When the user asks to **set up / configure / onboard** this repo for Repo Mesh (or to **re-init / reconfigure** an already-onboarded repo), run ONE guided, approval-gated conversation. You draft, the user approves, the daemon writes. Never auto-write a heuristic suggestion without an explicit user approval turn.
3769
+
3770
+ **Save scopes \u2014 label every draft with its scope before asking for approval:**
3771
+ - **repo-file (commit target)** \u2014 \`.adhdev/refine.json\`, \`.adhdev/worktree_bootstrap.json\`, \`.adhdev/change-impact.json\`, \`.adhdev/mesh.json\`. These are committed to the repository and shared with every machine/contributor.
3772
+ - **machine-local** \u2014 MAGI kind\u2192panel bindings and named MAGI panels, node providerPriority (\`~/.adhdev/meshes.json\`). These stay on this machine and are NOT committed.
3773
+
3774
+ **Guided sequence:**
3775
+ 1. **Scan (dry-run)** \u2014 Call \`mesh_init\` (write=false, the default). It returns per-domain suggested configs for refine / worktree_bootstrap / change-impact, a recommended providerPriority, AND \`currentConfig\` \u2014 the currently-saved config per domain (repo files + machine-local \`magiKindPanels\`). Nothing is written.
3776
+ 2. **Present drafts** \u2014 For each domain, show the user the suggested config with its **save scope label** (repo-file vs machine-local). When \`currentConfig\` already has a saved value for a domain (init on a partially-onboarded repo, or any reinit), present a **current-vs-suggested diff**, not just the suggestion.
3777
+ 3. **Approve \u2192 gated write** \u2014 Only after the user approves, call the matching gated-write tool:
3778
+ - repo \`.adhdev/*\` config files \u2192 \`mesh_init\` with \`write=true\` (and \`overwrite=true\` ONLY for domains the user approved replacing).
3779
+ - \`.adhdev/mesh.json\` (coordinator prompt / operating notes) \u2192 \`mesh_write_mesh_json_config\` (write=true, overwrite only if approved).
3780
+ - machine-local MAGI kind\u2192panel slots \u2192 \`mesh_magi_kind_panel_set\` (write=true). NOTE: a kind binding is a **wholesale replacement** of that kind's slot list \u2014 present the current-vs-new slots first.
3781
+ - machine-local named MAGI panels \u2192 \`mesh_magi_panel_set\`. providerPriority \u2192 apply via node policy update.
3782
+
3783
+ **init vs reinit:**
3784
+ - **\`mesh_init\`** \u2014 for a fresh, never-onboarded repo. Existing config files are kept (existing-wins) unless the user explicitly approves overwrite. Use for first-time setup.
3785
+ - **\`mesh_reinit\`** \u2014 for a repo that is already onboarded and needs its config refreshed. It re-suggests with OVERWRITE semantics and returns the current-vs-suggested \`currentConfig\` echo. Its first call is a DRY-RUN preview: you MUST present the per-section current-vs-suggested diff and get EXPLICIT per-section approval before re-invoking with write=true. Overwrite is a wholesale replacement, so it silently drops operator hand-edits if you skip the diff \u2014 never do that.
3786
+
3787
+ `;
3759
3788
  }
3760
3789
  });
3761
3790
 
@@ -28638,6 +28667,16 @@ function callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, his
28638
28667
  const result = fn({
28639
28668
  agentType,
28640
28669
  sessionId: normalizedSessionId,
28670
+ // Arm the native-history executor's session pin guard. When the
28671
+ // instance is already bound to a provider session, pass that id as
28672
+ // `providerSessionId` so the executor rejects any *other* newest
28673
+ // session it would otherwise pick (hermes ≥0.14 creates a fresh
28674
+ // `sessions` row per internal sub-session, so an unpinned
28675
+ // newest-wins query drifts to a different id on every read →
28676
+ // re-bind churn + unbounded history re-hydration). When there is no
28677
+ // bound id yet (first-bind / workspace-only discovery) this is '',
28678
+ // which leaves the guard disarmed so discovery still works.
28679
+ providerSessionId: normalizedSessionId,
28641
28680
  historySessionId: normalizedSessionId,
28642
28681
  workspace,
28643
28682
  format: canonicalHistory?.format,
@@ -39053,24 +39092,28 @@ function executeSqlite(src, input) {
39053
39092
  return null;
39054
39093
  }
39055
39094
  try {
39056
- let sessionRow;
39057
- try {
39058
- const sessionFloorSeconds = typeof input.sessionStartedAtMs === "number" ? Math.floor(input.sessionStartedAtMs / 1e3) : 0;
39059
- const stmt = db.prepare(src.session_query);
39095
+ const requested = input.providerSessionId || "";
39096
+ let sessionId;
39097
+ if (requested) {
39098
+ sessionId = requested;
39099
+ } else {
39100
+ let sessionRow;
39060
39101
  try {
39061
- sessionRow = stmt.get(sessionFloorSeconds);
39102
+ const sessionFloorSeconds = typeof input.sessionStartedAtMs === "number" ? Math.floor(input.sessionStartedAtMs / 1e3) : 0;
39103
+ const stmt = db.prepare(src.session_query);
39104
+ try {
39105
+ sessionRow = stmt.get(sessionFloorSeconds);
39106
+ } catch {
39107
+ sessionRow = stmt.get();
39108
+ }
39062
39109
  } catch {
39063
- sessionRow = stmt.get();
39110
+ return null;
39064
39111
  }
39065
- } catch {
39066
- return null;
39112
+ if (!sessionRow) return null;
39113
+ const sessionIdRaw = Object.values(sessionRow)[0];
39114
+ sessionId = sessionIdRaw == null ? "" : String(sessionIdRaw);
39067
39115
  }
39068
- if (!sessionRow) return null;
39069
- const sessionIdRaw = Object.values(sessionRow)[0];
39070
- const sessionId = sessionIdRaw == null ? "" : String(sessionIdRaw);
39071
39116
  if (!sessionId) return null;
39072
- const requested = input.providerSessionId || "";
39073
- if (requested && sessionId !== requested) return null;
39074
39117
  const messageRows = db.prepare(src.message_query).all(sessionId);
39075
39118
  if (!messageRows || messageRows.length === 0) return null;
39076
39119
  const mtime = safeMtimeMs(resolved);
@@ -42512,7 +42555,9 @@ var CliProviderInstance = class _CliProviderInstance {
42512
42555
  typeof data.providerSessionId === "string" ? data.providerSessionId : ""
42513
42556
  );
42514
42557
  if (patchedProviderSessionId) {
42515
- this.promoteProviderSessionId(patchedProviderSessionId);
42558
+ this.promoteProviderSessionId(patchedProviderSessionId, {
42559
+ authoritative: data.sessionEvent === "new_session"
42560
+ });
42516
42561
  }
42517
42562
  if (data.sessionEvent === "new_session") {
42518
42563
  this.runtimeMessages = [];
@@ -42807,9 +42852,13 @@ ${effect.notification.body || ""}`.trim();
42807
42852
  }
42808
42853
  return lines.join("\n");
42809
42854
  }
42810
- promoteProviderSessionId(sessionId) {
42855
+ promoteProviderSessionId(sessionId, opts = {}) {
42811
42856
  const nextSessionId = String(sessionId || "").trim();
42812
42857
  if (!nextSessionId || nextSessionId === this.providerSessionId) return;
42858
+ if (this.providerSessionId && !opts.authoritative) {
42859
+ LOG.debug("CLI", `[${this.type}] ignoring non-authoritative session id ${nextSessionId} (bound to ${this.providerSessionId})`);
42860
+ return;
42861
+ }
42813
42862
  const previousHistorySessionId = this.providerSessionId || this.instanceId;
42814
42863
  const previousProviderSessionId = this.providerSessionId;
42815
42864
  this.providerSessionId = nextSessionId;
@@ -46725,23 +46774,30 @@ function loadMessagesForSession(db, sessionId) {
46725
46774
  }
46726
46775
  return out;
46727
46776
  }
46728
- function readSession4(sessionPath) {
46777
+ function readSession4(sessionPath, requestedSessionId) {
46729
46778
  if (!sessionPath) return null;
46730
46779
  if (sessionPath === HERMES_STATE_DB) {
46731
46780
  const db = openDb();
46732
46781
  if (!db) return null;
46733
46782
  try {
46734
- const row = db.prepare(
46735
- `SELECT id, started_at FROM sessions
46736
- WHERE source = 'cli' AND message_count > 0
46737
- ORDER BY started_at DESC LIMIT 1`
46738
- ).get();
46739
- if (!row) return null;
46740
- const messages2 = loadMessagesForSession(db, row.id);
46783
+ const pinned = String(requestedSessionId || "").trim();
46784
+ let sessionId2;
46785
+ if (pinned) {
46786
+ sessionId2 = pinned;
46787
+ } else {
46788
+ const row = db.prepare(
46789
+ `SELECT id, started_at FROM sessions
46790
+ WHERE source = 'cli' AND message_count > 0
46791
+ ORDER BY started_at DESC LIMIT 1`
46792
+ ).get();
46793
+ if (!row) return null;
46794
+ sessionId2 = String(row.id);
46795
+ }
46796
+ const messages2 = loadMessagesForSession(db, sessionId2);
46741
46797
  if (messages2.length === 0) return null;
46742
46798
  return {
46743
46799
  messages: messages2,
46744
- providerSessionId: String(row.id),
46800
+ providerSessionId: sessionId2,
46745
46801
  source: "provider-native",
46746
46802
  sourcePath: sessionPath,
46747
46803
  sourceMtimeMs: statMtimeMs4(sessionPath),
@@ -46813,7 +46869,7 @@ function createNativeHistoryDispatcher(reader) {
46813
46869
  } catch {
46814
46870
  }
46815
46871
  }
46816
- const session = readByReader(reader, sourcePath, sessionId, workspace);
46872
+ const session = readByReader(reader, sourcePath, sessionId, workspace, requestedProviderSid);
46817
46873
  if (!session) return null;
46818
46874
  if (requestedProviderSid && session.providerSessionId && session.providerSessionId !== requestedProviderSid) {
46819
46875
  return null;
@@ -46976,7 +47032,7 @@ function resolveHermesPath(workspace, sessionId) {
46976
47032
  if (!fs24.existsSync(dir)) return null;
46977
47033
  return newestRecentFile2(dir, /^session_.*\.json$/);
46978
47034
  }
46979
- function readByReader(reader, sourcePath, sessionId, workspace) {
47035
+ function readByReader(reader, sourcePath, sessionId, workspace, requestedProviderSid) {
46980
47036
  switch (reader) {
46981
47037
  case "claude-cli":
46982
47038
  return readSession(sourcePath);
@@ -46984,8 +47040,13 @@ function readByReader(reader, sourcePath, sessionId, workspace) {
46984
47040
  return readSession2(sourcePath);
46985
47041
  case "antigravity-cli":
46986
47042
  return readSession3(sourcePath, sessionId || void 0, workspace || void 0);
47043
+ // hermes reads a *shared* state.db and would otherwise pick the newest
47044
+ // source='cli' session, which drifts every read (hermes ≥0.14 writes a
47045
+ // fresh row per internal sub-session). Pass the bound id so it reads
47046
+ // THAT session directly instead of newest-wins. claude/codex resolve a
47047
+ // per-session file upstream, so they need no equivalent pin here.
46987
47048
  case "hermes-cli":
46988
- return readSession4(sourcePath);
47049
+ return readSession4(sourcePath, requestedProviderSid || void 0);
46989
47050
  }
46990
47051
  }
46991
47052
  function cwdAsDashes(cwd) {
@@ -49672,6 +49733,88 @@ var meshCrudHandlers = {
49672
49733
  return { success: false, error: e.message };
49673
49734
  }
49674
49735
  },
49736
+ // Gated WRITE path for `.adhdev/mesh.json` — the sibling of export_mesh_json_config
49737
+ // (which only DRAFTS). Same write/overwrite/dry-run contract as mesh_init's config
49738
+ // writer: defaults to dry-run (no write), never clobbers an existing repo mesh.json
49739
+ // unless overwrite=true, and validates the scaffold before persisting. The scaffold
49740
+ // is built from the machine-local mesh entry (coordinator prompt override/append);
49741
+ // policy/operating-notes are intentionally NOT exported (see buildMeshJsonConfigScaffold).
49742
+ write_mesh_json_config: async (_ctx, args) => {
49743
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
49744
+ if (!meshId) return { success: false, error: "meshId required" };
49745
+ const workspace = typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
49746
+ const write = args?.write === true;
49747
+ const overwrite = args?.overwrite === true;
49748
+ try {
49749
+ const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
49750
+ const mesh = getMesh2(meshId);
49751
+ if (!mesh) return { success: false, error: "Mesh not found" };
49752
+ const {
49753
+ buildMeshJsonConfigScaffold: buildMeshJsonConfigScaffold2,
49754
+ serializeMeshJsonConfigScaffold: serializeMeshJsonConfigScaffold2,
49755
+ loadRepoMeshJsonConfig: loadRepoMeshJsonConfig2,
49756
+ normalizeRepoMeshDeclarativeConfig: normalizeRepoMeshDeclarativeConfig2,
49757
+ MESH_JSON_CONFIG_LOCATIONS: MESH_JSON_CONFIG_LOCATIONS2
49758
+ } = await Promise.resolve().then(() => (init_mesh_json_config(), mesh_json_config_exports));
49759
+ const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync24 } = await import("fs");
49760
+ const { dirname: dirname17, join: join49 } = await import("path");
49761
+ const scaffold = buildMeshJsonConfigScaffold2(mesh);
49762
+ const scaffoldJson = serializeMeshJsonConfigScaffold2(scaffold);
49763
+ const relativePath = MESH_JSON_CONFIG_LOCATIONS2[0];
49764
+ const absolutePath = join49(workspace, relativePath);
49765
+ const validation = normalizeRepoMeshDeclarativeConfig2(scaffold);
49766
+ if (!validation.valid) {
49767
+ return { success: false, meshId, error: `invalid mesh.json scaffold: ${validation.errors.join("; ")}` };
49768
+ }
49769
+ const existing = loadRepoMeshJsonConfig2(workspace);
49770
+ const existingPresent = existing.sourceType === "repo_file" || existing.sourceType === "invalid";
49771
+ if (existingPresent && !overwrite) {
49772
+ return {
49773
+ success: true,
49774
+ meshId,
49775
+ written: false,
49776
+ dryRun: !write,
49777
+ skippedReason: "already_exists",
49778
+ path: absolutePath,
49779
+ relativePath,
49780
+ existing: existing.config,
49781
+ existingSourceType: existing.sourceType,
49782
+ scaffold,
49783
+ scaffoldJson,
49784
+ note: "A repo mesh.json already exists \u2014 kept as-is. Re-run with overwrite=true to replace it (this silently drops operator hand-edits, so present a current-vs-suggested diff first)."
49785
+ };
49786
+ }
49787
+ if (!write) {
49788
+ return {
49789
+ success: true,
49790
+ meshId,
49791
+ written: false,
49792
+ dryRun: true,
49793
+ path: absolutePath,
49794
+ relativePath,
49795
+ scaffold,
49796
+ scaffoldJson,
49797
+ note: "Dry-run: nothing written. Re-run with write=true to persist to the repo (commit target). meshes.json is untouched."
49798
+ };
49799
+ }
49800
+ mkdirSync21(dirname17(absolutePath), { recursive: true });
49801
+ writeFileSync24(absolutePath, `${scaffoldJson}
49802
+ `, "utf-8");
49803
+ return {
49804
+ success: true,
49805
+ meshId,
49806
+ written: true,
49807
+ dryRun: false,
49808
+ path: absolutePath,
49809
+ relativePath,
49810
+ scaffold,
49811
+ scaffoldJson,
49812
+ note: "Wrote .adhdev/mesh.json (repo commit target). Commit it to the repo; meshes.json (machine-local) is unchanged."
49813
+ };
49814
+ } catch (e) {
49815
+ return { success: false, error: e.message };
49816
+ }
49817
+ },
49675
49818
  delete_mesh: async (_ctx, args) => {
49676
49819
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
49677
49820
  if (!meshId) return { success: false, error: "meshId required" };
@@ -50699,8 +50842,11 @@ var import_fs17 = require("fs");
50699
50842
  var import_path12 = require("path");
50700
50843
  init_refine_config();
50701
50844
  init_worktree_bootstrap_config();
50845
+ init_change_impact_config();
50846
+ init_mesh_config();
50702
50847
  var MESH_INIT_REFINE_CONFIG_PATH = MESH_REFINE_CONFIG_LOCATIONS[0];
50703
50848
  var MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH = MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS[0];
50849
+ var MESH_INIT_CHANGE_IMPACT_CONFIG_PATH = CHANGE_IMPACT_CONFIG_LOCATIONS[0];
50704
50850
  var CANDIDATE_STALE_INPUTS = [
50705
50851
  "package-lock.json",
50706
50852
  "pnpm-lock.yaml",
@@ -50782,15 +50928,46 @@ function runMeshInit(mesh, workspace, detected, options = {}) {
50782
50928
  write,
50783
50929
  overwrite
50784
50930
  });
50931
+ const changeImpactLoaded = loadChangeImpactConfig(workspace);
50932
+ const changeImpact = applyConfigSuggestion({
50933
+ workspace,
50934
+ relativePath: MESH_INIT_CHANGE_IMPACT_CONFIG_PATH,
50935
+ existing: changeImpactLoaded.sourceType === "repo_file" ? changeImpactLoaded.config : void 0,
50936
+ suggestedConfig: suggestChangeImpactConfig(workspace).suggestedConfig,
50937
+ validate: (config) => validateChangeImpactConfig(config, MESH_INIT_CHANGE_IMPACT_CONFIG_PATH).valid,
50938
+ write,
50939
+ overwrite
50940
+ });
50785
50941
  const providers = suggestNodeProviderPriority(detected);
50942
+ const refineLoaded = loadMeshRefineConfig(mesh, workspace);
50943
+ const bootstrapLoaded = loadMeshWorktreeBootstrapConfig(mesh, workspace);
50944
+ let magiKindPanels = {};
50945
+ try {
50946
+ magiKindPanels = listMagiKindPanels();
50947
+ } catch {
50948
+ magiKindPanels = {};
50949
+ }
50950
+ const currentConfig2 = {
50951
+ refine: refineLoaded.config,
50952
+ worktreeBootstrap: bootstrapLoaded.config,
50953
+ changeImpact: changeImpactLoaded.sourceType === "repo_file" ? changeImpactLoaded.config : void 0,
50954
+ sourceTypes: {
50955
+ refine: refineLoaded.sourceType,
50956
+ worktreeBootstrap: bootstrapLoaded.sourceType,
50957
+ changeImpact: changeImpactLoaded.sourceType
50958
+ },
50959
+ magiKindPanels
50960
+ };
50786
50961
  return {
50787
50962
  success: true,
50788
50963
  workspace,
50789
50964
  dryRun: !write,
50790
50965
  refine,
50791
50966
  worktreeBootstrap,
50967
+ changeImpact,
50792
50968
  providers,
50793
- note: write ? "Configs written to disk are the execution source of truth; suggestions are scaffold and only take effect once saved. providerPriority is a recommendation \u2014 apply it to node policy via clone/policy update." : "Dry-run: no files written. Re-run with write=true to persist the suggested configs. Heuristic suggestions never execute until saved as repo config."
50969
+ currentConfig: currentConfig2,
50970
+ note: write ? "Configs written to disk are the execution source of truth; suggestions are scaffold and only take effect once saved. providerPriority is a recommendation \u2014 apply it to node policy via clone/policy update. currentConfig echoes what was on disk before this run." : "Dry-run: no files written. Re-run with write=true to persist the suggested configs. Heuristic suggestions never execute until saved as repo config. Use currentConfig to diff current-vs-suggested before overwriting."
50794
50971
  };
50795
50972
  }
50796
50973
  function applyConfigSuggestion(input) {