@adhdev/daemon-core 1.0.18-rc.16 → 1.0.18-rc.18

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
@@ -30,6 +30,62 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
+ // src/providers/auto-approve-modes.ts
34
+ function isKnownDangerousLaunchArg(arg) {
35
+ const normalized = arg.trim();
36
+ if (KNOWN_DANGEROUS_LAUNCH_ARGS.has(normalized)) return true;
37
+ return normalized.startsWith("--dangerously-skip-permissions=") || normalized.startsWith("--dangerously-bypass-approvals-and-sandbox=");
38
+ }
39
+ function deriveAutoApproveModeRisk(mode) {
40
+ return Array.isArray(mode.launchArgs) && mode.launchArgs.some(isKnownDangerousLaunchArg) ? "dangerous" : mode.risk;
41
+ }
42
+ function inactiveMode(modeId = "") {
43
+ return { active: false, strategy: "pty-parse-default", modeId };
44
+ }
45
+ function resolveConfiguredMode(provider, mode, settings) {
46
+ if (mode.strategy === "post-boot-command") return inactiveMode(mode.id);
47
+ if (settings?.launchedByCoordinator === true && settings.delegatedWorkerDangerousModeAllow !== true && deriveAutoApproveModeRisk(mode) === "dangerous") {
48
+ const fallback = provider.autoApproveModes?.modes.find((candidate) => candidate.strategy === "pty-parse-default" && deriveAutoApproveModeRisk(candidate) !== "dangerous");
49
+ return fallback ? { active: true, strategy: fallback.strategy, modeId: fallback.id } : inactiveMode(mode.id);
50
+ }
51
+ return { active: true, strategy: mode.strategy, modeId: mode.id };
52
+ }
53
+ function resolveProviderAutoApproveMode(provider, settings) {
54
+ const config = provider.autoApproveModes;
55
+ const explicitModeId = settings?.autoApproveMode;
56
+ if (typeof explicitModeId === "string") {
57
+ const mode = config?.modes.find((candidate) => candidate.id === explicitModeId);
58
+ if (!mode) return inactiveMode(explicitModeId);
59
+ return resolveConfiguredMode(provider, mode, settings);
60
+ }
61
+ const explicitLegacy = settings?.autoApprove;
62
+ const providerLegacyDefault = provider.settings?.autoApprove?.default;
63
+ const legacyActive = typeof explicitLegacy === "boolean" ? explicitLegacy : typeof providerLegacyDefault === "boolean" ? providerLegacyDefault : false;
64
+ if (!legacyActive) return inactiveMode();
65
+ if (!config) {
66
+ return { active: true, strategy: "pty-parse-default", modeId: "legacy" };
67
+ }
68
+ const defaultMode = config.modes.find((mode) => mode.id === config.default);
69
+ if (!defaultMode) return inactiveMode(config.default);
70
+ return resolveConfiguredMode(provider, defaultMode, settings);
71
+ }
72
+ function findProviderAutoApproveMode(provider, modeId) {
73
+ return provider?.autoApproveModes?.modes.find((mode) => mode.id === modeId);
74
+ }
75
+ var KNOWN_DANGEROUS_LAUNCH_ARGS;
76
+ var init_auto_approve_modes = __esm({
77
+ "src/providers/auto-approve-modes.ts"() {
78
+ "use strict";
79
+ KNOWN_DANGEROUS_LAUNCH_ARGS = /* @__PURE__ */ new Set([
80
+ "--dangerously-skip-permissions",
81
+ "--dangerously-bypass-approvals-and-sandbox",
82
+ "bypassPermissions",
83
+ "sandbox_mode=danger-full-access",
84
+ "approval_policy=never"
85
+ ]);
86
+ }
87
+ });
88
+
33
89
  // src/repo-mesh-types.ts
34
90
  function normalizeMeshSchedulingStrategy(value) {
35
91
  if (typeof value !== "string") return DEFAULT_MESH_SCHEDULING_STRATEGY;
@@ -116,6 +172,11 @@ function mergeAndNormalizePolicy(base, patch) {
116
172
  } else {
117
173
  delete policy.autoConvergeCodeChange;
118
174
  }
175
+ if (policy.delegatedWorkerDangerousModeAllow === true) {
176
+ policy.delegatedWorkerDangerousModeAllow = true;
177
+ } else {
178
+ delete policy.delegatedWorkerDangerousModeAllow;
179
+ }
119
180
  if (policy.coordinatorIdlePushPolicy === "auto_silent_on_dispatch") {
120
181
  policy.coordinatorIdlePushPolicy = "auto_silent_on_dispatch";
121
182
  } else {
@@ -123,14 +184,38 @@ function mergeAndNormalizePolicy(base, patch) {
123
184
  }
124
185
  return policy;
125
186
  }
126
- function resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy) {
187
+ function resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy, provider, repoConfig, providerType) {
188
+ let enabled = true;
127
189
  if (typeof nodePolicy?.delegatedWorkerAutoApprove === "boolean") {
128
- return nodePolicy.delegatedWorkerAutoApprove;
129
- }
130
- if (typeof meshPolicy?.delegatedWorkerAutoApprove === "boolean") {
131
- return meshPolicy.delegatedWorkerAutoApprove;
132
- }
133
- return true;
190
+ enabled = nodePolicy.delegatedWorkerAutoApprove;
191
+ } else if (typeof meshPolicy?.delegatedWorkerAutoApprove === "boolean") {
192
+ enabled = meshPolicy.delegatedWorkerAutoApprove;
193
+ }
194
+ if (!enabled) return false;
195
+ const modes = provider?.autoApproveModes;
196
+ if (!modes) return true;
197
+ const requestedModeRaw = typeof providerType === "string" ? repoConfig?.providerDefaults?.autoApproveModes?.[providerType.trim()] : void 0;
198
+ const requestedModeId = typeof requestedModeRaw === "string" && requestedModeRaw.trim() ? requestedModeRaw.trim() : "";
199
+ const requestedMode = requestedModeId ? modes.modes.find((mode) => mode.id === requestedModeId) : void 0;
200
+ const selectedMode = requestedMode ?? modes.modes.find((mode) => mode.id === modes.default);
201
+ if (!selectedMode || selectedMode.strategy === "post-boot-command") return false;
202
+ const dangerousAllowed = resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy);
203
+ if (deriveAutoApproveModeRisk(selectedMode) === "dangerous" && !dangerousAllowed) {
204
+ const ptyFallback = modes.modes.find((mode) => mode.strategy === "pty-parse-default" && deriveAutoApproveModeRisk(mode) !== "dangerous");
205
+ return ptyFallback?.id || false;
206
+ }
207
+ return selectedMode.id;
208
+ }
209
+ function resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy) {
210
+ if (typeof nodePolicy?.delegatedWorkerDangerousModeAllow === "boolean") {
211
+ return nodePolicy.delegatedWorkerDangerousModeAllow;
212
+ }
213
+ return meshPolicy?.delegatedWorkerDangerousModeAllow === true;
214
+ }
215
+ function delegatedWorkerAutoApproveSettings(meshPolicy, nodePolicy, provider, repoConfig, providerType) {
216
+ const resolved = resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy, provider, repoConfig, providerType);
217
+ const delegatedWorkerDangerousModeAllow = resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy);
218
+ return typeof resolved === "string" ? { autoApprove: void 0, autoApproveMode: resolved, delegatedWorkerDangerousModeAllow } : { autoApprove: resolved, autoApproveMode: void 0, delegatedWorkerDangerousModeAllow };
134
219
  }
