@adhdev/daemon-core 1.0.18-rc.17 → 1.0.18-rc.19
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/config/mesh-json-config.d.ts +62 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +629 -400
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +592 -370
- package/dist/index.mjs.map +1 -1
- package/dist/repo-mesh-types.d.ts +25 -3
- package/package.json +3 -3
- package/src/commands/med-family/mesh-crud.ts +155 -0
- package/src/config/mesh-json-config.ts +103 -0
- package/src/index.ts +18 -0
- package/src/mesh/mesh-event-forwarding.ts +12 -0
- package/src/mesh/mesh-queue-assignment.ts +53 -3
- package/src/repo-mesh-types.ts +54 -7
package/dist/index.js
CHANGED
|
@@ -184,7 +184,7 @@ function mergeAndNormalizePolicy(base, patch) {
|
|
|
184
184
|
}
|
|
185
185
|
return policy;
|
|
186
186
|
}
|
|
187
|
-
function resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy, provider) {
|
|
187
|
+
function resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy, provider, repoConfig, providerType) {
|
|
188
188
|
let enabled = true;
|
|
189
189
|
if (typeof nodePolicy?.delegatedWorkerAutoApprove === "boolean") {
|
|
190
190
|
enabled = nodePolicy.delegatedWorkerAutoApprove;
|
|
@@ -194,14 +194,17 @@ function resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy, provider) {
|
|
|
194
194
|
if (!enabled) return false;
|
|
195
195
|
const modes = provider?.autoApproveModes;
|
|
196
196
|
if (!modes) return true;
|
|
197
|
-
const
|
|
198
|
-
|
|
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;
|
|
199
202
|
const dangerousAllowed = resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy);
|
|
200
|
-
if (deriveAutoApproveModeRisk(
|
|
203
|
+
if (deriveAutoApproveModeRisk(selectedMode) === "dangerous" && !dangerousAllowed) {
|
|
201
204
|
const ptyFallback = modes.modes.find((mode) => mode.strategy === "pty-parse-default" && deriveAutoApproveModeRisk(mode) !== "dangerous");
|
|
202
205
|
return ptyFallback?.id || false;
|
|
203
206
|
}
|
|
204
|
-
return
|
|
207
|
+
return selectedMode.id;
|
|
205
208
|
}
|
|
206
209
|
function resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy) {
|
|
207
210
|
if (typeof nodePolicy?.delegatedWorkerDangerousModeAllow === "boolean") {
|
|
@@ -209,8 +212,8 @@ function resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy) {
|
|
|
209
212
|
}
|
|
210
213
|
return meshPolicy?.delegatedWorkerDangerousModeAllow === true;
|
|
211
214
|
}
|
|
212
|
-
function delegatedWorkerAutoApproveSettings(meshPolicy, nodePolicy, provider) {
|
|
213
|
-
const resolved = resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy, provider);
|
|
215
|
+
function delegatedWorkerAutoApproveSettings(meshPolicy, nodePolicy, provider, repoConfig, providerType) {
|
|
216
|
+
const resolved = resolveDelegatedWorkerAutoApprove(meshPolicy, nodePolicy, provider, repoConfig, providerType);
|
|
214
217
|
const delegatedWorkerDangerousModeAllow = resolveDelegatedWorkerDangerousModeAllow(meshPolicy, nodePolicy);
|
|
215
218
|
return typeof resolved === "string" ? { autoApprove: void 0, autoApproveMode: resolved, delegatedWorkerDangerousModeAllow } : { autoApprove: resolved, autoApproveMode: void 0, delegatedWorkerDangerousModeAllow };
|
|
216
219
|
}
|
|
@@ -310,6 +313,267 @@ var init_repo_mesh_types = __esm({
|
|
|
310
313
|
}
|
|
311
314
|
});
|
|
312
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
|
+
|
|
313
577
|
// src/git/git-executor.ts
|
|
314
578
|
var git_executor_exports = {};
|
|
315
579
|
__export(git_executor_exports, {
|
|
@@ -526,10 +790,10 @@ function readInjected(value) {
|
|
|
526
790
|
}
|
|
527
791
|
function getDaemonBuildInfo() {
|
|
528
792
|
if (cached) return cached;
|
|
529
|
-
const commit = readInjected(true ? "
|
|
530
|
-
const commitShort = readInjected(true ? "
|
|
531
|
-
const version = readInjected(true ? "1.0.18-rc.
|
|
532
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
793
|
+
const commit = readInjected(true ? "957753ce64d49cf4222cb2675d7d919871d3f009" : void 0) ?? "unknown";
|
|
794
|
+
const commitShort = readInjected(true ? "957753ce" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
795
|
+
const version = readInjected(true ? "1.0.18-rc.19" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
796
|
+
const builtAt = readInjected(true ? "2026-07-23T07:07:10.469Z" : void 0);
|
|
533
797
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
534
798
|
return cached;
|
|
535
799
|
}
|
|
@@ -541,14 +805,14 @@ var init_build_info = __esm({
|
|
|
541
805
|
});
|
|
542
806
|
|
|
543
807
|
// src/git/change-impact-config.ts
|
|
544
|
-
function
|
|
808
|
+
function isRecord2(value) {
|
|
545
809
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
546
810
|
}
|
|
547
811
|
function isStringArray(value) {
|
|
548
812
|
return Array.isArray(value) && value.every((v) => typeof v === "string" && v.length > 0);
|
|
549
813
|
}
|
|
550
814
|
function validateTarget(value, key2, errors) {
|
|
551
|
-
if (!
|
|
815
|
+
if (!isRecord2(value)) {
|
|
552
816
|
errors.push(`impactTargets.${key2} must be an object`);
|
|
553
817
|
return void 0;
|
|
554
818
|
}
|
|
@@ -564,7 +828,7 @@ function validateTarget(value, key2, errors) {
|
|
|
564
828
|
}
|
|
565
829
|
function validateChangeImpactConfig(raw, source = "inline") {
|
|
566
830
|
const errors = [];
|
|
567
|
-
if (!
|
|
831
|
+
if (!isRecord2(raw)) {
|
|
568
832
|
return { valid: false, errors: [`${source}: config must be an object`] };
|
|
569
833
|
}
|
|
570
834
|
const config = {};
|
|
@@ -581,7 +845,7 @@ function validateChangeImpactConfig(raw, source = "inline") {
|
|
|
581
845
|
else errors.push("nonRuntimeRootFilePatterns must be an array of non-empty strings");
|
|
582
846
|
}
|
|
583
847
|
if (raw.impactTargets !== void 0) {
|
|
584
|
-
if (!
|
|
848
|
+
if (!isRecord2(raw.impactTargets)) {
|
|
585
849
|
errors.push("impactTargets must be an object");
|
|
586
850
|
} else {
|
|
587
851
|
const targets = {};
|
|
@@ -603,23 +867,23 @@ function validateChangeImpactConfig(raw, source = "inline") {
|
|
|
603
867
|
}
|
|
604
868
|
return { valid: errors.length === 0, errors, config: errors.length === 0 ? config : void 0 };
|
|
605
869
|
}
|
|
606
|
-
function
|
|
870
|
+
function parseConfigText2(path46, text) {
|
|
607
871
|
if (/\.json$/i.test(path46)) return JSON.parse(text);
|
|
608
|
-
return
|
|
872
|
+
return yaml2.load(text);
|
|
609
873
|
}
|
|
610
874
|
function loadChangeImpactConfig(repoRoot) {
|
|
611
875
|
for (const relative5 of CHANGE_IMPACT_CONFIG_LOCATIONS) {
|
|
612
|
-
const configPath = (0,
|
|
613
|
-
if (!(0,
|
|
876
|
+
const configPath = (0, import_path2.join)(repoRoot, relative5);
|
|
877
|
+
if (!(0, import_fs2.existsSync)(configPath)) continue;
|
|
614
878
|
try {
|
|
615
|
-
const text = (0,
|
|
879
|
+
const text = (0, import_fs2.readFileSync)(configPath, "utf-8");
|
|
616
880
|
let mtimeMs = 0;
|
|
617
881
|
try {
|
|
618
|
-
mtimeMs = (0,
|
|
882
|
+
mtimeMs = (0, import_fs2.statSync)(configPath).mtimeMs;
|
|
619
883
|
} catch {
|
|
620
884
|
mtimeMs = text.length;
|
|
621
885
|
}
|
|
622
|
-
const parsed =
|
|
886
|
+
const parsed = parseConfigText2(configPath, text);
|
|
623
887
|
const validation = validateChangeImpactConfig(parsed, relative5);
|
|
624
888
|
if (!validation.valid) {
|
|
625
889
|
return {
|
|
@@ -678,7 +942,7 @@ function globToRegExp(pattern) {
|
|
|
678
942
|
}
|
|
679
943
|
function listPackageDirs(packagesRoot) {
|
|
680
944
|
try {
|
|
681
|
-
return (0,
|
|
945
|
+
return (0, import_fs2.readdirSync)(packagesRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => entry.name);
|
|
682
946
|
} catch {
|
|
683
947
|
return [];
|
|
684
948
|
}
|
|
@@ -688,10 +952,10 @@ function suggestChangeImpactConfig(repoRoot) {
|
|
|
688
952
|
const daemon = /* @__PURE__ */ new Set();
|
|
689
953
|
const web = /* @__PURE__ */ new Set();
|
|
690
954
|
const unclassified = [];
|
|
691
|
-
const roots = ["packages", (0,
|
|
955
|
+
const roots = ["packages", (0, import_path2.join)("oss", "packages")];
|
|
692
956
|
for (const rel of roots) {
|
|
693
|
-
const packagesRoot = (0,
|
|
694
|
-
if (!(0,
|
|
957
|
+
const packagesRoot = (0, import_path2.join)(repoRoot, rel);
|
|
958
|
+
if (!(0, import_fs2.existsSync)(packagesRoot)) continue;
|
|
695
959
|
for (const name of listPackageDirs(packagesRoot)) {
|
|
696
960
|
if (/(^web[-.]|[-.]web$)/i.test(name) || /dashboard|frontend|ui$/i.test(name)) {
|
|
697
961
|
web.add(name);
|
|
@@ -733,13 +997,13 @@ function suggestChangeImpactConfig(repoRoot) {
|
|
|
733
997
|
discoveredPackages: { daemon: daemonRuntimePackages, web: webOnlyPackages, unclassified }
|
|
734
998
|
};
|
|
735
999
|
}
|
|
736
|
-
var
|
|
1000
|
+
var import_fs2, import_path2, yaml2, CHANGE_IMPACT_CONFIG_LOCATIONS, CHANGE_IMPACT_CONFIG_SCHEMA;
|
|
737
1001
|
var init_change_impact_config = __esm({
|
|
738
1002
|
"src/git/change-impact-config.ts"() {
|
|
739
1003
|
"use strict";
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
1004
|
+
import_fs2 = require("fs");
|
|
1005
|
+
import_path2 = require("path");
|
|
1006
|
+
yaml2 = __toESM(require("js-yaml"));
|
|
743
1007
|
CHANGE_IMPACT_CONFIG_LOCATIONS = [
|
|
744
1008
|
".adhdev/change-impact.json",
|
|
745
1009
|
".adhdev/change-impact.yaml",
|
|
@@ -1824,25 +2088,25 @@ function ensureMachineId(config) {
|
|
|
1824
2088
|
}
|
|
1825
2089
|
function getConfigDir() {
|
|
1826
2090
|
const override = process.env.ADHDEV_CONFIG_DIR;
|
|
1827
|
-
const dir = override && override.trim() ? override.trim() : (0,
|
|
1828
|
-
if (!(0,
|
|
1829
|
-
(0,
|
|
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 });
|
|
1830
2094
|
}
|
|
1831
2095
|
return dir;
|
|
1832
2096
|
}
|
|
1833
2097
|
function getDaemonDataDir() {
|
|
1834
|
-
const dir = (0,
|
|
1835
|
-
if (!(0,
|
|
1836
|
-
(0,
|
|
2098
|
+
const dir = (0, import_path3.join)(getConfigDir(), "daemon");
|
|
2099
|
+
if (!(0, import_fs3.existsSync)(dir)) {
|
|
2100
|
+
(0, import_fs3.mkdirSync)(dir, { recursive: true });
|
|
1837
2101
|
}
|
|
1838
2102
|
return dir;
|
|
1839
2103
|
}
|
|
1840
2104
|
function getConfigPath() {
|
|
1841
|
-
return (0,
|
|
2105
|
+
return (0, import_path3.join)(getConfigDir(), "config.json");
|
|
1842
2106
|
}
|
|
1843
2107
|
function migrateStateToStateFile(raw) {
|
|
1844
|
-
const statePath = (0,
|
|
1845
|
-
if ((0,
|
|
2108
|
+
const statePath = (0, import_path3.join)(getConfigDir(), "state.json");
|
|
2109
|
+
if ((0, import_fs3.existsSync)(statePath)) return;
|
|
1846
2110
|
const recentActivity = Array.isArray(raw.recentActivity) ? raw.recentActivity : [];
|
|
1847
2111
|
const savedProviderSessions = Array.isArray(raw.savedProviderSessions) ? raw.savedProviderSessions : [];
|
|
1848
2112
|
const legacySessionReads = isPlainObject(raw.recentSessionReads) ? raw.recentSessionReads : {};
|
|
@@ -1862,11 +2126,11 @@ function migrateStateToStateFile(raw) {
|
|
|
1862
2126
|
sessionReads: mergedReads,
|
|
1863
2127
|
sessionReadMarkers: cleanedMarkers
|
|
1864
2128
|
};
|
|
1865
|
-
(0,
|
|
2129
|
+
(0, import_fs3.writeFileSync)(statePath, JSON.stringify(state, null, 2), { encoding: "utf-8", mode: 384 });
|
|
1866
2130
|
}
|
|
1867
2131
|
function loadConfig() {
|
|
1868
2132
|
const configPath = getConfigPath();
|
|
1869
|
-
if (!(0,
|
|
2133
|
+
if (!(0, import_fs3.existsSync)(configPath)) {
|
|
1870
2134
|
const initialized = ensureMachineId({ ...DEFAULT_CONFIG });
|
|
1871
2135
|
try {
|
|
1872
2136
|
saveConfig(initialized.config);
|
|
@@ -1875,7 +2139,7 @@ function loadConfig() {
|
|
|
1875
2139
|
return initialized.config;
|
|
1876
2140
|
}
|
|
1877
2141
|
try {
|
|
1878
|
-
const raw = (0,
|
|
2142
|
+
const raw = (0, import_fs3.readFileSync)(configPath, "utf-8");
|
|
1879
2143
|
const parsed = JSON.parse(raw);
|
|
1880
2144
|
migrateStateToStateFile(parsed);
|
|
1881
2145
|
const normalizedInput = normalizeConfig(parsed);
|
|
@@ -1897,12 +2161,12 @@ function saveConfig(config) {
|
|
|
1897
2161
|
const configPath = getConfigPath();
|
|
1898
2162
|
const dir = getConfigDir();
|
|
1899
2163
|
const normalized = normalizeConfig(config);
|
|
1900
|
-
if (!(0,
|
|
1901
|
-
(0,
|
|
2164
|
+
if (!(0, import_fs3.existsSync)(dir)) {
|
|
2165
|
+
(0, import_fs3.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
1902
2166
|
}
|
|
1903
|
-
(0,
|
|
2167
|
+
(0, import_fs3.writeFileSync)(configPath, JSON.stringify(normalized, null, 2), { encoding: "utf-8", mode: 384 });
|
|
1904
2168
|
try {
|
|
1905
|
-
(0,
|
|
2169
|
+
(0, import_fs3.chmodSync)(configPath, 384);
|
|
1906
2170
|
} catch {
|
|
1907
2171
|
}
|
|
1908
2172
|
}
|
|
@@ -1929,13 +2193,13 @@ function isSetupComplete() {
|
|
|
1929
2193
|
function resetConfig() {
|
|
1930
2194
|
saveConfig({ ...DEFAULT_CONFIG });
|
|
1931
2195
|
}
|
|
1932
|
-
var import_os,
|
|
2196
|
+
var import_os, import_path3, import_fs3, import_crypto, DEFAULT_CONFIG, MACHINE_ID_PREFIX;
|
|
1933
2197
|
var init_config = __esm({
|
|
1934
2198
|
"src/config/config.ts"() {
|
|
1935
2199
|
"use strict";
|
|
1936
2200
|
import_os = require("os");
|
|
1937
|
-
|
|
1938
|
-
|
|
2201
|
+
import_path3 = require("path");
|
|
2202
|
+
import_fs3 = require("fs");
|
|
1939
2203
|
import_crypto = require("crypto");
|
|
1940
2204
|
DEFAULT_CONFIG = {
|
|
1941
2205
|
serverUrl: "https://api.adhf.dev",
|
|
@@ -3367,13 +3631,13 @@ __export(mesh_config_exports, {
|
|
|
3367
3631
|
updateNode: () => updateNode
|
|
3368
3632
|
});
|
|
3369
3633
|
function getMeshConfigPath() {
|
|
3370
|
-
return (0,
|
|
3634
|
+
return (0, import_path4.join)(getConfigDir(), "meshes.json");
|
|
3371
3635
|
}
|
|
3372
3636
|
function loadMeshConfig() {
|
|
3373
3637
|
const path46 = getMeshConfigPath();
|
|
3374
|
-
if (!(0,
|
|
3638
|
+
if (!(0, import_fs4.existsSync)(path46)) return { meshes: [] };
|
|
3375
3639
|
try {
|
|
3376
|
-
const raw = JSON.parse((0,
|
|
3640
|
+
const raw = JSON.parse((0, import_fs4.readFileSync)(path46, "utf-8"));
|
|
3377
3641
|
if (!raw || !Array.isArray(raw.meshes)) return { meshes: [] };
|
|
3378
3642
|
const config = raw;
|
|
3379
3643
|
const migrated = migrateLoadedMeshConfig(config);
|
|
@@ -3451,7 +3715,7 @@ function normalizeCapabilityTags(value) {
|
|
|
3451
3715
|
}
|
|
3452
3716
|
function saveMeshConfig(config) {
|
|
3453
3717
|
const path46 = getMeshConfigPath();
|
|
3454
|
-
(0,
|
|
3718
|
+
(0, import_fs4.writeFileSync)(path46, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 384 });
|
|
3455
3719
|
}
|
|
3456
3720
|
function normalizeRepoIdentity(remoteUrl) {
|
|
3457
3721
|
let identity = remoteUrl.trim();
|
|
@@ -3880,12 +4144,12 @@ function setDifficultyBrains(map) {
|
|
|
3880
4144
|
saveMeshConfig(stored);
|
|
3881
4145
|
return normalized;
|
|
3882
4146
|
}
|
|
3883
|
-
var
|
|
4147
|
+
var import_fs4, import_path4, import_crypto3, mergeMeshPolicy, MAGI_KIND_PANEL_KINDS, MAX_MAGI_KIND_SLOTS;
|
|
3884
4148
|
var init_mesh_config = __esm({
|
|
3885
4149
|
"src/config/mesh-config.ts"() {
|
|
3886
4150
|
"use strict";
|
|
3887
|
-
|
|
3888
|
-
|
|
4151
|
+
import_fs4 = require("fs");
|
|
4152
|
+
import_path4 = require("path");
|
|
3889
4153
|
import_crypto3 = require("crypto");
|
|
3890
4154
|
init_hash();
|
|
3891
4155
|
init_config();
|
|
@@ -5202,9 +5466,9 @@ function getPendingEventsPath(meshId, coordinatorDaemonId) {
|
|
|
5202
5466
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
5203
5467
|
if (coordinatorDaemonId) {
|
|
5204
5468
|
const safeDaemon = coordinatorDaemonId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
5205
|
-
return (0,
|
|
5469
|
+
return (0, import_path5.join)(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
|
|
5206
5470
|
}
|
|
5207
|
-
return (0,
|
|
5471
|
+
return (0, import_path5.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
|
|
5208
5472
|
}
|
|
5209
5473
|
function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
5210
5474
|
if (!meshId) return [];
|
|
@@ -5213,9 +5477,9 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
5213
5477
|
const paths = primaryDaemonId ? [getPendingEventsPath(meshId, primaryDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
5214
5478
|
const events = [];
|
|
5215
5479
|
for (const path46 of paths) {
|
|
5216
|
-
if (!(0,
|
|
5480
|
+
if (!(0, import_fs5.existsSync)(path46)) continue;
|
|
5217
5481
|
try {
|
|
5218
|
-
const raw = (0,
|
|
5482
|
+
const raw = (0, import_fs5.readFileSync)(path46, "utf-8");
|
|
5219
5483
|
const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
5220
5484
|
try {
|
|
5221
5485
|
return [JSON.parse(line)];
|
|
@@ -5305,9 +5569,9 @@ function prunePendingMeshCoordinatorEventsRetention() {
|
|
|
5305
5569
|
}
|
|
5306
5570
|
function trimPendingEventsIfNeeded(path46) {
|
|
5307
5571
|
try {
|
|
5308
|
-
if (!(0,
|
|
5309
|
-
if ((0,
|
|
5310
|
-
const lines = (0,
|
|
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);
|
|
5311
5575
|
if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
|
|
5312
5576
|
const dropped = lines.slice(0, lines.length - MAX_PENDING_EVENTS_KEEP);
|
|
5313
5577
|
for (const line of dropped) {
|
|
@@ -5343,7 +5607,7 @@ function trimPendingEventsIfNeeded(path46) {
|
|
|
5343
5607
|
LOG.warn("MeshEvents", `Failed to ledger-record trim-dropped ${event.event} for mesh ${event.meshId}: ${e?.message || e}`);
|
|
5344
5608
|
}
|
|
5345
5609
|
}
|
|
5346
|
-
(0,
|
|
5610
|
+
(0, import_fs5.writeFileSync)(path46, lines.slice(-MAX_PENDING_EVENTS_KEEP).join("\n") + "\n", "utf-8");
|
|
5347
5611
|
} catch {
|
|
5348
5612
|
}
|
|
5349
5613
|
}
|
|
@@ -5455,7 +5719,7 @@ function persistPendingMeshCoordinatorEvent(event) {
|
|
|
5455
5719
|
try {
|
|
5456
5720
|
const path46 = getPendingEventsPath(event.meshId, event.targetCoordinatorDaemonId);
|
|
5457
5721
|
trimPendingEventsIfNeeded(path46);
|
|
5458
|
-
(0,
|
|
5722
|
+
(0, import_fs5.appendFileSync)(path46, JSON.stringify(event) + "\n", "utf-8");
|
|
5459
5723
|
} catch (e) {
|
|
5460
5724
|
if (!sqliteOk) throw e;
|
|
5461
5725
|
LOG.warn("MeshEvents", `JSONL append failed for mesh ${event.meshId}; SQLite holds the event: ${e?.message || e}`);
|
|
@@ -5469,20 +5733,20 @@ function persistPendingMeshCoordinatorEvent(event) {
|
|
|
5469
5733
|
function atomicDrainFile(path46) {
|
|
5470
5734
|
const tmpPath = `${path46}.draining`;
|
|
5471
5735
|
try {
|
|
5472
|
-
(0,
|
|
5736
|
+
(0, import_fs5.renameSync)(path46, tmpPath);
|
|
5473
5737
|
} catch {
|
|
5474
5738
|
return null;
|
|
5475
5739
|
}
|
|
5476
5740
|
try {
|
|
5477
|
-
const content = (0,
|
|
5741
|
+
const content = (0, import_fs5.readFileSync)(tmpPath, "utf-8");
|
|
5478
5742
|
try {
|
|
5479
|
-
(0,
|
|
5743
|
+
(0, import_fs5.unlinkSync)(tmpPath);
|
|
5480
5744
|
} catch {
|
|
5481
5745
|
}
|
|
5482
5746
|
return content;
|
|
5483
5747
|
} catch {
|
|
5484
5748
|
try {
|
|
5485
|
-
(0,
|
|
5749
|
+
(0, import_fs5.unlinkSync)(tmpPath);
|
|
5486
5750
|
} catch {
|
|
5487
5751
|
}
|
|
5488
5752
|
return null;
|
|
@@ -5491,16 +5755,16 @@ function atomicDrainFile(path46) {
|
|
|
5491
5755
|
function selectiveDrainFile(path46, predicate) {
|
|
5492
5756
|
const tmpPath = `${path46}.draining`;
|
|
5493
5757
|
try {
|
|
5494
|
-
(0,
|
|
5758
|
+
(0, import_fs5.renameSync)(path46, tmpPath);
|
|
5495
5759
|
} catch {
|
|
5496
5760
|
return [];
|
|
5497
5761
|
}
|
|
5498
5762
|
let content;
|
|
5499
5763
|
try {
|
|
5500
|
-
content = (0,
|
|
5764
|
+
content = (0, import_fs5.readFileSync)(tmpPath, "utf-8");
|
|
5501
5765
|
} catch {
|
|
5502
5766
|
try {
|
|
5503
|
-
(0,
|
|
5767
|
+
(0, import_fs5.unlinkSync)(tmpPath);
|
|
5504
5768
|
} catch {
|
|
5505
5769
|
}
|
|
5506
5770
|
return [];
|
|
@@ -5523,12 +5787,12 @@ function selectiveDrainFile(path46, predicate) {
|
|
|
5523
5787
|
}
|
|
5524
5788
|
try {
|
|
5525
5789
|
if (keptLines.length > 0) {
|
|
5526
|
-
(0,
|
|
5790
|
+
(0, import_fs5.writeFileSync)(path46, keptLines.join("\n") + "\n", "utf-8");
|
|
5527
5791
|
}
|
|
5528
|
-
(0,
|
|
5792
|
+
(0, import_fs5.unlinkSync)(tmpPath);
|
|
5529
5793
|
} catch {
|
|
5530
5794
|
try {
|
|
5531
|
-
if ((0,
|
|
5795
|
+
if ((0, import_fs5.existsSync)(tmpPath) && !(0, import_fs5.existsSync)(path46)) (0, import_fs5.renameSync)(tmpPath, path46);
|
|
5532
5796
|
} catch {
|
|
5533
5797
|
}
|
|
5534
5798
|
return [];
|
|
@@ -5756,18 +6020,18 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
5756
6020
|
}
|
|
5757
6021
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
5758
6022
|
for (const path46 of paths) {
|
|
5759
|
-
if ((0,
|
|
5760
|
-
(0,
|
|
6023
|
+
if ((0, import_fs5.existsSync)(path46)) try {
|
|
6024
|
+
(0, import_fs5.unlinkSync)(path46);
|
|
5761
6025
|
} catch {
|
|
5762
6026
|
}
|
|
5763
6027
|
}
|
|
5764
6028
|
}
|
|
5765
|
-
var
|
|
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;
|
|
5766
6030
|
var init_mesh_events_pending = __esm({
|
|
5767
6031
|
"src/mesh/mesh-events-pending.ts"() {
|
|
5768
6032
|
"use strict";
|
|
5769
|
-
|
|
5770
|
-
|
|
6033
|
+
import_fs5 = require("fs");
|
|
6034
|
+
import_path5 = require("path");
|
|
5771
6035
|
import_crypto5 = require("crypto");
|
|
5772
6036
|
init_logger();
|
|
5773
6037
|
init_config();
|
|
@@ -7118,15 +7382,15 @@ function safeMeshId(meshId) {
|
|
|
7118
7382
|
return meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
7119
7383
|
}
|
|
7120
7384
|
function legacyQueuePath(meshId) {
|
|
7121
|
-
return (0,
|
|
7385
|
+
return (0, import_path6.join)(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
|
|
7122
7386
|
}
|
|
7123
7387
|
function cleanupStrayRootRuntimeDb(canonicalPath) {
|
|
7124
7388
|
try {
|
|
7125
|
-
const strayPath = (0,
|
|
7389
|
+
const strayPath = (0, import_path6.join)(getConfigDir(), "mesh-runtime.db");
|
|
7126
7390
|
if (strayPath === canonicalPath) return;
|
|
7127
|
-
if (!(0,
|
|
7128
|
-
if ((0,
|
|
7129
|
-
(0,
|
|
7391
|
+
if (!(0, import_fs6.existsSync)(strayPath)) return;
|
|
7392
|
+
if ((0, import_fs6.statSync)(strayPath).size !== 0) return;
|
|
7393
|
+
(0, import_fs6.unlinkSync)(strayPath);
|
|
7130
7394
|
if (!loggedStrayCleanup) {
|
|
7131
7395
|
loggedStrayCleanup = true;
|
|
7132
7396
|
LOG.info("MeshRuntimeStore", `Removed stray 0-byte root mesh-runtime.db at ${strayPath}`);
|
|
@@ -7140,17 +7404,17 @@ function cleanupStrayRootRuntimeDb(canonicalPath) {
|
|
|
7140
7404
|
}
|
|
7141
7405
|
function meshRuntimeStorePath() {
|
|
7142
7406
|
const dir = getLedgerDir();
|
|
7143
|
-
const nextPath = (0,
|
|
7407
|
+
const nextPath = (0, import_path6.join)(dir, "mesh-runtime.db");
|
|
7144
7408
|
cleanupStrayRootRuntimeDb(nextPath);
|
|
7145
|
-
if ((0,
|
|
7146
|
-
const legacyPath = (0,
|
|
7147
|
-
if (!(0,
|
|
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;
|
|
7148
7412
|
try {
|
|
7149
|
-
(0,
|
|
7413
|
+
(0, import_fs6.renameSync)(legacyPath, nextPath);
|
|
7150
7414
|
for (const suffix of ["-wal", "-shm"]) {
|
|
7151
7415
|
const legacyCompanion = `${legacyPath}${suffix}`;
|
|
7152
|
-
if ((0,
|
|
7153
|
-
(0,
|
|
7416
|
+
if ((0, import_fs6.existsSync)(legacyCompanion)) {
|
|
7417
|
+
(0, import_fs6.renameSync)(legacyCompanion, `${nextPath}${suffix}`);
|
|
7154
7418
|
}
|
|
7155
7419
|
}
|
|
7156
7420
|
} catch (err) {
|
|
@@ -7161,7 +7425,7 @@ function meshRuntimeStorePath() {
|
|
|
7161
7425
|
`Legacy beads.db\u2192mesh-runtime.db migration failed; using existing DB in-place to avoid data loss: ${err?.message || err}`
|
|
7162
7426
|
);
|
|
7163
7427
|
}
|
|
7164
|
-
return (0,
|
|
7428
|
+
return (0, import_fs6.existsSync)(nextPath) ? nextPath : legacyPath;
|
|
7165
7429
|
}
|
|
7166
7430
|
return nextPath;
|
|
7167
7431
|
}
|
|
@@ -7180,12 +7444,12 @@ function pruneMeshRuntimeRetention() {
|
|
|
7180
7444
|
return { ledger: 0, toolCalls: 0, terminalQueue: 0 };
|
|
7181
7445
|
}
|
|
7182
7446
|
}
|
|
7183
|
-
var
|
|
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;
|
|
7184
7448
|
var init_mesh_runtime_store = __esm({
|
|
7185
7449
|
"src/mesh/mesh-runtime-store.ts"() {
|
|
7186
7450
|
"use strict";
|
|
7187
|
-
|
|
7188
|
-
|
|
7451
|
+
import_fs6 = require("fs");
|
|
7452
|
+
import_path6 = require("path");
|
|
7189
7453
|
init_logger();
|
|
7190
7454
|
init_load_better_sqlite3();
|
|
7191
7455
|
init_config();
|
|
@@ -7216,8 +7480,8 @@ var init_mesh_runtime_store = __esm({
|
|
|
7216
7480
|
static WAL_MAX_BYTES = 50 * 1024 * 1024;
|
|
7217
7481
|
// 50 MB
|
|
7218
7482
|
constructor(dbPath) {
|
|
7219
|
-
const dir = (0,
|
|
7220
|
-
if (!(0,
|
|
7483
|
+
const dir = (0, import_path6.dirname)(dbPath);
|
|
7484
|
+
if (!(0, import_fs6.existsSync)(dir)) (0, import_fs6.mkdirSync)(dir, { recursive: true });
|
|
7221
7485
|
this.dbPath = dbPath;
|
|
7222
7486
|
this.db = new (loadDatabaseCtor())(dbPath);
|
|
7223
7487
|
this.db.pragma("journal_mode = WAL");
|
|
@@ -7596,8 +7860,8 @@ var init_mesh_runtime_store = __esm({
|
|
|
7596
7860
|
this.walWriteCounter = 0;
|
|
7597
7861
|
try {
|
|
7598
7862
|
const walPath = `${this.dbPath}-wal`;
|
|
7599
|
-
if (!(0,
|
|
7600
|
-
const size = (0,
|
|
7863
|
+
if (!(0, import_fs6.existsSync)(walPath)) return;
|
|
7864
|
+
const size = (0, import_fs6.statSync)(walPath).size;
|
|
7601
7865
|
if (size < _MeshRuntimeStore.WAL_MAX_BYTES) return;
|
|
7602
7866
|
process.stderr.write(
|
|
7603
7867
|
`[adhdev-mesh] WAL file ${Math.round(size / 1024 / 1024)}MB exceeds threshold; forcing checkpoint
|
|
@@ -7613,9 +7877,9 @@ var init_mesh_runtime_store = __esm({
|
|
|
7613
7877
|
const count = this.db.prepare("SELECT COUNT(*) AS count FROM mesh_queue WHERE mesh_id = ?").get(meshId);
|
|
7614
7878
|
if (count.count > 0) return;
|
|
7615
7879
|
const path46 = legacyQueuePath(meshId);
|
|
7616
|
-
if (!(0,
|
|
7880
|
+
if (!(0, import_fs6.existsSync)(path46)) return;
|
|
7617
7881
|
try {
|
|
7618
|
-
const entries = JSON.parse((0,
|
|
7882
|
+
const entries = JSON.parse((0, import_fs6.readFileSync)(path46, "utf-8"));
|
|
7619
7883
|
if (!Array.isArray(entries)) return;
|
|
7620
7884
|
const insert = this.db.prepare(`
|
|
7621
7885
|
INSERT OR REPLACE INTO mesh_queue (
|
|
@@ -9066,41 +9330,41 @@ function isNoteExpired(note, now) {
|
|
|
9066
9330
|
return now - created >= ttlDays * MS_PER_DAY;
|
|
9067
9331
|
}
|
|
9068
9332
|
function getLedgerDir() {
|
|
9069
|
-
const dir = (0,
|
|
9070
|
-
if (!(0,
|
|
9071
|
-
(0,
|
|
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 });
|
|
9072
9336
|
}
|
|
9073
9337
|
return dir;
|
|
9074
9338
|
}
|
|
9075
9339
|
function getLedgerPath(meshId) {
|
|
9076
9340
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
9077
|
-
return (0,
|
|
9341
|
+
return (0, import_path7.join)(getLedgerDir(), `${safe}.jsonl`);
|
|
9078
9342
|
}
|
|
9079
9343
|
function getRotatedPath(meshId, index) {
|
|
9080
9344
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
9081
|
-
return (0,
|
|
9345
|
+
return (0, import_path7.join)(getLedgerDir(), `${safe}.${index}.jsonl`);
|
|
9082
9346
|
}
|
|
9083
9347
|
function getArchivePath(meshId) {
|
|
9084
9348
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
9085
|
-
return (0,
|
|
9349
|
+
return (0, import_path7.join)(getLedgerDir(), `${safe}.archive.jsonl`);
|
|
9086
9350
|
}
|
|
9087
9351
|
function getRotatedArchivePath(meshId, index) {
|
|
9088
9352
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
9089
|
-
return (0,
|
|
9353
|
+
return (0, import_path7.join)(getLedgerDir(), `${safe}.archive.${index}.jsonl`);
|
|
9090
9354
|
}
|
|
9091
9355
|
function getArchivedCountsPath(meshId) {
|
|
9092
9356
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
9093
|
-
return (0,
|
|
9357
|
+
return (0, import_path7.join)(getLedgerDir(), `${safe}.archived-counts.json`);
|
|
9094
9358
|
}
|
|
9095
9359
|
function rotateArchiveFile(meshId, archivePath) {
|
|
9096
9360
|
let index = 1;
|
|
9097
|
-
while ((0,
|
|
9361
|
+
while ((0, import_fs7.existsSync)(getRotatedArchivePath(meshId, index))) {
|
|
9098
9362
|
index++;
|
|
9099
9363
|
if (index > 5) break;
|
|
9100
9364
|
}
|
|
9101
9365
|
if (index > 5) index = 5;
|
|
9102
9366
|
try {
|
|
9103
|
-
(0,
|
|
9367
|
+
(0, import_fs7.renameSync)(archivePath, getRotatedArchivePath(meshId, index));
|
|
9104
9368
|
} catch (e) {
|
|
9105
9369
|
process.stderr.write(`[adhdev-mesh] Archive rotation failed for mesh ${meshId}: ${e?.message || e}
|
|
9106
9370
|
`);
|
|
@@ -9108,9 +9372,9 @@ function rotateArchiveFile(meshId, archivePath) {
|
|
|
9108
9372
|
}
|
|
9109
9373
|
function readArchivedCounts(meshId) {
|
|
9110
9374
|
const path46 = getArchivedCountsPath(meshId);
|
|
9111
|
-
if (!(0,
|
|
9375
|
+
if (!(0, import_fs7.existsSync)(path46)) return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
9112
9376
|
try {
|
|
9113
|
-
return JSON.parse((0,
|
|
9377
|
+
return JSON.parse((0, import_fs7.readFileSync)(path46, "utf-8"));
|
|
9114
9378
|
} catch {
|
|
9115
9379
|
return { taskCompleted: 0, taskFailed: 0, taskStalled: 0, recoveryAttempted: 0, totalArchived: 0, lastArchivedAt: "" };
|
|
9116
9380
|
}
|
|
@@ -9126,7 +9390,7 @@ function updateArchivedCounts(meshId, archived) {
|
|
|
9126
9390
|
counts.totalArchived += archived.length;
|
|
9127
9391
|
counts.lastArchivedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9128
9392
|
try {
|
|
9129
|
-
(0,
|
|
9393
|
+
(0, import_fs7.writeFileSync)(getArchivedCountsPath(meshId), JSON.stringify(counts), { encoding: "utf-8", mode: 384 });
|
|
9130
9394
|
} catch {
|
|
9131
9395
|
}
|
|
9132
9396
|
}
|
|
@@ -9149,7 +9413,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
9149
9413
|
}
|
|
9150
9414
|
function compactLedger(meshId) {
|
|
9151
9415
|
const filePath = getLedgerPath(meshId);
|
|
9152
|
-
if (!(0,
|
|
9416
|
+
if (!(0, import_fs7.existsSync)(filePath)) return { archivedCount: 0, retainedCount: 0 };
|
|
9153
9417
|
const cutoff = Date.now() - ARCHIVE_TERMINAL_OLDER_THAN_MS;
|
|
9154
9418
|
const entries = readLedgerEntries(meshId);
|
|
9155
9419
|
const keep = [];
|
|
@@ -9164,11 +9428,11 @@ function compactLedger(meshId) {
|
|
|
9164
9428
|
if (archive.length === 0) return { archivedCount: 0, retainedCount: keep.length };
|
|
9165
9429
|
const archivePath = getArchivePath(meshId);
|
|
9166
9430
|
try {
|
|
9167
|
-
if ((0,
|
|
9431
|
+
if ((0, import_fs7.existsSync)(archivePath) && (0, import_fs7.statSync)(archivePath).size > 50 * 1024 * 1024) {
|
|
9168
9432
|
rotateArchiveFile(meshId, archivePath);
|
|
9169
9433
|
}
|
|
9170
9434
|
const archiveLines = archive.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
9171
|
-
(0,
|
|
9435
|
+
(0, import_fs7.appendFileSync)(archivePath, archiveLines, { encoding: "utf-8", mode: 384 });
|
|
9172
9436
|
updateArchivedCounts(meshId, archive);
|
|
9173
9437
|
} catch (e) {
|
|
9174
9438
|
process.stderr.write(`[adhdev-mesh] Ledger archive write failed for mesh ${meshId}: ${e?.message || e}
|
|
@@ -9177,7 +9441,7 @@ function compactLedger(meshId) {
|
|
|
9177
9441
|
}
|
|
9178
9442
|
try {
|
|
9179
9443
|
const keepLines = keep.length ? keep.map((e) => JSON.stringify(e)).join("\n") + "\n" : "";
|
|
9180
|
-
(0,
|
|
9444
|
+
(0, import_fs7.writeFileSync)(filePath, keepLines, { encoding: "utf-8", mode: 384 });
|
|
9181
9445
|
invalidateLedgerCache(meshId);
|
|
9182
9446
|
} catch (e) {
|
|
9183
9447
|
process.stderr.write(`[adhdev-mesh] Ledger compaction rewrite failed for mesh ${meshId}: ${e?.message || e}
|
|
@@ -9355,9 +9619,9 @@ function appendLedgerEntry(meshId, partial) {
|
|
|
9355
9619
|
...partial
|
|
9356
9620
|
};
|
|
9357
9621
|
const filePath = getLedgerPath(meshId);
|
|
9358
|
-
if ((0,
|
|
9622
|
+
if ((0, import_fs7.existsSync)(filePath)) {
|
|
9359
9623
|
try {
|
|
9360
|
-
const stat2 = (0,
|
|
9624
|
+
const stat2 = (0, import_fs7.statSync)(filePath);
|
|
9361
9625
|
if (stat2.size >= MAX_FILE_SIZE_BYTES) {
|
|
9362
9626
|
rotateLedgerFile(meshId, filePath);
|
|
9363
9627
|
} else if (stat2.size >= COMPACT_THRESHOLD_BYTES) {
|
|
@@ -9382,7 +9646,7 @@ function appendLedgerEntry(meshId, partial) {
|
|
|
9382
9646
|
}
|
|
9383
9647
|
try {
|
|
9384
9648
|
const line = JSON.stringify(entry) + "\n";
|
|
9385
|
-
(0,
|
|
9649
|
+
(0, import_fs7.appendFileSync)(filePath, line, { encoding: "utf-8", mode: 384 });
|
|
9386
9650
|
invalidateLedgerCache(meshId);
|
|
9387
9651
|
meshLedgerEvents.emit("append", meshId, entry);
|
|
9388
9652
|
if (entry.kind === OPERATING_NOTE_KIND || entry.kind === OPERATING_NOTE_TOMBSTONE_KIND) {
|
|
@@ -9474,7 +9738,7 @@ function pruneOperatingNotes(meshId, keepLatest = OPERATING_NOTE_KEEP_LATEST) {
|
|
|
9474
9738
|
const remaining = readLedgerFile(meshId).filter((e) => !removeIds.includes(e.id));
|
|
9475
9739
|
const filePath = getLedgerPath(meshId);
|
|
9476
9740
|
const lines = remaining.length ? remaining.map((e) => JSON.stringify(e)).join("\n") + "\n" : "";
|
|
9477
|
-
(0,
|
|
9741
|
+
(0, import_fs7.writeFileSync)(filePath, lines, { encoding: "utf-8", mode: 384 });
|
|
9478
9742
|
} catch {
|
|
9479
9743
|
}
|
|
9480
9744
|
invalidateLedgerCache(meshId);
|
|
@@ -9531,7 +9795,7 @@ function appendRemoteLedgerEntries(meshId, entries) {
|
|
|
9531
9795
|
}
|
|
9532
9796
|
try {
|
|
9533
9797
|
const lines = validEntries.map((e) => JSON.stringify(e)).join("\n") + "\n";
|
|
9534
|
-
(0,
|
|
9798
|
+
(0, import_fs7.appendFileSync)(ledgerPath, lines, { encoding: "utf-8", mode: 384 });
|
|
9535
9799
|
invalidateLedgerCache(meshId);
|
|
9536
9800
|
for (const entry of validEntries) {
|
|
9537
9801
|
meshLedgerEvents.emit("append", meshId, entry);
|
|
@@ -9543,10 +9807,10 @@ function appendRemoteLedgerEntries(meshId, entries) {
|
|
|
9543
9807
|
}
|
|
9544
9808
|
function readLedgerFile(meshId) {
|
|
9545
9809
|
const filePath = getLedgerPath(meshId);
|
|
9546
|
-
if (!(0,
|
|
9810
|
+
if (!(0, import_fs7.existsSync)(filePath)) return [];
|
|
9547
9811
|
let content;
|
|
9548
9812
|
try {
|
|
9549
|
-
content = (0,
|
|
9813
|
+
content = (0, import_fs7.readFileSync)(filePath, "utf-8");
|
|
9550
9814
|
} catch {
|
|
9551
9815
|
return [];
|
|
9552
9816
|
}
|
|
@@ -9811,24 +10075,24 @@ function getSessionRecoveryContext(meshId, opts) {
|
|
|
9811
10075
|
}
|
|
9812
10076
|
function rotateLedgerFile(meshId, currentPath) {
|
|
9813
10077
|
let index = 1;
|
|
9814
|
-
while ((0,
|
|
10078
|
+
while ((0, import_fs7.existsSync)(getRotatedPath(meshId, index))) {
|
|
9815
10079
|
index++;
|
|
9816
10080
|
if (index > 10) break;
|
|
9817
10081
|
}
|
|
9818
10082
|
if (index > 10) index = 10;
|
|
9819
10083
|
try {
|
|
9820
|
-
(0,
|
|
10084
|
+
(0, import_fs7.renameSync)(currentPath, getRotatedPath(meshId, index));
|
|
9821
10085
|
} catch (e) {
|
|
9822
10086
|
process.stderr.write(`[adhdev-mesh] Ledger rotation failed for mesh ${meshId}: ${e?.message || e}. File will continue to grow.
|
|
9823
10087
|
`);
|
|
9824
10088
|
}
|
|
9825
10089
|
}
|
|
9826
|
-
var
|
|
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;
|
|
9827
10091
|
var init_mesh_ledger = __esm({
|
|
9828
10092
|
"src/mesh/mesh-ledger.ts"() {
|
|
9829
10093
|
"use strict";
|
|
9830
|
-
|
|
9831
|
-
|
|
10094
|
+
import_fs7 = require("fs");
|
|
10095
|
+
import_path7 = require("path");
|
|
9832
10096
|
import_crypto8 = require("crypto");
|
|
9833
10097
|
init_config();
|
|
9834
10098
|
init_dist();
|
|
@@ -11213,13 +11477,13 @@ var init_mesh_coordinator = __esm({
|
|
|
11213
11477
|
|
|
11214
11478
|
// src/mesh/coordinator-registry.ts
|
|
11215
11479
|
function getRegistryPath() {
|
|
11216
|
-
return (0,
|
|
11480
|
+
return (0, import_path8.join)(getDaemonDataDir(), "mesh-coordinators.json");
|
|
11217
11481
|
}
|
|
11218
11482
|
function loadMeshCoordinatorRegistry() {
|
|
11219
11483
|
const path46 = getRegistryPath();
|
|
11220
|
-
if (!(0,
|
|
11484
|
+
if (!(0, import_fs8.existsSync)(path46)) return;
|
|
11221
11485
|
try {
|
|
11222
|
-
const raw = JSON.parse((0,
|
|
11486
|
+
const raw = JSON.parse((0, import_fs8.readFileSync)(path46, "utf-8"));
|
|
11223
11487
|
if (!Array.isArray(raw)) return;
|
|
11224
11488
|
_registry.clear();
|
|
11225
11489
|
for (const entry of raw) {
|
|
@@ -11232,7 +11496,7 @@ function loadMeshCoordinatorRegistry() {
|
|
|
11232
11496
|
}
|
|
11233
11497
|
function saveRegistry() {
|
|
11234
11498
|
try {
|
|
11235
|
-
(0,
|
|
11499
|
+
(0, import_fs8.writeFileSync)(
|
|
11236
11500
|
getRegistryPath(),
|
|
11237
11501
|
JSON.stringify([..._registry.values()], null, 2),
|
|
11238
11502
|
{ encoding: "utf-8", mode: 384 }
|
|
@@ -11265,12 +11529,12 @@ function getCoordinatorForSession(sessionId) {
|
|
|
11265
11529
|
function listCoordinatorsForWorkspace(workspace) {
|
|
11266
11530
|
return [..._registry.values()].filter((e) => e.workspace === workspace);
|
|
11267
11531
|
}
|
|
11268
|
-
var
|
|
11532
|
+
var import_path8, import_fs8, _registry;
|
|
11269
11533
|
var init_coordinator_registry = __esm({
|
|
11270
11534
|
"src/mesh/coordinator-registry.ts"() {
|
|
11271
11535
|
"use strict";
|
|
11272
|
-
|
|
11273
|
-
|
|
11536
|
+
import_path8 = require("path");
|
|
11537
|
+
import_fs8 = require("fs");
|
|
11274
11538
|
init_config();
|
|
11275
11539
|
_registry = /* @__PURE__ */ new Map();
|
|
11276
11540
|
}
|
|
@@ -11360,14 +11624,14 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
11360
11624
|
const rejectedCommands = [];
|
|
11361
11625
|
const deprecationWarnings = [];
|
|
11362
11626
|
let bootstrapMode = "inherit";
|
|
11363
|
-
if (!
|
|
11627
|
+
if (!isRecord3(config)) return { valid: false, errors: ["config must be an object"], bootstrapCommands, commands, rejectedCommands, bootstrapMode, deprecationWarnings };
|
|
11364
11628
|
if (config.version !== 1) errors.push("version must be 1");
|
|
11365
11629
|
if (config.allowAutoPublishSubmoduleMainCommits !== void 0 && typeof config.allowAutoPublishSubmoduleMainCommits !== "boolean") {
|
|
11366
11630
|
errors.push("allowAutoPublishSubmoduleMainCommits must be a boolean when provided");
|
|
11367
11631
|
}
|
|
11368
11632
|
const validation = config.validation;
|
|
11369
|
-
if (validation !== void 0 && !
|
|
11370
|
-
const rawBootstrapMode =
|
|
11633
|
+
if (validation !== void 0 && !isRecord3(validation)) errors.push("validation must be an object");
|
|
11634
|
+
const rawBootstrapMode = isRecord3(validation) ? validation.bootstrap : void 0;
|
|
11371
11635
|
if (rawBootstrapMode !== void 0) {
|
|
11372
11636
|
if (rawBootstrapMode === "inherit" || rawBootstrapMode === "skip") {
|
|
11373
11637
|
bootstrapMode = rawBootstrapMode;
|
|
@@ -11375,8 +11639,8 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
11375
11639
|
errors.push("validation.bootstrap must be 'inherit' or 'skip' when provided");
|
|
11376
11640
|
}
|
|
11377
11641
|
}
|
|
11378
|
-
const rawCommands =
|
|
11379
|
-
const rawBootstrapCommands =
|
|
11642
|
+
const rawCommands = isRecord3(validation) ? validation.commands : void 0;
|
|
11643
|
+
const rawBootstrapCommands = isRecord3(validation) ? validation.bootstrapCommands : void 0;
|
|
11380
11644
|
if (rawCommands !== void 0 && !Array.isArray(rawCommands)) errors.push("validation.commands must be an array");
|
|
11381
11645
|
if (rawBootstrapCommands !== void 0 && !Array.isArray(rawBootstrapCommands)) errors.push("validation.bootstrapCommands must be an array");
|
|
11382
11646
|
if (Array.isArray(rawBootstrapCommands) && rawBootstrapCommands.length > 0) {
|
|
@@ -11399,9 +11663,9 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
11399
11663
|
if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
|
|
11400
11664
|
return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands, bootstrapMode, deprecationWarnings };
|
|
11401
11665
|
}
|
|
11402
|
-
function
|
|
11666
|
+
function parseConfigText3(path46, text) {
|
|
11403
11667
|
if (/\.json$/i.test(path46)) return JSON.parse(text);
|
|
11404
|
-
return
|
|
11668
|
+
return yaml3.load(text);
|
|
11405
11669
|
}
|
|
11406
11670
|
function loadMeshRefineConfig(mesh, workspace) {
|
|
11407
11671
|
const policy = mesh?.policy && typeof mesh.policy === "object" && !Array.isArray(mesh.policy) ? mesh.policy : {};
|
|
@@ -11412,10 +11676,10 @@ function loadMeshRefineConfig(mesh, workspace) {
|
|
|
11412
11676
|
return { config: inline, source: "mesh.policy.refineConfig", sourceType: "mesh_policy" };
|
|
11413
11677
|
}
|
|
11414
11678
|
for (const relative5 of MESH_REFINE_CONFIG_LOCATIONS) {
|
|
11415
|
-
const configPath = (0,
|
|
11416
|
-
if (!(0,
|
|
11679
|
+
const configPath = (0, import_path9.join)(workspace, relative5);
|
|
11680
|
+
if (!(0, import_fs9.existsSync)(configPath)) continue;
|
|
11417
11681
|
try {
|
|
11418
|
-
const parsed =
|
|
11682
|
+
const parsed = parseConfigText3(configPath, (0, import_fs9.readFileSync)(configPath, "utf-8"));
|
|
11419
11683
|
const validation = validateMeshRefineConfig(parsed, relative5);
|
|
11420
11684
|
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
11421
11685
|
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
@@ -11431,20 +11695,20 @@ function loadMeshRefineConfig(mesh, workspace) {
|
|
|
11431
11695
|
}
|
|
11432
11696
|
function readPackageScripts(workspace) {
|
|
11433
11697
|
try {
|
|
11434
|
-
const parsed = JSON.parse((0,
|
|
11435
|
-
return
|
|
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 : {};
|
|
11436
11700
|
} catch {
|
|
11437
11701
|
return {};
|
|
11438
11702
|
}
|
|
11439
11703
|
}
|
|
11440
11704
|
function collectProjectContextSuggestions(mesh) {
|
|
11441
11705
|
const commands = mesh?.projectContext?.commands;
|
|
11442
|
-
if (!
|
|
11706
|
+
if (!isRecord3(commands)) return [];
|
|
11443
11707
|
const suggestions = [];
|
|
11444
11708
|
for (const category of MESH_REFINE_VALIDATION_CATEGORIES) {
|
|
11445
11709
|
const entries = Array.isArray(commands[category]) ? commands[category] : [];
|
|
11446
11710
|
for (const entry of entries) {
|
|
11447
|
-
if (
|
|
11711
|
+
if (isRecord3(entry) && typeof entry.command === "string") suggestions.push({ command: entry.command, category });
|
|
11448
11712
|
}
|
|
11449
11713
|
}
|
|
11450
11714
|
return suggestions;
|
|
@@ -11506,13 +11770,13 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
|
|
|
11506
11770
|
unavailableReason: validation.commands.length ? void 0 : "validation_unavailable: repo mesh/refine config has no validation.commands"
|
|
11507
11771
|
};
|
|
11508
11772
|
}
|
|
11509
|
-
var
|
|
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;
|
|
11510
11774
|
var init_refine_config = __esm({
|
|
11511
11775
|
"src/mesh/refine-config.ts"() {
|
|
11512
11776
|
"use strict";
|
|
11513
|
-
|
|
11514
|
-
|
|
11515
|
-
|
|
11777
|
+
import_fs9 = require("fs");
|
|
11778
|
+
import_path9 = require("path");
|
|
11779
|
+
yaml3 = __toESM(require("js-yaml"));
|
|
11516
11780
|
MESH_REFINE_VALIDATION_CATEGORIES = ["typecheck", "test", "lint", "build"];
|
|
11517
11781
|
MESH_REFINE_VALIDATION_SCOPES = ["none", "web", "daemon"];
|
|
11518
11782
|
MESH_REFINE_CONFIG_LOCATIONS = [
|
|
@@ -11603,7 +11867,7 @@ var init_refine_config = __esm({
|
|
|
11603
11867
|
SHELL_METACHAR_RE = /[;&|<>`$\n\r'"]/;
|
|
11604
11868
|
SAFE_TOKEN_RE = /^[A-Za-z0-9_@./:=+-]+$/;
|
|
11605
11869
|
SAFE_WIN32_EXEC_TOKEN_RE = /^[A-Za-z0-9_@./:=+\\-]+$/;
|
|
11606
|
-
|
|
11870
|
+
isRecord3 = isMeshConfigRecord;
|
|
11607
11871
|
}
|
|
11608
11872
|
});
|
|
11609
11873
|
|
|
@@ -11622,7 +11886,7 @@ function resolveWin32GlobalBin(trimmed) {
|
|
|
11622
11886
|
if (!dir) continue;
|
|
11623
11887
|
for (const ext of WIN_EXEC_EXT) {
|
|
11624
11888
|
const full = path10.join(dir, trimmed + ext);
|
|
11625
|
-
if ((0,
|
|
11889
|
+
if ((0, import_fs10.existsSync)(full)) return full;
|
|
11626
11890
|
}
|
|
11627
11891
|
}
|
|
11628
11892
|
return null;
|
|
@@ -11639,7 +11903,7 @@ function resolveWin32Executable(command) {
|
|
|
11639
11903
|
if (process.platform !== "win32") return command;
|
|
11640
11904
|
const trimmed = (command || "").trim();
|
|
11641
11905
|
if (!trimmed) return command;
|
|
11642
|
-
if (path10.isAbsolute(trimmed) && (0,
|
|
11906
|
+
if (path10.isAbsolute(trimmed) && (0, import_fs10.existsSync)(trimmed)) return trimmed;
|
|
11643
11907
|
try {
|
|
11644
11908
|
const out = (0, import_child_process.execFileSync)("where", [trimmed], {
|
|
11645
11909
|
encoding: "utf8",
|
|
@@ -11687,12 +11951,12 @@ function buildWin32ExecFileSpawn(resolvedCommand, args) {
|
|
|
11687
11951
|
windowsVerbatimArguments: true
|
|
11688
11952
|
};
|
|
11689
11953
|
}
|
|
11690
|
-
var import_child_process,
|
|
11954
|
+
var import_child_process, import_fs10, path10, DIRECT_EXEC_EXT, SHIM_EXEC_EXT, WIN_EXEC_EXT;
|
|
11691
11955
|
var init_resolve_executable = __esm({
|
|
11692
11956
|
"src/cli-adapters/resolve-executable.ts"() {
|
|
11693
11957
|
"use strict";
|
|
11694
11958
|
import_child_process = require("child_process");
|
|
11695
|
-
|
|
11959
|
+
import_fs10 = require("fs");
|
|
11696
11960
|
path10 = __toESM(require("path"));
|
|
11697
11961
|
DIRECT_EXEC_EXT = /* @__PURE__ */ new Set([".exe", ".com"]);
|
|
11698
11962
|
SHIM_EXEC_EXT = /* @__PURE__ */ new Set([".cmd", ".bat"]);
|
|
@@ -11832,7 +12096,7 @@ function isWorktreeBootstrapStaleRunning(node, nowMs = Date.now()) {
|
|
|
11832
12096
|
if (!Number.isFinite(startedMs)) return false;
|
|
11833
12097
|
if (nowMs - startedMs <= WORKTREE_BOOTSTRAP_STALE_RUNNING_MS) return false;
|
|
11834
12098
|
const workspace = typeof node?.workspace === "string" ? node.workspace.trim() : "";
|
|
11835
|
-
if (!workspace || !(0,
|
|
12099
|
+
if (!workspace || !(0, import_fs11.existsSync)(workspace)) return false;
|
|
11836
12100
|
try {
|
|
11837
12101
|
const out = (0, import_node_child_process3.execFileSync)(resolveWin32Executable("git"), ["status", "--porcelain"], {
|
|
11838
12102
|
cwd: workspace,
|
|
@@ -11853,9 +12117,9 @@ function shouldDeferDispatchForBootstrap(node, nowMs = Date.now()) {
|
|
|
11853
12117
|
if (node?.worktreeBootstrap?.status !== "running") return false;
|
|
11854
12118
|
return !isWorktreeBootstrapStaleRunning(node, nowMs);
|
|
11855
12119
|
}
|
|
11856
|
-
function
|
|
12120
|
+
function parseConfigText4(path46, text) {
|
|
11857
12121
|
if (/\.json$/i.test(path46)) return JSON.parse(text);
|
|
11858
|
-
return
|
|
12122
|
+
return yaml4.load(text);
|
|
11859
12123
|
}
|
|
11860
12124
|
function truncateOutput(value) {
|
|
11861
12125
|
const text = typeof value === "string" ? value : value == null ? "" : String(value);
|
|
@@ -11895,10 +12159,10 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
11895
12159
|
return { config: inline, source: "mesh.policy.worktreeBootstrapConfig", sourceType: "mesh_policy" };
|
|
11896
12160
|
}
|
|
11897
12161
|
for (const relative5 of MESH_WORKTREE_BOOTSTRAP_CONFIG_LOCATIONS) {
|
|
11898
|
-
const configPath = (0,
|
|
11899
|
-
if (!(0,
|
|
12162
|
+
const configPath = (0, import_path10.join)(workspace, relative5);
|
|
12163
|
+
if (!(0, import_fs11.existsSync)(configPath)) continue;
|
|
11900
12164
|
try {
|
|
11901
|
-
const parsed =
|
|
12165
|
+
const parsed = parseConfigText4(configPath, (0, import_fs11.readFileSync)(configPath, "utf-8"));
|
|
11902
12166
|
const validation = validateMeshWorktreeBootstrapConfig(parsed, relative5);
|
|
11903
12167
|
if (!validation.valid) return { source: relative5, sourceType: "invalid", path: configPath, error: String(validation.rejectedCommands[0]?.reason || validation.errors.join("; ")) };
|
|
11904
12168
|
return { config: parsed, source: relative5, sourceType: "repo_file", path: configPath };
|
|
@@ -11911,9 +12175,9 @@ function loadMeshWorktreeBootstrapConfig(mesh, workspace) {
|
|
|
11911
12175
|
function computeStaleInputsDigest(workspace, staleInputs) {
|
|
11912
12176
|
const digest = {};
|
|
11913
12177
|
for (const relative5 of staleInputs ?? []) {
|
|
11914
|
-
const filePath = (0,
|
|
12178
|
+
const filePath = (0, import_path10.join)(workspace, relative5);
|
|
11915
12179
|
try {
|
|
11916
|
-
digest[relative5] = (0, import_node_crypto2.createHash)("sha256").update((0,
|
|
12180
|
+
digest[relative5] = (0, import_node_crypto2.createHash)("sha256").update((0, import_fs11.readFileSync)(filePath)).digest("hex");
|
|
11917
12181
|
} catch {
|
|
11918
12182
|
digest[relative5] = "absent";
|
|
11919
12183
|
}
|
|
@@ -11984,10 +12248,10 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
|
|
|
11984
12248
|
staleInputs: loaded.config.staleInputs
|
|
11985
12249
|
};
|
|
11986
12250
|
const staleInputPaths = loaded.config.staleInputs ?? [];
|
|
11987
|
-
const initiallyAbsent = staleInputPaths.filter((p) => !(0,
|
|
12251
|
+
const initiallyAbsent = staleInputPaths.filter((p) => !(0, import_fs11.existsSync)((0, import_path10.join)(workspace, p)));
|
|
11988
12252
|
for (const command of validation.commands) {
|
|
11989
12253
|
if (initiallyAbsent.length > 0) {
|
|
11990
|
-
const appearedNow = initiallyAbsent.filter((p) => (0,
|
|
12254
|
+
const appearedNow = initiallyAbsent.filter((p) => (0, import_fs11.existsSync)((0, import_path10.join)(workspace, p)));
|
|
11991
12255
|
if (appearedNow.length > 0) {
|
|
11992
12256
|
state.status = "stale";
|
|
11993
12257
|
state.completedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -11995,7 +12259,7 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
|
|
|
11995
12259
|
return state;
|
|
11996
12260
|
}
|
|
11997
12261
|
}
|
|
11998
|
-
const cwd = command.cwd ? (0,
|
|
12262
|
+
const cwd = command.cwd ? (0, import_path10.resolve)(workspace, command.cwd) : workspace;
|
|
11999
12263
|
const startedAt = Date.now();
|
|
12000
12264
|
state.lastCommand = command.displayCommand;
|
|
12001
12265
|
const resolvedCommand = resolveWin32Executable(command.command);
|
|
@@ -12055,16 +12319,16 @@ async function runMeshWorktreeBootstrap(mesh, workspace) {
|
|
|
12055
12319
|
}
|
|
12056
12320
|
return state;
|
|
12057
12321
|
}
|
|
12058
|
-
var
|
|
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;
|
|
12059
12323
|
var init_worktree_bootstrap_config = __esm({
|
|
12060
12324
|
"src/mesh/worktree-bootstrap-config.ts"() {
|
|
12061
12325
|
"use strict";
|
|
12062
|
-
|
|
12063
|
-
|
|
12326
|
+
import_fs11 = require("fs");
|
|
12327
|
+
import_path10 = require("path");
|
|
12064
12328
|
import_node_child_process3 = require("child_process");
|
|
12065
12329
|
import_node_crypto2 = require("crypto");
|
|
12066
12330
|
import_node_util3 = require("util");
|
|
12067
|
-
|
|
12331
|
+
yaml4 = __toESM(require("js-yaml"));
|
|
12068
12332
|
init_resolve_executable();
|
|
12069
12333
|
init_refine_config();
|
|
12070
12334
|
WORKTREE_BOOTSTRAP_STALE_RUNNING_MS = 10 * 60 * 1e3;
|
|
@@ -12116,224 +12380,6 @@ var init_worktree_bootstrap_config = __esm({
|
|
|
12116
12380
|
}
|
|
12117
12381
|
});
|
|
12118
12382
|
|
|
12119
|
-
// src/config/mesh-json-config.ts
|
|
12120
|
-
var mesh_json_config_exports = {};
|
|
12121
|
-
__export(mesh_json_config_exports, {
|
|
12122
|
-
MESH_JSON_CONFIG_LOCATIONS: () => MESH_JSON_CONFIG_LOCATIONS,
|
|
12123
|
-
MESH_JSON_CONFIG_SCHEMA: () => MESH_JSON_CONFIG_SCHEMA,
|
|
12124
|
-
applyRepoMeshConfig: () => applyRepoMeshConfig,
|
|
12125
|
-
buildMeshJsonConfigScaffold: () => buildMeshJsonConfigScaffold,
|
|
12126
|
-
loadRepoMeshJsonConfig: () => loadRepoMeshJsonConfig,
|
|
12127
|
-
mergeEffectiveCoordinatorConfig: () => mergeEffectiveCoordinatorConfig,
|
|
12128
|
-
mergeEffectiveOperatingNotes: () => mergeEffectiveOperatingNotes,
|
|
12129
|
-
normalizeRepoMeshDeclarativeConfig: () => normalizeRepoMeshDeclarativeConfig,
|
|
12130
|
-
serializeMeshJsonConfigScaffold: () => serializeMeshJsonConfigScaffold
|
|
12131
|
-
});
|
|
12132
|
-
function isRecord3(value) {
|
|
12133
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
12134
|
-
}
|
|
12135
|
-
function parseConfigText4(path46, text) {
|
|
12136
|
-
if (/\.json$/i.test(path46)) return JSON.parse(text);
|
|
12137
|
-
return yaml4.load(text);
|
|
12138
|
-
}
|
|
12139
|
-
function normalizeOperatingNote(value) {
|
|
12140
|
-
if (!isRecord3(value)) return null;
|
|
12141
|
-
const text = typeof value.text === "string" ? value.text.trim() : "";
|
|
12142
|
-
if (!text) return null;
|
|
12143
|
-
const category = value.category === "provider_quirk" || value.category === "pattern_to_avoid" || value.category === "recovery_lesson" ? value.category : void 0;
|
|
12144
|
-
return {
|
|
12145
|
-
text,
|
|
12146
|
-
...category ? { category } : {},
|
|
12147
|
-
...typeof value.createdAt === "string" ? { createdAt: value.createdAt } : {},
|
|
12148
|
-
...typeof value.sourceCoordinator === "string" ? { sourceCoordinator: value.sourceCoordinator } : {},
|
|
12149
|
-
// Operating-notes lifecycle: a repo-declared note may pin itself or set an
|
|
12150
|
-
// explicit expiry, same as a runtime-recorded one. Phase 2 (b)/(c): it may
|
|
12151
|
-
// also declare supersedes/subjectKey to retire an earlier note or group
|
|
12152
|
-
// same-subject notes for folding.
|
|
12153
|
-
...value.pinned === true ? { pinned: true } : {},
|
|
12154
|
-
...typeof value.expiresAt === "string" ? { expiresAt: value.expiresAt } : {},
|
|
12155
|
-
...typeof value.supersedes === "string" ? { supersedes: value.supersedes } : {},
|
|
12156
|
-
...typeof value.subjectKey === "string" ? { subjectKey: value.subjectKey } : {}
|
|
12157
|
-
};
|
|
12158
|
-
}
|
|
12159
|
-
function normalizeRepoMeshDeclarativeConfig(parsed) {
|
|
12160
|
-
const errors = [];
|
|
12161
|
-
if (!isRecord3(parsed)) return { valid: false, errors: ["config must be an object"] };
|
|
12162
|
-
if (parsed.version !== 1) {
|
|
12163
|
-
return { valid: false, errors: [`version must be 1 (got ${JSON.stringify(parsed.version)})`] };
|
|
12164
|
-
}
|
|
12165
|
-
const config = { version: 1 };
|
|
12166
|
-
if (parsed.coordinator !== void 0) {
|
|
12167
|
-
if (isRecord3(parsed.coordinator)) {
|
|
12168
|
-
const coord = {};
|
|
12169
|
-
const c = parsed.coordinator;
|
|
12170
|
-
if (typeof c.systemPromptOverride === "string") coord.systemPromptOverride = c.systemPromptOverride;
|
|
12171
|
-
if (typeof c.systemPromptAppend === "string") coord.systemPromptAppend = c.systemPromptAppend;
|
|
12172
|
-
if (Number.isFinite(Number(c.maxPromptChars))) coord.maxPromptChars = Number(c.maxPromptChars);
|
|
12173
|
-
config.coordinator = coord;
|
|
12174
|
-
} else {
|
|
12175
|
-
errors.push("coordinator must be an object when provided");
|
|
12176
|
-
}
|
|
12177
|
-
}
|
|
12178
|
-
if (parsed.operatingNotes !== void 0) {
|
|
12179
|
-
if (Array.isArray(parsed.operatingNotes)) {
|
|
12180
|
-
const notes = parsed.operatingNotes.map(normalizeOperatingNote).filter((n) => n !== null);
|
|
12181
|
-
if (notes.length) config.operatingNotes = notes;
|
|
12182
|
-
} else {
|
|
12183
|
-
errors.push("operatingNotes must be an array when provided");
|
|
12184
|
-
}
|
|
12185
|
-
}
|
|
12186
|
-
if (parsed.limits !== void 0) {
|
|
12187
|
-
if (isRecord3(parsed.limits)) {
|
|
12188
|
-
const limits = {};
|
|
12189
|
-
if (Number.isFinite(Number(parsed.limits.maxNoteChars))) limits.maxNoteChars = Number(parsed.limits.maxNoteChars);
|
|
12190
|
-
if (Number.isFinite(Number(parsed.limits.maxNotes))) limits.maxNotes = Number(parsed.limits.maxNotes);
|
|
12191
|
-
if (Object.keys(limits).length) config.limits = limits;
|
|
12192
|
-
} else {
|
|
12193
|
-
errors.push("limits must be an object when provided");
|
|
12194
|
-
}
|
|
12195
|
-
}
|
|
12196
|
-
return { valid: true, config, errors };
|
|
12197
|
-
}
|
|
12198
|
-
function loadRepoMeshJsonConfig(workspace) {
|
|
12199
|
-
const bases = [];
|
|
12200
|
-
const ws = typeof workspace === "string" ? workspace.trim() : "";
|
|
12201
|
-
if (ws) bases.push(ws);
|
|
12202
|
-
let cwd = "";
|
|
12203
|
-
try {
|
|
12204
|
-
cwd = process.cwd();
|
|
12205
|
-
} catch {
|
|
12206
|
-
}
|
|
12207
|
-
if (cwd && cwd !== ws) bases.push(cwd);
|
|
12208
|
-
for (const base of bases) {
|
|
12209
|
-
for (const relative5 of MESH_JSON_CONFIG_LOCATIONS) {
|
|
12210
|
-
const configPath = (0, import_path10.join)(base, relative5);
|
|
12211
|
-
if (!(0, import_fs11.existsSync)(configPath)) continue;
|
|
12212
|
-
try {
|
|
12213
|
-
const parsed = parseConfigText4(configPath, (0, import_fs11.readFileSync)(configPath, "utf-8"));
|
|
12214
|
-
const result = normalizeRepoMeshDeclarativeConfig(parsed);
|
|
12215
|
-
if (!result.valid || !result.config) {
|
|
12216
|
-
return { source: relative5, sourceType: "invalid", path: configPath, error: result.errors.join("; ") };
|
|
12217
|
-
}
|
|
12218
|
-
return { config: result.config, source: relative5, sourceType: "repo_file", path: configPath };
|
|
12219
|
-
} catch (error) {
|
|
12220
|
-
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
12221
|
-
}
|
|
12222
|
-
}
|
|
12223
|
-
}
|
|
12224
|
-
return {
|
|
12225
|
-
source: "unavailable",
|
|
12226
|
-
sourceType: "unavailable",
|
|
12227
|
-
error: `No repo mesh config found. Checked: ${MESH_JSON_CONFIG_LOCATIONS.join(", ")}`
|
|
12228
|
-
};
|
|
12229
|
-
}
|
|
12230
|
-
function mergeEffectiveCoordinatorConfig(repoCoord, localCoord) {
|
|
12231
|
-
const out = { ...localCoord || {} };
|
|
12232
|
-
const localOverride = localCoord?.systemPromptOverride?.trim();
|
|
12233
|
-
const repoOverride = repoCoord?.systemPromptOverride?.trim();
|
|
12234
|
-
if (localOverride) {
|
|
12235
|
-
out.systemPromptOverride = localCoord.systemPromptOverride;
|
|
12236
|
-
} else if (repoOverride) {
|
|
12237
|
-
out.systemPromptOverride = repoCoord.systemPromptOverride;
|
|
12238
|
-
} else {
|
|
12239
|
-
delete out.systemPromptOverride;
|
|
12240
|
-
}
|
|
12241
|
-
const repoAppend = repoCoord?.systemPromptAppend?.trim() ? repoCoord.systemPromptAppend.trim() : "";
|
|
12242
|
-
const localAppendRaw = localCoord?.systemPromptAppend ?? localCoord?.systemPromptSuffix;
|
|
12243
|
-
const localAppend = localAppendRaw?.trim() ? localAppendRaw.trim() : "";
|
|
12244
|
-
const stacked = [repoAppend, localAppend].filter(Boolean).join("\n\n");
|
|
12245
|
-
if (stacked) {
|
|
12246
|
-
out.systemPromptAppend = stacked;
|
|
12247
|
-
delete out.systemPromptSuffix;
|
|
12248
|
-
}
|
|
12249
|
-
return out;
|
|
12250
|
-
}
|
|
12251
|
-
function mergeEffectiveOperatingNotes(repoNotes, ledgerNotes) {
|
|
12252
|
-
const usable = (notes) => Array.isArray(notes) ? notes.filter((n) => n && typeof n.text === "string" && n.text.trim()) : [];
|
|
12253
|
-
const repo = usable(repoNotes);
|
|
12254
|
-
const ledger = usable(ledgerNotes);
|
|
12255
|
-
const ledgerTexts = new Set(ledger.map((n) => n.text.trim()));
|
|
12256
|
-
const repoKept = repo.filter((n) => !ledgerTexts.has(n.text.trim()));
|
|
12257
|
-
const merged = [...repoKept, ...ledger];
|
|
12258
|
-
return merged.length ? merged : void 0;
|
|
12259
|
-
}
|
|
12260
|
-
function applyRepoMeshConfig(mesh, repoConfig) {
|
|
12261
|
-
if (!repoConfig) return mesh;
|
|
12262
|
-
return {
|
|
12263
|
-
...mesh,
|
|
12264
|
-
coordinator: mergeEffectiveCoordinatorConfig(repoConfig.coordinator, mesh.coordinator)
|
|
12265
|
-
};
|
|
12266
|
-
}
|
|
12267
|
-
function buildMeshJsonConfigScaffold(mesh) {
|
|
12268
|
-
const scaffold = { version: 1 };
|
|
12269
|
-
const coord = {};
|
|
12270
|
-
const override = mesh.coordinator?.systemPromptOverride;
|
|
12271
|
-
if (typeof override === "string" && override.trim()) coord.systemPromptOverride = override;
|
|
12272
|
-
const append = mesh.coordinator?.systemPromptAppend ?? mesh.coordinator?.systemPromptSuffix;
|
|
12273
|
-
if (typeof append === "string" && append.trim()) coord.systemPromptAppend = append;
|
|
12274
|
-
if (Object.keys(coord).length) scaffold.coordinator = coord;
|
|
12275
|
-
return scaffold;
|
|
12276
|
-
}
|
|
12277
|
-
function serializeMeshJsonConfigScaffold(config) {
|
|
12278
|
-
return JSON.stringify(config, null, 2);
|
|
12279
|
-
}
|
|
12280
|
-
var import_fs11, import_path10, yaml4, MESH_JSON_CONFIG_LOCATIONS, MESH_JSON_CONFIG_SCHEMA;
|
|
12281
|
-
var init_mesh_json_config = __esm({
|
|
12282
|
-
"src/config/mesh-json-config.ts"() {
|
|
12283
|
-
"use strict";
|
|
12284
|
-
import_fs11 = require("fs");
|
|
12285
|
-
import_path10 = require("path");
|
|
12286
|
-
yaml4 = __toESM(require("js-yaml"));
|
|
12287
|
-
MESH_JSON_CONFIG_LOCATIONS = [
|
|
12288
|
-
".adhdev/mesh.json",
|
|
12289
|
-
".adhdev/mesh.yaml",
|
|
12290
|
-
".adhdev/mesh.yml"
|
|
12291
|
-
];
|
|
12292
|
-
MESH_JSON_CONFIG_SCHEMA = {
|
|
12293
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
12294
|
-
title: "ADHDev Repo Mesh Declarative Config",
|
|
12295
|
-
type: "object",
|
|
12296
|
-
additionalProperties: false,
|
|
12297
|
-
required: ["version"],
|
|
12298
|
-
properties: {
|
|
12299
|
-
version: { const: 1 },
|
|
12300
|
-
coordinator: {
|
|
12301
|
-
type: "object",
|
|
12302
|
-
additionalProperties: false,
|
|
12303
|
-
properties: {
|
|
12304
|
-
systemPromptOverride: { type: "string" },
|
|
12305
|
-
systemPromptAppend: { type: "string" },
|
|
12306
|
-
maxPromptChars: { type: "number", minimum: 1 }
|
|
12307
|
-
}
|
|
12308
|
-
},
|
|
12309
|
-
operatingNotes: {
|
|
12310
|
-
type: "array",
|
|
12311
|
-
maxItems: 200,
|
|
12312
|
-
items: {
|
|
12313
|
-
type: "object",
|
|
12314
|
-
additionalProperties: false,
|
|
12315
|
-
required: ["text"],
|
|
12316
|
-
properties: {
|
|
12317
|
-
text: { type: "string", minLength: 1 },
|
|
12318
|
-
category: { enum: ["provider_quirk", "pattern_to_avoid", "recovery_lesson"] },
|
|
12319
|
-
createdAt: { type: "string" },
|
|
12320
|
-
sourceCoordinator: { type: "string" }
|
|
12321
|
-
}
|
|
12322
|
-
}
|
|
12323
|
-
},
|
|
12324
|
-
limits: {
|
|
12325
|
-
type: "object",
|
|
12326
|
-
additionalProperties: false,
|
|
12327
|
-
properties: {
|
|
12328
|
-
maxNoteChars: { type: "number", minimum: 1 },
|
|
12329
|
-
maxNotes: { type: "number", minimum: 1 }
|
|
12330
|
-
}
|
|
12331
|
-
}
|
|
12332
|
-
}
|
|
12333
|
-
};
|
|
12334
|
-
}
|
|
12335
|
-
});
|
|
12336
|
-
|
|
12337
12383
|
// src/mesh/mesh-fast-forward.ts
|
|
12338
12384
|
async function fastForwardMeshNode(args) {
|
|
12339
12385
|
const workspace = typeof args.workspace === "string" ? args.workspace.trim() : "";
|
|
@@ -16657,6 +16703,16 @@ function __resetIdleAutoFastForwardForTests() {
|
|
|
16657
16703
|
continuousAutoFastForwardLastScan.clear();
|
|
16658
16704
|
autoFastForwardWorkspaceLease.clear();
|
|
16659
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
|
+
}
|
|
16660
16716
|
function getMeshWithCache(components, meshId) {
|
|
16661
16717
|
const localMesh = getMesh(meshId);
|
|
16662
16718
|
const cachedMesh = components.router?.getCachedInlineMesh(meshId);
|
|
@@ -16919,7 +16975,9 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
|
|
|
16919
16975
|
...delegatedWorkerAutoApproveSettings(
|
|
16920
16976
|
mesh?.policy,
|
|
16921
16977
|
node?.policy,
|
|
16922
|
-
components.providerLoader?.getMeta(providerType)
|
|
16978
|
+
components.providerLoader?.getMeta(providerType),
|
|
16979
|
+
loadRepoConfigForNode(node),
|
|
16980
|
+
providerType
|
|
16923
16981
|
),
|
|
16924
16982
|
...localDaemonId ? { meshCoordinatorDaemonId: localDaemonId } : {},
|
|
16925
16983
|
// COMPLETION-PROPAGATION F5: (re)stamp the coordinator SESSION anchor from THIS
|
|
@@ -17358,10 +17416,10 @@ function liveSessionCountForNode(components, meshId, nodeId) {
|
|
|
17358
17416
|
}
|
|
17359
17417
|
return count;
|
|
17360
17418
|
}
|
|
17361
|
-
function nodeHasLiveSessionPendingClaim(components, meshId, nodeId) {
|
|
17419
|
+
function nodeHasLiveSessionPendingClaim(components, meshId, nodeId, task, node) {
|
|
17362
17420
|
if (inWindowAutoLaunchSessionIdsForNode(meshId, nodeId).length > 0) return true;
|
|
17363
17421
|
const busySessionIds = new Set(
|
|
17364
|
-
getQueue(meshId, { status: ["assigned"] }).filter((
|
|
17422
|
+
getQueue(meshId, { status: ["assigned"] }).filter((task2) => daemonIdsEquivalent(task2.assignedNodeId, nodeId)).map((task2) => readNonEmptyString(task2.assignedSessionId)).filter(Boolean)
|
|
17365
17423
|
);
|
|
17366
17424
|
return components.instanceManager.getByCategory("cli").some((inst) => {
|
|
17367
17425
|
const state = inst.getState();
|
|
@@ -17374,6 +17432,12 @@ function nodeHasLiveSessionPendingClaim(components, meshId, nodeId) {
|
|
|
17374
17432
|
if (isTerminalSessionStatus(status)) return false;
|
|
17375
17433
|
const sessionId = readNonEmptyString(state.instanceId);
|
|
17376
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
|
+
}
|
|
17377
17441
|
return true;
|
|
17378
17442
|
});
|
|
17379
17443
|
}
|
|
@@ -17654,7 +17718,7 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
17654
17718
|
sweepExpiredCooldowns();
|
|
17655
17719
|
continue;
|
|
17656
17720
|
}
|
|
17657
|
-
if (nodeHasLiveSessionPendingClaim(components, meshId, nodeId)) {
|
|
17721
|
+
if (nodeHasLiveSessionPendingClaim(components, meshId, nodeId, task, node)) {
|
|
17658
17722
|
markAutoLaunch(meshId, task.id, { status: "skipped", reason: "node_has_live_session_pending_claim", nodeId });
|
|
17659
17723
|
continue;
|
|
17660
17724
|
}
|
|
@@ -17697,7 +17761,9 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
17697
17761
|
...delegatedWorkerAutoApproveSettings(
|
|
17698
17762
|
mesh?.policy,
|
|
17699
17763
|
node?.policy,
|
|
17700
|
-
components.providerLoader?.getMeta(resolved.providerType)
|
|
17764
|
+
components.providerLoader?.getMeta(resolved.providerType),
|
|
17765
|
+
loadRepoConfigForNode(node),
|
|
17766
|
+
resolved.providerType
|
|
17701
17767
|
),
|
|
17702
17768
|
launchedByCoordinator: true,
|
|
17703
17769
|
autoLaunchedForQueueTaskId: task.id
|
|
@@ -18163,6 +18229,7 @@ var init_mesh_queue_assignment = __esm({
|
|
|
18163
18229
|
init_mesh_event_trace();
|
|
18164
18230
|
init_mesh_warmup_deadline();
|
|
18165
18231
|
init_repo_mesh_types();
|
|
18232
|
+
init_mesh_json_config();
|
|
18166
18233
|
init_dist();
|
|
18167
18234
|
init_mesh_node_slots();
|
|
18168
18235
|
init_mesh_events_stale();
|
|
@@ -21721,7 +21788,20 @@ function injectMeshSystemMessage(components, args) {
|
|
|
21721
21788
|
...delegatedWorkerAutoApproveSettings(
|
|
21722
21789
|
mesh?.policy,
|
|
21723
21790
|
node?.policy,
|
|
21724
|
-
components.providerLoader?.getMeta(recoveryContext.failedProviderType)
|
|
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
|
|
21725
21805
|
),
|
|
21726
21806
|
launchedByCoordinator: true
|
|
21727
21807
|
}
|
|
@@ -22112,6 +22192,7 @@ var init_mesh_event_forwarding = __esm({
|
|
|
22112
22192
|
init_mesh_event_trace();
|
|
22113
22193
|
init_snapshot();
|
|
22114
22194
|
init_repo_mesh_types();
|
|
22195
|
+
init_mesh_json_config();
|
|
22115
22196
|
init_dist();
|
|
22116
22197
|
init_mesh_events_stale();
|
|
22117
22198
|
init_mesh_task_inflight();
|
|
@@ -30556,6 +30637,9 @@ __export(index_exports, {
|
|
|
30556
30637
|
MAX_LEDGER_SLICE_LIMIT: () => MAX_LEDGER_SLICE_LIMIT,
|
|
30557
30638
|
MESH_CONVERGE_FAST_FORWARD_TAG: () => MESH_CONVERGE_FAST_FORWARD_TAG,
|
|
30558
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,
|
|
30559
30643
|
MESH_MAX_PARALLEL_TASKS_MAX: () => MESH_MAX_PARALLEL_TASKS_MAX,
|
|
30560
30644
|
MESH_MAX_PARALLEL_TASKS_MIN: () => MESH_MAX_PARALLEL_TASKS_MIN,
|
|
30561
30645
|
MESH_MISSION_LIST_HISTORY_ID_LIMIT: () => MESH_MISSION_LIST_HISTORY_ID_LIMIT,
|
|
@@ -30615,6 +30699,7 @@ __export(index_exports, {
|
|
|
30615
30699
|
buildMeshActiveWorkSummary: () => buildMeshActiveWorkSummary,
|
|
30616
30700
|
buildMeshAsyncRefineJobs: () => buildMeshAsyncRefineJobs,
|
|
30617
30701
|
buildMeshHostRequiredFailure: () => buildMeshHostRequiredFailure,
|
|
30702
|
+
buildMeshJsonConfigScaffold: () => buildMeshJsonConfigScaffold,
|
|
30618
30703
|
buildMeshLedgerReconciliationEvidence: () => buildMeshLedgerReconciliationEvidence,
|
|
30619
30704
|
buildMeshLedgerReplicaEvidence: () => buildMeshLedgerReplicaEvidence,
|
|
30620
30705
|
buildMeshMagiActivity: () => buildMeshMagiActivity,
|
|
@@ -30779,6 +30864,7 @@ __export(index_exports, {
|
|
|
30779
30864
|
loadMeshCoordinatorRegistry: () => loadMeshCoordinatorRegistry,
|
|
30780
30865
|
loadMeshRefineConfig: () => loadMeshRefineConfig,
|
|
30781
30866
|
loadMeshWorktreeBootstrapConfig: () => loadMeshWorktreeBootstrapConfig,
|
|
30867
|
+
loadRepoMeshJsonConfig: () => loadRepoMeshJsonConfig,
|
|
30782
30868
|
loadRepoSettings: () => loadRepoSettings,
|
|
30783
30869
|
loadState: () => loadState,
|
|
30784
30870
|
logCommand: () => logCommand,
|
|
@@ -30819,6 +30905,7 @@ __export(index_exports, {
|
|
|
30819
30905
|
normalizeMeshWorkerResult: () => normalizeMeshWorkerResult,
|
|
30820
30906
|
normalizeMessageParts: () => normalizeMessageParts,
|
|
30821
30907
|
normalizeRepoIdentity: () => normalizeRepoIdentity,
|
|
30908
|
+
normalizeRepoMeshDeclarativeConfig: () => normalizeRepoMeshDeclarativeConfig,
|
|
30822
30909
|
normalizeSessionModalFields: () => normalizeSessionModalFields,
|
|
30823
30910
|
parsePorcelainV2Status: () => parsePorcelainV2Status,
|
|
30824
30911
|
parseProviderSourceConfigUpdate: () => parseProviderSourceConfigUpdate,
|
|
@@ -30889,6 +30976,7 @@ __export(index_exports, {
|
|
|
30889
30976
|
runMeshWorktreeBootstrap: () => runMeshWorktreeBootstrap,
|
|
30890
30977
|
saveConfig: () => saveConfig,
|
|
30891
30978
|
saveState: () => saveState,
|
|
30979
|
+
serializeMeshJsonConfigScaffold: () => serializeMeshJsonConfigScaffold,
|
|
30892
30980
|
serializeV2EnvelopeToWire: () => serializeV2EnvelopeToWire,
|
|
30893
30981
|
setDebugRuntimeConfig: () => setDebugRuntimeConfig,
|
|
30894
30982
|
setLogLevel: () => setLogLevel,
|
|
@@ -31338,6 +31426,7 @@ function detectClaudeAskUserQuestionPromptFromJson(value, providerType = "claude
|
|
|
31338
31426
|
|
|
31339
31427
|
// src/index.ts
|
|
31340
31428
|
init_repo_mesh_types();
|
|
31429
|
+
init_mesh_json_config();
|
|
31341
31430
|
|
|
31342
31431
|
// src/git/index.ts
|
|
31343
31432
|
init_git_executor();
|
|
@@ -60653,6 +60742,139 @@ var meshCrudHandlers = {
|
|
|
60653
60742
|
return { success: false, error: e.message };
|
|
60654
60743
|
}
|
|
60655
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
|
+
},
|
|
60656
60878
|
delete_mesh: async (_ctx, args) => {
|
|
60657
60879
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
60658
60880
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
@@ -76776,6 +76998,9 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
76776
76998
|
MAX_LEDGER_SLICE_LIMIT,
|
|
76777
76999
|
MESH_CONVERGE_FAST_FORWARD_TAG,
|
|
76778
77000
|
MESH_CONVERGE_REFINE_TAG,
|
|
77001
|
+
MESH_JSON_CONFIG_LOCATIONS,
|
|
77002
|
+
MESH_JSON_CONFIG_SCHEMA,
|
|
77003
|
+
MESH_JSON_PROVIDER_DEFAULTS_EXAMPLE,
|
|
76779
77004
|
MESH_MAX_PARALLEL_TASKS_MAX,
|
|
76780
77005
|
MESH_MAX_PARALLEL_TASKS_MIN,
|
|
76781
77006
|
MESH_MISSION_LIST_HISTORY_ID_LIMIT,
|
|
@@ -76835,6 +77060,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
76835
77060
|
buildMeshActiveWorkSummary,
|
|
76836
77061
|
buildMeshAsyncRefineJobs,
|
|
76837
77062
|
buildMeshHostRequiredFailure,
|
|
77063
|
+
buildMeshJsonConfigScaffold,
|
|
76838
77064
|
buildMeshLedgerReconciliationEvidence,
|
|
76839
77065
|
buildMeshLedgerReplicaEvidence,
|
|
76840
77066
|
buildMeshMagiActivity,
|
|
@@ -76999,6 +77225,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
76999
77225
|
loadMeshCoordinatorRegistry,
|
|
77000
77226
|
loadMeshRefineConfig,
|
|
77001
77227
|
loadMeshWorktreeBootstrapConfig,
|
|
77228
|
+
loadRepoMeshJsonConfig,
|
|
77002
77229
|
loadRepoSettings,
|
|
77003
77230
|
loadState,
|
|
77004
77231
|
logCommand,
|
|
@@ -77039,6 +77266,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
77039
77266
|
normalizeMeshWorkerResult,
|
|
77040
77267
|
normalizeMessageParts,
|
|
77041
77268
|
normalizeRepoIdentity,
|
|
77269
|
+
normalizeRepoMeshDeclarativeConfig,
|
|
77042
77270
|
normalizeSessionModalFields,
|
|
77043
77271
|
parsePorcelainV2Status,
|
|
77044
77272
|
parseProviderSourceConfigUpdate,
|
|
@@ -77109,6 +77337,7 @@ var V1_CONTRACT_VERSION = "1.0.0";
|
|
|
77109
77337
|
runMeshWorktreeBootstrap,
|
|
77110
77338
|
saveConfig,
|
|
77111
77339
|
saveState,
|
|
77340
|
+
serializeMeshJsonConfigScaffold,
|
|
77112
77341
|
serializeV2EnvelopeToWire,
|
|
77113
77342
|
setDebugRuntimeConfig,
|
|
77114
77343
|
setLogLevel,
|