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