@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.mjs CHANGED
@@ -404,10 +404,10 @@ function readInjected(value) {
404
404
  }
405
405
  function getDaemonBuildInfo() {
406
406
  if (cached) return cached;
407
- const commit = readInjected(true ? "84f8b9ff2e41b3bbf8375a9e4594c0ec33905b6e" : void 0) ?? "unknown";
408
- const commitShort = readInjected(true ? "84f8b9ff" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
- const version = readInjected(true ? "0.9.82-rc.438" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
- const builtAt = readInjected(true ? "2026-07-01T02:03:18.523Z" : void 0);
407
+ const commit = readInjected(true ? "065287032ac520cf8950f90025e1758b873723b1" : void 0) ?? "unknown";
408
+ const commitShort = readInjected(true ? "06528703" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
409
+ const version = readInjected(true ? "0.9.82-rc.439" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
410
+ const builtAt = readInjected(true ? "2026-07-01T04:55:17.522Z" : void 0);
411
411
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
412
412
  return cached;
413
413
  }
@@ -3498,6 +3498,7 @@ Default branch: \`${mesh.defaultBranch}\`` : ""}`);
3498
3498
  sections.push(TOOLS_SECTION);
3499
3499
  sections.push(TOOL_EXPOSURE_PREFLIGHT_SECTION);
3500
3500
  sections.push(WORKFLOW_SECTION);
3501
+ sections.push(ONBOARDING_SECTION);
3501
3502
  sections.push(buildRulesSection(coordinatorCliType));
3502
3503
  return sections.join("\n\n");
3503
3504
  }
@@ -3530,6 +3531,7 @@ function expandPromptPlaceholders(template, ctx) {
3530
3531
  policy: buildPolicySection(mergeAndNormalizePolicy(void 0, mesh.policy)),
3531
3532
  tools: TOOLS_SECTION,
3532
3533
  workflow: WORKFLOW_SECTION,
3534
+ onboarding: ONBOARDING_SECTION,
3533
3535
  rules: buildRulesSection(coordinatorCliType),
3534
3536
  toolExposurePreflight: TOOL_EXPOSURE_PREFLIGHT_SECTION
3535
3537
  };
@@ -3688,7 +3690,7 @@ function buildRulesSection(coordinatorCliType) {
3688
3690
  - **Never fabricate tool results.** Always call the actual tool.
3689
3691
  - **Keep the user informed.** One or two sentences after each delegation round.${coordinatorNote}`;
3690
3692
  }
3691
- var TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION;
3693
+ var TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION, ONBOARDING_SECTION;
3692
3694
  var init_coordinator_prompt = __esm({
3693
3695
  "src/mesh/coordinator-prompt.ts"() {
3694
3696
  "use strict";
@@ -3717,7 +3719,12 @@ var init_coordinator_prompt = __esm({
3717
3719
  | \`mesh_clone_node\` | Create a worktree node for isolated parallel branch work |
3718
3720
  | \`mesh_refine_node\` | Validate and merge a completed worktree node back into its base branch |
3719
3721
  | \`mesh_remove_node\` | Remove a node (cleans up worktree if applicable) |
3720
- | \`mesh_cleanup_sessions\` | Manually clean up delegated session records for a node |`;
3722
+ | \`mesh_cleanup_sessions\` | Manually clean up delegated session records for a node |
3723
+ | \`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 |
3724
+ | \`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 |
3725
+ | \`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 |
3726
+ | \`mesh_magi_kind_panel_set\` | Bind a task_kind \u2192 MAGI kind-panel slots (machine-local, wholesale replacement \u2014 approve current-vs-new first) |
3727
+ | \`mesh_magi_kind_panel_list\` | List configured task_kind \u2192 MAGI kind-panel slot bindings (machine-local, read-only) |`;
3721
3728
  TOOL_EXPOSURE_PREFLIGHT_SECTION = `## Tool Exposure Preflight
3722
3729
 
3723
3730
  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\`.`;
@@ -3750,6 +3757,28 @@ Follow these recovery rules:
3750
3757
  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.
3751
3758
  3. **If no recovery context**: The stop may be intentional (normal completion). Use \`mesh_read_chat\` once to verify, then move on.
3752
3759
  4. **Always record what happened**: After handling a failure, briefly note the outcome in your report to the user.`;
3760
+ ONBOARDING_SECTION = `## Onboarding / Reinit
3761
+
3762
+ 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.
3763
+
3764
+ **Save scopes \u2014 label every draft with its scope before asking for approval:**
3765
+ - **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.
3766
+ - **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.
3767
+
3768
+ **Guided sequence:**
3769
+ 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.
3770
+ 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.
3771
+ 3. **Approve \u2192 gated write** \u2014 Only after the user approves, call the matching gated-write tool:
3772
+ - repo \`.adhdev/*\` config files \u2192 \`mesh_init\` with \`write=true\` (and \`overwrite=true\` ONLY for domains the user approved replacing).
3773
+ - \`.adhdev/mesh.json\` (coordinator prompt / operating notes) \u2192 \`mesh_write_mesh_json_config\` (write=true, overwrite only if approved).
3774
+ - 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.
3775
+ - machine-local named MAGI panels \u2192 \`mesh_magi_panel_set\`. providerPriority \u2192 apply via node policy update.
3776
+
3777
+ **init vs reinit:**
3778
+ - **\`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.
3779
+ - **\`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.
3780
+
3781
+ `;
3753
3782
  }
3754
3783
  });
3755
3784
 
@@ -28234,6 +28263,16 @@ function callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, his
28234
28263
  const result = fn({
28235
28264
  agentType,
28236
28265
  sessionId: normalizedSessionId,
28266
+ // Arm the native-history executor's session pin guard. When the
28267
+ // instance is already bound to a provider session, pass that id as
28268
+ // `providerSessionId` so the executor rejects any *other* newest
28269
+ // session it would otherwise pick (hermes ≥0.14 creates a fresh
28270
+ // `sessions` row per internal sub-session, so an unpinned
28271
+ // newest-wins query drifts to a different id on every read →
28272
+ // re-bind churn + unbounded history re-hydration). When there is no
28273
+ // bound id yet (first-bind / workspace-only discovery) this is '',
28274
+ // which leaves the guard disarmed so discovery still works.
28275
+ providerSessionId: normalizedSessionId,
28237
28276
  historySessionId: normalizedSessionId,
28238
28277
  workspace,
28239
28278
  format: canonicalHistory?.format,
@@ -38649,24 +38688,28 @@ function executeSqlite(src, input) {
38649
38688
  return null;
38650
38689
  }
38651
38690
  try {
38652
- let sessionRow;
38653
- try {
38654
- const sessionFloorSeconds = typeof input.sessionStartedAtMs === "number" ? Math.floor(input.sessionStartedAtMs / 1e3) : 0;
38655
- const stmt = db.prepare(src.session_query);
38691
+ const requested = input.providerSessionId || "";
38692
+ let sessionId;
38693
+ if (requested) {
38694
+ sessionId = requested;
38695
+ } else {
38696
+ let sessionRow;
38656
38697
  try {
38657
- sessionRow = stmt.get(sessionFloorSeconds);
38698
+ const sessionFloorSeconds = typeof input.sessionStartedAtMs === "number" ? Math.floor(input.sessionStartedAtMs / 1e3) : 0;
38699
+ const stmt = db.prepare(src.session_query);
38700
+ try {
38701
+ sessionRow = stmt.get(sessionFloorSeconds);
38702
+ } catch {
38703
+ sessionRow = stmt.get();
38704
+ }
38658
38705
  } catch {
38659
- sessionRow = stmt.get();
38706
+ return null;
38660
38707
  }
38661
- } catch {
38662
- return null;
38708
+ if (!sessionRow) return null;
38709
+ const sessionIdRaw = Object.values(sessionRow)[0];
38710
+ sessionId = sessionIdRaw == null ? "" : String(sessionIdRaw);
38663
38711
  }
38664
- if (!sessionRow) return null;
38665
- const sessionIdRaw = Object.values(sessionRow)[0];
38666
- const sessionId = sessionIdRaw == null ? "" : String(sessionIdRaw);
38667
38712
  if (!sessionId) return null;
38668
- const requested = input.providerSessionId || "";
38669
- if (requested && sessionId !== requested) return null;
38670
38713
  const messageRows = db.prepare(src.message_query).all(sessionId);
38671
38714
  if (!messageRows || messageRows.length === 0) return null;
38672
38715
  const mtime = safeMtimeMs(resolved);
@@ -42108,7 +42151,9 @@ var CliProviderInstance = class _CliProviderInstance {
42108
42151
  typeof data.providerSessionId === "string" ? data.providerSessionId : ""
42109
42152
  );
42110
42153
  if (patchedProviderSessionId) {
42111
- this.promoteProviderSessionId(patchedProviderSessionId);
42154
+ this.promoteProviderSessionId(patchedProviderSessionId, {
42155
+ authoritative: data.sessionEvent === "new_session"
42156
+ });
42112
42157
  }
42113
42158
  if (data.sessionEvent === "new_session") {
42114
42159
  this.runtimeMessages = [];
@@ -42403,9 +42448,13 @@ ${effect.notification.body || ""}`.trim();
42403
42448
  }
42404
42449
  return lines.join("\n");
42405
42450
  }
42406
- promoteProviderSessionId(sessionId) {
42451
+ promoteProviderSessionId(sessionId, opts = {}) {
42407
42452
  const nextSessionId = String(sessionId || "").trim();
42408
42453
  if (!nextSessionId || nextSessionId === this.providerSessionId) return;
42454
+ if (this.providerSessionId && !opts.authoritative) {
42455
+ LOG.debug("CLI", `[${this.type}] ignoring non-authoritative session id ${nextSessionId} (bound to ${this.providerSessionId})`);
42456
+ return;
42457
+ }
42409
42458
  const previousHistorySessionId = this.providerSessionId || this.instanceId;
42410
42459
  const previousProviderSessionId = this.providerSessionId;
42411
42460
  this.providerSessionId = nextSessionId;
@@ -46326,23 +46375,30 @@ function loadMessagesForSession(db, sessionId) {
46326
46375
  }
46327
46376
  return out;
46328
46377
  }
46329
- function readSession4(sessionPath) {
46378
+ function readSession4(sessionPath, requestedSessionId) {
46330
46379
  if (!sessionPath) return null;
46331
46380
  if (sessionPath === HERMES_STATE_DB) {
46332
46381
  const db = openDb();
46333
46382
  if (!db) return null;
46334
46383
  try {
46335
- const row = db.prepare(
46336
- `SELECT id, started_at FROM sessions
46337
- WHERE source = 'cli' AND message_count > 0
46338
- ORDER BY started_at DESC LIMIT 1`
46339
- ).get();
46340
- if (!row) return null;
46341
- const messages2 = loadMessagesForSession(db, row.id);
46384
+ const pinned = String(requestedSessionId || "").trim();
46385
+ let sessionId2;
46386
+ if (pinned) {
46387
+ sessionId2 = pinned;
46388
+ } else {
46389
+ const row = db.prepare(
46390
+ `SELECT id, started_at FROM sessions
46391
+ WHERE source = 'cli' AND message_count > 0
46392
+ ORDER BY started_at DESC LIMIT 1`
46393
+ ).get();
46394
+ if (!row) return null;
46395
+ sessionId2 = String(row.id);
46396
+ }
46397
+ const messages2 = loadMessagesForSession(db, sessionId2);
46342
46398
  if (messages2.length === 0) return null;
46343
46399
  return {
46344
46400
  messages: messages2,
46345
- providerSessionId: String(row.id),
46401
+ providerSessionId: sessionId2,
46346
46402
  source: "provider-native",
46347
46403
  sourcePath: sessionPath,
46348
46404
  sourceMtimeMs: statMtimeMs4(sessionPath),
@@ -46414,7 +46470,7 @@ function createNativeHistoryDispatcher(reader) {
46414
46470
  } catch {
46415
46471
  }
46416
46472
  }
46417
- const session = readByReader(reader, sourcePath, sessionId, workspace);
46473
+ const session = readByReader(reader, sourcePath, sessionId, workspace, requestedProviderSid);
46418
46474
  if (!session) return null;
46419
46475
  if (requestedProviderSid && session.providerSessionId && session.providerSessionId !== requestedProviderSid) {
46420
46476
  return null;
@@ -46577,7 +46633,7 @@ function resolveHermesPath(workspace, sessionId) {
46577
46633
  if (!fs24.existsSync(dir)) return null;
46578
46634
  return newestRecentFile2(dir, /^session_.*\.json$/);
46579
46635
  }
46580
- function readByReader(reader, sourcePath, sessionId, workspace) {
46636
+ function readByReader(reader, sourcePath, sessionId, workspace, requestedProviderSid) {
46581
46637
  switch (reader) {
46582
46638
  case "claude-cli":
46583
46639
  return readSession(sourcePath);
@@ -46585,8 +46641,13 @@ function readByReader(reader, sourcePath, sessionId, workspace) {
46585
46641
  return readSession2(sourcePath);
46586
46642
  case "antigravity-cli":
46587
46643
  return readSession3(sourcePath, sessionId || void 0, workspace || void 0);
46644
+ // hermes reads a *shared* state.db and would otherwise pick the newest
46645
+ // source='cli' session, which drifts every read (hermes ≥0.14 writes a
46646
+ // fresh row per internal sub-session). Pass the bound id so it reads
46647
+ // THAT session directly instead of newest-wins. claude/codex resolve a
46648
+ // per-session file upstream, so they need no equivalent pin here.
46588
46649
  case "hermes-cli":
46589
- return readSession4(sourcePath);
46650
+ return readSession4(sourcePath, requestedProviderSid || void 0);
46590
46651
  }
46591
46652
  }
46592
46653
  function cwdAsDashes(cwd) {
@@ -49273,6 +49334,88 @@ var meshCrudHandlers = {
49273
49334
  return { success: false, error: e.message };
49274
49335
  }
49275
49336
  },
49337
+ // Gated WRITE path for `.adhdev/mesh.json` — the sibling of export_mesh_json_config
49338
+ // (which only DRAFTS). Same write/overwrite/dry-run contract as mesh_init's config
49339
+ // writer: defaults to dry-run (no write), never clobbers an existing repo mesh.json
49340
+ // unless overwrite=true, and validates the scaffold before persisting. The scaffold
49341
+ // is built from the machine-local mesh entry (coordinator prompt override/append);
49342
+ // policy/operating-notes are intentionally NOT exported (see buildMeshJsonConfigScaffold).
49343
+ write_mesh_json_config: async (_ctx, args) => {
49344
+ const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
49345
+ if (!meshId) return { success: false, error: "meshId required" };
49346
+ const workspace = typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
49347
+ const write = args?.write === true;
49348
+ const overwrite = args?.overwrite === true;
49349
+ try {
49350
+ const { getMesh: getMesh2 } = await Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports));
49351
+ const mesh = getMesh2(meshId);
49352
+ if (!mesh) return { success: false, error: "Mesh not found" };
49353
+ const {
49354
+ buildMeshJsonConfigScaffold: buildMeshJsonConfigScaffold2,
49355
+ serializeMeshJsonConfigScaffold: serializeMeshJsonConfigScaffold2,
49356
+ loadRepoMeshJsonConfig: loadRepoMeshJsonConfig2,
49357
+ normalizeRepoMeshDeclarativeConfig: normalizeRepoMeshDeclarativeConfig2,
49358
+ MESH_JSON_CONFIG_LOCATIONS: MESH_JSON_CONFIG_LOCATIONS2
49359
+ } = await Promise.resolve().then(() => (init_mesh_json_config(), mesh_json_config_exports));
49360
+ const { mkdirSync: mkdirSync21, writeFileSync: writeFileSync24 } = await import("fs");
49361
+ const { dirname: dirname17, join: join49 } = await import("path");
49362
+ const scaffold = buildMeshJsonConfigScaffold2(mesh);
49363
+ const scaffoldJson = serializeMeshJsonConfigScaffold2(scaffold);
49364
+ const relativePath = MESH_JSON_CONFIG_LOCATIONS2[0];
49365
+ const absolutePath = join49(workspace, relativePath);
49366
+ const validation = normalizeRepoMeshDeclarativeConfig2(scaffold);
49367
+ if (!validation.valid) {
49368
+ return { success: false, meshId, error: `invalid mesh.json scaffold: ${validation.errors.join("; ")}` };
49369
+ }
49370
+ const existing = loadRepoMeshJsonConfig2(workspace);
49371
+ const existingPresent = existing.sourceType === "repo_file" || existing.sourceType === "invalid";
49372
+ if (existingPresent && !overwrite) {
49373
+ return {
49374
+ success: true,
49375
+ meshId,
49376
+ written: false,
49377
+ dryRun: !write,
49378
+ skippedReason: "already_exists",
49379
+ path: absolutePath,
49380
+ relativePath,
49381
+ existing: existing.config,
49382
+ existingSourceType: existing.sourceType,
49383
+ scaffold,
49384
+ scaffoldJson,
49385
+ 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)."
49386
+ };
49387
+ }
49388
+ if (!write) {
49389
+ return {
49390
+ success: true,
49391
+ meshId,
49392
+ written: false,
49393
+ dryRun: true,
49394
+ path: absolutePath,
49395
+ relativePath,
49396
+ scaffold,
49397
+ scaffoldJson,
49398
+ note: "Dry-run: nothing written. Re-run with write=true to persist to the repo (commit target). meshes.json is untouched."
49399
+ };
49400
+ }
49401
+ mkdirSync21(dirname17(absolutePath), { recursive: true });
49402
+ writeFileSync24(absolutePath, `${scaffoldJson}
49403
+ `, "utf-8");
49404
+ return {
49405
+ success: true,
49406
+ meshId,
49407
+ written: true,
49408
+ dryRun: false,
49409
+ path: absolutePath,
49410
+ relativePath,
49411
+ scaffold,
49412
+ scaffoldJson,
49413
+ note: "Wrote .adhdev/mesh.json (repo commit target). Commit it to the repo; meshes.json (machine-local) is unchanged."
49414
+ };
49415
+ } catch (e) {
49416
+ return { success: false, error: e.message };
49417
+ }
49418
+ },
49276
49419
  delete_mesh: async (_ctx, args) => {
49277
49420
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
49278
49421
  if (!meshId) return { success: false, error: "meshId required" };
@@ -50298,10 +50441,13 @@ init_mesh_fast_forward();
50298
50441
  // src/mesh/mesh-init.ts
50299
50442
  init_refine_config();
50300
50443
  init_worktree_bootstrap_config();
50444
+ init_change_impact_config();
50445
+ init_mesh_config();
50301
50446
  import { existsSync as existsSync38, mkdirSync as mkdirSync15, writeFileSync as writeFileSync18 } from "fs";
50302
50447
  import { dirname as dirname11, join as join41 } from "path";
50303
50448
  var MESH_INIT_REFINE_CONFIG_PATH = MESH_REFINE_CONFIG_LOCATIONS[0];
50304
50449
  var MESH_INIT_WORKTREE_BOOTSTRAP_CONFIG_PATH = MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS[0];
50450
+ var MESH_INIT_CHANGE_IMPACT_CONFIG_PATH = CHANGE_IMPACT_CONFIG_LOCATIONS[0];
50305
50451
  var CANDIDATE_STALE_INPUTS = [
50306
50452
  "package-lock.json",
50307
50453
  "pnpm-lock.yaml",
@@ -50383,15 +50529,46 @@ function runMeshInit(mesh, workspace, detected, options = {}) {
50383
50529
  write,
50384
50530
  overwrite
50385
50531
  });
50532
+ const changeImpactLoaded = loadChangeImpactConfig(workspace);
50533
+ const changeImpact = applyConfigSuggestion({
50534
+ workspace,
50535
+ relativePath: MESH_INIT_CHANGE_IMPACT_CONFIG_PATH,
50536
+ existing: changeImpactLoaded.sourceType === "repo_file" ? changeImpactLoaded.config : void 0,
50537
+ suggestedConfig: suggestChangeImpactConfig(workspace).suggestedConfig,
50538
+ validate: (config) => validateChangeImpactConfig(config, MESH_INIT_CHANGE_IMPACT_CONFIG_PATH).valid,
50539
+ write,
50540
+ overwrite
50541
+ });
50386
50542
  const providers = suggestNodeProviderPriority(detected);
50543
+ const refineLoaded = loadMeshRefineConfig(mesh, workspace);
50544
+ const bootstrapLoaded = loadMeshWorktreeBootstrapConfig(mesh, workspace);
50545
+ let magiKindPanels = {};
50546
+ try {
50547
+ magiKindPanels = listMagiKindPanels();
50548
+ } catch {
50549
+ magiKindPanels = {};
50550
+ }
50551
+ const currentConfig2 = {
50552
+ refine: refineLoaded.config,
50553
+ worktreeBootstrap: bootstrapLoaded.config,
50554
+ changeImpact: changeImpactLoaded.sourceType === "repo_file" ? changeImpactLoaded.config : void 0,
50555
+ sourceTypes: {
50556
+ refine: refineLoaded.sourceType,
50557
+ worktreeBootstrap: bootstrapLoaded.sourceType,
50558
+ changeImpact: changeImpactLoaded.sourceType
50559
+ },
50560
+ magiKindPanels
50561
+ };
50387
50562
  return {
50388
50563
  success: true,
50389
50564
  workspace,
50390
50565
  dryRun: !write,
50391
50566
  refine,
50392
50567
  worktreeBootstrap,
50568
+ changeImpact,
50393
50569
  providers,
50394
- 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."
50570
+ currentConfig: currentConfig2,
50571
+ 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."
50395
50572
  };
50396
50573
  }
50397
50574
  function applyConfigSuggestion(input) {