135
220
  function resolveAllowSendKeysDestructive(meshPolicy, nodePolicy) {
136
221
  if (typeof nodePolicy?.allowSendKeysDestructive === "boolean") {
@@ -160,6 +245,7 @@ var MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, MESH_CONVERGE_
160
245
  var init_repo_mesh_types = __esm({
161
246
  "src/repo-mesh-types.ts"() {
162
247
  "use strict";
248
+ init_auto_approve_modes();
163
249
  MESH_SCHEDULING_STRATEGIES = [
164
250
  "first_eligible",
165
251
  "least_loaded",
@@ -187,6 +273,7 @@ var init_repo_mesh_types = __esm({
187
273
  // any specific session manually; that override is preserved per-device.
188
274
  spawnedSessionVisibility: "hidden",
189
275
  delegatedWorkerAutoApprove: true,
276
+ delegatedWorkerDangerousModeAllow: false,
190
277
  sessionCleanupOnNodeRemove: "preserve",
191
278
  // MAGI auto-launches a worker session per pinned replica target with no idle
192
279
  // session; those stay idle-LIVE after their turn. Default ON (stop_and_delete)
@@ -226,6 +313,267 @@ var init_repo_mesh_types = __esm({
226
313
  }
227
314
  });
228
315
 
316
+ // src/config/mesh-json-config.ts
317
+ var mesh_json_config_exports = {};
318
+ __export(mesh_json_config_exports, {
319
+ MESH_JSON_CONFIG_LOCATIONS: () => MESH_JSON_CONFIG_LOCATIONS,
320
+ MESH_JSON_CONFIG_SCHEMA: () => MESH_JSON_CONFIG_SCHEMA,
321
+ MESH_JSON_PROVIDER_DEFAULTS_EXAMPLE: () => MESH_JSON_PROVIDER_DEFAULTS_EXAMPLE,
322
+ applyRepoMeshConfig: () => applyRepoMeshConfig,
323
+ buildMeshJsonConfigScaffold: () => buildMeshJsonConfigScaffold,
324
+ loadRepoMeshJsonConfig: () => loadRepoMeshJsonConfig,
325
+ mergeEffectiveCoordinatorConfig: () => mergeEffectiveCoordinatorConfig,
326
+ mergeEffectiveOperatingNotes: () => mergeEffectiveOperatingNotes,
327
+ normalizeRepoMeshDeclarativeConfig: () => normalizeRepoMeshDeclarativeConfig,
328
+ serializeMeshJsonConfigScaffold: () => serializeMeshJsonConfigScaffold
329
+ });
330
+ function isRecord(value) {
331
+ return !!value && typeof value === "object" && !Array.isArray(value);
332
+ }
333
+ function parseConfigText(path46, text) {
334
+ if (/\.json$/i.test(path46)) return JSON.parse(text);
335
+ return yaml.load(text);
336
+ }
337
+ function normalizeOperatingNote(value) {
338
+ if (!isRecord(value)) return null;
339
+ const text = typeof value.text === "string" ? value.text.trim() : "";
340
+ if (!text) return null;
341
+ const category = value.category === "provider_quirk" || value.category === "pattern_to_avoid" || value.category === "recovery_lesson" ? value.category : void 0;
342
+ return {
343
+ text,
344
+ ...category ? { category } : {},
345
+ ...typeof value.createdAt === "string" ? { createdAt: value.createdAt } : {},
346
+ ...typeof value.sourceCoordinator === "string" ? { sourceCoordinator: value.sourceCoordinator } : {},
347
+ // Operating-notes lifecycle: a repo-declared note may pin itself or set an
348
+ // explicit expiry, same as a runtime-recorded one. Phase 2 (b)/(c): it may
349
+ // also declare supersedes/subjectKey to retire an earlier note or group
350
+ // same-subject notes for folding.
351
+ ...value.pinned === true ? { pinned: true } : {},
352
+ ...typeof value.expiresAt === "string" ? { expiresAt: value.expiresAt } : {},
353
+ ...typeof value.supersedes === "string" ? { supersedes: value.supersedes } : {},
354
+ ...typeof value.subjectKey === "string" ? { subjectKey: value.subjectKey } : {}
355
+ };
356
+ }
357
+ function normalizeRepoMeshDeclarativeConfig(parsed) {
358
+ const errors = [];
359
+ if (!isRecord(parsed)) return { valid: false, errors: ["config must be an object"] };
360
+ if (parsed.version !== 1) {
361
+ return { valid: false, errors: [`version must be 1 (got ${JSON.stringify(parsed.version)})`] };
362
+ }
363
+ const config = { version: 1 };
364
+ if (parsed.coordinator !== void 0) {
365
+ if (isRecord(parsed.coordinator)) {
366
+ const coord = {};
367
+ const c = parsed.coordinator;
368
+ if (typeof c.systemPromptOverride === "string") coord.systemPromptOverride = c.systemPromptOverride;
369
+ if (typeof c.systemPromptAppend === "string") coord.systemPromptAppend = c.systemPromptAppend;
370
+ if (Number.isFinite(Number(c.maxPromptChars))) coord.maxPromptChars = Number(c.maxPromptChars);
371
+ config.coordinator = coord;
372
+ } else {
373
+ errors.push("coordinator must be an object when provided");
374
+ }
375
+ }
376
+ if (parsed.operatingNotes !== void 0) {
377
+ if (Array.isArray(parsed.operatingNotes)) {
378
+ const notes = parsed.operatingNotes.map(normalizeOperatingNote).filter((n) => n !== null);
379
+ if (notes.length) config.operatingNotes = notes;
380
+ } else {
381
+ errors.push("operatingNotes must be an array when provided");
382
+ }
383
+ }
384
+ if (parsed.limits !== void 0) {
385
+ if (isRecord(parsed.limits)) {
386
+ const limits = {};
387
+ if (Number.isFinite(Number(parsed.limits.maxNoteChars))) limits.maxNoteChars = Number(parsed.limits.maxNoteChars);
388
+ if (Number.isFinite(Number(parsed.limits.maxNotes))) limits.maxNotes = Number(parsed.limits.maxNotes);
389
+ if (Object.keys(limits).length) config.limits = limits;
390
+ } else {
391
+ errors.push("limits must be an object when provided");
392
+ }
393
+ }
394
+ if (parsed.providerDefaults !== void 0) {
395
+ if (isRecord(parsed.providerDefaults)) {
396
+ const pd = {};
397
+ const rawModes = parsed.providerDefaults.autoApproveModes;
398
+ if (rawModes !== void 0) {
399
+ if (isRecord(rawModes)) {
400
+ const modes = {};
401
+ for (const [providerType, modeId] of Object.entries(rawModes)) {
402
+ const type = typeof providerType === "string" ? providerType.trim() : "";
403
+ const id = typeof modeId === "string" ? modeId.trim() : "";
404
+ if (type && id) modes[type] = id;
405
+ }
406
+ if (Object.keys(modes).length) pd.autoApproveModes = modes;
407
+ } else {
408
+ errors.push("providerDefaults.autoApproveModes must be an object when provided");
409
+ }
410
+ }
411
+ if (Object.keys(pd).length) config.providerDefaults = pd;
412
+ } else {
413
+ errors.push("providerDefaults must be an object when provided");
414
+ }
415
+ }
416
+ return { valid: true, config, errors };
417
+ }
418
+ function loadRepoMeshJsonConfig(workspace) {
419
+ const bases = [];
420
+ const ws = typeof workspace === "string" ? workspace.trim() : "";
421
+ if (ws) bases.push(ws);
422
+ let cwd = "";
423
+ try {
424
+ cwd = process.cwd();
425
+ } catch {
426
+ }
427
+ if (cwd && cwd !== ws) bases.push(cwd);
428
+ for (const base of bases) {
429
+ for (const relative5 of MESH_JSON_CONFIG_LOCATIONS) {
430
+ const configPath = (0, import_path.join)(base, relative5);
431
+ if (!(0, import_fs.existsSync)(configPath)) continue;
432
+ try {
433
+ const parsed = parseConfigText(configPath, (0, import_fs.readFileSync)(configPath, "utf-8"));
434
+ const result = normalizeRepoMeshDeclarativeConfig(parsed);
435
+ if (!result.valid || !result.config) {
436
+ return { source: relative5, sourceType: "invalid", path: configPath, error: result.errors.join("; ") };
437
+ }
438
+ return { config: result.config, source: relative5, sourceType: "repo_file", path: configPath };
439
+ } catch (error) {
440
+ return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
441
+ }
442
+ }
443
+ }
444
+ return {
445
+ source: "unavailable",
446
+ sourceType: "unavailable",
447
+ error: `No repo mesh config found. Checked: ${MESH_JSON_CONFIG_LOCATIONS.join(", ")}`
448
+ };
449
+ }
450
+ function mergeEffectiveCoordinatorConfig(repoCoord, localCoord) {
451
+ const out = { ...localCoord || {} };
452
+ const localOverride = localCoord?.systemPromptOverride?.trim();
453
+ const repoOverride = repoCoord?.systemPromptOverride?.trim();
454
+ if (localOverride) {
455
+ out.systemPromptOverride = localCoord.systemPromptOverride;
456
+ } else if (repoOverride) {
457
+ out.systemPromptOverride = repoCoord.systemPromptOverride;
458
+ } else {
459
+ delete out.systemPromptOverride;
460
+ }
461
+ const repoAppend = repoCoord?.systemPromptAppend?.trim() ? repoCoord.systemPromptAppend.trim() : "";
462
+ const localAppendRaw = localCoord?.systemPromptAppend ?? localCoord?.systemPromptSuffix;
463
+ const localAppend = localAppendRaw?.trim() ? localAppendRaw.trim() : "";
464
+ const stacked = [repoAppend, localAppend].filter(Boolean).join("\n\n");
465
+ if (stacked) {
466
+ out.systemPromptAppend = stacked;
467
+ delete out.systemPromptSuffix;
468
+ }
469
+ return out;
470
+ }
471
+ function mergeEffectiveOperatingNotes(repoNotes, ledgerNotes) {
472
+ const usable = (notes) => Array.isArray(notes) ? notes.filter((n) => n && typeof n.text === "string" && n.text.trim()) : [];
473
+ const repo = usable(repoNotes);
474
+ const ledger = usable(ledgerNotes);
475
+ const ledgerTexts = new Set(ledger.map((n) => n.text.trim()));
476
+ const repoKept = repo.filter((n) => !ledgerTexts.has(n.text.trim()));
477
+ const merged = [...repoKept, ...ledger];
478
+ return merged.length ? merged : void 0;
479
+ }
480
+ function applyRepoMeshConfig(mesh, repoConfig) {
481
+ if (!repoConfig) return mesh;
482
+ return {
483
+ ...mesh,
484
+ coordinator: mergeEffectiveCoordinatorConfig(repoConfig.coordinator, mesh.coordinator)
485
+ };
486
+ }
487
+ function buildMeshJsonConfigScaffold(mesh) {
488
+ const scaffold = { version: 1 };
489
+ const coord = {};
490
+ const override = mesh.coordinator?.systemPromptOverride;
491
+ if (typeof override === "string" && override.trim()) coord.systemPromptOverride = override;
492
+ const append = mesh.coordinator?.systemPromptAppend ?? mesh.coordinator?.systemPromptSuffix;
493
+ if (typeof append === "string" && append.trim()) coord.systemPromptAppend = append;
494
+ if (Object.keys(coord).length) scaffold.coordinator = coord;
495
+ return scaffold;
496
+ }
497
+ function serializeMeshJsonConfigScaffold(config) {
498
+ return JSON.stringify(config, null, 2);
499
+ }
500
+ var import_fs, import_path, yaml, MESH_JSON_CONFIG_LOCATIONS, MESH_JSON_CONFIG_SCHEMA, MESH_JSON_PROVIDER_DEFAULTS_EXAMPLE;
501
+ var init_mesh_json_config = __esm({
502
+ "src/config/mesh-json-config.ts"() {
503
+ "use strict";
504
+ import_fs = require("fs");
505
+ import_path = require("path");
506
+ yaml = __toESM(require("js-yaml"));
507
+ MESH_JSON_CONFIG_LOCATIONS = [
508
+ ".adhdev/mesh.json",
509
+ ".adhdev/mesh.yaml",
510
+ ".adhdev/mesh.yml"
511
+ ];
512
+ MESH_JSON_CONFIG_SCHEMA = {
513
+ $schema: "https://json-schema.org/draft/2020-12/schema",
514
+ title: "ADHDev Repo Mesh Declarative Config",
515
+ type: "object",
516
+ additionalProperties: false,
517
+ required: ["version"],
518
+ properties: {
519
+ version: { const: 1 },
520
+ coordinator: {
521
+ type: "object",
522
+ additionalProperties: false,
523
+ properties: {
524
+ systemPromptOverride: { type: "string" },
525
+ systemPromptAppend: { type: "string" },
526
+ maxPromptChars: { type: "number", minimum: 1 }
527
+ }
528
+ },
529
+ operatingNotes: {
530
+ type: "array",
531
+ maxItems: 200,
532
+ items: {
533
+ type: "object",
534
+ additionalProperties: false,
535
+ required: ["text"],
536
+ properties: {
537
+ text: { type: "string", minLength: 1 },
538
+ category: { enum: ["provider_quirk", "pattern_to_avoid", "recovery_lesson"] },
539
+ createdAt: { type: "string" },
540
+ sourceCoordinator: { type: "string" }
541
+ }
542
+ }
543
+ },
544
+ limits: {
545
+ type: "object",
546
+ additionalProperties: false,
547
+ properties: {
548
+ maxNoteChars: { type: "number", minimum: 1 },
549
+ maxNotes: { type: "number", minimum: 1 }
550
+ }
551
+ },
552
+ providerDefaults: {
553
+ type: "object",
554
+ additionalProperties: false,
555
+ properties: {
556
+ // providerType → requested auto-approve mode ID. Mode IDs are
557
+ // validated against the live provider spec at resolve time; an
558
+ // unknown ID is ignored (provider default is used), so the schema
559
+ // only constrains the shape (string→string), not the ID values.
560
+ autoApproveModes: {
561
+ type: "object",
562
+ additionalProperties: { type: "string" }
563
+ }
564
+ }
565
+ }
566
+ }
567
+ };
568
+ MESH_JSON_PROVIDER_DEFAULTS_EXAMPLE = {
569
+ autoApproveModes: {
570
+ "claude-cli": "accept-edits",
571
+ "codex-cli": "auto"
572
+ }
573
+ };
574
+ }
575
+ });
576
+
229
577
  // src/git/git-executor.ts
230
578
  var git_executor_exports = {};
231
579
  __export(git_executor_exports, {
@@ -442,10 +790,10 @@ function readInjected(value) {
442
790
  }
443
791
  function getDaemonBuildInfo() {
444
792
  if (cached) return cached;
445
- const commit = readInjected(true ? "74f34080bcd7c145e55fd7e5fd492a40a4942bc4" : void 0) ?? "unknown";
446
- const commitShort = readInjected(true ? "74f34080" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
447
- const version = readInjected(true ? "1.0.18-rc.16" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
448
- const builtAt = readInjected(true ? "2026-07-23T02:29:46.281Z" : void 0);
793
+ const commit = readInjected(true ? "56b83deb250a8ea89ba1a7ec587720e165d20062" : void 0) ?? "unknown";
794
+ const commitShort = readInjected(true ? "56b83deb" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
795
+ const version = readInjected(true ? "1.0.18-rc.18" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
796
+ const builtAt = readInjected(true ? "2026-07-23T06:00:17.638Z" : void 0);
449
797
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
450
798
  return cached;
451
799
  }
@@ -457,14 +805,14 @@ var init_build_info = __esm({
457
805
  });
458
806
 
459
807
  // src/git/change-impact-config.ts
460
- function isRecord(value) {
808
+ function isRecord2(value) {
461
809
  return !!value && typeof value === "object" && !Array.isArray(value);
462
810
  }
463
811
  function isStringArray(value) {
464
812
  return Array.isArray(value) && value.every((v) => typeof v === "string" && v.length > 0);
465
813
  }
466
814
  function validateTarget(value, key2, errors) {
467
- if (!isRecord(value)) {
815
+ if (!isRecord2(value)) {
468
816
  errors.push(`impactTargets.${key2} must be an object`);
469
817
  return void 0;
470
818
  }
@@ -480,7 +828,7 @@ function validateTarget(value, key2, errors) {
480
828
  }
481
829
  function validateChangeImpactConfig(raw, source = "inline") {
482
830
  const errors = [];
483
- if (!isRecord(raw)) {
831
+ if (!isRecord2(raw)) {
484
832
  return { valid: false, errors: [`${source}: config must be an object`] };
485
833
  }
486
834
  const config = {};
@@ -497,7 +845,7 @@ function validateChangeImpactConfig(raw, source = "inline") {
497
845
  else errors.push("nonRuntimeRootFilePatterns must be an array of non-empty strings");
498
846
  }
499
847
  if (raw.impactTargets !== void 0) {
500
- if (!isRecord(raw.impactTargets)) {
848
+ if (!isRecord2(raw.impactTargets)) {
501
849
  errors.push("impactTargets must be an object");
502
850
  } else {
503
851
  const targets = {};
@@ -519,23 +867,23 @@ function validateChangeImpactConfig(raw, source = "inline") {
519
867
  }
520
868
  return { valid: errors.length === 0, errors, config: errors.length === 0 ? config : void 0 };
521
869
  }
522
- function parseConfigText(path46, text) {
870
+ function parseConfigText2(path46, text) {
523
871
  if (/\.json$/i.test(path46)) return JSON.parse(text);
524
- return yaml.load(text);
872
+ return yaml2.load(text);
525
873
  }
526
874
  function loadChangeImpactConfig(repoRoot) {
527
875
  for (const relative5 of CHANGE_IMPACT_CONFIG_LOCATIONS) {
528
- const configPath = (0, import_path.join)(repoRoot, relative5);
529
- if (!(0, import_fs.existsSync)(configPath)) continue;
876
+ const configPath = (0, import_path2.join)(repoRoot, relative5);
877
+ if (!(0, import_fs2.existsSync)(configPath)) continue;
530
878
  try {
531
- const text = (0, import_fs.readFileSync)(configPath, "utf-8");
879
+ const text = (0, import_fs2.readFileSync)(configPath, "utf-8");
532
880
  let mtimeMs = 0;
533
881
  try {
534
- mtimeMs = (0, import_fs.statSync)(configPath).mtimeMs;
882
+ mtimeMs = (0, import_fs2.statSync)(configPath).mtimeMs;
535
883
  } catch {
536
884
  mtimeMs = text.length;
537
885
  }
538
- const parsed = parseConfigText(configPath, text);
886
+ const parsed = parseConfigText2(configPath, text);
539
887
  const validation = validateChangeImpactConfig(parsed, relative5);
540
888
  if (!validation.valid) {
541
889
  return {
@@ -594,7 +942,7 @@ function globToRegExp(pattern) {
594
942
  }
595
943
  function listPackageDirs(packagesRoot) {
596
944
  try {
597
- return (0, import_fs.readdirSync)(packagesRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
945
+ return (0, import_fs2.readdirSync)(packagesRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
598
946
  } catch {
599
947
  return [];
600
948
  }
@@ -604,10 +952,10 @@ function suggestChangeImpactConfig(repoRoot) {
604
952
  const daemon = /* @__PURE__ */ new Set();
605
953
  const web = /* @__PURE__ */ new Set();
606
954
  const unclassified = [];
607
- const roots = ["packages", (0, import_path.join)("oss", "packages")];
955
+ const roots = ["packages", (0, import_path2.join)("oss", "packages")];
608
956
  for (const rel of roots) {
609
- const packagesRoot = (0, import_path.join)(repoRoot, rel);
610
- if (!(0, import_fs.existsSync)(packagesRoot)) continue;
957
+ const packagesRoot = (0, import_path2.join)(repoRoot, rel);
958
+ if (!(0, import_fs2.existsSync)(packagesRoot)) continue;
611
959
  for (const name of listPackageDirs(packagesRoot)) {
612
960
  if (/(^web[-.]|[-.]web$)/i.test(name) || /dashboard|frontend|ui$/i.test(name)) {
613
961
  web.add(name);
@@ -649,13 +997,13 @@ function suggestChangeImpactConfig(repoRoot) {
649
997
  discoveredPackages: { daemon: daemonRuntimePackages, web: webOnlyPackages, unclassified }
650
998
  };
651
999
  }
652
- var import_fs, import_path, yaml, CHANGE_IMPACT_CONFIG_LOCATIONS, CHANGE_IMPACT_CONFIG_SCHEMA;
1000
+ var import_fs2, import_path2, yaml2, CHANGE_IMPACT_CONFIG_LOCATIONS, CHANGE_IMPACT_CONFIG_SCHEMA;
653
1001
  var init_change_impact_config = __esm({
654
1002
  "src/git/change-impact-config.ts"() {
655
1003
  "use strict";
656
- import_fs = require("fs");
657
- import_path = require("path");
658
- yaml = __toESM(require("js-yaml"));
1004
+ import_fs2 = require("fs");
1005
+ import_path2 = require("path");
1006
+ yaml2 = __toESM(require("js-yaml"));
659
1007
  CHANGE_IMPACT_CONFIG_LOCATIONS = [
660
1008
  ".adhdev/change-impact.json",
661
1009
  ".adhdev/change-impact.yaml",
@@ -1740,25 +2088,25 @@ function ensureMachineId(config) {
1740
2088
  }
1741
2089
  function getConfigDir() {
1742
2090
  const override = process.env.ADHDEV_CONFIG_DIR;
1743
- const dir = override && override.trim() ? override.trim() : (0, import_path2.join)((0, import_os.homedir)(), ".adhdev");
1744
- if (!(0, import_fs2.existsSync)(dir)) {
1745
- (0, import_fs2.mkdirSync)(dir, { recursive: true });
2091
+ const dir = override && override.trim() ? override.trim() : (0, import_path3.join)((0, import_os.homedir)(), ".adhdev");
2092
+ if (!(0, import_fs3.existsSync)(dir)) {
2093
+ (0, import_fs3.mkdirSync)(dir, { recursive: true });
1746
2094
  }
1747
2095
  return dir;
1748
2096
  }
1749
2097
  function getDaemonDataDir() {
1750
- const dir = (0, import_path2.join)(getConfigDir(), "daemon");
1751
- if (!(0, import_fs2.existsSync)(dir)) {
1752
- (0, import_fs2.mkdirSync)(dir, { recursive: true });
2098
+ const dir = (0, import_path3.join)(getConfigDir(), "daemon");
2099
+ if (!(0, import_fs3.existsSync)(dir)) {
2100
+ (0, import_fs3.mkdirSync)(dir, { recursive: true });
1753
2101
  }
1754
2102
  return dir;
1755
2103
  }
1756
2104
  function getConfigPath() {
1757
- return (0, import_path2.join)(getConfigDir(), "config.json");
2105
+ return (0, import_path3.join)(getConfigDir(), "config.json");
1758
2106
  }
1759
2107
  function migrateStateToStateFile(raw) {
1760
- const statePath = (0, import_path2.join)(getConfigDir(), "state.json");
1761
- if ((0, import_fs2.existsSync)(statePath)) return;
2108
+ const statePath = (0, import_path3.join)(getConfigDir(), "state.json");
2109
+ if ((0, import_fs3.existsSync)(statePath)) return;
1762
2110
  const recentActivity = Array.isArray(raw.recentActivity) ? raw.recentActivity : [];
1763
2111
  const savedProviderSessions = Array.isArray(raw.savedProviderSessions) ? raw.savedProviderSessions : [];
1764
2112
  const legacySessionReads = isPlainObject(raw.recentSessionReads) ? raw.recentSessionReads : {};
@@ -1778,11 +2126,11 @@ function migrateStateToStateFile(raw) {
1778
2126
  sessionReads: mergedReads,
1779
2127
  sessionReadMarkers: cleanedMarkers
1780
2128
  };
1781
- (0, import_fs2.writeFileSync)(statePath, JSON.stringify(state, null, 2), { encoding: "utf-8", mode: 384 });
2129
+ (0, import_fs3.writeFileSync)(statePath, JSON.stringify(state, null, 2), { encoding: "utf-8", mode: 384 });
1782
2130
  }
1783
2131
  function loadConfig() {
1784
2132
  const configPath = getConfigPath();
1785
- if (!(0, import_fs2.existsSync)(configPath)) {
2133
+ if (!(0, import_fs3.existsSync)(configPath)) {
1786
2134
  const initialized = ensureMachineId({ ...DEFAULT_CONFIG });
1787
2135
  try {
1788
2136
  saveConfig(initialized.config);
@@ -1791,7 +2139,7 @@ function loadConfig() {
1791
2139
  return initialized.config;
1792
2140
  }
1793
2141
  try {
1794
- const raw = (0, import_fs2.readFileSync)(configPath, "utf-8");
2142
+ const raw = (0, import_fs3.readFileSync)(configPath, "utf-8");
1795
2143
  const parsed = JSON.parse(raw);
1796
2144
  migrateStateToStateFile(parsed);
1797
2145
  const normalizedInput = normalizeConfig(parsed);
@@ -1813,12 +2161,12 @@ function saveConfig(config) {
1813
2161
  const configPath = getConfigPath();
1814
2162
  const dir = getConfigDir();
1815
2163
  const normalized = normalizeConfig(config);
1816
- if (!(0, import_fs2.existsSync)(dir)) {
1817
- (0, import_fs2.mkdirSync)(dir, { recursive: true, mode: 448 });
2164
+ if (!(0, import_fs3.existsSync)(dir)) {
2165
+ (0, import_fs3.mkdirSync)(dir, { recursive: true, mode: 448 });
1818
2166
  }
1819
- (0, import_fs2.writeFileSync)(configPath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
2167
+ (0, import_fs3.writeFileSync)(configPath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
1820
2168
  try {
1821
- (0, import_fs2.chmodSync)(configPath, 384);
2169
+ (0, import_fs3.chmodSync)(configPath, 384);
1822
2170
  } catch {
1823
2171
  }
1824
2172
  }
@@ -1845,13 +2193,13 @@ function isSetupComplete() {
1845
2193
  function resetConfig() {
1846
2194
  saveConfig({ ...DEFAULT_CONFIG });
1847
2195
  }
1848
- var import_os, import_path2, import_fs2, import_crypto, DEFAULT_CONFIG, MACHINE_ID_PREFIX;
2196
+ var import_os, import_path3, import_fs3, import_crypto, DEFAULT_CONFIG, MACHINE_ID_PREFIX;
1849
2197
  var init_config = __esm({
1850
2198
  "src/config/config.ts"() {
1851
2199
  "use strict";
1852
2200
  import_os = require("os");
1853
- import_path2 = require("path");
1854
- import_fs2 = require("fs");
2201
+ import_path3 = require("path");
2202
+ import_fs3 = require("fs");
1855
2203
  import_crypto = require("crypto");
1856
2204
  DEFAULT_CONFIG = {
1857
2205
  serverUrl: "https://api.adhf.dev",
@@ -3283,13 +3631,13 @@ __export(mesh_config_exports, {
3283
3631
  updateNode: () => updateNode
3284
3632
  });
3285
3633
  function getMeshConfigPath() {
3286
- return (0, import_path3.join)(getConfigDir(), "meshes.json");
3634
+ return (0, import_path4.join)(getConfigDir(), "meshes.json");
3287
3635
  }
3288
3636
  function loadMeshConfig() {
3289
3637
  const path46 = getMeshConfigPath();
3290
- if (!(0, import_fs3.existsSync)(path46)) return { meshes: [] };
3638
+ if (!(0, import_fs4.existsSync)(path46)) return { meshes: [] };
3291
3639
  try {
3292
- const raw = JSON.parse((0, import_fs3.readFileSync)(path46, "utf-8"));
3640
+ const raw = JSON.parse((0, import_fs4.readFileSync)(path46, "utf-8"));
3293
3641
  if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
3294
3642
  const config = raw;
3295
3643
  const migrated = migrateLoadedMeshConfig(config);
@@ -3367,7 +3715,7 @@ function normalizeCapabilityTags(value) {
3367
3715
  }
3368
3716
  function saveMeshConfig(config) {
3369
3717
  const path46 = getMeshConfigPath();
3370
- (0, import_fs3.writeFileSync)(path46, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
3718
+ (0, import_fs4.writeFileSync)(path46, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
3371
3719
  }
3372
3720
  function normalizeRepoIdentity(remoteUrl) {
3373
3721
  let identity = remoteUrl.trim();
@@ -3796,12 +4144,12 @@ function setDifficultyBrains(map) {
3796
4144
  saveMeshConfig(stored);
3797
4145
  return normalized;
3798
4146
  }
3799
- var import_fs3, import_path3, import_crypto3, mergeMeshPolicy, MAGI_KIND_PANEL_KINDS, MAX_MAGI_KIND_SLOTS;
4147
+ var import_fs4, import_path4, import_crypto3, mergeMeshPolicy, MAGI_KIND_PANEL_KINDS, MAX_MAGI_KIND_SLOTS;
3800
4148
  var init_mesh_config = __esm({
3801
4149
  "src/config/mesh-config.ts"() {
3802
4150
  "use strict";
3803
- import_fs3 = require("fs");
3804
- import_path3 = require("path");
4151
+ import_fs4 = require("fs");
4152
+ import_path4 = require("path");
3805
4153
  import_crypto3 = require("crypto");
3806
4154
  init_hash();
3807
4155
  init_config();
@@ -5118,9 +5466,9 @@ function getPendingEventsPath(meshId, coordinatorDaemonId) {
5118
5466
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
5119
5467
  if (coordinatorDaemonId) {
5120
5468
  const safeDaemon = coordinatorDaemonId.replace(/[^a-zA-Z0-9_-]/g, "_");
5121
- return (0, import_path4.join)(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
5469
+ return (0, import_path5.join)(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
5122
5470
  }
5123
- return (0, import_path4.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
5471
+ return (0, import_path5.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
5124
5472
  }
5125
5473
  function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
5126
5474
  if (!meshId) return [];
@@ -5129,9 +5477,9 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
5129
5477
  const paths = primaryDaemonId ? [getPendingEventsPath(meshId, primaryDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
5130
5478
  const events = [];
5131
5479
  for (const path46 of paths) {
5132
- if (!(0, import_fs4.existsSync)(path46)) continue;
5480
+ if (!(0, import_fs5.existsSync)(path46)) continue;
5133
5481
  try {
5134
- const raw = (0, import_fs4.readFileSync)(path46, "utf-8");
5482
+ const raw = (0, import_fs5.readFileSync)(path46, "utf-8");
5135
5483
  const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
5136
5484
  try {
5137
5485
  return [JSON.parse(line)];
@@ -5221,9 +5569,9 @@ function prunePendingMeshCoordinatorEventsRetention() {
5221
5569
  }
5222
5570
  function trimPendingEventsIfNeeded(path46) {
5223
5571
  try {
5224
- if (!(0, import_fs4.existsSync)(path46)) return;
5225
- if ((0, import_fs4.statSync)(path46).size <= MAX_PENDING_EVENTS_BYTES) return;
5226
- const lines = (0, import_fs4.readFileSync)(path46, "utf-8").split("\n").filter(Boolean);
5572
+ if (!(0, import_fs5.existsSync)(path46)) return;
5573
+ if ((0, import_fs5.statSync)(path46).size <= MAX_PENDING_EVENTS_BYTES) return;
5574
+ const lines = (0, import_fs5.readFileSync)(path46, "utf-8").split("\n").filter(Boolean);
5227
5575
  if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
5228
5576
  const dropped = lines.slice(0, lines.length - MAX_PENDING_EVENTS_KEEP);
5229
5577
  for (const line of dropped) {
@@ -5259,7 +5607,7 @@ function trimPendingEventsIfNeeded(path46) {
5259
5607
  LOG.warn("MeshEvents", `Failed to ledger-record trim-dropped ${event.event} for mesh ${event.meshId}: ${e?.message || e}`);
5260
5608
  }
5261
5609
  }
5262
- (0, import_fs4.writeFileSync)(path46, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
5610
+ (0, import_fs5.writeFileSync)(path46, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
5263
5611
  } catch {
5264
5612
  }
5265
5613
  }
@@ -5371,7 +5719,7 @@ function persistPendingMeshCoordinatorEvent(event) {
5371
5719
  try {
5372
5720
  const path46 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
5373
5721
  trimPendingEventsIfNeeded(path46);
5374
- (0, import_fs4.appendFileSync)(path46, JSON.stringify(event) + "\n", "utf-8");
5722
+ (0, import_fs5.appendFileSync)(path46, JSON.stringify(event) + "\n", "utf-8");
5375
5723
  } catch (e) {
5376
5724
  if (!sqliteOk) throw e;
5377
5725
  LOG.warn("MeshEvents", `JSONL append failed for mesh ${event.meshId}; SQLite holds the event: ${e?.message || e}`);
@@ -5385,20 +5733,20 @@ function persistPendingMeshCoordinatorEvent(event) {
5385
5733
  function atomicDrainFile(path46) {
5386
5734
  const tmpPath = `${path46}.draining`;
5387
5735
  try {
5388
- (0, import_fs4.renameSync)(path46, tmpPath);
5736
+ (0, import_fs5.renameSync)(path46, tmpPath);
5389
5737
  } catch {
5390
5738
  return null;
5391
5739
  }
5392
5740
  try {
5393
- const content = (0, import_fs4.readFileSync)(tmpPath, "utf-8");
5741
+ const content = (0, import_fs5.readFileSync)(tmpPath, "utf-8");
5394
5742
  try {
5395
- (0, import_fs4.unlinkSync)(tmpPath);
5743
+ (0, import_fs5.unlinkSync)(tmpPath);
5396
5744
  } catch {
5397
5745
  }
5398
5746
  return content;
5399
5747
  } catch {
5400
5748
  try {
5401
- (0, import_fs4.unlinkSync)(tmpPath);
5749
+ (0, import_fs5.unlinkSync)(tmpPath);
5402
5750
  } catch {
5403
5751
  }
5404
5752
  return null;
@@ -5407,16 +5755,16 @@ function atomicDrainFile(path46) {
5407
5755
  function selectiveDrainFile(path46, predicate) {
5408
5756
  const tmpPath = `${path46}.draining`;
5409
5757
  try {
5410
- (0, import_fs4.renameSync)(path46, tmpPath);
5758
+ (0, import_fs5.renameSync)(path46, tmpPath);
5411
5759
  } catch {
5412
5760
  return [];
5413
5761
  }
5414
5762
  let content;
5415
5763
  try {
5416
- content = (0, import_fs4.readFileSync)(tmpPath, "utf-8");
5764
+ content = (0, import_fs5.readFileSync)(tmpPath, "utf-8");
5417
5765
  } catch {
5418
5766
  try {
5419
- (0, import_fs4.unlinkSync)(tmpPath);
5767
+ (0, import_fs5.unlinkSync)(tmpPath);
5420
5768
  } catch {
5421
5769
  }
5422
5770
  return [];
@@ -5439,12 +5787,12 @@ function selectiveDrainFile(path46, predicate) {
5439
5787
  }
5440
5788
  try {
5441
5789
  if (keptLines.length > 0) {
5442
- (0, import_fs4.writeFileSync)(path46, keptLines.join("\n") + "\n", "utf-8");
5790
+ (0, import_fs5.writeFileSync)(path46, keptLines.join("\n") + "\n", "utf-8");
5443
5791
  }
5444
- (0, import_fs4.unlinkSync)(tmpPath);
5792
+ (0, import_fs5.unlinkSync)(tmpPath);
5445
5793
  } catch {
5446
5794
  try {
5447
- if ((0, import_fs4.existsSync)(tmpPath) && !(0, import_fs4.existsSync)(path46)) (0, import_fs4.renameSync)(tmpPath, path46);
5795
+ if ((0, import_fs5.existsSync)(tmpPath) && !(0, import_fs5.existsSync)(path46)) (0, import_fs5.renameSync)(tmpPath, path46);
5448
5796
  } catch {
5449
5797
  }
5450
5798
  return [];
@@ -5672,18 +6020,18 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
5672
6020
  }
5673
6021
  const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
5674
6022
  for (const path46 of paths) {
5675
- if ((0, import_fs4.existsSync)(path46)) try {
5676
- (0, import_fs4.unlinkSync)(path46);
6023
+ if ((0, import_fs5.existsSync)(path46)) try {
6024
+ (0, import_fs5.unlinkSync)(path46);
5677
6025
  } catch {
5678
6026
  }
5679
6027
  }
5680
6028
  }
5681
- var import_fs4, import_path4, import_crypto5, REFINE_TERMINAL_EVENTS, meshV2DrainCounters, warnedV2Violations, loggedSqlitePendingDrainFailure, TERMINAL_COMPLETION_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP, PENDING_EVENTS_DRAINED_RETENTION_MS, PENDING_EVENTS_UNDRAINED_RETENTION_MS;
6029
+ var import_fs5, import_path5, import_crypto5, REFINE_TERMINAL_EVENTS, meshV2DrainCounters, warnedV2Violations, loggedSqlitePendingDrainFailure, TERMINAL_COMPLETION_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP, PENDING_EVENTS_DRAINED_RETENTION_MS, PENDING_EVENTS_UNDRAINED_RETENTION_MS;
5682
6030
  var init_mesh_events_pending = __esm({
5683
6031
  "src/mesh/mesh-events-pending.ts"() {
5684
6032
  "use strict";
5685
- import_fs4 = require("fs");
5686
- import_path4 = require("path");
6033
+ import_fs5 = require("fs");
6034
+ import_path5 = require("path");
5687
6035
  import_crypto5 = require("crypto");
5688
6036
  init_logger();
5689
6037
  init_config();
@@ -7034,15 +7382,15 @@ function safeMeshId(meshId) {
7034
7382
  return meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
7035
7383
  }
7036
7384
  function legacyQueuePath(meshId) {
7037
- return (0, import_path5.join)(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
7385
+ return (0, import_path6.join)(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
7038
7386
  }
7039
7387
  function cleanupStrayRootRuntimeDb(canonicalPath) {
7040
7388
  try {
7041
- const strayPath = (0, import_path5.join)(getConfigDir(), "mesh-runtime.db");
7389
+ const strayPath = (0, import_path6.join)(getConfigDir(), "mesh-runtime.db");
7042
7390
  if (strayPath === canonicalPath) return;
7043
- if (!(0, import_fs5.existsSync)(strayPath)) return;
7044
- if ((0, import_fs5.statSync)(strayPath).size !== 0) return;
7045
- (0, import_fs5.unlinkSync)(strayPath);
7391
+ if (!(0, import_fs6.existsSync)(strayPath)) return;
7392
+ if ((0, import_fs6.statSync)(strayPath).size !== 0) return;
7393
+ (0, import_fs6.unlinkSync)(strayPath);
7046
7394
  if (!loggedStrayCleanup) {
7047
7395
  loggedStrayCleanup = true;
7048
7396
  LOG.info("MeshRuntimeStore", `Removed stray 0-byte root mesh-runtime.db at ${strayPath}`);
@@ -7056,17 +7404,17 @@ function cleanupStrayRootRuntimeDb(canonicalPath) {
7056
7404
  }
7057
7405
  function meshRuntimeStorePath() {
7058
7406
  const dir = getLedgerDir();
7059
- const nextPath = (0, import_path5.join)(dir, "mesh-runtime.db");
7407
+ const nextPath = (0, import_path6.join)(dir, "mesh-runtime.db");
7060
7408
  cleanupStrayRootRuntimeDb(nextPath);
7061
- if ((0, import_fs5.existsSync)(nextPath)) return nextPath;
7062
- const legacyPath = (0, import_path5.join)(dir, "beads.db");
7063
- if (!(0, import_fs5.existsSync)(legacyPath)) return nextPath;
7409
+ if ((0, import_fs6.existsSync)(nextPath)) return nextPath;
7410
+ const legacyPath = (0, import_path6.join)(dir, "beads.db");
7411
+ if (!(0, import_fs6.existsSync)(legacyPath)) return nextPath;
7064
7412
  try {
7065
- (0, import_fs5.renameSync)(legacyPath, nextPath);
7413
+ (0, import_fs6.renameSync)(legacyPath, nextPath);
7066
7414
  for (const suffix of ["-wal", "-shm"]) {
7067
7415
  const legacyCompanion = `${legacyPath}${suffix}`;
7068
- if ((0, import_fs5.existsSync)(legacyCompanion)) {
7069
- (0, import_fs5.renameSync)(legacyCompanion, `${nextPath}${suffix}`);
7416
+ if ((0, import_fs6.existsSync)(legacyCompanion)) {
7417
+ (0, import_fs6.renameSync)(legacyCompanion, `${nextPath}${suffix}`);
7070
7418
  }
7071
7419
  }
7072
7420
  } catch (err) {
@@ -7077,7 +7425,7 @@ function meshRuntimeStorePath() {
7077
7425
  `Legacy beads.db\u2192mesh-runtime.db migration failed; using existing DB in-place to avoid data loss: ${err?.message || err}`
7078
7426
  );
7079
7427
  }
7080
- return (0, import_fs5.existsSync)(nextPath) ? nextPath : legacyPath;
7428
+ return (0, import_fs6.existsSync)(nextPath) ? nextPath : legacyPath;
7081
7429
  }
7082
7430
  return nextPath;
7083
7431
  }
@@ -7096,12 +7444,12 @@ function pruneMeshRuntimeRetention() {
7096
7444
  return { ledger: 0, toolCalls: 0, terminalQueue: 0 };
7097
7445
  }
7098
7446
  }
7099
- var import_fs5, import_path5, DatabaseCtor, loggedMigrationFailure, loggedStrayCleanup, MeshRuntimeStore, MESH_EVENT_LEDGER_RETENTION_MS, MESH_TOOL_CALL_LOG_RETENTION_MS, MESH_TERMINAL_QUEUE_RETENTION_MS;
7447
+ var import_fs6, import_path6, DatabaseCtor, loggedMigrationFailure, loggedStrayCleanup, MeshRuntimeStore, MESH_EVENT_LEDGER_RETENTION_MS, MESH_TOOL_CALL_LOG_RETENTION_MS, MESH_TERMINAL_QUEUE_RETENTION_MS;
7100
7448
  var init_mesh_runtime_store = __esm({
7101
7449
  "src/mesh/mesh-runtime-store.ts"() {
7102
7450
  "use strict";
7103
- import_fs5 = require("fs");
7104
- import_path5 = require("path");
7451
+ import_fs6 = require("fs");
7452
+ import_path6 = require("path");
7105
7453
  init_logger();
7106
7454
  init_load_better_sqlite3();
7107
7455
  init_config();
@@ -7132,8 +7480,8 @@ var init_mesh_runtime_store = __esm({
7132
7480
  static WAL_MAX_BYTES = 50 * 1024 * 1024;
7133
7481
  // 50 MB
7134
7482
  constructor(dbPath) {
7135
- const dir = (0, import_path5.dirname)(dbPath);
7136
- if (!(0, import_fs5.existsSync)(dir)) (0, import_fs5.mkdirSync)(dir, { recursive: true });
7483
+ const dir = (0, import_path6.dirname)(dbPath);
7484
+ if (!(0, import_fs6.existsSync)(dir)) (0, import_fs6.mkdirSync)(dir, { recursive: true });
7137
7485
  this.dbPath = dbPath;
7138
7486
  this.db = new (loadDatabaseCtor())(dbPath);
7139
7487
  this.db.pragma("journal_mode = WAL");
@@ -7512,8 +7860,8 @@ var init_mesh_runtime_store = __esm({
7512
7860
  this.walWriteCounter = 0;
7513
7861
  try {
7514
7862
  const walPath = `${this.dbPath}-wal`;
7515
- if (!(0, import_fs5.existsSync)(walPath)) return;
7516
- const size = (0, import_fs5.statSync)(walPath).size;
7863
+ if (!(0, import_fs6.existsSync)(walPath)) return;
7864
+ const size = (0, import_fs6.statSync)(walPath).size;
7517
7865
  if (size < _MeshRuntimeStore.WAL_MAX_BYTES) return;
7518
7866
  process.stderr.write(
7519
7867
  `[adhdev-mesh] WAL file ${Math.round(size / 1024 / 1024)}MB exceeds threshold; forcing checkpoint
@@ -7529,9 +7877,9 @@ var init_mesh_runtime_store = __esm({
7529
7877
  const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
7530
7878
  if (count.count > 0) return;
7531
7879
  const path46 = legacyQueuePath(meshId);
7532
- if (!(0, import_fs5.existsSync)(path46)) return;
7880
+ if (!(0, import_fs6.existsSync)(path46)) return;
7533
7881
  try {
7534
- const entries = JSON.parse((0, import_fs5.readFileSync)(path46, "utf-8"));
7882
+ const entries = JSON.parse((0, import_fs6.readFileSync)(path46, "utf-8"));
7535
7883
  if (!Array.isArray(entries)) return;
7536
7884
  const insert = this.db.prepare(`
7537
7885
  INSERT OR REPLACE INTO mesh_queue (
@@ -8982,41 +9330,41 @@ function isNoteExpired(note, now) {
8982
9330
  return now - created >= ttlDays * MS_PER_DAY;
8983
9331
  }
8984
9332
  function getLedgerDir() {
8985
- const dir = (0, import_path6.join)(getConfigDir(), LEDGER_DIR_NAME);
8986
- if (!(0, import_fs6.existsSync)(dir)) {
8987
- (0, import_fs6.mkdirSync)(dir, { recursive: true, mode: 448 });
9333
+ const dir = (0, import_path7.join)(getConfigDir(), LEDGER_DIR_NAME);
9334
+ if (!(0, import_fs7.existsSync)(dir)) {
9335
+ (0, import_fs7.mkdirSync)(dir, { recursive: true, mode: 448 });
8988
9336
  }
8989
9337
  return dir;
8990
9338
  }
8991
9339
  function getLedgerPath(meshId) {
8992
9340
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
8993
- return (0, import_path6.join)(getLedgerDir(), `${safe}.jsonl`);
9341
+ return (0, import_path7.join)(getLedgerDir(), `${safe}.jsonl`);
8994
9342
  }
8995
9343
  function getRotatedPath(meshId, index) {
8996
9344
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
8997
- return (0, import_path6.join)(getLedgerDir(), `${safe}.${index}.jsonl`);
9345
+ return (0, import_path7.join)(getLedgerDir(), `${safe}.${index}.jsonl`);
8998
9346
  }
8999
9347
  function getArchivePath(meshId) {
9000
9348
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
9001
- return (0, import_path6.join)(getLedgerDir(), `${safe}.archive.jsonl`);
9349
+ return (0, import_path7.join)(getLedgerDir(), `${safe}.archive.jsonl`);
9002
9350
  }
9003
9351
  function getRotatedArchivePath(meshId, index) {
9004
9352
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
9005
- return (0, import_path6.join)(getLedgerDir(), `${safe}.archive.${index}.jsonl`);
9353
+ return (0, import_path7.join)(getLedgerDir(), `${safe}.archive.${index}.jsonl`);
9006
9354
  }
9007
9355
  function getArchivedCountsPath(meshId) {
9008
9356
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
9009
- return (0, import_path6.join)(getLedgerDir(), `${safe}.archived-counts.json`);
9357
+ return (0, import_path7.join)(getLedgerDir(), `${safe}.archived-counts.json`);
9010
9358
  }
9011
9359
  function rotateArchiveFile(meshId, archivePath) {
9012
9360
  let index = 1;
9013
- while ((0, import_fs6.existsSync)(getRotatedArchivePath(meshId, index))) {
9361
+ while ((0, import_fs7.existsSync)(getRotatedArchivePath(meshId, index))) {
9014
9362
  index++;
9015
9363
  if (index > 5) break;
9016
9364
  }
9017
9365
  if (index > 5) index = 5;
9018
9366
  try {
9019
- (0, import_fs6.renameSync)(archivePath, getRotatedArchivePath(meshId, index));
9367
+ (0, import_fs7.renameSync)(archivePath, getRotatedArchivePath(meshId, index));
9020
9368
  } catch (e) {
9021
9369
  process.stderr.write(`[adhdev-mesh] Archive rotation failed for mesh ${meshId}: ${e?.message || e}
9022
9370
  `);
@@ -9024,9 +9372,9 @@ function rotateArchiveFile(meshId, archivePath) {
9024
9372
  }
9025
9373
  function readArchivedCounts(meshId) {
9026
9374
  const path46 = getArchivedCountsPath(meshId);
9027
- if (!(0, import_fs6.existsSync)(path46)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
9375
+ if (!(0, import_fs7.existsSync)(path46)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
9028
9376
  try {
9029
- return JSON.parse((0, import_fs6.readFileSync)(path46, "utf-8"));
9377
+ return JSON.parse((0, import_fs7.readFileSync)(path46, "utf-8"));
9030
9378
  } catch {
9031
9379
  return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
9032
9380
  }
@@ -9042,7 +9390,7 @@ function updateArchivedCounts(meshId, archived) {
9042
9390
  counts.totalArchived += archived.length;
9043
9391
  counts.lastArchivedAt = (/* @__PURE__ */ new Date()).toISOString();
9044
9392
  try {
9045
- (0, import_fs6.writeFileSync)(getArchivedCountsPath(meshId), JSON.stringify(counts), { encoding: "utf-8", mode: 384 });
9393
+ (0, import_fs7.writeFileSync)(getArchivedCountsPath(meshId), JSON.stringify(counts), { encoding: "utf-8", mode: 384 });
9046
9394
  } catch {
9047
9395
  }
9048
9396
  }
@@ -9065,7 +9413,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
9065
9413
  }
9066
9414
  function compactLedger(meshId) {
9067
9415
  const filePath = getLedgerPath(meshId);
9068
- if (!(0, import_fs6.existsSync)(filePath)) return { archivedCount: 0, retainedCount: 0 };
9416
+ if (!(0, import_fs7.existsSync)(filePath)) return { archivedCount: 0, retainedCount: 0 };
9069
9417
  const cutoff = Date.now() - ARCHIVE_TERMINAL_OLDER_THAN_MS;
9070
9418
  const entries = readLedgerEntries(meshId);
9071
9419
  const keep = [];
@@ -9080,11 +9428,11 @@ function compactLedger(meshId) {
9080
9428
  if (archive.length === 0) return { archivedCount: 0, retainedCount: keep.length };
9081
9429
  const archivePath = getArchivePath(meshId);
9082
9430
  try {
9083
- if ((0, import_fs6.existsSync)(archivePath) && (0, import_fs6.statSync)(archivePath).size > 50 * 1024 * 1024) {
9431
+ if ((0, import_fs7.existsSync)(archivePath) && (0, import_fs7.statSync)(archivePath).size > 50 * 1024 * 1024) {
9084
9432
  rotateArchiveFile(meshId, archivePath);
9085
9433
  }
9086
9434
  const archiveLines = archive.map((e) => JSON.stringify(e)).join("\n") + "\n";
9087
- (0, import_fs6.appendFileSync)(archivePath, archiveLines, { encoding: "utf-8", mode: 384 });
9435
+ (0, import_fs7.appendFileSync)(archivePath, archiveLines, { encoding: "utf-8", mode: 384 });
9088
9436
  updateArchivedCounts(meshId, archive);
9089
9437
  } catch (e) {
9090
9438
  process.stderr.write(`[adhdev-mesh] Ledger archive write failed for mesh ${meshId}: ${e?.message || e}
@@ -9093,7 +9441,7 @@ function compactLedger(meshId) {
9093
9441
  }
9094
9442
  try {
9095
9443
  const keepLines = keep.length ? keep.map((e) => JSON.stringify(e)).join("\n") + "\n" : "";
9096
- (0, import_fs6.writeFileSync)(filePath, keepLines, { encoding: "utf-8", mode: 384 });
9444
+ (0, import_fs7.writeFileSync)(filePath, keepLines, { encoding: "utf-8", mode: 384 });
9097
9445
  invalidateLedgerCache(meshId);
9098
9446
  } catch (e) {
9099
9447
  process.stderr.write(`[adhdev-mesh] Ledger compaction rewrite failed for mesh ${meshId}: ${e?.message || e}
@@ -9271,9 +9619,9 @@ function appendLedgerEntry(meshId, partial) {
9271
9619
  ...partial
9272
9620
  };
9273
9621
  const filePath = getLedgerPath(meshId);
9274
- if ((0, import_fs6.existsSync)(filePath)) {
9622
+ if ((0, import_fs7.existsSync)(filePath)) {
9275
9623
  try {
9276
- const stat2 = (0, import_fs6.statSync)(filePath);
9624
+ const stat2 = (0, import_fs7.statSync)(filePath);
9277
9625
  if (stat2.size >= MAX_FILE_SIZE_BYTES) {
9278
9626
  rotateLedgerFile(meshId, filePath);
9279
9627
  } else if (stat2.size >= COMPACT_THRESHOLD_BYTES) {
@@ -9298,7 +9646,7 @@ function appendLedgerEntry(meshId, partial) {
9298
9646
  }
9299
9647
  try {
9300
9648
  const line = JSON.stringify(entry) + "\n";
9301
- (0, import_fs6.appendFileSync)(filePath, line, { encoding: "utf-8", mode: 384 });
9649
+ (0, import_fs7.appendFileSync)(filePath, line, { encoding: "utf-8", mode: 384 });
9302
9650
  invalidateLedgerCache(meshId);
9303
9651
  meshLedgerEvents.emit("append", meshId, entry);
9304
9652
  if (entry.kind === OPERATING_NOTE_KIND || entry.kind === OPERATING_NOTE_TOMBSTONE_KIND) {
@@ -9390,7 +9738,7 @@ function pruneOperatingNotes(meshId, keepLatest = OPERATING_NOTE_KEEP_LATEST) {
9390
9738
  const remaining = readLedgerFile(meshId).filter((e) => !removeIds.includes(e.id));
9391
9739
  const filePath = getLedgerPath(meshId);
9392
9740
  const lines = remaining.length ? remaining.map((e) => JSON.stringify(e)).join("\n") + "\n" : "";
9393
- (0, import_fs6.writeFileSync)(filePath, lines, { encoding: "utf-8", mode: 384 });
9741
+ (0, import_fs7.writeFileSync)(filePath, lines, { encoding: "utf-8", mode: 384 });
9394
9742
  } catch {
9395
9743
  }
9396
9744
  invalidateLedgerCache(meshId);
@@ -9447,7 +9795,7 @@ function appendRemoteLedgerEntries(meshId, entries) {
9447
9795
  }
9448
9796
  try {
9449
9797
  const lines = validEntries.map((e) => JSON.stringify(e)).join("\n") + "\n";
9450
- (0, import_fs6.appendFileSync)(ledgerPath, lines, { encoding: "utf-8", mode: 384 });
9798
+ (0, import_fs7.appendFileSync)(ledgerPath, lines, { encoding: "utf-8", mode: 384 });
9451
9799
  invalidateLedgerCache(meshId);
9452
9800
  for (const entry of validEntries) {
9453
9801
  meshLedgerEvents.emit("append", meshId, entry);
@@ -9459,10 +9807,10 @@ function appendRemoteLedgerEntries(meshId, entries) {
9459
9807
  }
9460
9808
  function readLedgerFile(meshId) {
9461
9809
  const filePath = getLedgerPath(meshId);
9462
- if (!(0, import_fs6.existsSync)(filePath)) return [];
9810
+ if (!(0, import_fs7.existsSync)(filePath)) return [];
9463
9811
  let content;
9464
9812
  try {
9465
- content = (0, import_fs6.readFileSync)(filePath, "utf-8");
9813
+ content = (0, import_fs7.readFileSync)(filePath, "utf-8");
9466
9814
  } catch {
9467
9815
  return [];
9468
9816
  }
@@ -9727,24 +10075,24 @@ function getSessionRecoveryContext(meshId, opts) {
9727
10075
  }
9728
10076
  function rotateLedgerFile(meshId, currentPath) {
9729
10077
  let index = 1;
9730
- while ((0, import_fs6.existsSync)(getRotatedPath(meshId, index))) {
10078
+ while ((0, import_fs7.existsSync)(getRotatedPath(meshId, index))) {
9731
10079
  index++;
9732
10080
  if (index > 10) break;
9733
10081
  }
9734
10082
  if (index > 10) index = 10;
9735
10083
  try {
9736
- (0, import_fs6.renameSync)(currentPath, getRotatedPath(meshId, index));
10084
+ (0, import_fs7.renameSync)(currentPath, getRotatedPath(meshId, index));
9737
10085
  } catch (e) {
9738
10086
  process.stderr.write(`[adhdev-mesh] Ledger rotation failed for mesh ${meshId}: ${e?.message || e}. File will continue to grow.
9739
10087
  `);
9740
10088
  }
9741
10089
  }
9742
- var import_fs6, import_path6, import_crypto8, import_events, LEDGER_DIR_NAME, MAX_FILE_SIZE_BYTES, COMPACT_THRESHOLD_BYTES, ARCHIVE_TERMINAL_OLDER_THAN_MS, RECENT_FAILURE_WINDOW_MS, ARCHIVABLE_KINDS, DEFAULT_LEDGER_SLICE_LIMIT, MAX_LEDGER_SLICE_LIMIT, OPERATING_NOTE_KIND, OPERATING_NOTE_TOMBSTONE_KIND, OPERATING_NOTE_DEDUPE_WINDOW, OPERATING_NOTE_KEEP_LATEST, OPERATING_NOTE_CATEGORY_TTL_DAYS, MS_PER_DAY, meshLedgerEvents, ledgerReadCache, LEDGER_CACHE_TTL_MS, ledgerImportStoreRef, ledgerImportDone;
10090
+ var import_fs7, import_path7, import_crypto8, import_events, LEDGER_DIR_NAME, MAX_FILE_SIZE_BYTES, COMPACT_THRESHOLD_BYTES, ARCHIVE_TERMINAL_OLDER_THAN_MS, RECENT_FAILURE_WINDOW_MS, ARCHIVABLE_KINDS, DEFAULT_LEDGER_SLICE_LIMIT, MAX_LEDGER_SLICE_LIMIT, OPERATING_NOTE_KIND, OPERATING_NOTE_TOMBSTONE_KIND, OPERATING_NOTE_DEDUPE_WINDOW, OPERATING_NOTE_KEEP_LATEST, OPERATING_NOTE_CATEGORY_TTL_DAYS, MS_PER_DAY, meshLedgerEvents, ledgerReadCache, LEDGER_CACHE_TTL_MS, ledgerImportStoreRef, ledgerImportDone;
9743
10091
  var init_mesh_ledger = __esm({
9744
10092
  "src/mesh/mesh-ledger.ts"() {
9745
10093
  "use strict";
9746
- import_fs6 = require("fs");
9747
- import_path6 = require("path");
10094
+ import_fs7 = require("fs");
10095
+ import_path7 = require("path");
9748
10096
  import_crypto8 = require("crypto");
9749
10097
  init_config();
9750
10098
  init_dist();
@@ -11129,13 +11477,13 @@ var init_mesh_coordinator = __esm({
11129
11477
 
11130
11478
  // src/mesh/coordinator-registry.ts
11131
11479
  function getRegistryPath() {
11132
- return (0, import_path7.join)(getDaemonDataDir(), "mesh-coordinators.json");
11480
+ return (0, import_path8.join)(getDaemonDataDir(), "mesh-coordinators.json");
11133
11481
  }
11134
11482
  function loadMeshCoordinatorRegistry() {
11135
11483
  const path46 = getRegistryPath();
11136
- if (!(0, import_fs7.existsSync)(path46)) return;
11484
+ if (!(0, import_fs8.existsSync)(path46)) return;
11137
11485
  try {
11138
- const raw = JSON.parse((0, import_fs7.readFileSync)(path46, "utf-8"));
11486
+ const raw = JSON.parse((0, import_fs8.readFileSync)(path46, "utf-8"));
11139
11487
  if (!Array.isArray(raw)) return;
11140
11488
  _registry.clear();
11141
11489
  for (const entry of raw) {
@@ -11148,7 +11496,7 @@ function loadMeshCoordinatorRegistry() {
11148
11496
  }
11149
11497
  function saveRegistry() {
11150
11498
  try {
11151
- (0, import_fs7.writeFileSync)(
11499
+ (0, import_fs8.writeFileSync)(
11152
11500
  getRegistryPath(),
11153
11501
  JSON.stringify([..._registry.values()], null, 2),
11154
11502
  { encoding: "utf-8", mode: 384 }
@@ -11181,12 +11529,12 @@ function getCoordinatorForSession(sessionId) {
11181
11529
  function listCoordinatorsForWorkspace(workspace) {
11182
11530
  return [..._registry.values()].filter((e) => e.workspace === workspace);
11183
11531
  }
11184
- var import_path7, import_fs7, _registry;
11532
+ var import_path8, import_fs8, _registry;
11185
11533
  var init_coordinator_registry = __esm({
11186
11534
  "src/mesh/coordinator-registry.ts"() {
11187
11535
  "use strict";
11188
- import_path7 = require("path");
11189
- import_fs7 = require("fs");
11536
+ import_path8 = require("path");
11537
+ import_fs8 = require("fs");
11190
11538
  init_config();
11191
11539
  _registry = /* @__PURE__ */ new Map();
11192
11540
  }
@@ -11276,14 +11624,14 @@ function validateMeshRefineConfig(config, source = "inline") {
11276
11624
  const rejectedCommands = [];
11277
11625
  const deprecationWarnings = [];
11278
11626
  let bootstrapMode = "inherit";
11279
- if (!isRecord2(config)) return { valid: false, errors: ["config must be an object"], bootstrapCommands, commands, rejectedCommands, bootstrapMode, deprecationWarnings };
11627
+ if (!isRecord3(config)) return { valid: false, errors: ["config must be an object"], bootstrapCommands, commands, rejectedCommands, bootstrapMode, deprecationWarnings };
11280
11628
  if (config.version !== 1) errors.push("version must be 1");
11281
11629
  if (config.allowAutoPublishSubmoduleMainCommits !== void 0 && typeof config.allowAutoPublishSubmoduleMainCommits !== "boolean") {
11282
11630
  errors.push("allowAutoPublishSubmoduleMainCommits must be a boolean when provided");
11283
11631
  }
11284
11632
  const validation = config.validation;
11285
- if (validation !== void 0 && !isRecord2(validation)) errors.push("validation must be an object");
11286
- const rawBootstrapMode = isRecord2(validation) ? validation.bootstrap : void 0;
11633
+ if (validation !== void 0 && !isRecord3(validation)) errors.push("validation must be an object");
11634
+ const rawBootstrapMode = isRecord3(validation) ? validation.bootstrap : void 0;
11287
11635
  if (rawBootstrapMode !== void 0) {
11288
11636
  if (rawBootstrapMode === "inherit" || rawBootstrapMode === "skip") {
11289
11637
  bootstrapMode = rawBootstrapMode;
@@ -11291,8 +11639,8 @@ function validateMeshRefineConfig(config, source = "inline") {
11291
11639
  errors.push("validation.bootstrap must be 'inherit' or 'skip' when provided");
11292
11640
  }
11293
11641
  }
11294
- const rawCommands = isRecord2(validation) ? validation.commands : void 0;
11295
- const rawBootstrapCommands = isRecord2(validation) ? validation.bootstrapCommands : void 0;
11642
+ const rawCommands = isRecord3(validation) ? validation.commands : void 0;
11643
+ const rawBootstrapCommands = isRecord3(validation) ? validation.bootstrapCommands : void 0;
11296
11644
  if (rawCommands !== void 0 && !Array.isArray(rawCommands)) errors.push("validation.commands must be an array");
11297
11645
  if (rawBootstrapCommands !== void 0 && !Array.isArray(rawBootstrapCommands)) errors.push("validation.bootstrapCommands must be an array");
11298
11646
  if (Array.isArray(rawBootstrapCommands) && rawBootstrapCommands.length > 0) {
@@ -11315,9 +11663,9 @@ function validateMeshRefineConfig(config, source = "inline") {
11315
11663
  if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
11316
11664
  return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands, bootstrapMode, deprecationWarnings };
11317
11665
  }
11318
- function parseConfigText2(path46, text) {
11666
+ function parseConfigText3(path46, text) {
11319
11667
  if (/\.json$/i.test(path46)) return JSON.parse(text);
11320
- return yaml2.load(text);
11668
+ return yaml3.load(text);
11321
11669
  }
11322
11670
  function loadMeshRefineConfig(mesh, workspace) {
11323
11671
  const policy = mesh?.policy && typeof mesh.policy === "object" && !Array.isArray(mesh.policy) ? mesh.policy : {};
@@ -11328,10 +11676,10 @@ function loadMeshRefineConfig(mesh, workspace) {
11328
11676
  return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
11329
11677
  }
11330
11678
  for (const relative5 of MESH_REFINE_CONFIG_LOCATIONS) {
11331
- const configPath = (0, import_path8.join)(workspace, relative5);
11332
- if (!(0, import_fs8.existsSync)(configPath)) continue;
11679
+ const configPath = (0, import_path9.join)(workspace, relative5);
11680
+ if (!(0, import_fs9.existsSync)(configPath)) continue;
11333
11681
  try {
11334
- const parsed = parseConfigText2(configPath, (0, import_fs8.readFileSync)(configPath, "utf-8"));
11682
+ const parsed = parseConfigText3(configPath, (0, import_fs9.readFileSync)(configPath, "utf-8"));
11335
11683
  const validation = validateMeshRefineConfig(parsed, relative5);
11336
11684
  if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
11337
11685
  return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
@@ -11347,20 +11695,20 @@ function loadMeshRefineConfig(mesh, workspace) {
11347
11695
  }
11348
11696
  function readPackageScripts(workspace) {
11349
11697
  try {
11350
- const parsed = JSON.parse((0, import_fs8.readFileSync)((0, import_path8.join)(workspace, "package.json"), "utf-8"));
11351
- return isRecord2(parsed?.scripts) ? parsed.scripts : {};
11698
+ const parsed = JSON.parse((0, import_fs9.readFileSync)((0, import_path9.join)(workspace, "package.json"), "utf-8"));
11699
+ return isRecord3(parsed?.scripts) ? parsed.scripts : {};
11352
11700
  } catch {
11353
11701
  return {};
11354
11702
  }
11355
11703
  }
11356
11704
  function collectProjectContextSuggestions(mesh) {
11357
11705
  const commands = mesh?.projectContext?.commands;
11358
- if (!isRecord2(commands)) return [];
11706
+ if (!isRecord3(commands)) return [];
11359
11707
  const suggestions = [];
11360
11708
  for (const category of MESH_REFINE_VALIDATION_CATEGORIES) {
11361
11709
  const entries = Array.isArray(commands[category]) ? commands[category] : [];
11362
11710
  for (const entry of entries) {
11363
- if (isRecord2(entry) && typeof entry.command === "string") suggestions.push({ command: entry.command, category });
11711
+ if (isRecord3(entry) && typeof entry.command === "string") suggestions.push({ command: entry.command, category });
11364
11712
  }
11365
11713
  }
11366
11714
  return suggestions;
@@ -11422,13 +11770,13 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
11422
11770
  unavailableReason: validation.commands.length ? void 0 : "validation_unavailable: repo mesh/refine config has no validation.commands"
11423
11771
  };
11424
11772
  }
11425
- var import_fs8, import_path8, yaml2, MESH_REFINE_VALIDATION_CATEGORIES, MESH_REFINE_VALIDATION_SCOPES, MESH_REFINE_CONFIG_LOCATIONS, MESH_REFINE_CONFIG_SCHEMA, SHELL_METACHAR_RE, SAFE_TOKEN_RE, SAFE_WIN32_EXEC_TOKEN_RE, isRecord2;
11773
+ var import_fs9, import_path9, yaml3, MESH_REFINE_VALIDATION_CATEGORIES, MESH_REFINE_VALIDATION_SCOPES, MESH_REFINE_CONFIG_LOCATIONS, MESH_REFINE_CONFIG_SCHEMA, SHELL_METACHAR_RE, SAFE_TOKEN_RE, SAFE_WIN32_EXEC_TOKEN_RE, isRecord3;
11426
11774
  var init_refine_config = __esm({
11427
11775
  "src/mesh/refine-config.ts"() {
11428
11776
  "use strict";
11429
- import_fs8 = require("fs");
11430
- import_path8 = require("path");
11431
- yaml2 = __toESM(require("js-yaml"));
11777
+ import_fs9 = require("fs");
11778
+ import_path9 = require("path");
11779
+ yaml3 = __toESM(require("js-yaml"));
11432
11780
  MESH_REFINE_VALIDATION_CATEGORIES = ["typecheck", "test", "lint", "build"];
11433
11781
  MESH_REFINE_VALIDATION_SCOPES = ["none", "web", "daemon"];
11434
11782
  MESH_REFINE_CONFIG_LOCATIONS = [
@@ -11519,7 +11867,7 @@ var init_refine_config = __esm({
11519
11867
  SHELL_METACHAR_RE = /[;&|<>`$\n\r'"]/;
11520
11868
  SAFE_TOKEN_RE = /^[A-Za-z0-9_@./:=+-]+$/;
11521
11869
  SAFE_WIN32_EXEC_TOKEN_RE = /^[A-Za-z0-9_@./:=+\\-]+$/;
11522
- isRecord2 = isMeshConfigRecord;
11870
+ isRecord3 = isMeshConfigRecord;
11523
11871
  }
11524
11872
  });
11525
11873
 
@@ -11538,7 +11886,7 @@ function resolveWin32GlobalBin(trimmed) {
11538
11886
  if (!dir) continue;
11539
11887
  for (const ext of WIN_EXEC_EXT) {
11540
11888
  const full = path10.join(dir, trimmed + ext);
11541
- if ((0, import_fs9.existsSync)(full)) return full;
11889
+ if ((0, import_fs10.existsSync)(full)) return full;
11542
11890
  }
11543
11891
  }
11544
11892
  return null;
@@ -11555,7 +11903,7 @@ function resolveWin32Executable(command) {
11555
11903
  if (process.platform !== "win32") return command;
11556
11904
  const trimmed = (command || "").trim();
11557
11905
  if (!trimmed) return command;
11558
- if (path10.isAbsolute(trimmed) && (0, import_fs9.existsSync)(trimmed)) return trimmed;
11906
+ if (path10.isAbsolute(trimmed) && (0, import_fs10.existsSync)(trimmed)) return trimmed;
11559
11907
  try {
11560
11908
  const out = (0, import_child_process.execFileSync)("where", [trimmed], {
11561
11909
  encoding: "utf8",
@@ -11603,12 +11951,12 @@ function buildWin32ExecFileSpawn(resolvedCommand, args) {
11603
11951
  windowsVerbatimArguments: true
11604
11952
  };
11605
11953
  }
11606
- var import_child_process, import_fs9, path10, DIRECT_EXEC_EXT, SHIM_EXEC_EXT, WIN_EXEC_EXT;
11954
+ var import_child_process, import_fs10, path10, DIRECT_EXEC_EXT, SHIM_EXEC_EXT, WIN_EXEC_EXT;
11607
11955
  var init_resolve_executable = __esm({
11608
11956
  "src/cli-adapters/resolve-executable.ts"() {
11609
11957
  "use strict";
11610
11958
  import_child_process = require("child_process");
11611
- import_fs9 = require("fs");
11959
+ import_fs10 = require("fs");
11612
11960
  path10 = __toESM(require("path"));
11613
11961
  DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
11614
11962
  SHIM_EXEC_EXT = /* @__PURE__ */ new Set([".cmd", ".bat"]);
@@ -11748,7 +12096,7 @@ function isWorktreeBootstrapStaleRunning(node, nowMs = Date.now()) {
11748
12096
  if (!Number.isFinite(startedMs)) return false;
11749
12097
  if (nowMs - startedMs <= WORKTREE_BOOTSTRAP_STALE_RUNNING_MS) return false;
11750
12098
  const workspace = typeof node?.workspace === "string" ? node.workspace.trim() : "";
11751
- if (!workspace || !(0, import_fs10.existsSync)(workspace)) return false;
12099
+ if (!workspace || !(0, import_fs11.existsSync)(workspace)) return false;
11752
12100
  try {
11753
12101
  const out = (0, import_node_child_process3.execFileSync)(resolveWin32Executable("git"), ["status", "--porcelain"], {
11754
12102
  cwd: workspace,
@@ -11769,9 +12117,9 @@ function shouldDeferDispatchForBootstrap(node, nowMs = Date.now()) {
11769
12117
  if (node?.worktreeBootstrap?.status !== "running") return false;
11770
12118
  return !isWorktreeBootstrapStaleRunning(node, nowMs);
11771
12119
  }
11772
- function parseConfigText3(path46, text) {
12120
+ function parseConfigText4(path46, text) {
11773
12121
  if (/\.json$/i.test(path46)) return JSON.parse(text);
11774
- return yaml3.load(text);
12122
+ return yaml4.load(text);
11775
12123
  }
11776
12124
  function truncateOutput(value) {
11777
12125
  const text = typeof value === "string" ? value : value == null ? "" : String(value);
@@ -11811,10 +12159,10 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
11811
12159
  return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
11812
12160
  }
11813
12161
  for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
11814
- const configPath = (0, import_path9.join)(workspace, relative5);
11815
- if (!(0, import_fs10.existsSync)(configPath)) continue;
12162
+ const configPath = (0, import_path10.join)(workspace, relative5);
12163
+ if (!(0, import_fs11.existsSync)(configPath)) continue;
11816
12164
  try {
11817
- const parsed = parseConfigText3(configPath, (0, import_fs10.readFileSync)(configPath, "utf-8"));
12165
+ const parsed = parseConfigText4(configPath, (0, import_fs11.readFileSync)(configPath, "utf-8"));
11818
12166
  const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
11819
12167
  if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
11820
12168
  return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
@@ -11827,9 +12175,9 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
11827
12175
  function computeStaleInputsDigest(workspace, staleInputs) {
11828
12176
  const digest = {};
11829
12177
  for (const relative5 of staleInputs ?? []) {
11830
- const filePath = (0, import_path9.join)(workspace, relative5);
12178
+ const filePath = (0, import_path10.join)(workspace, relative5);
11831
12179
  try {
11832
- digest[relative5] = (0, import_node_crypto2.createHash)("sha256").update((0, import_fs10.readFileSync)(filePath)).digest("hex");
12180
+ digest[relative5] = (0, import_node_crypto2.createHash)("sha256").update((0, import_fs11.readFileSync)(filePath)).digest("hex");
11833
12181
  } catch {
11834
12182
  digest[relative5] = "absent";
11835
12183
  }
@@ -11900,10 +12248,10 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
11900
12248
  staleInputs: loaded.config.staleInputs
11901
12249
  };
11902
12250
  const staleInputPaths = loaded.config.staleInputs ?? [];
11903
- const initiallyAbsent = staleInputPaths.filter((p) => !(0, import_fs10.existsSync)((0, import_path9.join)(workspace, p)));
12251
+ const initiallyAbsent = staleInputPaths.filter((p) => !(0, import_fs11.existsSync)((0, import_path10.join)(workspace, p)));
11904
12252
  for (const command of validation.commands) {
11905
12253
  if (initiallyAbsent.length > 0) {
11906
- const appearedNow = initiallyAbsent.filter((p) => (0, import_fs10.existsSync)((0, import_path9.join)(workspace, p)));
12254
+ const appearedNow = initiallyAbsent.filter((p) => (0, import_fs11.existsSync)((0, import_path10.join)(workspace, p)));
11907
12255
  if (appearedNow.length > 0) {
11908
12256
  state.status = "stale";
11909
12257
  state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -11911,7 +12259,7 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
11911
12259
  return state;
11912
12260
  }
11913
12261
  }
11914
- const cwd = command.cwd ? (0, import_path9.resolve)(workspace, command.cwd) : workspace;
12262
+ const cwd = command.cwd ? (0, import_path10.resolve)(workspace, command.cwd) : workspace;
11915
12263
  const startedAt = Date.now();
11916
12264
  state.lastCommand = command.displayCommand;
11917
12265
  const resolvedCommand = resolveWin32Executable(command.command);
@@ -11971,16 +12319,16 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
11971
12319
  }
11972
12320
  return state;
11973
12321
  }
11974
- var import_fs10, import_path9, import_node_child_process3, import_node_crypto2, import_node_util3, yaml3, WORKTREE_BOOTSTRAP_STALE_RUNNING_MS, SUBMODULE_DEFAULT_BRANCH_FALLBACK, MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS, MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA, DEFAULT_TIMEOUT_MS2, DEFAULT_OUTPUT_LIMIT_BYTES, OUTPUT_SUMMARY_CHARS;
12322
+ var import_fs11, import_path10, import_node_child_process3, import_node_crypto2, import_node_util3, yaml4, WORKTREE_BOOTSTRAP_STALE_RUNNING_MS, SUBMODULE_DEFAULT_BRANCH_FALLBACK, MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS, MESH_WORKTREE_BOOTSTRAP_CONFIG_SCHEMA, DEFAULT_TIMEOUT_MS2, DEFAULT_OUTPUT_LIMIT_BYTES, OUTPUT_SUMMARY_CHARS;
11975
12323
  var init_worktree_bootstrap_config = __esm({
11976
12324
  "src/mesh/worktree-bootstrap-config.ts"() {
11977
12325
  "use strict";
11978
- import_fs10 = require("fs");
11979
- import_path9 = require("path");
12326
+ import_fs11 = require("fs");
12327
+ import_path10 = require("path");
11980
12328
  import_node_child_process3 = require("child_process");
11981
12329
  import_node_crypto2 = require("crypto");
11982
12330
  import_node_util3 = require("util");
11983
- yaml3 = __toESM(require("js-yaml"));
12331
+ yaml4 = __toESM(require("js-yaml"));
11984
12332
  init_resolve_executable();
11985
12333
  init_refine_config();
11986
12334
  WORKTREE_BOOTSTRAP_STALE_RUNNING_MS = 10 * 60 * 1e3;
@@ -12032,224 +12380,6 @@ var init_worktree_bootstrap_config = __esm({
12032
12380
  }
12033
12381
  });
12034
12382
 
12035
- // src/config/mesh-json-config.ts
12036
- var mesh_json_config_exports = {};
12037
- __export(mesh_json_config_exports, {
12038
- MESH_JSON_CONFIG_LOCATIONS: () => MESH_JSON_CONFIG_LOCATIONS,
12039
- MESH_JSON_CONFIG_SCHEMA: () => MESH_JSON_CONFIG_SCHEMA,
12040
- applyRepoMeshConfig: () => applyRepoMeshConfig,
12041
- buildMeshJsonConfigScaffold: () => buildMeshJsonConfigScaffold,
12042
- loadRepoMeshJsonConfig: () => loadRepoMeshJsonConfig,
12043
- mergeEffectiveCoordinatorConfig: () => mergeEffectiveCoordinatorConfig,
12044
- mergeEffectiveOperatingNotes: () => mergeEffectiveOperatingNotes,
12045
- normalizeRepoMeshDeclarativeConfig: () => normalizeRepoMeshDeclarativeConfig,
12046
- serializeMeshJsonConfigScaffold: () => serializeMeshJsonConfigScaffold
12047
- });
12048
- function isRecord3(value) {
12049
- return !!value && typeof value === "object" && !Array.isArray(value);
12050
- }
12051
- function parseConfigText4(path46, text) {
12052
- if (/\.json$/i.test(path46)) return JSON.parse(text);
12053
- return yaml4.load(text);
12054
- }
12055
- function normalizeOperatingNote(value) {
12056
- if (!isRecord3(value)) return null;
12057
- const text = typeof value.text === "string" ? value.text.trim() : "";
12058
- if (!text) return null;
12059
- const category = value.category === "provider_quirk" || value.category === "pattern_to_avoid" || value.category === "recovery_lesson" ? value.category : void 0;
12060
- return {
12061
- text,
12062
- ...category ? { category } : {},
12063
- ...typeof value.createdAt === "string" ? { createdAt: value.createdAt } : {},
12064
- ...typeof value.sourceCoordinator === "string" ? { sourceCoordinator: value.sourceCoordinator } : {},
12065
- // Operating-notes lifecycle: a repo-declared note may pin itself or set an
12066
- // explicit expiry, same as a runtime-recorded one. Phase 2 (b)/(c): it may
12067
- // also declare supersedes/subjectKey to retire an earlier note or group
12068
- // same-subject notes for folding.
12069
- ...value.pinned === true ? { pinned: true } : {},
12070
- ...typeof value.expiresAt === "string" ? { expiresAt: value.expiresAt } : {},
12071
- ...typeof value.supersedes === "string" ? { supersedes: value.supersedes } : {},
12072
- ...typeof value.subjectKey === "string" ? { subjectKey: value.subjectKey } : {}
12073
- };
12074
- }
12075
- function normalizeRepoMeshDeclarativeConfig(parsed) {
12076
- const errors = [];
12077
- if (!isRecord3(parsed)) return { valid: false, errors: ["config must be an object"] };
12078
- if (parsed.version !== 1) {
12079
- return { valid: false, errors: [`version must be 1 (got ${JSON.stringify(parsed.version)})`] };
12080
- }
12081
- const config = { version: 1 };
12082
- if (parsed.coordinator !== void 0) {
12083
- if (isRecord3(parsed.coordinator)) {
12084
- const coord = {};
12085
- const c = parsed.coordinator;
12086
- if (typeof c.systemPromptOverride === "string") coord.systemPromptOverride = c.systemPromptOverride;
12087
- if (typeof c.systemPromptAppend === "string") coord.systemPromptAppend = c.systemPromptAppend;
12088
- if (Number.isFinite(Number(c.maxPromptChars))) coord.maxPromptChars = Number(c.maxPromptChars);
12089
- config.coordinator = coord;
12090
- } else {
12091
- errors.push("coordinator must be an object when provided");
12092
- }
12093
- }
12094
- if (parsed.operatingNotes !== void 0) {
12095
- if (Array.isArray(parsed.operatingNotes)) {
12096
- const notes = parsed.operatingNotes.map(normalizeOperatingNote).filter((n) => n !== null);
12097
- if (notes.length) config.operatingNotes = notes;
12098
- } else {
12099
- errors.push("operatingNotes must be an array when provided");
12100
- }
12101
- }
12102
- if (parsed.limits !== void 0) {
12103
- if (isRecord3(parsed.limits)) {
12104
- const limits = {};
12105
- if (Number.isFinite(Number(parsed.limits.maxNoteChars))) limits.maxNoteChars = Number(parsed.limits.maxNoteChars);
12106
- if (Number.isFinite(Number(parsed.limits.maxNotes))) limits.maxNotes = Number(parsed.limits.maxNotes);
12107
- if (Object.keys(limits).length) config.limits = limits;
12108
- } else {
12109
- errors.push("limits must be an object when provided");
12110
- }
12111
- }
12112
- return { valid: true, config, errors };
12113
- }
12114
- function loadRepoMeshJsonConfig(workspace) {
12115
- const bases = [];
12116
- const ws = typeof workspace === "string" ? workspace.trim() : "";
12117
- if (ws) bases.push(ws);
12118
- let cwd = "";
12119
- try {
12120
- cwd = process.cwd();
12121
- } catch {
12122
- }
12123
- if (cwd && cwd !== ws) bases.push(cwd);
12124
- for (const base of bases) {
12125
- for (const relative5 of MESH_JSON_CONFIG_LOCATIONS) {
12126
- const configPath = (0, import_path10.join)(base, relative5);
12127
- if (!(0, import_fs11.existsSync)(configPath)) continue;
12128
- try {
12129
- const parsed = parseConfigText4(configPath, (0, import_fs11.readFileSync)(configPath, "utf-8"));
12130
- const result = normalizeRepoMeshDeclarativeConfig(parsed);
12131
- if (!result.valid || !result.config) {
12132
- return { source: relative5, sourceType: "invalid", path: configPath, error: result.errors.join("; ") };
12133
- }
12134
- return { config: result.config, source: relative5, sourceType: "repo_file", path: configPath };
12135
- } catch (error) {
12136
- return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
12137
- }
12138
- }
12139
- }
12140
- return {
12141
- source: "unavailable",
12142
- sourceType: "unavailable",
12143
- error: `No repo mesh config found. Checked: ${MESH_JSON_CONFIG_LOCATIONS.join(", ")}`
12144
- };
12145
- }
12146
- function mergeEffectiveCoordinatorConfig(repoCoord, localCoord) {
12147
- const out = { ...localCoord || {} };
12148
- const localOverride = localCoord?.systemPromptOverride?.trim();
12149
- const repoOverride = repoCoord?.systemPromptOverride?.trim();
12150
- if (localOverride) {
12151
- out.systemPromptOverride = localCoord.systemPromptOverride;
12152
- } else if (repoOverride) {
12153
- out.systemPromptOverride = repoCoord.systemPromptOverride;
12154
- } else {
12155
- delete out.systemPromptOverride;
12156
- }
12157
- const repoAppend = repoCoord?.systemPromptAppend?.trim() ? repoCoord.systemPromptAppend.trim() : "";
12158
- const localAppendRaw = localCoord?.systemPromptAppend ?? localCoord?.systemPromptSuffix;
12159
- const localAppend = localAppendRaw?.trim() ? localAppendRaw.trim() : "";
12160
- const stacked = [repoAppend, localAppend].filter(Boolean).join("\n\n");
12161
- if (stacked) {
12162
- out.systemPromptAppend = stacked;
12163
- delete out.systemPromptSuffix;
12164
- }
12165
- return out;
12166
- }
12167
- function mergeEffectiveOperatingNotes(repoNotes, ledgerNotes) {
12168
- const usable = (notes) => Array.isArray(notes) ? notes.filter((n) => n && typeof n.text === "string" && n.text.trim()) : [];
12169
- const repo = usable(repoNotes);
12170
- const ledger = usable(ledgerNotes);
12171
- const ledgerTexts = new Set(ledger.map((n) => n.text.trim()));
12172
- const repoKept = repo.filter((n) => !ledgerTexts.has(n.text.trim()));
12173
- const merged = [...repoKept, ...ledger];
12174
- return merged.length ? merged : void 0;
12175
- }
12176
- function applyRepoMeshConfig(mesh, repoConfig) {
12177
- if (!repoConfig) return mesh;
12178
- return {
12179
- ...mesh,
12180
- coordinator: mergeEffectiveCoordinatorConfig(repoConfig.coordinator, mesh.coordinator)
12181
- };
12182
- }
12183
- function buildMeshJsonConfigScaffold(mesh) {
12184
- const scaffold = { version: 1 };
12185
- const coord = {};
12186
- const override = mesh.coordinator?.systemPromptOverride;
12187
- if (typeof override === "string" && override.trim()) coord.systemPromptOverride = override;
12188
- const append = mesh.coordinator?.systemPromptAppend ?? mesh.coordinator?.systemPromptSuffix;
12189
- if (typeof append === "string" && append.trim()) coord.systemPromptAppend = append;
12190
- if (Object.keys(coord).length) scaffold.coordinator = coord;
12191
- return scaffold;
12192
- }
12193
- function serializeMeshJsonConfigScaffold(config) {
12194
- return JSON.stringify(config, null, 2);
12195
- }
12196
- var import_fs11, import_path10, yaml4, MESH_JSON_CONFIG_LOCATIONS, MESH_JSON_CONFIG_SCHEMA;
12197
- var init_mesh_json_config = __esm({
12198
- "src/config/mesh-json-config.ts"() {
12199
- "use strict";
12200
- import_fs11 = require("fs");
12201
- import_path10 = require("path");
12202
- yaml4 = __toESM(require("js-yaml"));
12203
- MESH_JSON_CONFIG_LOCATIONS = [
12204
- ".adhdev/mesh.json",
12205
- ".adhdev/mesh.yaml",
12206
- ".adhdev/mesh.yml"
12207
- ];
12208
- MESH_JSON_CONFIG_SCHEMA = {
12209
- $schema: "https://json-schema.org/draft/2020-12/schema",
12210
- title: "ADHDev Repo Mesh Declarative Config",
12211
- type: "object",
12212
- additionalProperties: false,
12213
- required: ["version"],
12214
- properties: {
12215
- version: { const: 1 },
12216
- coordinator: {
12217
- type: "object",
12218
- additionalProperties: false,
12219
- properties: {
12220
- systemPromptOverride: { type: "string" },
12221
- systemPromptAppend: { type: "string" },
12222
- maxPromptChars: { type: "number", minimum: 1 }
12223
- }
12224
- },
12225
- operatingNotes: {
12226
- type: "array",
12227
- maxItems: 200,
12228
- items: {
12229
- type: "object",
12230
- additionalProperties: false,
12231
- required: ["text"],
12232
- properties: {
12233
- text: { type: "string", minLength: 1 },
12234
- category: { enum: ["provider_quirk", "pattern_to_avoid", "recovery_lesson"] },
12235
- createdAt: { type: "string" },
12236
- sourceCoordinator: { type: "string" }
12237
- }
12238
- }
12239
- },
12240
- limits: {
12241
- type: "object",
12242
- additionalProperties: false,
12243
- properties: {
12244
- maxNoteChars: { type: "number", minimum: 1 },
12245
- maxNotes: { type: "number", minimum: 1 }
12246
- }
12247
- }
12248
- }
12249
- };
12250
- }
12251
- });
12252
-
12253
12383
  // src/mesh/mesh-fast-forward.ts
12254
12384
  async function fastForwardMeshNode(args) {
12255
12385
  const workspace = typeof args.workspace === "string" ? args.workspace.trim() : "";
@@ -16573,6 +16703,16 @@ function __resetIdleAutoFastForwardForTests() {
16573
16703
  continuousAutoFastForwardLastScan.clear();
16574
16704
  autoFastForwardWorkspaceLease.clear();
16575
16705
  }
16706
+ function loadRepoConfigForNode(node) {
16707
+ const workspace = typeof node?.workspace === "string" && node.workspace.trim() ? node.workspace.trim() : "";
16708
+ if (!workspace) return null;
16709
+ try {
16710
+ const result = loadRepoMeshJsonConfig(workspace);
16711
+ return result.sourceType === "repo_file" && result.config ? result.config : null;
16712
+ } catch {
16713
+ return null;
16714
+ }
16715
+ }
16576
16716
  function getMeshWithCache(components, meshId) {
16577
16717
  const localMesh = getMesh(meshId);
16578
16718
  const cachedMesh = components.router?.getCachedInlineMesh(meshId);
@@ -16832,7 +16972,13 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
16832
16972
  meshNodeFor: meshId,
16833
16973
  meshNodeId: nodeId,
16834
16974
  launchedByCoordinator: true,
16835
- autoApprove: resolveDelegatedWorkerAutoApprove(mesh?.policy, node?.policy),
16975
+ ...delegatedWorkerAutoApproveSettings(
16976
+ mesh?.policy,
16977
+ node?.policy,
16978
+ components.providerLoader?.getMeta(providerType),
16979
+ loadRepoConfigForNode(node),
16980
+ providerType
16981
+ ),
16836
16982
  ...localDaemonId ? { meshCoordinatorDaemonId: localDaemonId } : {},
16837
16983
  // COMPLETION-PROPAGATION F5: (re)stamp the coordinator SESSION anchor from THIS
16838
16984
  // task's sourceCoordinatorSessionId with PRIORITY — a manually-launched (or reused)
@@ -17270,10 +17416,10 @@ function liveSessionCountForNode(components, meshId, nodeId) {
17270
17416
  }
17271
17417
  return count;
17272
17418
  }
17273
- function nodeHasLiveSessionPendingClaim(components, meshId, nodeId) {
17419
+ function nodeHasLiveSessionPendingClaim(components, meshId, nodeId, task, node) {
17274
17420
  if (inWindowAutoLaunchSessionIdsForNode(meshId, nodeId).length > 0) return true;
17275
17421
  const busySessionIds = new Set(
17276
- getQueue(meshId, { status: ["assigned"] }).filter((task) => daemonIdsEquivalent(task.assignedNodeId, nodeId)).map((task) => readNonEmptyString(task.assignedSessionId)).filter(Boolean)
17422
+ getQueue(meshId, { status: ["assigned"] }).filter((task2) => daemonIdsEquivalent(task2.assignedNodeId, nodeId)).map((task2) => readNonEmptyString(task2.assignedSessionId)).filter(Boolean)
17277
17423
  );
17278
17424
  return components.instanceManager.getByCategory("cli").some((inst) => {
17279
17425
  const state = inst.getState();
@@ -17286,6 +17432,12 @@ function nodeHasLiveSessionPendingClaim(components, meshId, nodeId) {
17286
17432
  if (isTerminalSessionStatus(status)) return false;
17287
17433
  const sessionId = readNonEmptyString(state.instanceId);
17288
17434
  if (sessionId && busySessionIds.has(sessionId)) return false;
17435
+ if (task.requiredTags?.length) {
17436
+ const sessionProviderType = state.type || readNonEmptyString(settings.providerType);
17437
+ if (sessionProviderType && !nodeSatisfiesRequiredTags(task.requiredTags, buildMeshNodeCapabilityTags(node, sessionProviderType))) {
17438
+ return false;
17439
+ }
17440
+ }
17289
17441
  return true;
17290
17442
  });
17291
17443
  }
@@ -17566,7 +17718,7 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
17566
17718
  sweepExpiredCooldowns();
17567
17719
  continue;
17568
17720
  }
17569
- if (nodeHasLiveSessionPendingClaim(components, meshId, nodeId)) {
17721
+ if (nodeHasLiveSessionPendingClaim(components, meshId, nodeId, task, node)) {
17570
17722
  markAutoLaunch(meshId, task.id, { status: "skipped", reason: "node_has_live_session_pending_claim", nodeId });
17571
17723
  continue;
17572
17724
  }
@@ -17605,8 +17757,14 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
17605
17757
  spawnedSessionVisibility: mesh?.policy?.spawnedSessionVisibility || "hidden",
17606
17758
  // Coordinator-dispatched worker: auto-approve unless mesh/node policy
17607
17759
  // opts out (default true). Lands in settingsOverride and beats the
17608
- // global per-provider-type autoApprove config (see shouldAutoApprove).
17609
- autoApprove: resolveDelegatedWorkerAutoApprove(mesh?.policy, node?.policy),
17760
+ // global per-provider-type boolean/mode through explicit opposite-key clearing.
17761
+ ...delegatedWorkerAutoApproveSettings(
17762
+ mesh?.policy,
17763
+ node?.policy,
17764
+ components.providerLoader?.getMeta(resolved.providerType),
17765
+ loadRepoConfigForNode(node),
17766
+ resolved.providerType
17767
+ ),
17610
17768
  launchedByCoordinator: true,
17611
17769
  autoLaunchedForQueueTaskId: task.id
17612
17770
  };
@@ -18071,6 +18229,7 @@ var init_mesh_queue_assignment = __esm({
18071
18229
  init_mesh_event_trace();
18072
18230
  init_mesh_warmup_deadline();
18073
18231
  init_repo_mesh_types();
18232
+ init_mesh_json_config();
18074
18233
  init_dist();
18075
18234
  init_mesh_node_slots();
18076
18235
  init_mesh_events_stale();
@@ -20446,6 +20605,7 @@ function buildAvailableProviders(providerLoader) {
20446
20605
  ...provider.lastDetection !== void 0 ? { lastDetection: provider.lastDetection } : {},
20447
20606
  ...provider.lastVerification !== void 0 ? { lastVerification: provider.lastVerification } : {},
20448
20607
  ...provider.meshCoordinator !== void 0 ? { meshCoordinator: provider.meshCoordinator } : {},
20608
+ ...provider.autoApproveModes !== void 0 ? { autoApproveModes: provider.autoApproveModes } : {},
20449
20609
  ...trust ? {
20450
20610
  trust,
20451
20611
  trustDescription: describeTrust2(trust),
@@ -21625,7 +21785,24 @@ function injectMeshSystemMessage(components, args) {
21625
21785
  spawnedSessionVisibility: mesh?.policy?.spawnedSessionVisibility || "hidden",
21626
21786
  // Coordinator-dispatched recovery relaunch: same auto-approve
21627
21787
  // policy as the primary worker launch path.
21628
- autoApprove: resolveDelegatedWorkerAutoApprove(mesh?.policy, node?.policy),
21788
+ ...delegatedWorkerAutoApproveSettings(
21789
+ mesh?.policy,
21790
+ node?.policy,
21791
+ components.providerLoader?.getMeta(recoveryContext.failedProviderType),
21792
+ // Recovery relaunch: same repo-declared requested mode as the
21793
+ // primary path. node.workspace missing → null → provider default.
21794
+ (() => {
21795
+ const ws = typeof node?.workspace === "string" && node.workspace.trim() ? node.workspace.trim() : "";
21796
+ if (!ws) return null;
21797
+ try {
21798
+ const r = loadRepoMeshJsonConfig(ws);
21799
+ return r.sourceType === "repo_file" && r.config ? r.config : null;
21800
+ } catch {
21801
+ return null;
21802
+ }
21803
+ })(),
21804
+ recoveryContext.failedProviderType
21805
+ ),
21629
21806
  launchedByCoordinator: true
21630
21807
  }
21631
21808
  }).catch((e) => LOG.error("MeshRecovery", `Failed to auto-relaunch session for ${node.id}: ${e?.message}`));
@@ -22015,6 +22192,7 @@ var init_mesh_event_forwarding = __esm({
22015
22192
  init_mesh_event_trace();
22016
22193
  init_snapshot();
22017
22194
  init_repo_mesh_types();
22195
+ init_mesh_json_config();
22018
22196
  init_dist();
22019
22197
  init_mesh_events_stale();
22020
22198
  init_mesh_task_inflight();
@@ -24279,6 +24457,20 @@ var init_provider_schema = __esm({
24279
24457
  }
24280
24458
  }
24281
24459
  },
24460
+ autoApproveModes: {
24461
+ type: "object",
24462
+ description: "Provider-specific auto-approve choices and their launch/runtime strategy.",
24463
+ required: ["default", "modes"],
24464
+ additionalProperties: false,
24465
+ properties: {
24466
+ default: { type: "string", minLength: 1 },
24467
+ modes: {
24468
+ type: "array",
24469
+ minItems: 1,
24470
+ items: { $ref: "#/$defs/autoApproveMode" }
24471
+ }
24472
+ }
24473
+ },
24282
24474
  sendDelayMs: {
24283
24475
  type: "number",
24284
24476
  minimum: 0,
@@ -24652,6 +24844,36 @@ var init_provider_schema = __esm({
24652
24844
  }
24653
24845
  },
24654
24846
  $defs: {
24847
+ autoApproveMode: {
24848
+ type: "object",
24849
+ required: ["id", "label", "strategy", "risk"],
24850
+ additionalProperties: false,
24851
+ properties: {
24852
+ id: { type: "string", minLength: 1 },
24853
+ label: { type: "string", minLength: 1 },
24854
+ strategy: { enum: ["pty-parse-default", "launch-args", "post-boot-command"] },
24855
+ risk: { enum: ["safe", "caution", "dangerous"] },
24856
+ warning: { type: "string", minLength: 1 },
24857
+ launchArgs: {
24858
+ type: "array",
24859
+ items: { type: "string", minLength: 1 }
24860
+ },
24861
+ removeArgs: {
24862
+ type: "array",
24863
+ items: { type: "string", minLength: 1 }
24864
+ }
24865
+ },
24866
+ allOf: [
24867
+ {
24868
+ if: { properties: { strategy: { const: "launch-args" } }, required: ["strategy"] },
24869
+ then: { required: ["launchArgs"], properties: { launchArgs: { minItems: 1 } } }
24870
+ },
24871
+ {
24872
+ if: { properties: { risk: { const: "dangerous" } }, required: ["risk"] },
24873
+ then: { required: ["warning"] }
24874
+ }
24875
+ ]
24876
+ },
24655
24877
  patternList: {
24656
24878
  type: "array",
24657
24879
  items: {
@@ -30415,6 +30637,9 @@ __export(index_exports, {
30415
30637
  MAX_LEDGER_SLICE_LIMIT: () => MAX_LEDGER_SLICE_LIMIT,
30416
30638
  MESH_CONVERGE_FAST_FORWARD_TAG: () => MESH_CONVERGE_FAST_FORWARD_TAG,
30417
30639
  MESH_CONVERGE_REFINE_TAG: () => MESH_CONVERGE_REFINE_TAG,
30640
+ MESH_JSON_CONFIG_LOCATIONS: () => MESH_JSON_CONFIG_LOCATIONS,
30641
+ MESH_JSON_CONFIG_SCHEMA: () => MESH_JSON_CONFIG_SCHEMA,
30642
+ MESH_JSON_PROVIDER_DEFAULTS_EXAMPLE: () => MESH_JSON_PROVIDER_DEFAULTS_EXAMPLE,
30418
30643
  MESH_MAX_PARALLEL_TASKS_MAX: () => MESH_MAX_PARALLEL_TASKS_MAX,
30419
30644
  MESH_MAX_PARALLEL_TASKS_MIN: () => MESH_MAX_PARALLEL_TASKS_MIN,
30420
30645
  MESH_MISSION_LIST_HISTORY_ID_LIMIT: () => MESH_MISSION_LIST_HISTORY_ID_LIMIT,
@@ -30474,6 +30699,7 @@ __export(index_exports, {
30474
30699
  buildMeshActiveWorkSummary: () => buildMeshActiveWorkSummary,
30475
30700
  buildMeshAsyncRefineJobs: () => buildMeshAsyncRefineJobs,
30476
30701
  buildMeshHostRequiredFailure: () => buildMeshHostRequiredFailure,
30702
+ buildMeshJsonConfigScaffold: () => buildMeshJsonConfigScaffold,
30477
30703
  buildMeshLedgerReconciliationEvidence: () => buildMeshLedgerReconciliationEvidence,
30478
30704
  buildMeshLedgerReplicaEvidence: () => buildMeshLedgerReplicaEvidence,
30479
30705
  buildMeshMagiActivity: () => buildMeshMagiActivity,
@@ -30524,6 +30750,7 @@ __export(index_exports, {
30524
30750
  createSessionDelivery: () => createSessionDelivery,
30525
30751
  createWorktree: () => createWorktree,
30526
30752
  daemonIdsEquivalent: () => daemonIdsEquivalent,
30753
+ delegatedWorkerAutoApproveSettings: () => delegatedWorkerAutoApproveSettings,
30527
30754
  deleteDirectDispatchesByTaskId: () => deleteDirectDispatchesByTaskId,
30528
30755
  deleteMesh: () => deleteMesh,
30529
30756
  deriveMeshNodeHealthFromGit: () => deriveMeshNodeHealthFromGit,
@@ -30637,6 +30864,7 @@ __export(index_exports, {
30637
30864
  loadMeshCoordinatorRegistry: () => loadMeshCoordinatorRegistry,
30638
30865
  loadMeshRefineConfig: () => loadMeshRefineConfig,
30639
30866
  loadMeshWorktreeBootstrapConfig: () => loadMeshWorktreeBootstrapConfig,
30867
+ loadRepoMeshJsonConfig: () => loadRepoMeshJsonConfig,
30640
30868
  loadRepoSettings: () => loadRepoSettings,
30641
30869
  loadState: () => loadState,
30642
30870
  logCommand: () => logCommand,
@@ -30677,6 +30905,7 @@ __export(index_exports, {
30677
30905
  normalizeMeshWorkerResult: () => normalizeMeshWorkerResult,
30678
30906
  normalizeMessageParts: () => normalizeMessageParts,
30679
30907
  normalizeRepoIdentity: () => normalizeRepoIdentity,
30908
+ normalizeRepoMeshDeclarativeConfig: () => normalizeRepoMeshDeclarativeConfig,
30680
30909
  normalizeSessionModalFields: () => normalizeSessionModalFields,
30681
30910
  parsePorcelainV2Status: () => parsePorcelainV2Status,
30682
30911
  parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
@@ -30723,6 +30952,7 @@ __export(index_exports, {
30723
30952
  resolveCurrentGlobalInstallSurface: () => resolveCurrentGlobalInstallSurface,
30724
30953
  resolveDebugRuntimeConfig: () => resolveDebugRuntimeConfig,
30725
30954
  resolveDelegatedWorkerAutoApprove: () => resolveDelegatedWorkerAutoApprove,
30955
+ resolveDelegatedWorkerDangerousModeAllow: () => resolveDelegatedWorkerDangerousModeAllow,
30726
30956
  resolveDeliveryDecision: () => resolveDeliveryDecision,
30727
30957
  resolveEffectiveMeshNodeHealth: () => resolveEffectiveMeshNodeHealth,
30728
30958
  resolveGitRepository: () => resolveGitRepository,
@@ -30746,6 +30976,7 @@ __export(index_exports, {
30746
30976
  runMeshWorktreeBootstrap: () => runMeshWorktreeBootstrap,
30747
30977
  saveConfig: () => saveConfig,
30748
30978
  saveState: () => saveState,
30979
+ serializeMeshJsonConfigScaffold: () => serializeMeshJsonConfigScaffold,
30749
30980
  serializeV2EnvelopeToWire: () => serializeV2EnvelopeToWire,
30750
30981
  setDebugRuntimeConfig: () => setDebugRuntimeConfig,
30751
30982
  setLogLevel: () => setLogLevel,
@@ -31195,6 +31426,7 @@ function detectClaudeAskUserQuestionPromptFromJson(value, providerType = "claude
31195
31426
 
31196
31427
  // src/index.ts
31197
31428
  init_repo_mesh_types();
31429
+ init_mesh_json_config();
31198
31430
 
31199
31431
  // src/git/index.ts
31200
31432
  init_git_executor();
@@ -49432,6 +49664,7 @@ function formatMarkerTimestamp(timestamp) {
49432
49664
  }
49433
49665
 
49434
49666
  // src/providers/cli-provider-instance.ts
49667
+ init_auto_approve_modes();
49435
49668
  function approvalModalSignature(message, affirmativeAnchor) {
49436
49669
  return [typeof message === "string" ? message.trim() : "", affirmativeAnchor].join("::");
49437
49670
  }
@@ -51412,7 +51645,7 @@ var CliProviderInstance = class _CliProviderInstance {
51412
51645
  * resolveModal, so a plain turn that never saw an approval always returns false.
51413
51646
  */
51414
51647
  inApprovalResumeGrace(now = Date.now()) {
51415
- if (!this.isAutonomousMeshSession() || !this.shouldAutoApprove()) return false;
51648
+ if (!this.isAutonomousMeshSession() || !this.shouldUsePtyAutoApprove()) return false;
51416
51649
  const resolvedAt = typeof this.adapter?.lastApprovalResolvedAt === "number" ? this.adapter.lastApprovalResolvedAt : 0;
51417
51650
  if (resolvedAt <= 0) return false;
51418
51651
  return now - resolvedAt < _CliProviderInstance.APPROVAL_RESUME_GRACE_MS;
@@ -51517,7 +51750,7 @@ var CliProviderInstance = class _CliProviderInstance {
51517
51750
  return;
51518
51751
  }
51519
51752
  const latestStatus = this.adapter.getStatus({ allowParse: false });
51520
- const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldAutoApprove();
51753
+ const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldUsePtyAutoApprove();
51521
51754
  const latestVisibleStatus = latestAutoApproveActive || this.autoApproveBusy ? "generating" : latestStatus.status;
51522
51755
  LOG.debug("CLI", `[${this.type}] flush attempt: adapterStatus=${latestStatus.status} latestVisible=${latestVisibleStatus} generatingStartedAt=${this.generatingStartedAt} isWaitingForResponse=${!!this.adapter?.isWaitingForResponse} hasPartial=${!!this.adapter.getPartialResponse?.()}`);
51523
51756
  if (latestVisibleStatus !== "idle") {
@@ -51787,7 +52020,7 @@ var CliProviderInstance = class _CliProviderInstance {
51787
52020
  * session, where a human answers the prompt, is returned untouched).
51788
52021
  */
51789
52022
  stabilizeFlappingApprovalStatus(adapterStatus, now = Date.now()) {
51790
- if (!this.isAutonomousMeshSession() || !this.shouldAutoApprove()) return adapterStatus;
52023
+ if (!this.isAutonomousMeshSession() || !this.shouldUsePtyAutoApprove()) return adapterStatus;
51791
52024
  const rawStatus = adapterStatus?.status;
51792
52025
  const resolvedAt = typeof this.adapter?.lastApprovalResolvedAt === "number" ? this.adapter.lastApprovalResolvedAt : 0;
51793
52026
  if (rawStatus === "waiting_approval") {
@@ -51817,7 +52050,11 @@ var CliProviderInstance = class _CliProviderInstance {
51817
52050
  return adapterStatus;
51818
52051
  }
51819
52052
  maybeAutoApproveStatus(adapterStatus, now = Date.now()) {
51820
- if (adapterStatus?.status === "waiting_approval" && this.shouldAutoApprove() && this.manualAttendance.isAttended(now)) {
52053
+ if (!this.shouldUsePtyAutoApprove()) {
52054
+ this.resetPtyAutoApproveState();
52055
+ return false;
52056
+ }
52057
+ if (adapterStatus?.status === "waiting_approval" && this.shouldUsePtyAutoApprove() && this.manualAttendance.isAttended(now)) {
51821
52058
  this.lastAutoApprovalSignature = "";
51822
52059
  this.pendingAutoApprovalSignature = "";
51823
52060
  this.pendingAutoApprovalSince = 0;
@@ -51832,7 +52069,7 @@ var CliProviderInstance = class _CliProviderInstance {
51832
52069
  }, this.manualAttendance.remainingMs(now) + 20);
51833
52070
  return false;
51834
52071
  }
51835
- const autoApproveActive = adapterStatus?.status === "waiting_approval" && this.shouldAutoApprove();
52072
+ const autoApproveActive = adapterStatus?.status === "waiting_approval" && this.shouldUsePtyAutoApprove();
51836
52073
  if (!autoApproveActive) {
51837
52074
  this.lastAutoApprovalSignature = "";
51838
52075
  if (this.pendingAutoApprovalSince) {
@@ -52527,15 +52764,34 @@ ${buttons.join("\n")}`;
52527
52764
  get cliName() {
52528
52765
  return this.provider.name;
52529
52766
  }
52767
+ resolveAutoApproveMode() {
52768
+ return resolveProviderAutoApproveMode(this.provider, this.settings);
52769
+ }
52770
+ /** Legacy boolean view retained for internal/test compatibility. */
52530
52771
  shouldAutoApprove() {
52531
- if (typeof this.settings.autoApprove === "boolean") {
52532
- return this.settings.autoApprove;
52772
+ return this.resolveAutoApproveMode().active;
52773
+ }
52774
+ shouldUsePtyAutoApprove() {
52775
+ const resolved = this.resolveAutoApproveMode();
52776
+ return this.shouldAutoApprove() && resolved.strategy === "pty-parse-default";
52777
+ }
52778
+ resetPtyAutoApproveState() {
52779
+ this.lastAutoApprovalSignature = "";
52780
+ this.pendingAutoApprovalSignature = "";
52781
+ this.pendingAutoApprovalSince = 0;
52782
+ this.autoApproveInactiveSince = 0;
52783
+ this.autoApproveMaskSince = 0;
52784
+ this.stalledApprovalNudgeEpisode = 0;
52785
+ this.autoApproveLastModalSeenAt = 0;
52786
+ this.autoApproveBusy = false;
52787
+ if (this.autoApproveSettleTimer) {
52788
+ clearTimeout(this.autoApproveSettleTimer);
52789
+ this.autoApproveSettleTimer = null;
52533
52790
  }
52534
- const providerDefault = this.provider.settings?.autoApprove?.default;
52535
- if (typeof providerDefault === "boolean") {
52536
- return providerDefault;
52791
+ if (this.autoApproveBusyTimer) {
52792
+ clearTimeout(this.autoApproveBusyTimer);
52793
+ this.autoApproveBusyTimer = null;
52537
52794
  }
52538
- return false;
52539
52795
  }
52540
52796
  /** @see ProviderInstance.noteManualInteraction */
52541
52797
  noteManualInteraction(now = Date.now(), opts) {
@@ -52551,7 +52807,7 @@ ${buttons.join("\n")}`;
52551
52807
  * CLI-specific modal text.
52552
52808
  */
52553
52809
  autoApproveEffectivelyActive(status, now = Date.now()) {
52554
- return status === "waiting_approval" && this.shouldAutoApprove() && !this.manualAttendance.isAttended(now);
52810
+ return status === "waiting_approval" && this.shouldUsePtyAutoApprove() && !this.manualAttendance.isAttended(now);
52555
52811
  }
52556
52812
  // STATUS-MISMATCH: true once the current auto-approve episode has been masking
52557
52813
  // waiting_approval behind `generating` for longer than AUTO_APPROVE_MASK_STALL_MS without
@@ -52561,7 +52817,7 @@ ${buttons.join("\n")}`;
52561
52817
  // maybeAutoApproveStatus (driven by getState + the recheck timer during a waiting episode);
52562
52818
  // this read is side-effect-free so getStatusMetadata can consult it too.
52563
52819
  autoApproveMaskStalled(now = Date.now()) {
52564
- return this.autoApproveMaskSince > 0 && now - this.autoApproveMaskSince > _CliProviderInstance.AUTO_APPROVE_MASK_STALL_MS;
52820
+ return this.shouldUsePtyAutoApprove() && this.autoApproveMaskSince > 0 && now - this.autoApproveMaskSince > _CliProviderInstance.AUTO_APPROVE_MASK_STALL_MS;
52565
52821
  }
52566
52822
  /**
52567
52823
  * NOTIF-APPROVAL-MASKED (Q1b): surface a delegated worker's STALLED auto-approve modal
@@ -52585,6 +52841,7 @@ ${buttons.join("\n")}`;
52585
52841
  * mask-clock value) so a modal that flaps between parsed/unparsed states is announced once.
52586
52842
  */
52587
52843
  maybeEmitStalledApprovalNudge(adapterStatus, now) {
52844
+ if (!this.shouldUsePtyAutoApprove()) return;
52588
52845
  if (!this.isMeshWorkerSession()) return;
52589
52846
  if (adapterStatus?.status !== "waiting_approval") return;
52590
52847
  if (!this.autoApproveMaskStalled(now)) return;
@@ -54125,6 +54382,7 @@ function shouldRestoreHostedRuntime(record, managerTag) {
54125
54382
  }
54126
54383
 
54127
54384
  // src/commands/cli-manager.ts
54385
+ init_auto_approve_modes();
54128
54386
  function isExplicitCommand(command) {
54129
54387
  const trimmed = command.trim();
54130
54388
  return path30.isAbsolute(trimmed) || trimmed.includes("/") || trimmed.includes("\\") || trimmed.startsWith("~");
@@ -54351,6 +54609,24 @@ function expandThinkingLaunchArgs(template, level, levelMap) {
54351
54609
  const mapped = levelMap && typeof levelMap[raw] === "string" && levelMap[raw].trim() ? levelMap[raw].trim() : raw;
54352
54610
  return template.map((part) => part.includes("{{level}}") ? part.replace("{{level}}", mapped) : part);
54353
54611
  }
54612
+ function matchesRemovedLaunchArg(arg, removeArg) {
54613
+ return arg === removeArg || removeArg.startsWith("--") && arg.startsWith(`${removeArg}=`);
54614
+ }
54615
+ function applyAutoApproveModeLaunchArgs(provider, cliArgs, settings) {
54616
+ if (!provider) return { provider, cliArgs };
54617
+ const resolved = resolveProviderAutoApproveMode(provider, settings);
54618
+ if (!resolved.active || resolved.strategy !== "launch-args") return { provider, cliArgs };
54619
+ const mode = findProviderAutoApproveMode(provider, resolved.modeId);
54620
+ if (!mode || !Array.isArray(mode.launchArgs) || mode.launchArgs.length === 0) return { provider, cliArgs };
54621
+ const removeArgs = Array.isArray(mode.removeArgs) ? mode.removeArgs : [];
54622
+ const baseArgs = provider.spawn?.args;
54623
+ const filteredBaseArgs = Array.isArray(baseArgs) && removeArgs.length > 0 ? baseArgs.filter((arg) => !removeArgs.some((removeArg) => matchesRemovedLaunchArg(arg, removeArg))) : baseArgs;
54624
+ const launchProvider = filteredBaseArgs === baseArgs ? provider : { ...provider, spawn: { ...provider.spawn, args: filteredBaseArgs } };
54625
+ return {
54626
+ provider: launchProvider,
54627
+ cliArgs: [...mode.launchArgs, ...cliArgs || []]
54628
+ };
54629
+ }
54354
54630
  function readSubcommandSessionId(args, subcommands) {
54355
54631
  const resumeIndex = args.findIndex((arg) => subcommands.includes(arg));
54356
54632
  if (resumeIndex < 0) return void 0;
@@ -54781,22 +55057,30 @@ Run 'adhdev doctor' for detailed diagnostics.`
54781
55057
  if (provider) {
54782
55058
  console.log(colorize("cyan", ` \u{1F4E6} Using provider: ${provider.name} (${provider.type})`));
54783
55059
  }
54784
- const modelLaunchArgs = expandModelLaunchArgs(provider?.modelLaunchArgs, initialModel);
54785
- const cliArgsWithModel = modelLaunchArgs ? [...modelLaunchArgs, ...cliArgs || []] : cliArgs;
55060
+ const launchSettings = {
55061
+ ...this.providerLoader.getSettings(normalizedType),
55062
+ ...options?.settingsOverride || {}
55063
+ };
55064
+ const versionResolvedProvider = provider ? this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider : void 0;
55065
+ const autoApproveLaunch = applyAutoApproveModeLaunchArgs(versionResolvedProvider, cliArgs, launchSettings);
55066
+ const launchProvider = autoApproveLaunch.provider || provider;
55067
+ const cliArgsWithAutoApprove = autoApproveLaunch.cliArgs;
55068
+ const modelLaunchArgs = expandModelLaunchArgs(launchProvider?.modelLaunchArgs, initialModel);
55069
+ const cliArgsWithModel = modelLaunchArgs ? [...modelLaunchArgs, ...cliArgsWithAutoApprove || []] : cliArgsWithAutoApprove;
54786
55070
  if (initialModel && !modelLaunchArgs) {
54787
55071
  LOG.warn("CLI", `[${normalizedType}] initialModel='${initialModel}' requested but provider declares no modelLaunchArgs template \u2014 launching without model selection.`);
54788
55072
  }
54789
55073
  const initialThinkingLevel = options?.initialThinkingLevel;
54790
- const thinkingLaunchArgs = expandThinkingLaunchArgs(provider?.thinkingLaunchArgs, initialThinkingLevel, provider?.thinkingLevelMap);
55074
+ const thinkingLaunchArgs = expandThinkingLaunchArgs(launchProvider?.thinkingLaunchArgs, initialThinkingLevel, launchProvider?.thinkingLevelMap);
54791
55075
  const cliArgsWithBrain = thinkingLaunchArgs ? [...thinkingLaunchArgs, ...cliArgsWithModel || []] : cliArgsWithModel;
54792
55076
  if (initialThinkingLevel && !thinkingLaunchArgs) {
54793
55077
  LOG.warn("CLI", `[${normalizedType}] initialThinkingLevel='${initialThinkingLevel}' requested but provider declares no thinkingLaunchArgs template \u2014 launching without thinking-level selection.`);
54794
55078
  }
54795
- const sessionBinding = resolveCliSessionBinding(provider, normalizedType, cliArgsWithBrain, options?.resumeSessionId);
55079
+ const sessionBinding = resolveCliSessionBinding(launchProvider, normalizedType, cliArgsWithBrain, options?.resumeSessionId);
54796
55080
  const resolvedCliArgs = sessionBinding.cliArgs;
54797
55081
  const instanceManager = this.deps.getInstanceManager();
54798
- if (provider && instanceManager) {
54799
- const resolvedProvider = this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider;
55082
+ if (launchProvider && instanceManager) {
55083
+ const resolvedProvider = launchProvider;
54800
55084
  await this.registerCliInstance(
54801
55085
  key2,
54802
55086
  normalizedType,
@@ -54804,7 +55088,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
54804
55088
  resolvedDir,
54805
55089
  resolvedCliArgs,
54806
55090
  resolvedProvider,
54807
- { ...this.providerLoader.getSettings(normalizedType), ...options?.settingsOverride || {} },
55091
+ launchSettings,
54808
55092
  false,
54809
55093
  {
54810
55094
  providerSessionId: sessionBinding.providerSessionId,
@@ -55643,6 +55927,7 @@ init_hash();
55643
55927
  init_logger();
55644
55928
 
55645
55929
  // src/providers/provider-schema.ts
55930
+ init_auto_approve_modes();
55646
55931
  init_open_panel_support();
55647
55932
  var VALID_CAPABILITY_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
55648
55933
  var VALID_INPUT_STRATEGIES2 = /* @__PURE__ */ new Set(["native", "native_acp", "resource_link", "text_fallback", "paste", "upload"]);
@@ -55708,6 +55993,7 @@ var KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
55708
55993
  "providerVersion",
55709
55994
  "status",
55710
55995
  "details",
55996
+ "autoApproveModes",
55711
55997
  "modelLaunchArgs",
55712
55998
  "modelOptions",
55713
55999
  "thinkingLaunchArgs",
@@ -55769,6 +56055,7 @@ function validateProviderDefinition(raw) {
55769
56055
  validateCapabilities(provider, controls, errors);
55770
56056
  validateNativeHistory(provider.nativeHistory, errors);
55771
56057
  validateMeshCoordinator(provider.meshCoordinator, errors);
56058
+ validateAutoApproveModes(provider.autoApproveModes, errors);
55772
56059
  for (const control of controls) {
55773
56060
  validateControl(control, errors);
55774
56061
  }
@@ -55777,6 +56064,75 @@ function validateProviderDefinition(raw) {
55777
56064
  }
55778
56065
  return { errors, warnings };
55779
56066
  }
56067
+ function validateAutoApproveModes(raw, errors) {
56068
+ if (raw === void 0) return;
56069
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
56070
+ errors.push("autoApproveModes must be an object");
56071
+ return;
56072
+ }
56073
+ const config = raw;
56074
+ const defaultModeId = typeof config.default === "string" ? config.default.trim() : "";
56075
+ if (!defaultModeId) {
56076
+ errors.push("autoApproveModes.default must be a non-empty string");
56077
+ } else {
56078
+ config.default = defaultModeId;
56079
+ }
56080
+ if (!Array.isArray(config.modes) || config.modes.length === 0) {
56081
+ errors.push("autoApproveModes.modes must be a non-empty array");
56082
+ return;
56083
+ }
56084
+ const ids = /* @__PURE__ */ new Set();
56085
+ for (const [index, rawMode] of config.modes.entries()) {
56086
+ const prefix = `autoApproveModes.modes[${index}]`;
56087
+ if (!rawMode || typeof rawMode !== "object" || Array.isArray(rawMode)) {
56088
+ errors.push(`${prefix} must be an object`);
56089
+ continue;
56090
+ }
56091
+ const mode = rawMode;
56092
+ const id = typeof mode.id === "string" ? mode.id.trim() : "";
56093
+ if (!id) {
56094
+ errors.push(`${prefix}.id must be a non-empty string`);
56095
+ } else if (ids.has(id)) {
56096
+ errors.push(`${prefix}.id must be unique (duplicate: ${id})`);
56097
+ } else {
56098
+ ids.add(id);
56099
+ mode.id = id;
56100
+ }
56101
+ if (typeof mode.label !== "string" || !mode.label.trim()) {
56102
+ errors.push(`${prefix}.label must be a non-empty string`);
56103
+ }
56104
+ const strategy = mode.strategy;
56105
+ if (!["pty-parse-default", "launch-args", "post-boot-command"].includes(String(strategy))) {
56106
+ errors.push(`${prefix}.strategy must be one of: pty-parse-default, launch-args, post-boot-command`);
56107
+ } else if (strategy === "post-boot-command") {
56108
+ errors.push(`${prefix}.strategy post-boot-command is reserved and unsupported in v1`);
56109
+ }
56110
+ const risk = mode.risk;
56111
+ if (!["safe", "caution", "dangerous"].includes(String(risk))) {
56112
+ errors.push(`${prefix}.risk must be one of: safe, caution, dangerous`);
56113
+ }
56114
+ for (const field of ["launchArgs", "removeArgs"]) {
56115
+ const value = mode[field];
56116
+ if (value !== void 0 && (!Array.isArray(value) || value.some((arg) => typeof arg !== "string" || !arg.trim()))) {
56117
+ errors.push(`${prefix}.${field} must be an array of non-empty strings when provided`);
56118
+ }
56119
+ }
56120
+ if (strategy === "launch-args" && (!Array.isArray(mode.launchArgs) || mode.launchArgs.length === 0)) {
56121
+ errors.push(`${prefix}.launchArgs must be a non-empty array for launch-args strategy`);
56122
+ }
56123
+ if (["safe", "caution", "dangerous"].includes(String(risk)) && deriveAutoApproveModeRisk(mode) === "dangerous") {
56124
+ mode.risk = "dangerous";
56125
+ }
56126
+ if (mode.risk === "dangerous" && (typeof mode.warning !== "string" || !mode.warning.trim())) {
56127
+ errors.push(`${prefix}.warning is required for dangerous modes`);
56128
+ } else if (mode.warning !== void 0 && (typeof mode.warning !== "string" || !mode.warning.trim())) {
56129
+ errors.push(`${prefix}.warning must be a non-empty string when provided`);
56130
+ }
56131
+ }
56132
+ if (defaultModeId && !ids.has(defaultModeId)) {
56133
+ errors.push(`autoApproveModes.default must reference an existing mode id: ${defaultModeId}`);
56134
+ }
56135
+ }
55780
56136
  function validateCapabilities(provider, controls, errors) {
55781
56137
  const capabilities = provider.capabilities;
55782
56138
  if (provider.contractVersion === 2) {
@@ -60386,6 +60742,139 @@ var meshCrudHandlers = {
60386
60742
  return { success: false, error: e.message };
60387
60743
  }
60388
60744
  },
60745
+ // READ path for `.adhdev/mesh.json` — returns the currently-committed repo
60746
+ // config (parsed + normalized) for a workspace so a UI can render/edit the
60747
+ // existing declarative zones (notably `providerDefaults.autoApproveModes`)
60748
+ // WITHOUT re-deriving them from the machine-local scaffold. Never writes.
60749
+ // `config` is undefined when no repo file exists (sourceType 'unavailable') or
60750
+ // it is unparseable (sourceType 'invalid', with the parse error surfaced).
60751
+ read_mesh_json_config: async (_ctx, args) => {
60752
+ const workspace = typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
60753
+ try {
60754
+ const { loadRepoMeshJsonConfig: loadRepoMeshJsonConfig2 } = await Promise.resolve().then(() => (init_mesh_json_config(), mesh_json_config_exports));
60755
+ const loaded = loadRepoMeshJsonConfig2(workspace);
60756
+ return {
60757
+ success: true,
60758
+ workspace,
60759
+ sourceType: loaded.sourceType,
60760
+ source: loaded.source,
60761
+ ...loaded.path ? { path: loaded.path } : {},
60762
+ ...loaded.error ? { error: loaded.error } : {},
60763
+ config: loaded.config,
60764
+ // Convenience projection so the UI does not have to reach into config.
60765
+ providerDefaults: loaded.config?.providerDefaults
60766
+ };
60767
+ } catch (e) {
60768
+ return { success: false, error: e.message };
60769
+ }
60770
+ },
60771
+ // Partial-edit WRITE path for `.adhdev/mesh.json` `providerDefaults` — a
60772
+ // READ-MODIFY-WRITE that preserves operator hand-edits. Unlike
60773
+ // write_mesh_json_config (which rebuilds the WHOLE file from the machine-local
60774
+ // scaffold and can silently drop hand-edited zones), this parses the existing
60775
+ // repo file, merges ONLY the providerDefaults.autoApproveModes zone, and
60776
+ // re-serializes — coordinator prompt, operating notes and limits authored in
60777
+ // the repo are carried through untouched. Defaults to dry-run.
60778
+ //
60779
+ // args: { workspace?, autoApproveModes: Record<providerType,modeId>, write?, merge? }
60780
+ // merge=true (default): per-provider merge into the existing map; a modeId of
60781
+ // '' | null removes that provider's entry. merge=false: REPLACE the whole
60782
+ // autoApproveModes map with the supplied one.
60783
+ set_mesh_provider_defaults: async (_ctx, args) => {
60784
+ const workspace = typeof args?.workspace === "string" && args.workspace.trim() ? args.workspace.trim() : process.cwd();
60785
+ const write = args?.write === true;
60786
+ const merge = args?.merge !== false;
60787
+ const inputModes = args?.autoApproveModes;
60788
+ if (inputModes !== void 0 && (typeof inputModes !== "object" || inputModes === null || Array.isArray(inputModes))) {
60789
+ return { success: false, error: "autoApproveModes must be an object (providerType \u2192 modeId) when provided" };
60790
+ }
60791
+ try {
60792
+ const {
60793
+ loadRepoMeshJsonConfig: loadRepoMeshJsonConfig2,
60794
+ normalizeRepoMeshDeclarativeConfig: normalizeRepoMeshDeclarativeConfig2,
60795
+ MESH_JSON_CONFIG_LOCATIONS: MESH_JSON_CONFIG_LOCATIONS2
60796
+ } = await Promise.resolve().then(() => (init_mesh_json_config(), mesh_json_config_exports));
60797
+ const { existsSync: existsSync57, readFileSync: readFileSync44, mkdirSync: mkdirSync23, writeFileSync: writeFileSync25 } = await import("fs");
60798
+ const { dirname: dirname19, join: join54 } = await import("path");
60799
+ const yaml6 = await import("js-yaml");
60800
+ const relativePath = MESH_JSON_CONFIG_LOCATIONS2[0];
60801
+ let baseDoc = { version: 1 };
60802
+ let existingPath = join54(workspace, relativePath);
60803
+ let existedAsYaml = false;
60804
+ for (const relative5 of MESH_JSON_CONFIG_LOCATIONS2) {
60805
+ const candidate = join54(workspace, relative5);
60806
+ if (!existsSync57(candidate)) continue;
60807
+ try {
60808
+ const text = readFileSync44(candidate, "utf-8");
60809
+ const parsed = /\.json$/i.test(candidate) ? JSON.parse(text) : yaml6.load(text);
60810
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
60811
+ baseDoc = parsed;
60812
+ existingPath = candidate;
60813
+ existedAsYaml = !/\.json$/i.test(candidate);
60814
+ }
60815
+ } catch (e) {
60816
+ return { success: false, error: `existing ${relative5} is unparseable, refusing to overwrite: ${e?.message || e}` };
60817
+ }
60818
+ break;
60819
+ }
60820
+ const existingPd = baseDoc.providerDefaults && typeof baseDoc.providerDefaults === "object" && !Array.isArray(baseDoc.providerDefaults) ? baseDoc.providerDefaults : {};
60821
+ const existingModes = existingPd.autoApproveModes && typeof existingPd.autoApproveModes === "object" && !Array.isArray(existingPd.autoApproveModes) ? { ...existingPd.autoApproveModes } : {};
60822
+ const nextModes = merge ? existingModes : {};
60823
+ if (inputModes) {
60824
+ for (const [providerType, modeId] of Object.entries(inputModes)) {
60825
+ const type = typeof providerType === "string" ? providerType.trim() : "";
60826
+ if (!type) continue;
60827
+ const id = typeof modeId === "string" ? modeId.trim() : "";
60828
+ if (id) nextModes[type] = id;
60829
+ else delete nextModes[type];
60830
+ }
60831
+ }
60832
+ const nextDoc = { ...baseDoc, version: 1 };
60833
+ if (Object.keys(nextModes).length) {
60834
+ nextDoc.providerDefaults = { ...existingPd, autoApproveModes: nextModes };
60835
+ } else {
60836
+ if (nextDoc.providerDefaults) {
60837
+ const { autoApproveModes, ...restPd } = nextDoc.providerDefaults;
60838
+ if (Object.keys(restPd).length) nextDoc.providerDefaults = restPd;
60839
+ else delete nextDoc.providerDefaults;
60840
+ }
60841
+ }
60842
+ const validation = normalizeRepoMeshDeclarativeConfig2(nextDoc);
60843
+ if (!validation.valid) {
60844
+ return { success: false, error: `merged mesh.json is invalid: ${validation.errors.join("; ")}` };
60845
+ }
60846
+ const absolutePath = existingPath;
60847
+ const serialized = existedAsYaml ? yaml6.dump(nextDoc, { indent: 2 }) : `${JSON.stringify(nextDoc, null, 2)}
60848
+ `;
60849
+ if (!write) {
60850
+ return {
60851
+ success: true,
60852
+ written: false,
60853
+ dryRun: true,
60854
+ path: absolutePath,
60855
+ relativePath,
60856
+ merge,
60857
+ providerDefaults: nextDoc.providerDefaults,
60858
+ preview: serialized,
60859
+ note: "Dry-run: nothing written. Re-run with write=true to persist. Only the providerDefaults zone is merged; other repo zones are preserved."
60860
+ };
60861
+ }
60862
+ mkdirSync23(dirname19(absolutePath), { recursive: true });
60863
+ writeFileSync25(absolutePath, serialized, "utf-8");
60864
+ return {
60865
+ success: true,
60866
+ written: true,
60867
+ dryRun: false,
60868
+ path: absolutePath,
60869
+ relativePath,
60870
+ merge,
60871
+ providerDefaults: nextDoc.providerDefaults,
60872
+ note: "Wrote providerDefaults into .adhdev/mesh.json (read-modify-write; other zones preserved). Commit it to the repo."
60873
+ };
60874
+ } catch (e) {
60875
+ return { success: false, error: e.message };
60876
+ }
60877
+ },
60389
60878
  delete_mesh: async (_ctx, args) => {
60390
60879
  const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
60391
60880
  if (!meshId) return { success: false, error: "meshId required" };
@@ -76509,6 +76998,9 @@ var V1_CONTRACT_VERSION = "1.0.0";
76509
76998
  MAX_LEDGER_SLICE_LIMIT,
76510
76999
  MESH_CONVERGE_FAST_FORWARD_TAG,
76511
77000
  MESH_CONVERGE_REFINE_TAG,
77001
+ MESH_JSON_CONFIG_LOCATIONS,
77002
+ MESH_JSON_CONFIG_SCHEMA,
77003
+ MESH_JSON_PROVIDER_DEFAULTS_EXAMPLE,
76512
77004
  MESH_MAX_PARALLEL_TASKS_MAX,
76513
77005
  MESH_MAX_PARALLEL_TASKS_MIN,
76514
77006
  MESH_MISSION_LIST_HISTORY_ID_LIMIT,
@@ -76568,6 +77060,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
76568
77060
  buildMeshActiveWorkSummary,
76569
77061
  buildMeshAsyncRefineJobs,
76570
77062
  buildMeshHostRequiredFailure,
77063
+ buildMeshJsonConfigScaffold,
76571
77064
  buildMeshLedgerReconciliationEvidence,
76572
77065
  buildMeshLedgerReplicaEvidence,
76573
77066
  buildMeshMagiActivity,
@@ -76618,6 +77111,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
76618
77111
  createSessionDelivery,
76619
77112
  createWorktree,
76620
77113
  daemonIdsEquivalent,
77114
+ delegatedWorkerAutoApproveSettings,
76621
77115
  deleteDirectDispatchesByTaskId,
76622
77116
  deleteMesh,
76623
77117
  deriveMeshNodeHealthFromGit,
@@ -76731,6 +77225,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
76731
77225
  loadMeshCoordinatorRegistry,
76732
77226
  loadMeshRefineConfig,
76733
77227
  loadMeshWorktreeBootstrapConfig,
77228
+ loadRepoMeshJsonConfig,
76734
77229
  loadRepoSettings,
76735
77230
  loadState,
76736
77231
  logCommand,
@@ -76771,6 +77266,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
76771
77266
  normalizeMeshWorkerResult,
76772
77267
  normalizeMessageParts,
76773
77268
  normalizeRepoIdentity,
77269
+ normalizeRepoMeshDeclarativeConfig,
76774
77270
  normalizeSessionModalFields,
76775
77271
  parsePorcelainV2Status,
76776
77272
  parseProviderSourceConfigUpdate,
@@ -76817,6 +77313,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
76817
77313
  resolveCurrentGlobalInstallSurface,
76818
77314
  resolveDebugRuntimeConfig,
76819
77315
  resolveDelegatedWorkerAutoApprove,
77316
+ resolveDelegatedWorkerDangerousModeAllow,
76820
77317
  resolveDeliveryDecision,
76821
77318
  resolveEffectiveMeshNodeHealth,
76822
77319
  resolveGitRepository,
@@ -76840,6 +77337,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
76840
77337
  runMeshWorktreeBootstrap,
76841
77338
  saveConfig,
76842
77339
  saveState,
77340
+ serializeMeshJsonConfigScaffold,
76843
77341
  serializeV2EnvelopeToWire,
76844
77342
  setDebugRuntimeConfig,
76845
77343
  setLogLevel,