@adhdev/daemon-core 0.9.82-rc.411 → 0.9.82-rc.413
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/med-family/mesh-crud.d.ts +27 -0
- package/dist/config/mesh-json-config.d.ts +31 -131
- package/dist/config/repo-settings.d.ts +77 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +817 -802
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +804 -791
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-ledger.d.ts +1 -1
- package/dist/mesh/mesh-task-inflight.d.ts +46 -0
- package/package.json +2 -2
- package/src/commands/high-family/mesh-coordinator-launch.ts +9 -4
- package/src/commands/med-family/mesh-crud.ts +85 -8
- package/src/commands/med-family/mesh-queue.ts +14 -0
- package/src/config/mesh-json-config.ts +40 -281
- package/src/config/repo-settings.ts +111 -0
- package/src/index.ts +6 -1
- package/src/mesh/mesh-ledger.ts +10 -0
- package/src/mesh/mesh-missions.ts +86 -1
- package/src/mesh/mesh-queue-assignment.ts +69 -61
- package/src/mesh/mesh-task-inflight.ts +70 -0
- package/src/mesh/mesh-work-queue.ts +25 -0
package/dist/index.mjs
CHANGED
|
@@ -17,9 +17,9 @@ var __export = (target, all) => {
|
|
|
17
17
|
};
|
|
18
18
|
var __copyProps = (to, from, except, desc) => {
|
|
19
19
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
-
for (let
|
|
21
|
-
if (!__hasOwnProp.call(to,
|
|
22
|
-
__defProp(to,
|
|
20
|
+
for (let key2 of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key2) && key2 !== except)
|
|
22
|
+
__defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
|
|
23
23
|
}
|
|
24
24
|
return to;
|
|
25
25
|
};
|
|
@@ -31,14 +31,6 @@ function normalizeMeshSchedulingStrategy(value) {
|
|
|
31
31
|
const trimmed = value.trim();
|
|
32
32
|
return MESH_SCHEDULING_STRATEGIES.includes(trimmed) ? trimmed : DEFAULT_MESH_SCHEDULING_STRATEGY;
|
|
33
33
|
}
|
|
34
|
-
function normalizeMeshDistribution(value) {
|
|
35
|
-
if (typeof value !== "string") return DEFAULT_MESH_DISTRIBUTION;
|
|
36
|
-
const trimmed = value.trim();
|
|
37
|
-
return MESH_DISTRIBUTIONS.includes(trimmed) ? trimmed : DEFAULT_MESH_DISTRIBUTION;
|
|
38
|
-
}
|
|
39
|
-
function distributionToStrategy(distribution) {
|
|
40
|
-
return distribution === "spread" ? "least_loaded" : "first_eligible";
|
|
41
|
-
}
|
|
42
34
|
function resolveNodeSchedulingPriority(nodePolicy) {
|
|
43
35
|
const raw = Number(nodePolicy?.schedulingPriority);
|
|
44
36
|
return Number.isFinite(raw) ? raw : 0;
|
|
@@ -125,7 +117,7 @@ function resolveProviderMaxParallel(nodePolicy, providerType) {
|
|
|
125
117
|
}
|
|
126
118
|
return void 0;
|
|
127
119
|
}
|
|
128
|
-
var MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY,
|
|
120
|
+
var MESH_SCHEDULING_STRATEGIES, DEFAULT_MESH_SCHEDULING_STRATEGY, MESH_CONVERGE_REFINE_TAG, MESH_CONVERGE_FAST_FORWARD_TAG, DEFAULT_MESH_POLICY, SESSION_CLEANUP_MODES, SPAWNED_SESSION_VISIBILITY_MODES, DIRTY_WORKSPACE_BEHAVIORS, MESH_MAX_PARALLEL_TASKS_MIN, MESH_MAX_PARALLEL_TASKS_MAX, DEFAULT_MESH_READONLY_MULTIPLIER;
|
|
129
121
|
var init_repo_mesh_types = __esm({
|
|
130
122
|
"src/repo-mesh-types.ts"() {
|
|
131
123
|
"use strict";
|
|
@@ -136,8 +128,6 @@ var init_repo_mesh_types = __esm({
|
|
|
136
128
|
"priority_only"
|
|
137
129
|
];
|
|
138
130
|
DEFAULT_MESH_SCHEDULING_STRATEGY = "first_eligible";
|
|
139
|
-
MESH_DISTRIBUTIONS = ["spread", "in_order"];
|
|
140
|
-
DEFAULT_MESH_DISTRIBUTION = "spread";
|
|
141
131
|
MESH_CONVERGE_REFINE_TAG = "converge=refine";
|
|
142
132
|
MESH_CONVERGE_FAST_FORWARD_TAG = "converge=fast_forward";
|
|
143
133
|
DEFAULT_MESH_POLICY = {
|
|
@@ -394,10 +384,10 @@ function readInjected(value) {
|
|
|
394
384
|
}
|
|
395
385
|
function getDaemonBuildInfo() {
|
|
396
386
|
if (cached) return cached;
|
|
397
|
-
const commit = readInjected(true ? "
|
|
398
|
-
const commitShort = readInjected(true ? "
|
|
399
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
400
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
387
|
+
const commit = readInjected(true ? "7a774e95a82354f5357197b3c84f63e68b5f7a5d" : void 0) ?? "unknown";
|
|
388
|
+
const commitShort = readInjected(true ? "7a774e95" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
389
|
+
const version = readInjected(true ? "0.9.82-rc.413" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
390
|
+
const builtAt = readInjected(true ? "2026-06-28T11:48:26.300Z" : void 0);
|
|
401
391
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
402
392
|
return cached;
|
|
403
393
|
}
|
|
@@ -418,18 +408,18 @@ function isRecord(value) {
|
|
|
418
408
|
function isStringArray(value) {
|
|
419
409
|
return Array.isArray(value) && value.every((v) => typeof v === "string" && v.length > 0);
|
|
420
410
|
}
|
|
421
|
-
function validateTarget(value,
|
|
411
|
+
function validateTarget(value, key2, errors) {
|
|
422
412
|
if (!isRecord(value)) {
|
|
423
|
-
errors.push(`impactTargets.${
|
|
413
|
+
errors.push(`impactTargets.${key2} must be an object`);
|
|
424
414
|
return void 0;
|
|
425
415
|
}
|
|
426
416
|
const { recommendedCommand } = value;
|
|
427
417
|
if (typeof recommendedCommand !== "string" || !recommendedCommand.length) {
|
|
428
|
-
errors.push(`impactTargets.${
|
|
418
|
+
errors.push(`impactTargets.${key2}.recommendedCommand must be a non-empty string`);
|
|
429
419
|
return void 0;
|
|
430
420
|
}
|
|
431
421
|
for (const k of Object.keys(value)) {
|
|
432
|
-
if (k !== "recommendedCommand") errors.push(`impactTargets.${
|
|
422
|
+
if (k !== "recommendedCommand") errors.push(`impactTargets.${key2}.${k} is not a recognized field (only recommendedCommand)`);
|
|
433
423
|
}
|
|
434
424
|
return { recommendedCommand };
|
|
435
425
|
}
|
|
@@ -456,20 +446,20 @@ function validateChangeImpactConfig(raw, source = "inline") {
|
|
|
456
446
|
errors.push("impactTargets must be an object");
|
|
457
447
|
} else {
|
|
458
448
|
const targets = {};
|
|
459
|
-
for (const
|
|
460
|
-
if (
|
|
461
|
-
errors.push(`impactTargets.${
|
|
449
|
+
for (const key2 of Object.keys(raw.impactTargets)) {
|
|
450
|
+
if (key2 !== "daemon" && key2 !== "web" && key2 !== "none") {
|
|
451
|
+
errors.push(`impactTargets.${key2} is not a recognized impact kind (daemon|web|none)`);
|
|
462
452
|
continue;
|
|
463
453
|
}
|
|
464
|
-
const target = validateTarget(raw.impactTargets[
|
|
465
|
-
if (target) targets[
|
|
454
|
+
const target = validateTarget(raw.impactTargets[key2], key2, errors);
|
|
455
|
+
if (target) targets[key2] = target;
|
|
466
456
|
}
|
|
467
457
|
if (Object.keys(targets).length) config.impactTargets = targets;
|
|
468
458
|
}
|
|
469
459
|
}
|
|
470
|
-
for (const
|
|
471
|
-
if (!["daemonRuntimePackages", "webOnlyPackages", "nonRuntimeRootFilePatterns", "impactTargets"].includes(
|
|
472
|
-
errors.push(`unknown config key '${
|
|
460
|
+
for (const key2 of Object.keys(raw)) {
|
|
461
|
+
if (!["daemonRuntimePackages", "webOnlyPackages", "nonRuntimeRootFilePatterns", "impactTargets"].includes(key2)) {
|
|
462
|
+
errors.push(`unknown config key '${key2}'`);
|
|
473
463
|
}
|
|
474
464
|
}
|
|
475
465
|
return { valid: errors.length === 0, errors, config: errors.length === 0 ? config : void 0 };
|
|
@@ -798,12 +788,12 @@ function resolveChangeImpactConfigForRepo(repoRoot, options) {
|
|
|
798
788
|
return { config: null, sourceKey: "forced-default" };
|
|
799
789
|
}
|
|
800
790
|
if (options.changeImpactConfig !== void 0) {
|
|
801
|
-
let
|
|
791
|
+
let key2 = "injected";
|
|
802
792
|
try {
|
|
803
|
-
|
|
793
|
+
key2 = `injected:${JSON.stringify(options.changeImpactConfig)}`;
|
|
804
794
|
} catch {
|
|
805
795
|
}
|
|
806
|
-
return { config: options.changeImpactConfig, sourceKey:
|
|
796
|
+
return { config: options.changeImpactConfig, sourceKey: key2 };
|
|
807
797
|
}
|
|
808
798
|
if (!repoRoot) {
|
|
809
799
|
return { config: null, sourceKey: "no-repo-root" };
|
|
@@ -2365,9 +2355,9 @@ function dismissSessionNotification(state, sessionId, notificationId, providerSe
|
|
|
2365
2355
|
].filter(Boolean)));
|
|
2366
2356
|
const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
|
|
2367
2357
|
const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
|
|
2368
|
-
for (const
|
|
2369
|
-
nextSessionNotificationDismissals[
|
|
2370
|
-
delete nextSessionNotificationUnreadOverrides[
|
|
2358
|
+
for (const key2 of dismissalKeys) {
|
|
2359
|
+
nextSessionNotificationDismissals[key2] = dismissalId;
|
|
2360
|
+
delete nextSessionNotificationUnreadOverrides[key2];
|
|
2371
2361
|
}
|
|
2372
2362
|
return {
|
|
2373
2363
|
...state,
|
|
@@ -2384,9 +2374,9 @@ function markSessionNotificationUnread(state, sessionId, notificationId, provide
|
|
|
2384
2374
|
].filter(Boolean)));
|
|
2385
2375
|
const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
|
|
2386
2376
|
const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
|
|
2387
|
-
for (const
|
|
2388
|
-
nextSessionNotificationUnreadOverrides[
|
|
2389
|
-
delete nextSessionNotificationDismissals[
|
|
2377
|
+
for (const key2 of unreadKeys) {
|
|
2378
|
+
nextSessionNotificationUnreadOverrides[key2] = unreadId;
|
|
2379
|
+
delete nextSessionNotificationDismissals[key2];
|
|
2390
2380
|
}
|
|
2391
2381
|
return {
|
|
2392
2382
|
...state,
|
|
@@ -2450,11 +2440,11 @@ function markSessionSeen(state, sessionId, seenAt = Date.now(), completionMarker
|
|
|
2450
2440
|
const nextSessionReadMarkers = { ...prevMarkers };
|
|
2451
2441
|
const nextSessionNotificationDismissals = { ...state.sessionNotificationDismissals || {} };
|
|
2452
2442
|
const nextSessionNotificationUnreadOverrides = { ...state.sessionNotificationUnreadOverrides || {} };
|
|
2453
|
-
for (const
|
|
2454
|
-
nextSessionReads[
|
|
2455
|
-
if (nextMarker) nextSessionReadMarkers[
|
|
2456
|
-
delete nextSessionNotificationDismissals[
|
|
2457
|
-
delete nextSessionNotificationUnreadOverrides[
|
|
2443
|
+
for (const key2 of readKeys) {
|
|
2444
|
+
nextSessionReads[key2] = Math.max(prev[key2] || 0, seenAt);
|
|
2445
|
+
if (nextMarker) nextSessionReadMarkers[key2] = nextMarker;
|
|
2446
|
+
delete nextSessionNotificationDismissals[key2];
|
|
2447
|
+
delete nextSessionNotificationUnreadOverrides[key2];
|
|
2458
2448
|
}
|
|
2459
2449
|
return {
|
|
2460
2450
|
...state,
|
|
@@ -3157,6 +3147,12 @@ function machineCoreFromDaemonId(id) {
|
|
|
3157
3147
|
}
|
|
3158
3148
|
return trimmed;
|
|
3159
3149
|
}
|
|
3150
|
+
function canonicalDaemonId(id) {
|
|
3151
|
+
const core = machineCoreFromDaemonId(id);
|
|
3152
|
+
if (!core) return void 0;
|
|
3153
|
+
if (!core.startsWith("mach_")) return core;
|
|
3154
|
+
return `daemon_${core}`;
|
|
3155
|
+
}
|
|
3160
3156
|
function daemonIdsEquivalent(a, b) {
|
|
3161
3157
|
const coreA = machineCoreFromDaemonId(a);
|
|
3162
3158
|
const coreB = machineCoreFromDaemonId(b);
|
|
@@ -3321,8 +3317,8 @@ function expandPromptPlaceholders(template, ctx) {
|
|
|
3321
3317
|
rules: buildRulesSection(coordinatorCliType),
|
|
3322
3318
|
toolExposurePreflight: TOOL_EXPOSURE_PREFLIGHT_SECTION
|
|
3323
3319
|
};
|
|
3324
|
-
return template.replace(/\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g, (m,
|
|
3325
|
-
return Object.prototype.hasOwnProperty.call(replacements,
|
|
3320
|
+
return template.replace(/\{\{\s*([a-zA-Z_][a-zA-Z0-9_]*)\s*\}\}/g, (m, key2) => {
|
|
3321
|
+
return Object.prototype.hasOwnProperty.call(replacements, key2) ? replacements[key2] : m;
|
|
3326
3322
|
});
|
|
3327
3323
|
}
|
|
3328
3324
|
function buildNodeStatusSection(nodes) {
|
|
@@ -4721,6 +4717,33 @@ var init_mesh_delivery_policy = __esm({
|
|
|
4721
4717
|
}
|
|
4722
4718
|
});
|
|
4723
4719
|
|
|
4720
|
+
// src/mesh/mesh-task-inflight.ts
|
|
4721
|
+
function key(meshId, taskId) {
|
|
4722
|
+
return `${meshId}::${taskId}`;
|
|
4723
|
+
}
|
|
4724
|
+
function beginTaskDispatchInFlight(meshId, taskId) {
|
|
4725
|
+
if (!meshId || !taskId) return false;
|
|
4726
|
+
const k = key(meshId, taskId);
|
|
4727
|
+
if (inFlight.has(k)) return false;
|
|
4728
|
+
inFlight.add(k);
|
|
4729
|
+
return true;
|
|
4730
|
+
}
|
|
4731
|
+
function isTaskDispatchInFlight(meshId, taskId) {
|
|
4732
|
+
if (!meshId || !taskId) return false;
|
|
4733
|
+
return inFlight.has(key(meshId, taskId));
|
|
4734
|
+
}
|
|
4735
|
+
function endTaskDispatchInFlight(meshId, taskId) {
|
|
4736
|
+
if (!meshId || !taskId) return;
|
|
4737
|
+
inFlight.delete(key(meshId, taskId));
|
|
4738
|
+
}
|
|
4739
|
+
var inFlight;
|
|
4740
|
+
var init_mesh_task_inflight = __esm({
|
|
4741
|
+
"src/mesh/mesh-task-inflight.ts"() {
|
|
4742
|
+
"use strict";
|
|
4743
|
+
inFlight = /* @__PURE__ */ new Set();
|
|
4744
|
+
}
|
|
4745
|
+
});
|
|
4746
|
+
|
|
4724
4747
|
// src/mesh/mesh-work-queue.ts
|
|
4725
4748
|
var mesh_work_queue_exports = {};
|
|
4726
4749
|
__export(mesh_work_queue_exports, {
|
|
@@ -4988,14 +5011,14 @@ function firstProviderPriority(policy) {
|
|
|
4988
5011
|
if (!Array.isArray(raw)) return void 0;
|
|
4989
5012
|
return raw.find((type) => typeof type === "string" && type.trim())?.trim();
|
|
4990
5013
|
}
|
|
4991
|
-
function readNodeOverride(node,
|
|
5014
|
+
function readNodeOverride(node, key2) {
|
|
4992
5015
|
const overrides = node?.userOverrides;
|
|
4993
5016
|
if (!overrides || typeof overrides !== "object" || Array.isArray(overrides)) return null;
|
|
4994
|
-
const value = overrides[
|
|
5017
|
+
const value = overrides[key2];
|
|
4995
5018
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
4996
5019
|
}
|
|
4997
|
-
function readNodeReporter(node,
|
|
4998
|
-
const value =
|
|
5020
|
+
function readNodeReporter(node, key2) {
|
|
5021
|
+
const value = key2 === "platform" ? node?.reportedPlatform : node?.reportedArch;
|
|
4999
5022
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
5000
5023
|
}
|
|
5001
5024
|
function buildMeshNodeCapabilityTags(node, providerType) {
|
|
@@ -5214,6 +5237,7 @@ function updateTaskStatus(meshId, taskId, status, opts) {
|
|
|
5214
5237
|
if (!entry) return null;
|
|
5215
5238
|
entry.status = status;
|
|
5216
5239
|
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
5240
|
+
if (status !== "assigned") endTaskDispatchInFlight(meshId, taskId);
|
|
5217
5241
|
if (DEPENDENCY_FAILURE_TERMINALS.has(status)) propagateDependencyFailure(meshId, taskId);
|
|
5218
5242
|
return entry;
|
|
5219
5243
|
});
|
|
@@ -5238,6 +5262,7 @@ function cancelTask(meshId, taskId, opts) {
|
|
|
5238
5262
|
entry.cancelledAt = now;
|
|
5239
5263
|
if (opts?.reason) entry.cancelReason = opts.reason;
|
|
5240
5264
|
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
5265
|
+
endTaskDispatchInFlight(meshId, taskId);
|
|
5241
5266
|
propagateDependencyFailure(meshId, taskId);
|
|
5242
5267
|
return entry;
|
|
5243
5268
|
});
|
|
@@ -5247,6 +5272,11 @@ function requeueTask(meshId, taskId, opts) {
|
|
|
5247
5272
|
return withQueueLock(meshId, () => {
|
|
5248
5273
|
const entry = MeshRuntimeStore.getInstance().findQueueEntryById(meshId, taskId);
|
|
5249
5274
|
if (!entry) return null;
|
|
5275
|
+
if (!opts?.force && isTaskDispatchInFlight(meshId, taskId)) {
|
|
5276
|
+
LOG.warn("MeshQueue", `Refusing to requeue task ${taskId} on mesh ${meshId}: it is actively dispatched/generating (single-flight in-flight). Requeueing now would open a duplicate second dispatch into another session. Pass force to override.`);
|
|
5277
|
+
return entry;
|
|
5278
|
+
}
|
|
5279
|
+
endTaskDispatchInFlight(meshId, taskId);
|
|
5250
5280
|
const currentCount = entry.requeueCount || 0;
|
|
5251
5281
|
const maxRetries = opts?.maxRetries ?? entry.maxRetries ?? 1;
|
|
5252
5282
|
if (!opts?.force && currentCount >= maxRetries) {
|
|
@@ -5291,6 +5321,7 @@ function reclaimStrandedAssignedTask(meshId, taskId, opts) {
|
|
|
5291
5321
|
delete entry.dispatchTimestamp;
|
|
5292
5322
|
entry.strandedReclaimCount = reclaims;
|
|
5293
5323
|
entry.updatedAt = now;
|
|
5324
|
+
endTaskDispatchInFlight(meshId, taskId);
|
|
5294
5325
|
if (reclaims > MAX_STRANDED_RECLAIMS) {
|
|
5295
5326
|
entry.status = "failed";
|
|
5296
5327
|
entry.cancelReason = `stranded_dispatch_unrecovered: reclaimed ${reclaims - 1} time(s) without a confirmed dispatch`;
|
|
@@ -5334,6 +5365,7 @@ function updateSessionTaskStatus(meshId, sessionId, status, opts) {
|
|
|
5334
5365
|
}
|
|
5335
5366
|
entry.status = status;
|
|
5336
5367
|
store.updateQueueEntry(entry);
|
|
5368
|
+
if (status !== "assigned") endTaskDispatchInFlight(meshId, entry.id);
|
|
5337
5369
|
if (DEPENDENCY_FAILURE_TERMINALS.has(status)) propagateDependencyFailure(meshId, entry.id);
|
|
5338
5370
|
return entry;
|
|
5339
5371
|
});
|
|
@@ -5447,6 +5479,7 @@ var init_mesh_work_queue = __esm({
|
|
|
5447
5479
|
init_logger();
|
|
5448
5480
|
init_mesh_ledger();
|
|
5449
5481
|
init_mesh_delivery_policy();
|
|
5482
|
+
init_mesh_task_inflight();
|
|
5450
5483
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
5451
5484
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
5452
5485
|
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
@@ -7092,6 +7125,9 @@ __export(mesh_missions_exports, {
|
|
|
7092
7125
|
upsertMeshMission: () => upsertMeshMission
|
|
7093
7126
|
});
|
|
7094
7127
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
7128
|
+
function summarizeGoalForLedger(goal) {
|
|
7129
|
+
return goal.length > LEDGER_GOAL_SUMMARY_MAX ? goal.slice(0, LEDGER_GOAL_SUMMARY_MAX) : goal;
|
|
7130
|
+
}
|
|
7095
7131
|
function normalizeMissionStatus(value) {
|
|
7096
7132
|
return MESH_MISSION_STATUSES.includes(value) ? value : "active";
|
|
7097
7133
|
}
|
|
@@ -7104,6 +7140,8 @@ function upsertMeshMission(meshId, input) {
|
|
|
7104
7140
|
const id = typeof input.id === "string" && input.id.trim() ? input.id.trim() : randomUUID7();
|
|
7105
7141
|
const store = MeshRuntimeStore.getInstance();
|
|
7106
7142
|
const existing = store.getMission(meshId, id);
|
|
7143
|
+
const prevStatus = existing ? normalizeMissionStatus(existing.status) : null;
|
|
7144
|
+
const prevGoal = existing?.goal ?? "";
|
|
7107
7145
|
const record = {
|
|
7108
7146
|
id,
|
|
7109
7147
|
meshId,
|
|
@@ -7113,7 +7151,61 @@ function upsertMeshMission(meshId, input) {
|
|
|
7113
7151
|
};
|
|
7114
7152
|
store.upsertMission(record);
|
|
7115
7153
|
const saved = store.getMission(meshId, id);
|
|
7116
|
-
|
|
7154
|
+
const result = { ...saved, status: normalizeMissionStatus(saved.status) };
|
|
7155
|
+
appendMissionLedgerEntries(meshId, {
|
|
7156
|
+
isCreate: !existing,
|
|
7157
|
+
record: result,
|
|
7158
|
+
prevStatus,
|
|
7159
|
+
prevGoal
|
|
7160
|
+
});
|
|
7161
|
+
return result;
|
|
7162
|
+
}
|
|
7163
|
+
function appendMissionLedgerEntries(meshId, args) {
|
|
7164
|
+
const { isCreate, record, prevStatus, prevGoal } = args;
|
|
7165
|
+
try {
|
|
7166
|
+
if (isCreate) {
|
|
7167
|
+
const goal = record.goal ?? "";
|
|
7168
|
+
appendLedgerEntry(meshId, {
|
|
7169
|
+
kind: "mission_created",
|
|
7170
|
+
payload: {
|
|
7171
|
+
missionId: record.id,
|
|
7172
|
+
title: record.title,
|
|
7173
|
+
goalSummary: summarizeGoalForLedger(goal),
|
|
7174
|
+
goalLength: goal.length,
|
|
7175
|
+
goalTruncated: goal.length > LEDGER_GOAL_SUMMARY_MAX,
|
|
7176
|
+
status: record.status
|
|
7177
|
+
}
|
|
7178
|
+
});
|
|
7179
|
+
return;
|
|
7180
|
+
}
|
|
7181
|
+
if (prevStatus !== null && prevStatus !== record.status) {
|
|
7182
|
+
appendLedgerEntry(meshId, {
|
|
7183
|
+
kind: "mission_status_changed",
|
|
7184
|
+
payload: {
|
|
7185
|
+
missionId: record.id,
|
|
7186
|
+
title: record.title,
|
|
7187
|
+
fromStatus: prevStatus,
|
|
7188
|
+
toStatus: record.status
|
|
7189
|
+
}
|
|
7190
|
+
});
|
|
7191
|
+
}
|
|
7192
|
+
const nextGoal = record.goal ?? "";
|
|
7193
|
+
if (nextGoal !== prevGoal) {
|
|
7194
|
+
appendLedgerEntry(meshId, {
|
|
7195
|
+
kind: "mission_goal_updated",
|
|
7196
|
+
payload: {
|
|
7197
|
+
missionId: record.id,
|
|
7198
|
+
title: record.title,
|
|
7199
|
+
prevGoalSummary: summarizeGoalForLedger(prevGoal),
|
|
7200
|
+
nextGoalSummary: summarizeGoalForLedger(nextGoal),
|
|
7201
|
+
prevGoalLength: prevGoal.length,
|
|
7202
|
+
nextGoalLength: nextGoal.length,
|
|
7203
|
+
goalTruncated: prevGoal.length > LEDGER_GOAL_SUMMARY_MAX || nextGoal.length > LEDGER_GOAL_SUMMARY_MAX
|
|
7204
|
+
}
|
|
7205
|
+
});
|
|
7206
|
+
}
|
|
7207
|
+
} catch {
|
|
7208
|
+
}
|
|
7117
7209
|
}
|
|
7118
7210
|
function getMeshMissions(meshId, statuses) {
|
|
7119
7211
|
return MeshRuntimeStore.getInstance().getMissions(meshId, statuses).map((m) => ({ ...m, status: normalizeMissionStatus(m.status) }));
|
|
@@ -7217,13 +7309,15 @@ function buildMissionPromptSection(meshId) {
|
|
|
7217
7309
|
);
|
|
7218
7310
|
return lines.join("\n");
|
|
7219
7311
|
}
|
|
7220
|
-
var MESH_MISSION_STATUSES, GOAL_PREVIEW_MAX, COMPACT_STATUS_GOAL_PREVIEW_MAX;
|
|
7312
|
+
var LEDGER_GOAL_SUMMARY_MAX, MESH_MISSION_STATUSES, GOAL_PREVIEW_MAX, COMPACT_STATUS_GOAL_PREVIEW_MAX;
|
|
7221
7313
|
var init_mesh_missions = __esm({
|
|
7222
7314
|
"src/mesh/mesh-missions.ts"() {
|
|
7223
7315
|
"use strict";
|
|
7224
7316
|
init_mesh_runtime_store();
|
|
7225
7317
|
init_mesh_work_queue();
|
|
7226
7318
|
init_mesh_task_stats();
|
|
7319
|
+
init_mesh_ledger();
|
|
7320
|
+
LEDGER_GOAL_SUMMARY_MAX = 200;
|
|
7227
7321
|
MESH_MISSION_STATUSES = ["active", "paused", "completed", "abandoned"];
|
|
7228
7322
|
GOAL_PREVIEW_MAX = 120;
|
|
7229
7323
|
COMPACT_STATUS_GOAL_PREVIEW_MAX = 80;
|
|
@@ -7451,7 +7545,7 @@ function resolveNodeEvidence(nodeId, ledgerEntries) {
|
|
|
7451
7545
|
timestamp: entry.timestamp,
|
|
7452
7546
|
...entry.sessionId ? { sessionId: entry.sessionId } : {},
|
|
7453
7547
|
bootstrap: readRecord3(validationSummary?.bootstrap),
|
|
7454
|
-
validation: validationSummary ? Object.fromEntries(Object.entries(validationSummary).filter(([
|
|
7548
|
+
validation: validationSummary ? Object.fromEntries(Object.entries(validationSummary).filter(([key2]) => key2 !== "bootstrap")) : null,
|
|
7455
7549
|
checkpoint: readRecord3(result?.checkpoint),
|
|
7456
7550
|
worker: null,
|
|
7457
7551
|
...readRecord3(payload.finalBranchConvergenceState) ?? readRecord3(result?.finalBranchConvergenceState) ? { finalBranchConvergenceState: readRecord3(payload.finalBranchConvergenceState) ?? readRecord3(result?.finalBranchConvergenceState) } : {},
|
|
@@ -7720,7 +7814,7 @@ function resolveMeshCoordinatorSetup(options) {
|
|
|
7720
7814
|
};
|
|
7721
7815
|
}
|
|
7722
7816
|
function renderMeshCoordinatorTemplate(template, values) {
|
|
7723
|
-
return template.replace(/\{\{\s*(meshId|workspace|serverName|adhdevMcpCommand|adhdevMcpArgs)\s*\}\}/g, (_,
|
|
7817
|
+
return template.replace(/\{\{\s*(meshId|workspace|serverName|adhdevMcpCommand|adhdevMcpArgs)\s*\}\}/g, (_, key2) => values[key2] || "");
|
|
7724
7818
|
}
|
|
7725
7819
|
function replaceLegacyCliCommandMcpArgs(command, args) {
|
|
7726
7820
|
return command.replace(
|
|
@@ -7729,9 +7823,9 @@ function replaceLegacyCliCommandMcpArgs(command, args) {
|
|
|
7729
7823
|
);
|
|
7730
7824
|
}
|
|
7731
7825
|
function resolveHermesCoordinatorHome(meshId, workspace) {
|
|
7732
|
-
const
|
|
7826
|
+
const key2 = `${meshId || "mesh"}
|
|
7733
7827
|
${resolve7(workspace || os4.tmpdir())}`;
|
|
7734
|
-
const hash = shortHash(
|
|
7828
|
+
const hash = shortHash(key2);
|
|
7735
7829
|
return join10(os4.tmpdir(), `adhdev-hermes-mesh-coordinator-${hash}`);
|
|
7736
7830
|
}
|
|
7737
7831
|
function resolveMcpConfigPath(configPath, workspace) {
|
|
@@ -8201,9 +8295,9 @@ function suggestMeshRefineConfig(mesh, workspace) {
|
|
|
8201
8295
|
const seen = /* @__PURE__ */ new Set();
|
|
8202
8296
|
const suggestions = [];
|
|
8203
8297
|
for (const entry of [...collectProjectContextSuggestions(mesh), ...collectPackageScriptSuggestions(workspace)]) {
|
|
8204
|
-
const
|
|
8205
|
-
if (seen.has(
|
|
8206
|
-
seen.add(
|
|
8298
|
+
const key2 = `${entry.command} ${(entry.args || []).join(" ")}`.trim();
|
|
8299
|
+
if (seen.has(key2)) continue;
|
|
8300
|
+
seen.add(key2);
|
|
8207
8301
|
suggestions.push(entry);
|
|
8208
8302
|
}
|
|
8209
8303
|
return {
|
|
@@ -8677,6 +8771,216 @@ var init_worktree_bootstrap_config = __esm({
|
|
|
8677
8771
|
}
|
|
8678
8772
|
});
|
|
8679
8773
|
|
|
8774
|
+
// src/config/mesh-json-config.ts
|
|
8775
|
+
var mesh_json_config_exports = {};
|
|
8776
|
+
__export(mesh_json_config_exports, {
|
|
8777
|
+
MESH_JSON_CONFIG_LOCATIONS: () => MESH_JSON_CONFIG_LOCATIONS,
|
|
8778
|
+
MESH_JSON_CONFIG_SCHEMA: () => MESH_JSON_CONFIG_SCHEMA,
|
|
8779
|
+
applyRepoMeshConfig: () => applyRepoMeshConfig,
|
|
8780
|
+
buildMeshJsonConfigScaffold: () => buildMeshJsonConfigScaffold,
|
|
8781
|
+
loadRepoMeshJsonConfig: () => loadRepoMeshJsonConfig,
|
|
8782
|
+
mergeEffectiveCoordinatorConfig: () => mergeEffectiveCoordinatorConfig,
|
|
8783
|
+
mergeEffectiveOperatingNotes: () => mergeEffectiveOperatingNotes,
|
|
8784
|
+
normalizeRepoMeshDeclarativeConfig: () => normalizeRepoMeshDeclarativeConfig,
|
|
8785
|
+
serializeMeshJsonConfigScaffold: () => serializeMeshJsonConfigScaffold
|
|
8786
|
+
});
|
|
8787
|
+
import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
|
|
8788
|
+
import { join as join15 } from "path";
|
|
8789
|
+
import * as yaml4 from "js-yaml";
|
|
8790
|
+
function isRecord3(value) {
|
|
8791
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
8792
|
+
}
|
|
8793
|
+
function parseConfigText4(path43, text) {
|
|
8794
|
+
if (/\.json$/i.test(path43)) return JSON.parse(text);
|
|
8795
|
+
return yaml4.load(text);
|
|
8796
|
+
}
|
|
8797
|
+
function normalizeOperatingNote(value) {
|
|
8798
|
+
if (!isRecord3(value)) return null;
|
|
8799
|
+
const text = typeof value.text === "string" ? value.text.trim() : "";
|
|
8800
|
+
if (!text) return null;
|
|
8801
|
+
const category = value.category === "provider_quirk" || value.category === "pattern_to_avoid" || value.category === "recovery_lesson" ? value.category : void 0;
|
|
8802
|
+
return {
|
|
8803
|
+
text,
|
|
8804
|
+
...category ? { category } : {},
|
|
8805
|
+
...typeof value.createdAt === "string" ? { createdAt: value.createdAt } : {},
|
|
8806
|
+
...typeof value.sourceCoordinator === "string" ? { sourceCoordinator: value.sourceCoordinator } : {}
|
|
8807
|
+
};
|
|
8808
|
+
}
|
|
8809
|
+
function normalizeRepoMeshDeclarativeConfig(parsed) {
|
|
8810
|
+
const errors = [];
|
|
8811
|
+
if (!isRecord3(parsed)) return { valid: false, errors: ["config must be an object"] };
|
|
8812
|
+
if (parsed.version !== 1) {
|
|
8813
|
+
return { valid: false, errors: [`version must be 1 (got ${JSON.stringify(parsed.version)})`] };
|
|
8814
|
+
}
|
|
8815
|
+
const config = { version: 1 };
|
|
8816
|
+
if (parsed.coordinator !== void 0) {
|
|
8817
|
+
if (isRecord3(parsed.coordinator)) {
|
|
8818
|
+
const coord = {};
|
|
8819
|
+
const c = parsed.coordinator;
|
|
8820
|
+
if (typeof c.systemPromptOverride === "string") coord.systemPromptOverride = c.systemPromptOverride;
|
|
8821
|
+
if (typeof c.systemPromptAppend === "string") coord.systemPromptAppend = c.systemPromptAppend;
|
|
8822
|
+
if (Number.isFinite(Number(c.maxPromptChars))) coord.maxPromptChars = Number(c.maxPromptChars);
|
|
8823
|
+
config.coordinator = coord;
|
|
8824
|
+
} else {
|
|
8825
|
+
errors.push("coordinator must be an object when provided");
|
|
8826
|
+
}
|
|
8827
|
+
}
|
|
8828
|
+
if (parsed.operatingNotes !== void 0) {
|
|
8829
|
+
if (Array.isArray(parsed.operatingNotes)) {
|
|
8830
|
+
const notes = parsed.operatingNotes.map(normalizeOperatingNote).filter((n) => n !== null);
|
|
8831
|
+
if (notes.length) config.operatingNotes = notes;
|
|
8832
|
+
} else {
|
|
8833
|
+
errors.push("operatingNotes must be an array when provided");
|
|
8834
|
+
}
|
|
8835
|
+
}
|
|
8836
|
+
if (parsed.limits !== void 0) {
|
|
8837
|
+
if (isRecord3(parsed.limits)) {
|
|
8838
|
+
const limits = {};
|
|
8839
|
+
if (Number.isFinite(Number(parsed.limits.maxNoteChars))) limits.maxNoteChars = Number(parsed.limits.maxNoteChars);
|
|
8840
|
+
if (Number.isFinite(Number(parsed.limits.maxNotes))) limits.maxNotes = Number(parsed.limits.maxNotes);
|
|
8841
|
+
if (Object.keys(limits).length) config.limits = limits;
|
|
8842
|
+
} else {
|
|
8843
|
+
errors.push("limits must be an object when provided");
|
|
8844
|
+
}
|
|
8845
|
+
}
|
|
8846
|
+
return { valid: true, config, errors };
|
|
8847
|
+
}
|
|
8848
|
+
function loadRepoMeshJsonConfig(workspace) {
|
|
8849
|
+
const bases = [];
|
|
8850
|
+
const ws = typeof workspace === "string" ? workspace.trim() : "";
|
|
8851
|
+
if (ws) bases.push(ws);
|
|
8852
|
+
let cwd = "";
|
|
8853
|
+
try {
|
|
8854
|
+
cwd = process.cwd();
|
|
8855
|
+
} catch {
|
|
8856
|
+
}
|
|
8857
|
+
if (cwd && cwd !== ws) bases.push(cwd);
|
|
8858
|
+
for (const base of bases) {
|
|
8859
|
+
for (const relative5 of MESH_JSON_CONFIG_LOCATIONS) {
|
|
8860
|
+
const configPath = join15(base, relative5);
|
|
8861
|
+
if (!existsSync14(configPath)) continue;
|
|
8862
|
+
try {
|
|
8863
|
+
const parsed = parseConfigText4(configPath, readFileSync11(configPath, "utf-8"));
|
|
8864
|
+
const result = normalizeRepoMeshDeclarativeConfig(parsed);
|
|
8865
|
+
if (!result.valid || !result.config) {
|
|
8866
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: result.errors.join("; ") };
|
|
8867
|
+
}
|
|
8868
|
+
return { config: result.config, source: relative5, sourceType: "repo_file", path: configPath };
|
|
8869
|
+
} catch (error) {
|
|
8870
|
+
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
8871
|
+
}
|
|
8872
|
+
}
|
|
8873
|
+
}
|
|
8874
|
+
return {
|
|
8875
|
+
source: "unavailable",
|
|
8876
|
+
sourceType: "unavailable",
|
|
8877
|
+
error: `No repo mesh config found. Checked: ${MESH_JSON_CONFIG_LOCATIONS.join(", ")}`
|
|
8878
|
+
};
|
|
8879
|
+
}
|
|
8880
|
+
function mergeEffectiveCoordinatorConfig(repoCoord, localCoord) {
|
|
8881
|
+
const out = { ...localCoord || {} };
|
|
8882
|
+
const localOverride = localCoord?.systemPromptOverride?.trim();
|
|
8883
|
+
const repoOverride = repoCoord?.systemPromptOverride?.trim();
|
|
8884
|
+
if (localOverride) {
|
|
8885
|
+
out.systemPromptOverride = localCoord.systemPromptOverride;
|
|
8886
|
+
} else if (repoOverride) {
|
|
8887
|
+
out.systemPromptOverride = repoCoord.systemPromptOverride;
|
|
8888
|
+
} else {
|
|
8889
|
+
delete out.systemPromptOverride;
|
|
8890
|
+
}
|
|
8891
|
+
const repoAppend = repoCoord?.systemPromptAppend?.trim() ? repoCoord.systemPromptAppend.trim() : "";
|
|
8892
|
+
const localAppendRaw = localCoord?.systemPromptAppend ?? localCoord?.systemPromptSuffix;
|
|
8893
|
+
const localAppend = localAppendRaw?.trim() ? localAppendRaw.trim() : "";
|
|
8894
|
+
const stacked = [repoAppend, localAppend].filter(Boolean).join("\n\n");
|
|
8895
|
+
if (stacked) {
|
|
8896
|
+
out.systemPromptAppend = stacked;
|
|
8897
|
+
delete out.systemPromptSuffix;
|
|
8898
|
+
}
|
|
8899
|
+
return out;
|
|
8900
|
+
}
|
|
8901
|
+
function mergeEffectiveOperatingNotes(repoNotes, ledgerNotes) {
|
|
8902
|
+
const usable = (notes) => Array.isArray(notes) ? notes.filter((n) => n && typeof n.text === "string" && n.text.trim()) : [];
|
|
8903
|
+
const repo = usable(repoNotes);
|
|
8904
|
+
const ledger = usable(ledgerNotes);
|
|
8905
|
+
const ledgerTexts = new Set(ledger.map((n) => n.text.trim()));
|
|
8906
|
+
const repoKept = repo.filter((n) => !ledgerTexts.has(n.text.trim()));
|
|
8907
|
+
const merged = [...repoKept, ...ledger];
|
|
8908
|
+
return merged.length ? merged : void 0;
|
|
8909
|
+
}
|
|
8910
|
+
function applyRepoMeshConfig(mesh, repoConfig) {
|
|
8911
|
+
if (!repoConfig) return mesh;
|
|
8912
|
+
return {
|
|
8913
|
+
...mesh,
|
|
8914
|
+
coordinator: mergeEffectiveCoordinatorConfig(repoConfig.coordinator, mesh.coordinator)
|
|
8915
|
+
};
|
|
8916
|
+
}
|
|
8917
|
+
function buildMeshJsonConfigScaffold(mesh) {
|
|
8918
|
+
const scaffold = { version: 1 };
|
|
8919
|
+
const coord = {};
|
|
8920
|
+
const override = mesh.coordinator?.systemPromptOverride;
|
|
8921
|
+
if (typeof override === "string" && override.trim()) coord.systemPromptOverride = override;
|
|
8922
|
+
const append = mesh.coordinator?.systemPromptAppend ?? mesh.coordinator?.systemPromptSuffix;
|
|
8923
|
+
if (typeof append === "string" && append.trim()) coord.systemPromptAppend = append;
|
|
8924
|
+
if (Object.keys(coord).length) scaffold.coordinator = coord;
|
|
8925
|
+
return scaffold;
|
|
8926
|
+
}
|
|
8927
|
+
function serializeMeshJsonConfigScaffold(config) {
|
|
8928
|
+
return JSON.stringify(config, null, 2);
|
|
8929
|
+
}
|
|
8930
|
+
var MESH_JSON_CONFIG_LOCATIONS, MESH_JSON_CONFIG_SCHEMA;
|
|
8931
|
+
var init_mesh_json_config = __esm({
|
|
8932
|
+
"src/config/mesh-json-config.ts"() {
|
|
8933
|
+
"use strict";
|
|
8934
|
+
MESH_JSON_CONFIG_LOCATIONS = [
|
|
8935
|
+
".adhdev/mesh.json",
|
|
8936
|
+
".adhdev/mesh.yaml",
|
|
8937
|
+
".adhdev/mesh.yml"
|
|
8938
|
+
];
|
|
8939
|
+
MESH_JSON_CONFIG_SCHEMA = {
|
|
8940
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
8941
|
+
title: "ADHDev Repo Mesh Declarative Config",
|
|
8942
|
+
type: "object",
|
|
8943
|
+
additionalProperties: false,
|
|
8944
|
+
required: ["version"],
|
|
8945
|
+
properties: {
|
|
8946
|
+
version: { const: 1 },
|
|
8947
|
+
coordinator: {
|
|
8948
|
+
type: "object",
|
|
8949
|
+
additionalProperties: false,
|
|
8950
|
+
properties: {
|
|
8951
|
+
systemPromptOverride: { type: "string" },
|
|
8952
|
+
systemPromptAppend: { type: "string" },
|
|
8953
|
+
maxPromptChars: { type: "number", minimum: 1 }
|
|
8954
|
+
}
|
|
8955
|
+
},
|
|
8956
|
+
operatingNotes: {
|
|
8957
|
+
type: "array",
|
|
8958
|
+
maxItems: 200,
|
|
8959
|
+
items: {
|
|
8960
|
+
type: "object",
|
|
8961
|
+
additionalProperties: false,
|
|
8962
|
+
required: ["text"],
|
|
8963
|
+
properties: {
|
|
8964
|
+
text: { type: "string", minLength: 1 },
|
|
8965
|
+
category: { enum: ["provider_quirk", "pattern_to_avoid", "recovery_lesson"] },
|
|
8966
|
+
createdAt: { type: "string" },
|
|
8967
|
+
sourceCoordinator: { type: "string" }
|
|
8968
|
+
}
|
|
8969
|
+
}
|
|
8970
|
+
},
|
|
8971
|
+
limits: {
|
|
8972
|
+
type: "object",
|
|
8973
|
+
additionalProperties: false,
|
|
8974
|
+
properties: {
|
|
8975
|
+
maxNoteChars: { type: "number", minimum: 1 },
|
|
8976
|
+
maxNotes: { type: "number", minimum: 1 }
|
|
8977
|
+
}
|
|
8978
|
+
}
|
|
8979
|
+
}
|
|
8980
|
+
};
|
|
8981
|
+
}
|
|
8982
|
+
});
|
|
8983
|
+
|
|
8680
8984
|
// src/mesh/mesh-fast-forward.ts
|
|
8681
8985
|
async function fastForwardMeshNode(args) {
|
|
8682
8986
|
const workspace = typeof args.workspace === "string" ? args.workspace.trim() : "";
|
|
@@ -10082,8 +10386,8 @@ var init_mesh_events_utils = __esm({
|
|
|
10082
10386
|
});
|
|
10083
10387
|
|
|
10084
10388
|
// src/mesh/mesh-events-pending.ts
|
|
10085
|
-
import { appendFileSync as appendFileSync2, existsSync as
|
|
10086
|
-
import { join as
|
|
10389
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync15, readFileSync as readFileSync12, renameSync as renameSync4, statSync as statSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
10390
|
+
import { join as join16 } from "path";
|
|
10087
10391
|
import { randomUUID as randomUUID8 } from "crypto";
|
|
10088
10392
|
function normalizeCoordinatorDaemonIds(coordinatorDaemonId) {
|
|
10089
10393
|
return expandDaemonIdForms(coordinatorDaemonId);
|
|
@@ -10147,9 +10451,9 @@ function getPendingEventsPath(meshId, coordinatorDaemonId) {
|
|
|
10147
10451
|
const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
10148
10452
|
if (coordinatorDaemonId) {
|
|
10149
10453
|
const safeDaemon = coordinatorDaemonId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
10150
|
-
return
|
|
10454
|
+
return join16(getLedgerDir(), `${safe}-${safeDaemon}.pending-events.jsonl`);
|
|
10151
10455
|
}
|
|
10152
|
-
return
|
|
10456
|
+
return join16(getLedgerDir(), `${safe}.pending-events.jsonl`);
|
|
10153
10457
|
}
|
|
10154
10458
|
function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
10155
10459
|
if (!meshId) return [];
|
|
@@ -10158,9 +10462,9 @@ function readPendingMeshCoordinatorEventsFromDisk(meshId, coordinatorDaemonId) {
|
|
|
10158
10462
|
const paths = primaryDaemonId ? [getPendingEventsPath(meshId, primaryDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
10159
10463
|
const events = [];
|
|
10160
10464
|
for (const path43 of paths) {
|
|
10161
|
-
if (!
|
|
10465
|
+
if (!existsSync15(path43)) continue;
|
|
10162
10466
|
try {
|
|
10163
|
-
const raw =
|
|
10467
|
+
const raw = readFileSync12(path43, "utf-8");
|
|
10164
10468
|
const parsed = raw.split("\n").filter(Boolean).flatMap((line) => {
|
|
10165
10469
|
try {
|
|
10166
10470
|
return [JSON.parse(line)];
|
|
@@ -10235,9 +10539,9 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
|
10235
10539
|
}
|
|
10236
10540
|
function trimPendingEventsIfNeeded(path43) {
|
|
10237
10541
|
try {
|
|
10238
|
-
if (!
|
|
10542
|
+
if (!existsSync15(path43)) return;
|
|
10239
10543
|
if (statSync6(path43).size <= MAX_PENDING_EVENTS_BYTES) return;
|
|
10240
|
-
const lines =
|
|
10544
|
+
const lines = readFileSync12(path43, "utf-8").split("\n").filter(Boolean);
|
|
10241
10545
|
if (lines.length <= MAX_PENDING_EVENTS_KEEP) return;
|
|
10242
10546
|
const dropped = lines.slice(0, lines.length - MAX_PENDING_EVENTS_KEEP);
|
|
10243
10547
|
for (const line of dropped) {
|
|
@@ -10321,7 +10625,7 @@ function atomicDrainFile(path43) {
|
|
|
10321
10625
|
return null;
|
|
10322
10626
|
}
|
|
10323
10627
|
try {
|
|
10324
|
-
const content =
|
|
10628
|
+
const content = readFileSync12(tmpPath, "utf-8");
|
|
10325
10629
|
try {
|
|
10326
10630
|
unlinkSync2(tmpPath);
|
|
10327
10631
|
} catch {
|
|
@@ -10344,7 +10648,7 @@ function selectiveDrainFile(path43, predicate) {
|
|
|
10344
10648
|
}
|
|
10345
10649
|
let content;
|
|
10346
10650
|
try {
|
|
10347
|
-
content =
|
|
10651
|
+
content = readFileSync12(tmpPath, "utf-8");
|
|
10348
10652
|
} catch {
|
|
10349
10653
|
try {
|
|
10350
10654
|
unlinkSync2(tmpPath);
|
|
@@ -10375,7 +10679,7 @@ function selectiveDrainFile(path43, predicate) {
|
|
|
10375
10679
|
unlinkSync2(tmpPath);
|
|
10376
10680
|
} catch {
|
|
10377
10681
|
try {
|
|
10378
|
-
if (
|
|
10682
|
+
if (existsSync15(tmpPath) && !existsSync15(path43)) renameSync4(tmpPath, path43);
|
|
10379
10683
|
} catch {
|
|
10380
10684
|
}
|
|
10381
10685
|
return [];
|
|
@@ -10470,7 +10774,7 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
10470
10774
|
}
|
|
10471
10775
|
const paths = coordinatorDaemonId ? [getPendingEventsPath(meshId, coordinatorDaemonId), getPendingEventsPath(meshId)] : [getPendingEventsPath(meshId)];
|
|
10472
10776
|
for (const path43 of paths) {
|
|
10473
|
-
if (
|
|
10777
|
+
if (existsSync15(path43)) try {
|
|
10474
10778
|
unlinkSync2(path43);
|
|
10475
10779
|
} catch {
|
|
10476
10780
|
}
|
|
@@ -11233,7 +11537,7 @@ var init_provider_cli_shared = __esm({
|
|
|
11233
11537
|
import { exec } from "child_process";
|
|
11234
11538
|
import * as os6 from "os";
|
|
11235
11539
|
import * as path12 from "path";
|
|
11236
|
-
import { existsSync as
|
|
11540
|
+
import { existsSync as existsSync16 } from "fs";
|
|
11237
11541
|
function parseVersion(raw) {
|
|
11238
11542
|
const match = raw.match(/v?(\d+\.\d+(?:\.\d+)?(?:-[a-zA-Z0-9.]+)?)/);
|
|
11239
11543
|
return match ? match[1] : raw.split("\n")[0].slice(0, 100);
|
|
@@ -11257,7 +11561,7 @@ function resolveCommandPath(command) {
|
|
|
11257
11561
|
if (isExplicitCommandPath(trimmed)) {
|
|
11258
11562
|
const expanded = expandHome(trimmed);
|
|
11259
11563
|
const candidate = path12.isAbsolute(expanded) ? expanded : path12.resolve(expanded);
|
|
11260
|
-
return
|
|
11564
|
+
return existsSync16(candidate) ? candidate : null;
|
|
11261
11565
|
}
|
|
11262
11566
|
return null;
|
|
11263
11567
|
}
|
|
@@ -11267,7 +11571,7 @@ async function resolveDetectionPath(command, whichCmd) {
|
|
|
11267
11571
|
const whichResult = await execAsync(`${whichCmd} ${shellQuote(command)}`);
|
|
11268
11572
|
if (whichResult) return whichResult.split("\n")[0];
|
|
11269
11573
|
const resolved = findBinary(command);
|
|
11270
|
-
if (path12.isAbsolute(resolved) &&
|
|
11574
|
+
if (path12.isAbsolute(resolved) && existsSync16(resolved)) return resolved;
|
|
11271
11575
|
return null;
|
|
11272
11576
|
}
|
|
11273
11577
|
function execAsync(cmd, timeoutMs = 5e3) {
|
|
@@ -11485,347 +11789,11 @@ var init_mesh_warmup_deadline = __esm({
|
|
|
11485
11789
|
}
|
|
11486
11790
|
});
|
|
11487
11791
|
|
|
11488
|
-
// src/config/mesh-json-config.ts
|
|
11489
|
-
var mesh_json_config_exports = {};
|
|
11490
|
-
__export(mesh_json_config_exports, {
|
|
11491
|
-
MESH_JSON_CONFIG_LOCATIONS: () => MESH_JSON_CONFIG_LOCATIONS,
|
|
11492
|
-
MESH_JSON_CONFIG_SCHEMA: () => MESH_JSON_CONFIG_SCHEMA,
|
|
11493
|
-
__resetMeshJsonConfigCacheForTests: () => __resetMeshJsonConfigCacheForTests,
|
|
11494
|
-
applyRepoMeshConfig: () => applyRepoMeshConfig,
|
|
11495
|
-
buildMeshJsonConfigScaffold: () => buildMeshJsonConfigScaffold,
|
|
11496
|
-
diffPolicyFromDefault: () => diffPolicyFromDefault,
|
|
11497
|
-
loadMeshJsonConfig: () => loadMeshJsonConfig,
|
|
11498
|
-
loadRepoMeshJsonConfig: () => loadRepoMeshJsonConfig,
|
|
11499
|
-
mergeEffectiveCoordinatorConfig: () => mergeEffectiveCoordinatorConfig,
|
|
11500
|
-
mergeEffectiveMeshPolicy: () => mergeEffectiveMeshPolicy,
|
|
11501
|
-
mergeEffectiveOperatingNotes: () => mergeEffectiveOperatingNotes,
|
|
11502
|
-
normalizeRepoMeshDeclarativeConfig: () => normalizeRepoMeshDeclarativeConfig,
|
|
11503
|
-
serializeMeshJsonConfigScaffold: () => serializeMeshJsonConfigScaffold,
|
|
11504
|
-
validateMeshJsonConfig: () => validateMeshJsonConfig
|
|
11505
|
-
});
|
|
11506
|
-
import { existsSync as existsSync16, readFileSync as readFileSync12, statSync as statSync7 } from "fs";
|
|
11507
|
-
import { join as join18 } from "path";
|
|
11508
|
-
import * as yaml4 from "js-yaml";
|
|
11509
|
-
function isRecord3(value) {
|
|
11510
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
11511
|
-
}
|
|
11512
|
-
function parseConfigText4(path43, text) {
|
|
11513
|
-
if (/\.json$/i.test(path43)) return JSON.parse(text);
|
|
11514
|
-
return yaml4.load(text);
|
|
11515
|
-
}
|
|
11516
|
-
function normalizeOperatingNote(value) {
|
|
11517
|
-
if (!isRecord3(value)) return null;
|
|
11518
|
-
const text = typeof value.text === "string" ? value.text.trim() : "";
|
|
11519
|
-
if (!text) return null;
|
|
11520
|
-
const category = value.category === "provider_quirk" || value.category === "pattern_to_avoid" || value.category === "recovery_lesson" ? value.category : void 0;
|
|
11521
|
-
return {
|
|
11522
|
-
text,
|
|
11523
|
-
...category ? { category } : {},
|
|
11524
|
-
...typeof value.createdAt === "string" ? { createdAt: value.createdAt } : {},
|
|
11525
|
-
...typeof value.sourceCoordinator === "string" ? { sourceCoordinator: value.sourceCoordinator } : {}
|
|
11526
|
-
};
|
|
11527
|
-
}
|
|
11528
|
-
function normalizeRepoMeshDeclarativeConfig(parsed) {
|
|
11529
|
-
const errors = [];
|
|
11530
|
-
if (!isRecord3(parsed)) return { valid: false, errors: ["config must be an object"] };
|
|
11531
|
-
if (parsed.version !== 1) {
|
|
11532
|
-
return { valid: false, errors: [`version must be 1 (got ${JSON.stringify(parsed.version)})`] };
|
|
11533
|
-
}
|
|
11534
|
-
const config = { version: 1 };
|
|
11535
|
-
if (parsed.policy !== void 0) {
|
|
11536
|
-
if (isRecord3(parsed.policy)) {
|
|
11537
|
-
config.policy = parsed.policy;
|
|
11538
|
-
} else {
|
|
11539
|
-
errors.push("policy must be an object when provided");
|
|
11540
|
-
}
|
|
11541
|
-
}
|
|
11542
|
-
if (parsed.coordinator !== void 0) {
|
|
11543
|
-
if (isRecord3(parsed.coordinator)) {
|
|
11544
|
-
const coord = {};
|
|
11545
|
-
const c = parsed.coordinator;
|
|
11546
|
-
if (typeof c.systemPromptOverride === "string") coord.systemPromptOverride = c.systemPromptOverride;
|
|
11547
|
-
if (typeof c.systemPromptAppend === "string") coord.systemPromptAppend = c.systemPromptAppend;
|
|
11548
|
-
if (Number.isFinite(Number(c.maxPromptChars))) coord.maxPromptChars = Number(c.maxPromptChars);
|
|
11549
|
-
config.coordinator = coord;
|
|
11550
|
-
} else {
|
|
11551
|
-
errors.push("coordinator must be an object when provided");
|
|
11552
|
-
}
|
|
11553
|
-
}
|
|
11554
|
-
if (parsed.operatingNotes !== void 0) {
|
|
11555
|
-
if (Array.isArray(parsed.operatingNotes)) {
|
|
11556
|
-
const notes = parsed.operatingNotes.map(normalizeOperatingNote).filter((n) => n !== null);
|
|
11557
|
-
if (notes.length) config.operatingNotes = notes;
|
|
11558
|
-
} else {
|
|
11559
|
-
errors.push("operatingNotes must be an array when provided");
|
|
11560
|
-
}
|
|
11561
|
-
}
|
|
11562
|
-
if (parsed.limits !== void 0) {
|
|
11563
|
-
if (isRecord3(parsed.limits)) {
|
|
11564
|
-
const limits = {};
|
|
11565
|
-
if (Number.isFinite(Number(parsed.limits.maxNoteChars))) limits.maxNoteChars = Number(parsed.limits.maxNoteChars);
|
|
11566
|
-
if (Number.isFinite(Number(parsed.limits.maxNotes))) limits.maxNotes = Number(parsed.limits.maxNotes);
|
|
11567
|
-
if (Object.keys(limits).length) config.limits = limits;
|
|
11568
|
-
} else {
|
|
11569
|
-
errors.push("limits must be an object when provided");
|
|
11570
|
-
}
|
|
11571
|
-
}
|
|
11572
|
-
return { valid: true, config, errors };
|
|
11573
|
-
}
|
|
11574
|
-
function loadRepoMeshJsonConfig(workspace) {
|
|
11575
|
-
const bases = [];
|
|
11576
|
-
const ws = typeof workspace === "string" ? workspace.trim() : "";
|
|
11577
|
-
if (ws) bases.push(ws);
|
|
11578
|
-
let cwd = "";
|
|
11579
|
-
try {
|
|
11580
|
-
cwd = process.cwd();
|
|
11581
|
-
} catch {
|
|
11582
|
-
}
|
|
11583
|
-
if (cwd && cwd !== ws) bases.push(cwd);
|
|
11584
|
-
for (const base of bases) {
|
|
11585
|
-
for (const relative5 of MESH_JSON_CONFIG_LOCATIONS) {
|
|
11586
|
-
const configPath = join18(base, relative5);
|
|
11587
|
-
if (!existsSync16(configPath)) continue;
|
|
11588
|
-
try {
|
|
11589
|
-
const parsed = parseConfigText4(configPath, readFileSync12(configPath, "utf-8"));
|
|
11590
|
-
const result = normalizeRepoMeshDeclarativeConfig(parsed);
|
|
11591
|
-
if (!result.valid || !result.config) {
|
|
11592
|
-
return { source: relative5, sourceType: "invalid", path: configPath, error: result.errors.join("; ") };
|
|
11593
|
-
}
|
|
11594
|
-
return { config: result.config, source: relative5, sourceType: "repo_file", path: configPath };
|
|
11595
|
-
} catch (error) {
|
|
11596
|
-
return { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error) };
|
|
11597
|
-
}
|
|
11598
|
-
}
|
|
11599
|
-
}
|
|
11600
|
-
return {
|
|
11601
|
-
source: "unavailable",
|
|
11602
|
-
sourceType: "unavailable",
|
|
11603
|
-
error: `No repo mesh config found. Checked: ${MESH_JSON_CONFIG_LOCATIONS.join(", ")}`
|
|
11604
|
-
};
|
|
11605
|
-
}
|
|
11606
|
-
function deepEqual(a, b) {
|
|
11607
|
-
if (a === b) return true;
|
|
11608
|
-
try {
|
|
11609
|
-
return JSON.stringify(a) === JSON.stringify(b);
|
|
11610
|
-
} catch {
|
|
11611
|
-
return false;
|
|
11612
|
-
}
|
|
11613
|
-
}
|
|
11614
|
-
function diffPolicyFromDefault(local) {
|
|
11615
|
-
if (!local || typeof local !== "object") return {};
|
|
11616
|
-
const out = {};
|
|
11617
|
-
const def = mergeAndNormalizePolicy(void 0, void 0);
|
|
11618
|
-
for (const [key, value] of Object.entries(local)) {
|
|
11619
|
-
if (value === void 0) continue;
|
|
11620
|
-
if (!deepEqual(value, def[key])) out[key] = value;
|
|
11621
|
-
}
|
|
11622
|
-
return out;
|
|
11623
|
-
}
|
|
11624
|
-
function mergeEffectiveMeshPolicy(repoPolicy, localPolicy) {
|
|
11625
|
-
const repoMerged = mergeAndNormalizePolicy(void 0, repoPolicy);
|
|
11626
|
-
const localOverrides = diffPolicyFromDefault(localPolicy);
|
|
11627
|
-
return mergeAndNormalizePolicy(repoMerged, localOverrides);
|
|
11628
|
-
}
|
|
11629
|
-
function mergeEffectiveCoordinatorConfig(repoCoord, localCoord) {
|
|
11630
|
-
const out = { ...localCoord || {} };
|
|
11631
|
-
const localOverride = localCoord?.systemPromptOverride?.trim();
|
|
11632
|
-
const repoOverride = repoCoord?.systemPromptOverride?.trim();
|
|
11633
|
-
if (localOverride) {
|
|
11634
|
-
out.systemPromptOverride = localCoord.systemPromptOverride;
|
|
11635
|
-
} else if (repoOverride) {
|
|
11636
|
-
out.systemPromptOverride = repoCoord.systemPromptOverride;
|
|
11637
|
-
} else {
|
|
11638
|
-
delete out.systemPromptOverride;
|
|
11639
|
-
}
|
|
11640
|
-
const repoAppend = repoCoord?.systemPromptAppend?.trim() ? repoCoord.systemPromptAppend.trim() : "";
|
|
11641
|
-
const localAppendRaw = localCoord?.systemPromptAppend ?? localCoord?.systemPromptSuffix;
|
|
11642
|
-
const localAppend = localAppendRaw?.trim() ? localAppendRaw.trim() : "";
|
|
11643
|
-
const stacked = [repoAppend, localAppend].filter(Boolean).join("\n\n");
|
|
11644
|
-
if (stacked) {
|
|
11645
|
-
out.systemPromptAppend = stacked;
|
|
11646
|
-
delete out.systemPromptSuffix;
|
|
11647
|
-
}
|
|
11648
|
-
return out;
|
|
11649
|
-
}
|
|
11650
|
-
function mergeEffectiveOperatingNotes(repoNotes, ledgerNotes) {
|
|
11651
|
-
const usable = (notes) => Array.isArray(notes) ? notes.filter((n) => n && typeof n.text === "string" && n.text.trim()) : [];
|
|
11652
|
-
const repo = usable(repoNotes);
|
|
11653
|
-
const ledger = usable(ledgerNotes);
|
|
11654
|
-
const ledgerTexts = new Set(ledger.map((n) => n.text.trim()));
|
|
11655
|
-
const repoKept = repo.filter((n) => !ledgerTexts.has(n.text.trim()));
|
|
11656
|
-
const merged = [...repoKept, ...ledger];
|
|
11657
|
-
return merged.length ? merged : void 0;
|
|
11658
|
-
}
|
|
11659
|
-
function applyRepoMeshConfig(mesh, repoConfig) {
|
|
11660
|
-
if (!repoConfig) return mesh;
|
|
11661
|
-
return {
|
|
11662
|
-
...mesh,
|
|
11663
|
-
policy: mergeEffectiveMeshPolicy(repoConfig.policy, mesh.policy),
|
|
11664
|
-
coordinator: mergeEffectiveCoordinatorConfig(repoConfig.coordinator, mesh.coordinator)
|
|
11665
|
-
};
|
|
11666
|
-
}
|
|
11667
|
-
function buildMeshJsonConfigScaffold(mesh) {
|
|
11668
|
-
const scaffold = {
|
|
11669
|
-
version: 1,
|
|
11670
|
-
policy: mergeAndNormalizePolicy(void 0, mesh.policy)
|
|
11671
|
-
};
|
|
11672
|
-
const coord = {};
|
|
11673
|
-
const override = mesh.coordinator?.systemPromptOverride;
|
|
11674
|
-
if (typeof override === "string" && override.trim()) coord.systemPromptOverride = override;
|
|
11675
|
-
const append = mesh.coordinator?.systemPromptAppend ?? mesh.coordinator?.systemPromptSuffix;
|
|
11676
|
-
if (typeof append === "string" && append.trim()) coord.systemPromptAppend = append;
|
|
11677
|
-
if (Object.keys(coord).length) scaffold.coordinator = coord;
|
|
11678
|
-
return scaffold;
|
|
11679
|
-
}
|
|
11680
|
-
function serializeMeshJsonConfigScaffold(config) {
|
|
11681
|
-
return JSON.stringify(config, null, 2);
|
|
11682
|
-
}
|
|
11683
|
-
function validateMeshJsonConfig(raw, source = "inline") {
|
|
11684
|
-
const errors = [];
|
|
11685
|
-
if (!isRecord3(raw)) {
|
|
11686
|
-
return { valid: false, errors: [`${source}: config must be an object`] };
|
|
11687
|
-
}
|
|
11688
|
-
const config = {};
|
|
11689
|
-
const policy = raw.policy;
|
|
11690
|
-
const schedulingRaw = isRecord3(policy) ? policy.scheduling : void 0;
|
|
11691
|
-
if (schedulingRaw !== void 0) {
|
|
11692
|
-
if (!isRecord3(schedulingRaw)) {
|
|
11693
|
-
errors.push("policy.scheduling must be an object");
|
|
11694
|
-
} else {
|
|
11695
|
-
const scheduling = {};
|
|
11696
|
-
if (schedulingRaw.distribution !== void 0) {
|
|
11697
|
-
if (typeof schedulingRaw.distribution !== "string" || !["spread", "in_order"].includes(schedulingRaw.distribution.trim())) {
|
|
11698
|
-
errors.push("policy.scheduling.distribution must be 'spread' or 'in_order'");
|
|
11699
|
-
} else {
|
|
11700
|
-
scheduling.distribution = normalizeMeshDistribution(schedulingRaw.distribution);
|
|
11701
|
-
}
|
|
11702
|
-
}
|
|
11703
|
-
if (schedulingRaw.maxParallel !== void 0) {
|
|
11704
|
-
const n = Number(schedulingRaw.maxParallel);
|
|
11705
|
-
if (!Number.isFinite(n) || n < MESH_MAX_PARALLEL_TASKS_MIN || n > MESH_MAX_PARALLEL_TASKS_MAX) {
|
|
11706
|
-
errors.push(`policy.scheduling.maxParallel must be a number in [${MESH_MAX_PARALLEL_TASKS_MIN}, ${MESH_MAX_PARALLEL_TASKS_MAX}]`);
|
|
11707
|
-
} else {
|
|
11708
|
-
scheduling.maxParallel = Math.floor(n);
|
|
11709
|
-
}
|
|
11710
|
-
}
|
|
11711
|
-
if (schedulingRaw.readonlyMultiplier !== void 0) {
|
|
11712
|
-
const n = Number(schedulingRaw.readonlyMultiplier);
|
|
11713
|
-
if (!Number.isFinite(n) || n < 1) {
|
|
11714
|
-
errors.push("policy.scheduling.readonlyMultiplier must be a number >= 1");
|
|
11715
|
-
} else {
|
|
11716
|
-
scheduling.readonlyMultiplier = Math.floor(n);
|
|
11717
|
-
}
|
|
11718
|
-
}
|
|
11719
|
-
for (const key of Object.keys(schedulingRaw)) {
|
|
11720
|
-
if (!["distribution", "maxParallel", "readonlyMultiplier"].includes(key)) {
|
|
11721
|
-
errors.push(`policy.scheduling.${key} is not a recognized field`);
|
|
11722
|
-
}
|
|
11723
|
-
}
|
|
11724
|
-
if (Object.keys(scheduling).length) config.scheduling = scheduling;
|
|
11725
|
-
}
|
|
11726
|
-
}
|
|
11727
|
-
return { valid: errors.length === 0, errors, config: errors.length === 0 ? config : void 0 };
|
|
11728
|
-
}
|
|
11729
|
-
function loadMeshJsonConfig(repoRoot) {
|
|
11730
|
-
if (!repoRoot) {
|
|
11731
|
-
return { source: "unavailable", sourceType: "unavailable", error: "no repo root", sourceKey: "unavailable" };
|
|
11732
|
-
}
|
|
11733
|
-
for (const relative5 of MESH_JSON_CONFIG_LOCATIONS) {
|
|
11734
|
-
const configPath = join18(repoRoot, relative5);
|
|
11735
|
-
if (!existsSync16(configPath)) continue;
|
|
11736
|
-
let mtimeMs = 0;
|
|
11737
|
-
try {
|
|
11738
|
-
mtimeMs = statSync7(configPath).mtimeMs;
|
|
11739
|
-
} catch {
|
|
11740
|
-
mtimeMs = 0;
|
|
11741
|
-
}
|
|
11742
|
-
const cacheKey = configPath;
|
|
11743
|
-
const sourceKey = `file:${configPath}:${mtimeMs}`;
|
|
11744
|
-
const cached3 = cache.get(cacheKey);
|
|
11745
|
-
if (cached3 && cached3.sourceKey === sourceKey) return cached3.result;
|
|
11746
|
-
let result;
|
|
11747
|
-
try {
|
|
11748
|
-
const text = readFileSync12(configPath, "utf-8");
|
|
11749
|
-
const parsed = parseConfigText4(configPath, text);
|
|
11750
|
-
const validation = validateMeshJsonConfig(parsed, relative5);
|
|
11751
|
-
result = validation.valid ? { config: validation.config, source: relative5, sourceType: "repo_file", path: configPath, sourceKey } : { source: relative5, sourceType: "invalid", path: configPath, error: validation.errors.join("; "), sourceKey: `invalid:${configPath}:${mtimeMs}` };
|
|
11752
|
-
} catch (error) {
|
|
11753
|
-
result = { source: relative5, sourceType: "invalid", path: configPath, error: error?.message || String(error), sourceKey: `error:${configPath}` };
|
|
11754
|
-
}
|
|
11755
|
-
cache.set(cacheKey, { sourceKey: result.sourceKey, result });
|
|
11756
|
-
return result;
|
|
11757
|
-
}
|
|
11758
|
-
return {
|
|
11759
|
-
source: "unavailable",
|
|
11760
|
-
sourceType: "unavailable",
|
|
11761
|
-
error: `No .adhdev/mesh config found. Checked: ${MESH_JSON_CONFIG_LOCATIONS.join(", ")}`,
|
|
11762
|
-
sourceKey: "unavailable"
|
|
11763
|
-
};
|
|
11764
|
-
}
|
|
11765
|
-
function __resetMeshJsonConfigCacheForTests() {
|
|
11766
|
-
cache.clear();
|
|
11767
|
-
}
|
|
11768
|
-
var MESH_JSON_CONFIG_LOCATIONS, MESH_JSON_CONFIG_SCHEMA, cache;
|
|
11769
|
-
var init_mesh_json_config = __esm({
|
|
11770
|
-
"src/config/mesh-json-config.ts"() {
|
|
11771
|
-
"use strict";
|
|
11772
|
-
init_repo_mesh_types();
|
|
11773
|
-
MESH_JSON_CONFIG_LOCATIONS = [
|
|
11774
|
-
".adhdev/mesh.json",
|
|
11775
|
-
".adhdev/mesh.yaml",
|
|
11776
|
-
".adhdev/mesh.yml"
|
|
11777
|
-
];
|
|
11778
|
-
MESH_JSON_CONFIG_SCHEMA = {
|
|
11779
|
-
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
11780
|
-
title: "ADHDev Repo Mesh Declarative Config",
|
|
11781
|
-
type: "object",
|
|
11782
|
-
additionalProperties: false,
|
|
11783
|
-
required: ["version"],
|
|
11784
|
-
properties: {
|
|
11785
|
-
version: { const: 1 },
|
|
11786
|
-
// policy is validated/normalized through mergeAndNormalizePolicy at merge
|
|
11787
|
-
// time; the schema here only asserts it is an object.
|
|
11788
|
-
policy: { type: "object" },
|
|
11789
|
-
coordinator: {
|
|
11790
|
-
type: "object",
|
|
11791
|
-
additionalProperties: false,
|
|
11792
|
-
properties: {
|
|
11793
|
-
systemPromptOverride: { type: "string" },
|
|
11794
|
-
systemPromptAppend: { type: "string" },
|
|
11795
|
-
maxPromptChars: { type: "number", minimum: 1 }
|
|
11796
|
-
}
|
|
11797
|
-
},
|
|
11798
|
-
operatingNotes: {
|
|
11799
|
-
type: "array",
|
|
11800
|
-
maxItems: 200,
|
|
11801
|
-
items: {
|
|
11802
|
-
type: "object",
|
|
11803
|
-
additionalProperties: false,
|
|
11804
|
-
required: ["text"],
|
|
11805
|
-
properties: {
|
|
11806
|
-
text: { type: "string", minLength: 1 },
|
|
11807
|
-
category: { enum: ["provider_quirk", "pattern_to_avoid", "recovery_lesson"] },
|
|
11808
|
-
createdAt: { type: "string" },
|
|
11809
|
-
sourceCoordinator: { type: "string" }
|
|
11810
|
-
}
|
|
11811
|
-
}
|
|
11812
|
-
},
|
|
11813
|
-
limits: {
|
|
11814
|
-
type: "object",
|
|
11815
|
-
additionalProperties: false,
|
|
11816
|
-
properties: {
|
|
11817
|
-
maxNoteChars: { type: "number", minimum: 1 },
|
|
11818
|
-
maxNotes: { type: "number", minimum: 1 }
|
|
11819
|
-
}
|
|
11820
|
-
}
|
|
11821
|
-
}
|
|
11822
|
-
};
|
|
11823
|
-
cache = /* @__PURE__ */ new Map();
|
|
11824
|
-
}
|
|
11825
|
-
});
|
|
11826
|
-
|
|
11827
11792
|
// src/mesh/mesh-queue-assignment.ts
|
|
11828
11793
|
import { existsSync as existsSync17 } from "fs";
|
|
11794
|
+
function localCoordinatorDaemonId() {
|
|
11795
|
+
return canonicalDaemonId(readNonEmptyString2(loadConfig().machineId));
|
|
11796
|
+
}
|
|
11829
11797
|
function __resetIdleAutoFastForwardForTests() {
|
|
11830
11798
|
idleAutoFastForwardLastAttempt.clear();
|
|
11831
11799
|
}
|
|
@@ -11911,6 +11879,7 @@ function deliverTaskToSession(dispatchThunk, ctx, warmup) {
|
|
|
11911
11879
|
if (timer) clearTimeout(timer);
|
|
11912
11880
|
LOG.error("MeshQueue", `Failed to dispatch task via ${ctx.transport} to node ${ctx.nodeId}: ${e?.message}`);
|
|
11913
11881
|
updateSessionDeliveryStatus(delivery.id, "failed", { lastError: e?.message, incrementAttempt: true });
|
|
11882
|
+
endTaskDispatchInFlight(ctx.meshId, ctx.task.id);
|
|
11914
11883
|
updateTaskStatus(ctx.meshId, ctx.task.id, "pending");
|
|
11915
11884
|
try {
|
|
11916
11885
|
appendLedgerEntry(ctx.meshId, {
|
|
@@ -11984,10 +11953,11 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
|
|
|
11984
11953
|
return false;
|
|
11985
11954
|
}
|
|
11986
11955
|
LOG.info("MeshQueue", `Node ${nodeId} (${sessionId}) pulled task ${task.id}`);
|
|
11956
|
+
beginTaskDispatchInFlight(meshId, task.id);
|
|
11987
11957
|
if (node?.daemonId && components.dispatchMeshCommand) {
|
|
11988
11958
|
const isLocalNode = components.cliManager.adapters.has(sessionId);
|
|
11989
11959
|
if (!isLocalNode) {
|
|
11990
|
-
const localDaemonIdForDispatch =
|
|
11960
|
+
const localDaemonIdForDispatch = localCoordinatorDaemonId();
|
|
11991
11961
|
const sourceCoordinatorSessionId = readNonEmptyString2(task.sourceCoordinatorSessionId) || void 0;
|
|
11992
11962
|
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
11993
11963
|
const remoteDaemonId = node.daemonId;
|
|
@@ -12026,7 +11996,7 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
|
|
|
12026
11996
|
try {
|
|
12027
11997
|
const inst = components.instanceManager.getInstance(sessionId);
|
|
12028
11998
|
if (inst && typeof inst.updateSettings === "function") {
|
|
12029
|
-
const localDaemonId =
|
|
11999
|
+
const localDaemonId = localCoordinatorDaemonId();
|
|
12030
12000
|
const localSourceCoordinatorSessionId = readNonEmptyString2(task.sourceCoordinatorSessionId);
|
|
12031
12001
|
inst.updateSettings({
|
|
12032
12002
|
meshNodeFor: meshId,
|
|
@@ -12051,7 +12021,7 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
|
|
|
12051
12021
|
meshId,
|
|
12052
12022
|
nodeId,
|
|
12053
12023
|
taskId: task.id,
|
|
12054
|
-
...
|
|
12024
|
+
...localCoordinatorDaemonId() ? { coordinatorDaemonId: localCoordinatorDaemonId() } : {},
|
|
12055
12025
|
...readNonEmptyString2(task.sourceCoordinatorSessionId) ? { coordinatorSessionId: readNonEmptyString2(task.sourceCoordinatorSessionId) } : {}
|
|
12056
12026
|
}
|
|
12057
12027
|
}),
|
|
@@ -12063,7 +12033,7 @@ function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType)
|
|
|
12063
12033
|
task,
|
|
12064
12034
|
transport: "local",
|
|
12065
12035
|
...readNonEmptyString2(task.sourceCoordinatorSessionId) ? { sourceCoordinatorSessionId: readNonEmptyString2(task.sourceCoordinatorSessionId) } : {},
|
|
12066
|
-
...
|
|
12036
|
+
...localCoordinatorDaemonId() ? { sourceCoordinatorDaemonId: localCoordinatorDaemonId() } : {}
|
|
12067
12037
|
}
|
|
12068
12038
|
);
|
|
12069
12039
|
return true;
|
|
@@ -12145,8 +12115,8 @@ function notifyCoordinatorOfActionableSkip(meshId, taskId, reason, nodeId) {
|
|
|
12145
12115
|
}
|
|
12146
12116
|
function sweepExpiredCooldowns() {
|
|
12147
12117
|
const now = Date.now();
|
|
12148
|
-
for (const [
|
|
12149
|
-
if (now >= until) autoLaunchCooldownUntil.delete(
|
|
12118
|
+
for (const [key2, until] of autoLaunchCooldownUntil) {
|
|
12119
|
+
if (now >= until) autoLaunchCooldownUntil.delete(key2);
|
|
12150
12120
|
}
|
|
12151
12121
|
}
|
|
12152
12122
|
function normalizeProviderPriority(policy) {
|
|
@@ -12192,7 +12162,7 @@ function nodeHasActiveMeshWork(components, meshId, nodeId, currentSessionId) {
|
|
|
12192
12162
|
const settings = state.settings || {};
|
|
12193
12163
|
if (readNonEmptyString2(settings.meshNodeFor) !== meshId) return false;
|
|
12194
12164
|
const instNodeId = readNonEmptyString2(settings.meshNodeId) || readNonEmptyString2(settings.nodeId);
|
|
12195
|
-
if (instNodeId
|
|
12165
|
+
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
12196
12166
|
const sessionId = readNonEmptyString2(state.instanceId);
|
|
12197
12167
|
if (currentSessionId && sessionId === currentSessionId && isIdleSessionState(state)) return false;
|
|
12198
12168
|
return sessionStateLooksActive(state);
|
|
@@ -12224,7 +12194,7 @@ function resolveAutoLaunchTarget(components, node) {
|
|
|
12224
12194
|
const daemonId = readNonEmptyString2(node?.daemonId);
|
|
12225
12195
|
if (!daemonId) return { mode: "skip", reason: "remote_auto_launch_unsupported" };
|
|
12226
12196
|
if (!components.dispatchMeshCommand) return { mode: "skip", reason: "remote_auto_launch_unsupported" };
|
|
12227
|
-
const coordinatorDaemonId =
|
|
12197
|
+
const coordinatorDaemonId = localCoordinatorDaemonId();
|
|
12228
12198
|
if (!coordinatorDaemonId) return { mode: "skip", reason: "remote_auto_launch_no_coordinator_daemon_id" };
|
|
12229
12199
|
return { mode: "remote", daemonId, coordinatorDaemonId };
|
|
12230
12200
|
}
|
|
@@ -12235,31 +12205,12 @@ function activeReadonlyAssignedCount(meshId) {
|
|
|
12235
12205
|
return getQueue(meshId, { status: ["assigned"] }).filter(isTaskReadonly).length;
|
|
12236
12206
|
}
|
|
12237
12207
|
function nodeHasActiveAssignment(meshId, nodeId) {
|
|
12238
|
-
return getQueue(meshId, { status: ["assigned"] }).some((task) => task.assignedNodeId
|
|
12208
|
+
return getQueue(meshId, { status: ["assigned"] }).some((task) => daemonIdsEquivalent(task.assignedNodeId, nodeId));
|
|
12239
12209
|
}
|
|
12240
12210
|
function nodeActiveLoad(meshId, nodeId) {
|
|
12241
12211
|
return MeshRuntimeStore.getInstance().nodeActiveAssignmentCount(meshId, nodeId);
|
|
12242
12212
|
}
|
|
12243
|
-
function resolveMeshRepoRootForScheduling(mesh) {
|
|
12244
|
-
const nodes = Array.isArray(mesh?.nodes) ? mesh.nodes : [];
|
|
12245
|
-
const pickRoot = (n) => readNonEmptyString2(n?.repoRoot) || readNonEmptyString2(n?.workspace);
|
|
12246
|
-
const base = nodes.find((n) => n?.isLocalWorktree !== true && pickRoot(n));
|
|
12247
|
-
if (base) return pickRoot(base);
|
|
12248
|
-
const anyNode = nodes.find((n) => pickRoot(n));
|
|
12249
|
-
return anyNode ? pickRoot(anyNode) : "";
|
|
12250
|
-
}
|
|
12251
|
-
function resolveMeshSchedulingOverride(mesh) {
|
|
12252
|
-
const repoRoot = resolveMeshRepoRootForScheduling(mesh);
|
|
12253
|
-
if (!repoRoot) return void 0;
|
|
12254
|
-
try {
|
|
12255
|
-
return loadMeshJsonConfig(repoRoot).config?.scheduling;
|
|
12256
|
-
} catch {
|
|
12257
|
-
return void 0;
|
|
12258
|
-
}
|
|
12259
|
-
}
|
|
12260
12213
|
function resolveSchedulingStrategy(mesh) {
|
|
12261
|
-
const override = resolveMeshSchedulingOverride(mesh);
|
|
12262
|
-
if (override?.distribution) return distributionToStrategy(override.distribution);
|
|
12263
12214
|
return normalizeMeshSchedulingStrategy(mesh?.policy?.schedulingStrategy);
|
|
12264
12215
|
}
|
|
12265
12216
|
function orderEligibleNodes(meshId, strategy, nodes, opts) {
|
|
@@ -12284,7 +12235,7 @@ function orderEligibleNodes(meshId, strategy, nodes, opts) {
|
|
|
12284
12235
|
});
|
|
12285
12236
|
}
|
|
12286
12237
|
function activeProviderAssignedCount(meshId, nodeId, providerType) {
|
|
12287
|
-
return getQueue(meshId, { status: ["assigned"] }).filter((task) => task.assignedNodeId
|
|
12238
|
+
return getQueue(meshId, { status: ["assigned"] }).filter((task) => daemonIdsEquivalent(task.assignedNodeId, nodeId) && task.assignedProviderType === providerType).length;
|
|
12288
12239
|
}
|
|
12289
12240
|
function sessionHasActiveAssignment(meshId, sessionId) {
|
|
12290
12241
|
if (getQueue(meshId, { status: ["assigned"] }).some((task) => task.assignedSessionId === sessionId)) {
|
|
@@ -12303,7 +12254,7 @@ function liveSessionCountForNode(components, meshId, nodeId) {
|
|
|
12303
12254
|
const settings = state.settings || {};
|
|
12304
12255
|
if (readNonEmptyString2(settings.meshNodeFor) !== meshId) return false;
|
|
12305
12256
|
const instNodeId = readNonEmptyString2(settings.meshNodeId) || readNonEmptyString2(settings.nodeId);
|
|
12306
|
-
if (instNodeId
|
|
12257
|
+
if (!daemonIdsEquivalent(instNodeId, nodeId)) return false;
|
|
12307
12258
|
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
12308
12259
|
return !isTerminalSessionStatus(status);
|
|
12309
12260
|
}).length;
|
|
@@ -12402,11 +12353,8 @@ async function maybeAutoLaunchOneQueueSession(components, meshId, mesh) {
|
|
|
12402
12353
|
const queue = getQueue(meshId);
|
|
12403
12354
|
const pending = queue.filter((task) => task.status === "pending");
|
|
12404
12355
|
if (!pending.length) return false;
|
|
12405
|
-
const
|
|
12406
|
-
const
|
|
12407
|
-
schedulingOverride?.maxParallel ?? mesh?.policy?.maxParallelTasks
|
|
12408
|
-
);
|
|
12409
|
-
const maxReadonlyParallelTasks = resolveMaxReadonlyParallelTasks(maxParallelTasks, schedulingOverride?.readonlyMultiplier);
|
|
12356
|
+
const maxParallelTasks = resolveMaxParallelTasks(mesh?.policy?.maxParallelTasks);
|
|
12357
|
+
const maxReadonlyParallelTasks = resolveMaxReadonlyParallelTasks(maxParallelTasks);
|
|
12410
12358
|
for (const task of pending) {
|
|
12411
12359
|
const isReadonly = isTaskReadonly(task);
|
|
12412
12360
|
if (isReadonly) {
|
|
@@ -12819,12 +12767,12 @@ var init_mesh_queue_assignment = __esm({
|
|
|
12819
12767
|
init_mesh_event_trace();
|
|
12820
12768
|
init_mesh_warmup_deadline();
|
|
12821
12769
|
init_repo_mesh_types();
|
|
12822
|
-
init_mesh_json_config();
|
|
12823
12770
|
init_dist();
|
|
12824
12771
|
init_mesh_events_stale();
|
|
12825
12772
|
init_mesh_events_utils();
|
|
12826
12773
|
init_mesh_events_pending();
|
|
12827
12774
|
init_worktree_bootstrap_config();
|
|
12775
|
+
init_mesh_task_inflight();
|
|
12828
12776
|
IDLE_AUTO_FAST_FORWARD_THROTTLE_MS = 30 * 60 * 1e3;
|
|
12829
12777
|
idleAutoFastForwardLastAttempt = /* @__PURE__ */ new Map();
|
|
12830
12778
|
DISPATCH_CONFIRM_TIMEOUT_MS = 12e4;
|
|
@@ -12925,8 +12873,8 @@ function recordUnroutableDelegateEvent(routing, eventName) {
|
|
|
12925
12873
|
if (last !== void 0 && now - last < UNROUTABLE_DIAGNOSTIC_DEDUP_MS) return false;
|
|
12926
12874
|
recentUnroutableDiagnostics.set(dedupKey, now);
|
|
12927
12875
|
if (recentUnroutableDiagnostics.size > 256) {
|
|
12928
|
-
for (const [
|
|
12929
|
-
if (now - ts2 >= UNROUTABLE_DIAGNOSTIC_DEDUP_MS) recentUnroutableDiagnostics.delete(
|
|
12876
|
+
for (const [key2, ts2] of recentUnroutableDiagnostics) {
|
|
12877
|
+
if (now - ts2 >= UNROUTABLE_DIAGNOSTIC_DEDUP_MS) recentUnroutableDiagnostics.delete(key2);
|
|
12930
12878
|
}
|
|
12931
12879
|
}
|
|
12932
12880
|
try {
|
|
@@ -13191,9 +13139,9 @@ async function updateDarwinMemoryCache() {
|
|
|
13191
13139
|
for (const line of stdout.split("\n")) {
|
|
13192
13140
|
const m = line.match(/^\s*Pages\s+([^:]+):\s+([\d,]+)\s*\.?/);
|
|
13193
13141
|
if (!m) continue;
|
|
13194
|
-
const
|
|
13142
|
+
const key2 = m[1].trim().toLowerCase().replace(/\s+/g, "_");
|
|
13195
13143
|
const n = parseInt(m[2].replace(/,/g, ""), 10);
|
|
13196
|
-
if (!Number.isNaN(n)) counts[
|
|
13144
|
+
if (!Number.isNaN(n)) counts[key2] = n;
|
|
13197
13145
|
}
|
|
13198
13146
|
const free = counts["free"] ?? 0;
|
|
13199
13147
|
const inactive = counts["inactive"] ?? 0;
|
|
@@ -13417,7 +13365,7 @@ function trimStructuredStrings(value, maxChars) {
|
|
|
13417
13365
|
if (Array.isArray(value)) return value.map((item) => trimStructuredStrings(item, maxChars));
|
|
13418
13366
|
if (!value || typeof value !== "object") return value;
|
|
13419
13367
|
return Object.fromEntries(
|
|
13420
|
-
Object.entries(value).map(([
|
|
13368
|
+
Object.entries(value).map(([key2, nested]) => [key2, trimStructuredStrings(nested, maxChars)])
|
|
13421
13369
|
);
|
|
13422
13370
|
}
|
|
13423
13371
|
function estimateBytes(value) {
|
|
@@ -14008,9 +13956,9 @@ function readMessageMeta(message) {
|
|
|
14008
13956
|
function readStringField(value) {
|
|
14009
13957
|
return typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
14010
13958
|
}
|
|
14011
|
-
function readRecordField(message, meta,
|
|
13959
|
+
function readRecordField(message, meta, key2) {
|
|
14012
13960
|
const record = message;
|
|
14013
|
-
return record[
|
|
13961
|
+
return record[key2] ?? meta?.[key2];
|
|
14014
13962
|
}
|
|
14015
13963
|
function readVisibilityField(message, meta) {
|
|
14016
13964
|
return readStringField(readRecordField(message, meta, "visibility"));
|
|
@@ -14021,7 +13969,7 @@ function readTranscriptVisibilityField(message, meta) {
|
|
|
14021
13969
|
}
|
|
14022
13970
|
function hasBooleanMarker(message, meta, keys) {
|
|
14023
13971
|
const record = message;
|
|
14024
|
-
return keys.some((
|
|
13972
|
+
return keys.some((key2) => record[key2] === true || meta?.[key2] === true);
|
|
14025
13973
|
}
|
|
14026
13974
|
function isActivityKind(kind) {
|
|
14027
13975
|
return kind === "thought" || kind === "tool" || kind === "terminal";
|
|
@@ -14213,9 +14161,9 @@ function extractProviderControlValues(controls, data) {
|
|
|
14213
14161
|
const values = {};
|
|
14214
14162
|
const explicit = data.controlValues;
|
|
14215
14163
|
if (explicit && typeof explicit === "object") {
|
|
14216
|
-
for (const [
|
|
14164
|
+
for (const [key2, value] of Object.entries(explicit)) {
|
|
14217
14165
|
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
14218
|
-
values[
|
|
14166
|
+
values[key2] = value;
|
|
14219
14167
|
}
|
|
14220
14168
|
}
|
|
14221
14169
|
}
|
|
@@ -14679,26 +14627,26 @@ function getGitSummaryForWorkspace(workspace, options) {
|
|
|
14679
14627
|
if (!workspace) return void 0;
|
|
14680
14628
|
return options.getGitSummaryForWorkspace?.(workspace) || void 0;
|
|
14681
14629
|
}
|
|
14682
|
-
function findCdpManager(cdpManagers,
|
|
14683
|
-
const exact = cdpManagers.get(
|
|
14630
|
+
function findCdpManager(cdpManagers, key2) {
|
|
14631
|
+
const exact = cdpManagers.get(key2);
|
|
14684
14632
|
if (exact) return exact.isConnected ? exact : null;
|
|
14685
|
-
const prefix =
|
|
14633
|
+
const prefix = key2 + "_";
|
|
14686
14634
|
const matches = [...cdpManagers.entries()].filter(([k, m]) => m.isConnected && k.startsWith(prefix));
|
|
14687
14635
|
if (matches.length === 1) return matches[0][1];
|
|
14688
14636
|
return null;
|
|
14689
14637
|
}
|
|
14690
|
-
function hasCdpManager(cdpManagers,
|
|
14691
|
-
if (cdpManagers.has(
|
|
14692
|
-
const prefix =
|
|
14638
|
+
function hasCdpManager(cdpManagers, key2) {
|
|
14639
|
+
if (cdpManagers.has(key2)) return true;
|
|
14640
|
+
const prefix = key2 + "_";
|
|
14693
14641
|
for (const k of cdpManagers.keys()) {
|
|
14694
14642
|
if (k.startsWith(prefix)) return true;
|
|
14695
14643
|
}
|
|
14696
14644
|
return false;
|
|
14697
14645
|
}
|
|
14698
|
-
function isCdpConnected(cdpManagers,
|
|
14699
|
-
const exact = cdpManagers.get(
|
|
14646
|
+
function isCdpConnected(cdpManagers, key2) {
|
|
14647
|
+
const exact = cdpManagers.get(key2);
|
|
14700
14648
|
if (exact?.isConnected) return true;
|
|
14701
|
-
const prefix =
|
|
14649
|
+
const prefix = key2 + "_";
|
|
14702
14650
|
for (const [k, m] of cdpManagers.entries()) {
|
|
14703
14651
|
if (m.isConnected && k.startsWith(prefix)) return true;
|
|
14704
14652
|
}
|
|
@@ -15035,11 +14983,11 @@ function buildRecentReadDebugSignature(snapshot) {
|
|
|
15035
14983
|
String(snapshot.messageUpdatedAt)
|
|
15036
14984
|
].join("|");
|
|
15037
14985
|
}
|
|
15038
|
-
function shouldEmitRecentReadDebugLog(
|
|
14986
|
+
function shouldEmitRecentReadDebugLog(cache, snapshot) {
|
|
15039
14987
|
const nextSignature = buildRecentReadDebugSignature(snapshot);
|
|
15040
|
-
const previousSignature =
|
|
14988
|
+
const previousSignature = cache.get(snapshot.sessionId);
|
|
15041
14989
|
if (previousSignature === nextSignature) return false;
|
|
15042
|
-
|
|
14990
|
+
cache.set(snapshot.sessionId, nextSignature);
|
|
15043
14991
|
return true;
|
|
15044
14992
|
}
|
|
15045
14993
|
function buildDetectedIdeInfos(detectedIdes, cdpManagers) {
|
|
@@ -16594,9 +16542,9 @@ function recordHeldTerminalEventsToLedger(meshId, drainDaemonIds, reason, heldFo
|
|
|
16594
16542
|
for (const event of pending) {
|
|
16595
16543
|
if (!shouldForceInjectMeshEvent(event.event)) continue;
|
|
16596
16544
|
const fingerprint = buildPendingEventFingerprint(event);
|
|
16597
|
-
const
|
|
16598
|
-
if (heldEventLedgerRecorded.has(
|
|
16599
|
-
heldEventLedgerRecorded.add(
|
|
16545
|
+
const key2 = `${meshId}::${fingerprint || `${event.event}::${event.nodeId || ""}::${event.queuedAt}`}`;
|
|
16546
|
+
if (heldEventLedgerRecorded.has(key2)) continue;
|
|
16547
|
+
heldEventLedgerRecorded.add(key2);
|
|
16600
16548
|
const finalSummary = readMeshCompletionSummary(event.metadataEvent);
|
|
16601
16549
|
try {
|
|
16602
16550
|
appendLedgerEntry(meshId, {
|
|
@@ -16617,7 +16565,7 @@ function recordHeldTerminalEventsToLedger(meshId, drainDaemonIds, reason, heldFo
|
|
|
16617
16565
|
});
|
|
16618
16566
|
LOG.info("MeshReconcile", `Ledger-recorded held ${event.event} for mesh ${meshId} (reason ${reason}) \u2014 recoverable from ledger`);
|
|
16619
16567
|
} catch (e) {
|
|
16620
|
-
heldEventLedgerRecorded.delete(
|
|
16568
|
+
heldEventLedgerRecorded.delete(key2);
|
|
16621
16569
|
LOG.warn("MeshReconcile", `Failed to ledger-record held ${event.event} for mesh ${meshId}: ${e?.message || e}`);
|
|
16622
16570
|
}
|
|
16623
16571
|
}
|
|
@@ -17082,9 +17030,9 @@ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds,
|
|
|
17082
17030
|
const activeTaskKeys = new Set(
|
|
17083
17031
|
dispatches.map((d) => readNonEmptyString2(d.taskId)).filter(Boolean).map((taskId) => inFlightSynthKey(mesh.id, taskId))
|
|
17084
17032
|
);
|
|
17085
|
-
for (const
|
|
17086
|
-
if (
|
|
17087
|
-
inFlightAckedHoldState.delete(
|
|
17033
|
+
for (const key2 of inFlightAckedHoldState.keys()) {
|
|
17034
|
+
if (key2.startsWith(`${mesh.id}::`) && !activeTaskKeys.has(key2)) {
|
|
17035
|
+
inFlightAckedHoldState.delete(key2);
|
|
17088
17036
|
}
|
|
17089
17037
|
}
|
|
17090
17038
|
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
@@ -18670,8 +18618,8 @@ function extractButtonsFromRule(rule, hay) {
|
|
|
18670
18618
|
label += " " + next.trim();
|
|
18671
18619
|
j += 1;
|
|
18672
18620
|
}
|
|
18673
|
-
const
|
|
18674
|
-
buttons.push({ index: idx, label, key, current });
|
|
18621
|
+
const key2 = keyTemplate.replace(/\{index\}/g, String(idx));
|
|
18622
|
+
buttons.push({ index: idx, label, key: key2, current });
|
|
18675
18623
|
i = j - 1;
|
|
18676
18624
|
}
|
|
18677
18625
|
} else {
|
|
@@ -18681,8 +18629,8 @@ function extractButtonsFromRule(rule, hay) {
|
|
|
18681
18629
|
const idx = Number(m[1]);
|
|
18682
18630
|
const label = String(m[2] ?? "").trim();
|
|
18683
18631
|
if (!Number.isFinite(idx) || idx <= 0 || !label) continue;
|
|
18684
|
-
const
|
|
18685
|
-
buttons.push({ index: idx, label, key, current: hasCursorMarker(m[0]) });
|
|
18632
|
+
const key2 = keyTemplate.replace(/\{index\}/g, String(idx));
|
|
18633
|
+
buttons.push({ index: idx, label, key: key2, current: hasCursorMarker(m[0]) });
|
|
18686
18634
|
}
|
|
18687
18635
|
}
|
|
18688
18636
|
const block2 = lastContiguousNumberedBlock(buttons);
|
|
@@ -18762,12 +18710,12 @@ function evalCond(cond, sections, fullScreen, cursor, prevLines, clock, legacyTr
|
|
|
18762
18710
|
return { kind: "elapsed", result, detail: `elapsed ${age}ms / ${cond.elapsed_ms}ms`, remainingMs };
|
|
18763
18711
|
}
|
|
18764
18712
|
if (isStable(cond)) {
|
|
18765
|
-
const
|
|
18766
|
-
const lastChanged = clock.regionLastChangedAt.get(
|
|
18713
|
+
const key2 = regionKey(cond.cursor_above);
|
|
18714
|
+
const lastChanged = clock.regionLastChangedAt.get(key2) ?? clock.stateEnteredAt;
|
|
18767
18715
|
const stableFor = clock.now - lastChanged;
|
|
18768
18716
|
const result = stableFor >= cond.stable_ms;
|
|
18769
18717
|
const remainingMs = result ? 0 : cond.stable_ms - stableFor;
|
|
18770
|
-
const where =
|
|
18718
|
+
const where = key2 === WHOLE_SCREEN ? "screen" : `cursor_above=${cond.cursor_above}`;
|
|
18771
18719
|
return { kind: "stable", result, detail: `stable ${where} ${stableFor}ms / ${cond.stable_ms}ms`, remainingMs };
|
|
18772
18720
|
}
|
|
18773
18721
|
if (isRegex(cond) || isChanged(cond)) {
|
|
@@ -22711,16 +22659,16 @@ function normalizeModuleName(request) {
|
|
|
22711
22659
|
}
|
|
22712
22660
|
function buildFsShim() {
|
|
22713
22661
|
const shim = {};
|
|
22714
|
-
for (const
|
|
22715
|
-
if (
|
|
22716
|
-
const real = nodeFs[
|
|
22717
|
-
if (real !== void 0) shim[
|
|
22662
|
+
for (const key2 of FS_READ_ONLY_MEMBERS) {
|
|
22663
|
+
if (key2 === "promises") continue;
|
|
22664
|
+
const real = nodeFs[key2];
|
|
22665
|
+
if (real !== void 0) shim[key2] = real;
|
|
22718
22666
|
}
|
|
22719
22667
|
const realPromises = nodeFs.promises || {};
|
|
22720
22668
|
const promisesShim = {};
|
|
22721
|
-
for (const
|
|
22722
|
-
const real = realPromises[
|
|
22723
|
-
if (real !== void 0) promisesShim[
|
|
22669
|
+
for (const key2 of FS_PROMISES_READ_ONLY_MEMBERS) {
|
|
22670
|
+
const real = realPromises[key2];
|
|
22671
|
+
if (real !== void 0) promisesShim[key2] = real;
|
|
22724
22672
|
}
|
|
22725
22673
|
shim.promises = promisesShim;
|
|
22726
22674
|
return shim;
|
|
@@ -22803,10 +22751,10 @@ function _uninstallProviderProcessShimForTest() {
|
|
|
22803
22751
|
function buildProcessShim() {
|
|
22804
22752
|
const real = globalThis.process;
|
|
22805
22753
|
const shim = /* @__PURE__ */ Object.create(null);
|
|
22806
|
-
for (const
|
|
22807
|
-
if (DANGEROUS_PROCESS_METHODS.has(String(
|
|
22754
|
+
for (const key2 of Object.keys(real)) {
|
|
22755
|
+
if (DANGEROUS_PROCESS_METHODS.has(String(key2))) continue;
|
|
22808
22756
|
try {
|
|
22809
|
-
shim[
|
|
22757
|
+
shim[key2] = real[key2];
|
|
22810
22758
|
} catch {
|
|
22811
22759
|
}
|
|
22812
22760
|
}
|
|
@@ -23611,10 +23559,10 @@ var GitWorkspaceMonitor = class {
|
|
|
23611
23559
|
const compactSummary = createGitCompactSummary(status, diffSummary);
|
|
23612
23560
|
const timestamp = this.now();
|
|
23613
23561
|
const seq = ++this.seq;
|
|
23614
|
-
const
|
|
23562
|
+
const key2 = this.keyForWorkspace(normalized.workspace);
|
|
23615
23563
|
const update = {
|
|
23616
23564
|
topic: "workspace.git",
|
|
23617
|
-
key,
|
|
23565
|
+
key: key2,
|
|
23618
23566
|
workspace: normalized.workspace,
|
|
23619
23567
|
status,
|
|
23620
23568
|
diffSummary,
|
|
@@ -23622,7 +23570,7 @@ var GitWorkspaceMonitor = class {
|
|
|
23622
23570
|
timestamp
|
|
23623
23571
|
};
|
|
23624
23572
|
const cacheEntry = {
|
|
23625
|
-
key,
|
|
23573
|
+
key: key2,
|
|
23626
23574
|
workspace: normalized.workspace,
|
|
23627
23575
|
status,
|
|
23628
23576
|
diffSummary,
|
|
@@ -23766,11 +23714,11 @@ function validateRepoPath(args) {
|
|
|
23766
23714
|
}
|
|
23767
23715
|
return { path: args.path.trim() };
|
|
23768
23716
|
}
|
|
23769
|
-
function validateSnapshotId(args,
|
|
23770
|
-
if (typeof args?.[
|
|
23771
|
-
return failure("invalid_args", `${
|
|
23717
|
+
function validateSnapshotId(args, key2) {
|
|
23718
|
+
if (typeof args?.[key2] !== "string" || !args[key2].trim()) {
|
|
23719
|
+
return failure("invalid_args", `${key2} must be a non-empty string`);
|
|
23772
23720
|
}
|
|
23773
|
-
return args[
|
|
23721
|
+
return args[key2].trim();
|
|
23774
23722
|
}
|
|
23775
23723
|
function parseSnapshotReason(args) {
|
|
23776
23724
|
if (args?.reason === void 0 || args?.reason === null || args?.reason === "") {
|
|
@@ -24252,6 +24200,29 @@ init_mesh_review_inbox();
|
|
|
24252
24200
|
init_coordinator_registry();
|
|
24253
24201
|
init_refine_config();
|
|
24254
24202
|
init_worktree_bootstrap_config();
|
|
24203
|
+
|
|
24204
|
+
// src/config/repo-settings.ts
|
|
24205
|
+
init_mesh_json_config();
|
|
24206
|
+
init_refine_config();
|
|
24207
|
+
init_worktree_bootstrap_config();
|
|
24208
|
+
init_change_impact_config();
|
|
24209
|
+
function loadRepoSettings(opts) {
|
|
24210
|
+
const workspace = typeof opts.workspace === "string" ? opts.workspace : "";
|
|
24211
|
+
const mesh = opts.mesh;
|
|
24212
|
+
const repoRoot = typeof opts.repoRoot === "string" && opts.repoRoot ? opts.repoRoot : workspace;
|
|
24213
|
+
const meshJson = loadRepoMeshJsonConfig(workspace);
|
|
24214
|
+
return {
|
|
24215
|
+
coordinator: meshJson.config?.coordinator,
|
|
24216
|
+
operatingNotes: meshJson.config?.operatingNotes,
|
|
24217
|
+
limits: meshJson.config?.limits,
|
|
24218
|
+
meshJson,
|
|
24219
|
+
refine: loadMeshRefineConfig(mesh, workspace),
|
|
24220
|
+
worktreeBootstrap: loadMeshWorktreeBootstrapConfig(mesh, workspace),
|
|
24221
|
+
changeImpact: loadChangeImpactConfig(repoRoot)
|
|
24222
|
+
};
|
|
24223
|
+
}
|
|
24224
|
+
|
|
24225
|
+
// src/index.ts
|
|
24255
24226
|
init_mesh_ledger();
|
|
24256
24227
|
init_mesh_fast_forward();
|
|
24257
24228
|
|
|
@@ -24438,7 +24409,7 @@ init_state_store();
|
|
|
24438
24409
|
// src/detection/ide-detector.ts
|
|
24439
24410
|
import { exec as exec3 } from "child_process";
|
|
24440
24411
|
import { promisify as promisify5 } from "util";
|
|
24441
|
-
import { existsSync as existsSync20, statSync as
|
|
24412
|
+
import { existsSync as existsSync20, statSync as statSync8 } from "fs";
|
|
24442
24413
|
import { platform as platform5, homedir as homedir8 } from "os";
|
|
24443
24414
|
import * as path14 from "path";
|
|
24444
24415
|
|
|
@@ -24530,7 +24501,7 @@ function findCliCommand(command) {
|
|
|
24530
24501
|
const fullPath = path14.join(p, trimmed + ext);
|
|
24531
24502
|
try {
|
|
24532
24503
|
if (existsSync20(fullPath)) {
|
|
24533
|
-
const stat2 =
|
|
24504
|
+
const stat2 = statSync8(fullPath);
|
|
24534
24505
|
if (stat2.isFile() && (isWin || stat2.mode & 73)) {
|
|
24535
24506
|
return fullPath;
|
|
24536
24507
|
}
|
|
@@ -26159,10 +26130,10 @@ var StatusMonitor = class {
|
|
|
26159
26130
|
return events;
|
|
26160
26131
|
}
|
|
26161
26132
|
/** Cooldown check — prevent sending the same notification too frequently */
|
|
26162
|
-
shouldAlert(
|
|
26163
|
-
const last = this.lastAlertTime.get(
|
|
26133
|
+
shouldAlert(key2, now) {
|
|
26134
|
+
const last = this.lastAlertTime.get(key2) || 0;
|
|
26164
26135
|
if (now - last > this.config.alertCooldownSec * 1e3) {
|
|
26165
|
-
this.lastAlertTime.set(
|
|
26136
|
+
this.lastAlertTime.set(key2, now);
|
|
26166
26137
|
return true;
|
|
26167
26138
|
}
|
|
26168
26139
|
return false;
|
|
@@ -26210,16 +26181,16 @@ var savedHistoryBackgroundRefresh = /* @__PURE__ */ new Set();
|
|
|
26210
26181
|
var savedHistoryRollupInFlight = /* @__PURE__ */ new Set();
|
|
26211
26182
|
var BOUNDED_TAIL_CACHE_MAX_ENTRIES = 64;
|
|
26212
26183
|
var boundedTailReadCache = /* @__PURE__ */ new Map();
|
|
26213
|
-
function readBoundedTailCache(
|
|
26214
|
-
const cached3 = boundedTailReadCache.get(
|
|
26184
|
+
function readBoundedTailCache(key2, signature) {
|
|
26185
|
+
const cached3 = boundedTailReadCache.get(key2);
|
|
26215
26186
|
if (!cached3 || cached3.signature !== signature) return null;
|
|
26216
|
-
boundedTailReadCache.delete(
|
|
26217
|
-
boundedTailReadCache.set(
|
|
26187
|
+
boundedTailReadCache.delete(key2);
|
|
26188
|
+
boundedTailReadCache.set(key2, cached3);
|
|
26218
26189
|
return cached3.result;
|
|
26219
26190
|
}
|
|
26220
|
-
function writeBoundedTailCache(
|
|
26221
|
-
boundedTailReadCache.delete(
|
|
26222
|
-
boundedTailReadCache.set(
|
|
26191
|
+
function writeBoundedTailCache(key2, signature, result) {
|
|
26192
|
+
boundedTailReadCache.delete(key2);
|
|
26193
|
+
boundedTailReadCache.set(key2, { signature, result });
|
|
26223
26194
|
while (boundedTailReadCache.size > BOUNDED_TAIL_CACHE_MAX_ENTRIES) {
|
|
26224
26195
|
const oldest = boundedTailReadCache.keys().next().value;
|
|
26225
26196
|
if (oldest === void 0) break;
|
|
@@ -26655,21 +26626,21 @@ function shouldScheduleSavedHistoryRollupForSignature(signature) {
|
|
|
26655
26626
|
return shouldScheduleSavedHistoryRollup(size);
|
|
26656
26627
|
}
|
|
26657
26628
|
function scheduleSavedHistoryRollup(agentType, historySessionId) {
|
|
26658
|
-
const
|
|
26659
|
-
if (!historySessionId || savedHistoryRollupInFlight.has(
|
|
26660
|
-
savedHistoryRollupInFlight.add(
|
|
26629
|
+
const key2 = `${agentType}:${historySessionId}`;
|
|
26630
|
+
if (!historySessionId || savedHistoryRollupInFlight.has(key2)) return;
|
|
26631
|
+
savedHistoryRollupInFlight.add(key2);
|
|
26661
26632
|
setTimeout(() => {
|
|
26662
26633
|
try {
|
|
26663
26634
|
new ChatHistoryWriter().compactHistorySession(agentType, historySessionId);
|
|
26664
26635
|
} finally {
|
|
26665
|
-
savedHistoryRollupInFlight.delete(
|
|
26636
|
+
savedHistoryRollupInFlight.delete(key2);
|
|
26666
26637
|
}
|
|
26667
26638
|
}, 0);
|
|
26668
26639
|
}
|
|
26669
26640
|
function scheduleSavedHistoryBackgroundRefresh(agentType, dir) {
|
|
26670
|
-
const
|
|
26671
|
-
if (savedHistoryBackgroundRefresh.has(
|
|
26672
|
-
savedHistoryBackgroundRefresh.add(
|
|
26641
|
+
const key2 = `${agentType}:${dir}`;
|
|
26642
|
+
if (savedHistoryBackgroundRefresh.has(key2)) return;
|
|
26643
|
+
savedHistoryBackgroundRefresh.add(key2);
|
|
26673
26644
|
setTimeout(() => {
|
|
26674
26645
|
try {
|
|
26675
26646
|
if (!fs6.existsSync(dir)) return;
|
|
@@ -26689,7 +26660,7 @@ function scheduleSavedHistoryBackgroundRefresh(agentType, dir) {
|
|
|
26689
26660
|
}
|
|
26690
26661
|
} catch {
|
|
26691
26662
|
} finally {
|
|
26692
|
-
savedHistoryBackgroundRefresh.delete(
|
|
26663
|
+
savedHistoryBackgroundRefresh.delete(key2);
|
|
26693
26664
|
}
|
|
26694
26665
|
}, 0);
|
|
26695
26666
|
}
|
|
@@ -27455,14 +27426,14 @@ function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
|
|
|
27455
27426
|
return false;
|
|
27456
27427
|
}
|
|
27457
27428
|
}
|
|
27458
|
-
function getNativeHistoryScriptName(canonicalHistory,
|
|
27459
|
-
const configured = canonicalHistory?.scripts?.[
|
|
27429
|
+
function getNativeHistoryScriptName(canonicalHistory, key2) {
|
|
27430
|
+
const configured = canonicalHistory?.scripts?.[key2];
|
|
27460
27431
|
if (typeof configured === "string" && configured.trim()) return configured.trim();
|
|
27461
|
-
return
|
|
27432
|
+
return key2 === "readSession" ? "readNativeHistory" : "listNativeHistory";
|
|
27462
27433
|
}
|
|
27463
|
-
function getProviderNativeHistoryScript(scripts, canonicalHistory,
|
|
27434
|
+
function getProviderNativeHistoryScript(scripts, canonicalHistory, key2) {
|
|
27464
27435
|
if (!canonicalHistory?.scripts) return null;
|
|
27465
|
-
const fn = scripts?.[getNativeHistoryScriptName(canonicalHistory,
|
|
27436
|
+
const fn = scripts?.[getNativeHistoryScriptName(canonicalHistory, key2)];
|
|
27466
27437
|
return typeof fn === "function" ? fn : null;
|
|
27467
27438
|
}
|
|
27468
27439
|
function normalizeProviderNativeHistoryRecords(agentType, historySessionId, records) {
|
|
@@ -28196,11 +28167,11 @@ function validateControlValues(controlValues, source) {
|
|
|
28196
28167
|
throw new Error(`${source}: controlValues must be an object when provided`);
|
|
28197
28168
|
}
|
|
28198
28169
|
const normalized = {};
|
|
28199
|
-
for (const [
|
|
28170
|
+
for (const [key2, value] of Object.entries(controlValues)) {
|
|
28200
28171
|
if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") {
|
|
28201
|
-
throw new Error(`${source}: controlValues.${
|
|
28172
|
+
throw new Error(`${source}: controlValues.${key2} must be string, number, or boolean`);
|
|
28202
28173
|
}
|
|
28203
|
-
normalized[
|
|
28174
|
+
normalized[key2] = value;
|
|
28204
28175
|
}
|
|
28205
28176
|
return normalized;
|
|
28206
28177
|
}
|
|
@@ -28953,7 +28924,7 @@ var DaemonCdpScanner = class {
|
|
|
28953
28924
|
for (const [ide, ports] of Object.entries(portMap)) {
|
|
28954
28925
|
const primaryPort = ports[0];
|
|
28955
28926
|
const alreadyConnected = [...this.ctx.cdpManagers.entries()].some(
|
|
28956
|
-
([
|
|
28927
|
+
([key2, m]) => m.isConnected && (key2 === ide || key2.startsWith(ide + "_"))
|
|
28957
28928
|
);
|
|
28958
28929
|
if (alreadyConnected) continue;
|
|
28959
28930
|
if (this.opts.multiWindow) {
|
|
@@ -29127,8 +29098,8 @@ var DaemonCdpInitializer = class {
|
|
|
29127
29098
|
for (let i = 0; i < targets.length; i++) {
|
|
29128
29099
|
const target = targets[i];
|
|
29129
29100
|
let alreadyTracked = false;
|
|
29130
|
-
for (const [
|
|
29131
|
-
if ((
|
|
29101
|
+
for (const [key2, m] of cdpManagers.entries()) {
|
|
29102
|
+
if ((key2 === ide || key2.startsWith(`${ide}_`)) && m.targetId === target.id) {
|
|
29132
29103
|
alreadyTracked = true;
|
|
29133
29104
|
break;
|
|
29134
29105
|
}
|
|
@@ -29160,29 +29131,29 @@ var DaemonCdpInitializer = class {
|
|
|
29160
29131
|
async pruneStaleManagers(port, ide, targets) {
|
|
29161
29132
|
const trackedTargetIds = new Set(targets.map((target) => target.id));
|
|
29162
29133
|
const removals = [];
|
|
29163
|
-
for (const [
|
|
29164
|
-
if (!(
|
|
29134
|
+
for (const [key2, manager] of this.config.cdpManagers.entries()) {
|
|
29135
|
+
if (!(key2 === ide || key2.startsWith(`${ide}_`))) continue;
|
|
29165
29136
|
if (manager.getPort() !== port) continue;
|
|
29166
29137
|
if (targets.length === 0) {
|
|
29167
|
-
removals.push({ key, manager, reason: "ide_closed" });
|
|
29138
|
+
removals.push({ key: key2, manager, reason: "ide_closed" });
|
|
29168
29139
|
continue;
|
|
29169
29140
|
}
|
|
29170
29141
|
if (manager.targetId && !trackedTargetIds.has(manager.targetId)) {
|
|
29171
|
-
removals.push({ key, manager, reason: "target_closed" });
|
|
29142
|
+
removals.push({ key: key2, manager, reason: "target_closed" });
|
|
29172
29143
|
continue;
|
|
29173
29144
|
}
|
|
29174
|
-
if (
|
|
29175
|
-
removals.push({ key, manager, reason: "target_rekeyed" });
|
|
29145
|
+
if (key2 === ide && !manager.targetId && targets.length > 1) {
|
|
29146
|
+
removals.push({ key: key2, manager, reason: "target_rekeyed" });
|
|
29176
29147
|
}
|
|
29177
29148
|
}
|
|
29178
|
-
for (const { key, manager, reason } of removals) {
|
|
29149
|
+
for (const { key: key2, manager, reason } of removals) {
|
|
29179
29150
|
try {
|
|
29180
29151
|
manager.disconnect();
|
|
29181
29152
|
} catch {
|
|
29182
29153
|
}
|
|
29183
|
-
this.config.cdpManagers.delete(
|
|
29184
|
-
LOG.info("IDE", `Detached window: ${
|
|
29185
|
-
await this.config.onDisconnected?.(ide, manager,
|
|
29154
|
+
this.config.cdpManagers.delete(key2);
|
|
29155
|
+
LOG.info("IDE", `Detached window: ${key2} (${reason})`);
|
|
29156
|
+
await this.config.onDisconnected?.(ide, manager, key2, reason);
|
|
29186
29157
|
}
|
|
29187
29158
|
}
|
|
29188
29159
|
// ─── Periodic scanning ───
|
|
@@ -29508,7 +29479,7 @@ function sanitizeTraceValue(value, traceContent) {
|
|
|
29508
29479
|
if (Array.isArray(value)) return value.map((entry) => sanitizeTraceValue(entry, traceContent));
|
|
29509
29480
|
if (value && typeof value === "object") {
|
|
29510
29481
|
return Object.fromEntries(
|
|
29511
|
-
Object.entries(value).map(([
|
|
29482
|
+
Object.entries(value).map(([key2, nested]) => [key2, sanitizeTraceValue(nested, traceContent)])
|
|
29512
29483
|
);
|
|
29513
29484
|
}
|
|
29514
29485
|
return value;
|
|
@@ -29517,7 +29488,7 @@ function sanitizeTraceValue(value, traceContent) {
|
|
|
29517
29488
|
if (Array.isArray(value)) return value.map((entry) => sanitizeTraceValue(entry, traceContent));
|
|
29518
29489
|
if (value && typeof value === "object") {
|
|
29519
29490
|
return Object.fromEntries(
|
|
29520
|
-
Object.entries(value).map(([
|
|
29491
|
+
Object.entries(value).map(([key2, nested]) => [key2, sanitizeTraceValue(nested, traceContent)])
|
|
29521
29492
|
);
|
|
29522
29493
|
}
|
|
29523
29494
|
return value;
|
|
@@ -29825,8 +29796,8 @@ function maxSequence(messages) {
|
|
|
29825
29796
|
}
|
|
29826
29797
|
function isSupersetOf(candidate, required) {
|
|
29827
29798
|
if (required.size === 0) return true;
|
|
29828
|
-
for (const
|
|
29829
|
-
if (!candidate.has(
|
|
29799
|
+
for (const key2 of required) {
|
|
29800
|
+
if (!candidate.has(key2)) return false;
|
|
29830
29801
|
}
|
|
29831
29802
|
return true;
|
|
29832
29803
|
}
|
|
@@ -29839,17 +29810,17 @@ function chatSourceSessionKey(providerType, sessionId) {
|
|
|
29839
29810
|
var ChatSourceRegistry = class {
|
|
29840
29811
|
records = /* @__PURE__ */ new Map();
|
|
29841
29812
|
/** Snapshot of current state for diagnostics. Does not mutate. */
|
|
29842
|
-
getState(
|
|
29843
|
-
return this.records.get(
|
|
29813
|
+
getState(key2) {
|
|
29814
|
+
return this.records.get(key2)?.state ?? INITIAL_CHAT_SOURCE_STATE;
|
|
29844
29815
|
}
|
|
29845
29816
|
/** Recent transitions, newest last. Empty array when nothing has happened. */
|
|
29846
|
-
getTransitions(
|
|
29847
|
-
return this.records.get(
|
|
29817
|
+
getTransitions(key2) {
|
|
29818
|
+
return this.records.get(key2)?.transitions ?? [];
|
|
29848
29819
|
}
|
|
29849
29820
|
/** Drop a session. Caller should invoke this when the session is destroyed
|
|
29850
29821
|
* to avoid unbounded growth across long-lived daemons. */
|
|
29851
|
-
clear(
|
|
29852
|
-
this.records.delete(
|
|
29822
|
+
clear(key2) {
|
|
29823
|
+
this.records.delete(key2);
|
|
29853
29824
|
}
|
|
29854
29825
|
/** Drop all sessions. Test helper. */
|
|
29855
29826
|
clearAll() {
|
|
@@ -29861,15 +29832,15 @@ var ChatSourceRegistry = class {
|
|
|
29861
29832
|
* under `key`; callers may treat the decision as authoritative without
|
|
29862
29833
|
* re-reading.
|
|
29863
29834
|
*/
|
|
29864
|
-
observe(
|
|
29865
|
-
const prev = this.records.get(
|
|
29835
|
+
observe(key2, observation, at = Date.now()) {
|
|
29836
|
+
const prev = this.records.get(key2);
|
|
29866
29837
|
const prevState = prev?.state ?? INITIAL_CHAT_SOURCE_STATE;
|
|
29867
29838
|
const prevLockedSince = prev?.lockedSince;
|
|
29868
29839
|
const result = transitionChatSourceState(prevState, observation, at, prevLockedSince);
|
|
29869
29840
|
const transitions = prev?.transitions ?? [];
|
|
29870
29841
|
const nextTransitions = appendTransition(transitions, result.transition);
|
|
29871
29842
|
const lockedSince = result.lockState.lockedSince;
|
|
29872
|
-
this.records.set(
|
|
29843
|
+
this.records.set(key2, {
|
|
29873
29844
|
state: result.next,
|
|
29874
29845
|
lockedSince,
|
|
29875
29846
|
transitions: nextTransitions
|
|
@@ -30552,8 +30523,8 @@ function readLiveCodexWorkspaceNativeHistory(agentStr, args) {
|
|
|
30552
30523
|
});
|
|
30553
30524
|
return { ...history, lookup: "workspace" };
|
|
30554
30525
|
}
|
|
30555
|
-
function shouldPreserveReadChatPayloadField(
|
|
30556
|
-
return
|
|
30526
|
+
function shouldPreserveReadChatPayloadField(key2) {
|
|
30527
|
+
return key2 === "messageSource" || key2 === "transcriptProvenance";
|
|
30557
30528
|
}
|
|
30558
30529
|
function updateMessageSourceReturnedCount(value, returnedMessageCount) {
|
|
30559
30530
|
if (!value || typeof value !== "object" || Array.isArray(value)) return value;
|
|
@@ -30723,7 +30694,7 @@ function buildReadChatCommandResult(payload, args, h) {
|
|
|
30723
30694
|
const visibleMessages = includeActivity ? filteredMessages.filter((m) => isUserFacingChatMessage(m) || isActivityChatMessage(m)) : filterUserFacingChatMessages(filteredMessages);
|
|
30724
30695
|
const sync = buildFullTail(visibleMessages, normalizeReadChatTailLimit(args));
|
|
30725
30696
|
const hiddenMsgCount = Math.max(0, messages.length - visibleMessages.length);
|
|
30726
|
-
const preservedPayloadFields = Object.fromEntries(Object.entries(payload).filter(([
|
|
30697
|
+
const preservedPayloadFields = Object.fromEntries(Object.entries(payload).filter(([key2]) => shouldPreserveReadChatPayloadField(key2)));
|
|
30727
30698
|
if (preservedPayloadFields.messageSource) {
|
|
30728
30699
|
preservedPayloadFields.messageSource = updateMessageSourceReturnedCount(preservedPayloadFields.messageSource, sync.messages.length);
|
|
30729
30700
|
}
|
|
@@ -31475,8 +31446,8 @@ function sanitizeDebugBundleValue(value, options = {}, depth = 0, keyHint = "")
|
|
|
31475
31446
|
const record = value;
|
|
31476
31447
|
const result = {};
|
|
31477
31448
|
const entries = Object.entries(record).slice(0, normalizedOptions.maxObjectKeys);
|
|
31478
|
-
for (const [
|
|
31479
|
-
result[
|
|
31449
|
+
for (const [key2, item] of entries) {
|
|
31450
|
+
result[key2] = sanitizeDebugBundleValue(item, normalizedOptions, depth + 1, key2);
|
|
31480
31451
|
}
|
|
31481
31452
|
const remaining = Object.keys(record).length - entries.length;
|
|
31482
31453
|
if (remaining > 0) result.__truncatedKeys = remaining;
|
|
@@ -31802,14 +31773,14 @@ function callLegacyTextScript(script, text) {
|
|
|
31802
31773
|
if (typeof script !== "function") return null;
|
|
31803
31774
|
return script(text);
|
|
31804
31775
|
}
|
|
31805
|
-
function isRecentDuplicateSend(
|
|
31776
|
+
function isRecentDuplicateSend(key2) {
|
|
31806
31777
|
const now = Date.now();
|
|
31807
31778
|
for (const [candidate, ts2] of recentSendByTarget.entries()) {
|
|
31808
31779
|
if (now - ts2 > RECENT_SEND_WINDOW_MS) recentSendByTarget.delete(candidate);
|
|
31809
31780
|
}
|
|
31810
|
-
const previous = recentSendByTarget.get(
|
|
31781
|
+
const previous = recentSendByTarget.get(key2);
|
|
31811
31782
|
if (previous && now - previous <= RECENT_SEND_WINDOW_MS) return true;
|
|
31812
|
-
recentSendByTarget.set(
|
|
31783
|
+
recentSendByTarget.set(key2, now);
|
|
31813
31784
|
return false;
|
|
31814
31785
|
}
|
|
31815
31786
|
function didProviderConfirmSend(result) {
|
|
@@ -32672,23 +32643,23 @@ async function handleCdpRemoteAction(h, args) {
|
|
|
32672
32643
|
try {
|
|
32673
32644
|
switch (action) {
|
|
32674
32645
|
case "input_key": {
|
|
32675
|
-
const { type: evType, key, code, text, unmodifiedText, modifiers } = params;
|
|
32646
|
+
const { type: evType, key: key2, code, text, unmodifiedText, modifiers } = params;
|
|
32676
32647
|
const mod = typeof modifiers === "number" ? modifiers : 0;
|
|
32677
|
-
const vk = KEY_TO_VK[
|
|
32648
|
+
const vk = KEY_TO_VK[key2] || (key2.length === 1 ? key2.charCodeAt(0) : 0);
|
|
32678
32649
|
if (evType === "char") {
|
|
32679
32650
|
await h.getCdp().send("Input.dispatchKeyEvent", {
|
|
32680
32651
|
type: "char",
|
|
32681
|
-
key,
|
|
32652
|
+
key: key2,
|
|
32682
32653
|
code,
|
|
32683
|
-
text: text ||
|
|
32684
|
-
unmodifiedText: unmodifiedText || text ||
|
|
32654
|
+
text: text || key2,
|
|
32655
|
+
unmodifiedText: unmodifiedText || text || key2,
|
|
32685
32656
|
...vk ? { windowsVirtualKeyCode: vk, nativeVirtualKeyCode: vk } : {},
|
|
32686
32657
|
...mod ? { modifiers: mod } : {}
|
|
32687
32658
|
});
|
|
32688
32659
|
} else {
|
|
32689
32660
|
await h.getCdp().send("Input.dispatchKeyEvent", {
|
|
32690
32661
|
type: "rawKeyDown",
|
|
32691
|
-
key,
|
|
32662
|
+
key: key2,
|
|
32692
32663
|
code,
|
|
32693
32664
|
...text ? { text } : {},
|
|
32694
32665
|
...vk ? { windowsVirtualKeyCode: vk, nativeVirtualKeyCode: vk } : {},
|
|
@@ -32696,7 +32667,7 @@ async function handleCdpRemoteAction(h, args) {
|
|
|
32696
32667
|
});
|
|
32697
32668
|
await h.getCdp().send("Input.dispatchKeyEvent", {
|
|
32698
32669
|
type: "keyUp",
|
|
32699
|
-
key,
|
|
32670
|
+
key: key2,
|
|
32700
32671
|
code,
|
|
32701
32672
|
...vk ? { windowsVirtualKeyCode: vk, nativeVirtualKeyCode: vk } : {},
|
|
32702
32673
|
...mod ? { modifiers: mod } : {}
|
|
@@ -33095,21 +33066,21 @@ function handleGetProviderSettings(h, args) {
|
|
|
33095
33066
|
}
|
|
33096
33067
|
async function handleSetProviderSetting(h, args) {
|
|
33097
33068
|
const loader = h.ctx.providerLoader;
|
|
33098
|
-
const { providerType, key, value } = args || {};
|
|
33099
|
-
if (!providerType || !
|
|
33069
|
+
const { providerType, key: key2, value } = args || {};
|
|
33070
|
+
if (!providerType || !key2 || value === void 0) {
|
|
33100
33071
|
return { success: false, error: "providerType, key, and value are required" };
|
|
33101
33072
|
}
|
|
33102
|
-
const result = loader?.setSetting(providerType,
|
|
33073
|
+
const result = loader?.setSetting(providerType, key2, value);
|
|
33103
33074
|
if (result) {
|
|
33104
33075
|
if (h.ctx.instanceManager) {
|
|
33105
33076
|
const allSettings = loader?.getSettings(providerType) || {};
|
|
33106
33077
|
const updated = h.ctx.instanceManager.updateInstanceSettings(providerType, allSettings);
|
|
33107
|
-
LOG.info("Command", `[set_provider_setting] ${providerType}.${
|
|
33078
|
+
LOG.info("Command", `[set_provider_setting] ${providerType}.${key2}=${JSON.stringify(value)} \u2192 ${updated} instance(s) updated`);
|
|
33108
33079
|
}
|
|
33109
|
-
await h.ctx.onProviderSettingChanged?.(providerType,
|
|
33110
|
-
return { success: true, providerType, key, value };
|
|
33080
|
+
await h.ctx.onProviderSettingChanged?.(providerType, key2, value);
|
|
33081
|
+
return { success: true, providerType, key: key2, value };
|
|
33111
33082
|
}
|
|
33112
|
-
return { success: false, error: `Failed to set ${providerType}.${
|
|
33083
|
+
return { success: false, error: `Failed to set ${providerType}.${key2} \u2014 invalid key, value, or not a public setting` };
|
|
33113
33084
|
}
|
|
33114
33085
|
function handleGetProviderSourceConfig(h, _args) {
|
|
33115
33086
|
const loader = h.ctx.providerLoader;
|
|
@@ -33155,9 +33126,9 @@ function normalizeProviderScriptArgs(args, scriptName) {
|
|
|
33155
33126
|
normalizedArgs.mode = normalizedArgs.value;
|
|
33156
33127
|
}
|
|
33157
33128
|
}
|
|
33158
|
-
for (const
|
|
33159
|
-
if (
|
|
33160
|
-
normalizedArgs[
|
|
33129
|
+
for (const key2 of ["mode", "model", "message", "action", "button", "text", "sessionId", "value"]) {
|
|
33130
|
+
if (key2 in normalizedArgs && !(key2.toUpperCase() in normalizedArgs)) {
|
|
33131
|
+
normalizedArgs[key2.toUpperCase()] = normalizedArgs[key2];
|
|
33161
33132
|
}
|
|
33162
33133
|
}
|
|
33163
33134
|
return normalizedArgs;
|
|
@@ -33557,10 +33528,10 @@ function summarizeCommandArgs(args) {
|
|
|
33557
33528
|
"value"
|
|
33558
33529
|
];
|
|
33559
33530
|
const entries = [];
|
|
33560
|
-
for (const
|
|
33561
|
-
if (!(
|
|
33562
|
-
const value =
|
|
33563
|
-
entries.push(`${
|
|
33531
|
+
for (const key2 of preferredKeys) {
|
|
33532
|
+
if (!(key2 in args) || args[key2] === void 0) continue;
|
|
33533
|
+
const value = key2 === "text" || key2 === "message" ? `${String(args[key2] || "").length} chars` : key2 === "data" ? `${String(args[key2] || "").length} chars` : summarizeLogValue(args[key2]);
|
|
33534
|
+
entries.push(`${key2}=${value}`);
|
|
33564
33535
|
}
|
|
33565
33536
|
return entries.length ? entries.join(" ") : "{...}";
|
|
33566
33537
|
}
|
|
@@ -33612,12 +33583,12 @@ var DaemonCommandHandler = class {
|
|
|
33612
33583
|
* Get provider module — _currentProviderType (agentType priority) use.
|
|
33613
33584
|
*/
|
|
33614
33585
|
getProvider(overrideType) {
|
|
33615
|
-
const
|
|
33616
|
-
if (!
|
|
33617
|
-
const result = this._ctx.providerLoader.resolve(
|
|
33586
|
+
const key2 = overrideType || this._currentRoute.providerType || this._currentRoute.session?.providerType || this._currentRoute.managerKey;
|
|
33587
|
+
if (!key2 || !this._ctx.providerLoader) return void 0;
|
|
33588
|
+
const result = this._ctx.providerLoader.resolve(key2);
|
|
33618
33589
|
if (result) return result;
|
|
33619
|
-
const baseType =
|
|
33620
|
-
if (baseType !==
|
|
33590
|
+
const baseType = key2.split("_")[0];
|
|
33591
|
+
if (baseType !== key2) return this._ctx.providerLoader.resolve(baseType);
|
|
33621
33592
|
return void 0;
|
|
33622
33593
|
}
|
|
33623
33594
|
/** Get a provider script by name from ProviderLoader. */
|
|
@@ -33675,11 +33646,11 @@ var DaemonCommandHandler = class {
|
|
|
33675
33646
|
return this._ctx.adapters.get(target) || null;
|
|
33676
33647
|
}
|
|
33677
33648
|
// ─── Private helpers ──────────────────────────────
|
|
33678
|
-
inferProviderType(
|
|
33679
|
-
if (!
|
|
33680
|
-
const session = this._ctx.sessionRegistry?.get(
|
|
33649
|
+
inferProviderType(key2) {
|
|
33650
|
+
if (!key2) return void 0;
|
|
33651
|
+
const session = this._ctx.sessionRegistry?.get(key2);
|
|
33681
33652
|
if (session?.providerType) return session.providerType;
|
|
33682
|
-
return
|
|
33653
|
+
return key2.split("_")[0];
|
|
33683
33654
|
}
|
|
33684
33655
|
resolveRoute(args) {
|
|
33685
33656
|
const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
|
|
@@ -35377,16 +35348,16 @@ var coordinatorPromptHandlers = {
|
|
|
35377
35348
|
const m = matchAppend || matchOverride;
|
|
35378
35349
|
if (!m) continue;
|
|
35379
35350
|
const isAppend = !!matchAppend;
|
|
35380
|
-
const
|
|
35351
|
+
const key2 = m[1];
|
|
35381
35352
|
const full = path43.join(dir, name);
|
|
35382
35353
|
let content = "";
|
|
35383
35354
|
try {
|
|
35384
35355
|
content = fs38.readFileSync(full, "utf8");
|
|
35385
35356
|
} catch {
|
|
35386
35357
|
}
|
|
35387
|
-
if (!entries[
|
|
35388
|
-
if (isAppend) entries[
|
|
35389
|
-
else entries[
|
|
35358
|
+
if (!entries[key2]) entries[key2] = { override: "", append: "" };
|
|
35359
|
+
if (isAppend) entries[key2].append = content;
|
|
35360
|
+
else entries[key2].override = content;
|
|
35390
35361
|
}
|
|
35391
35362
|
}
|
|
35392
35363
|
} catch (error) {
|
|
@@ -35398,14 +35369,14 @@ var coordinatorPromptHandlers = {
|
|
|
35398
35369
|
const fs38 = await import("fs");
|
|
35399
35370
|
const path43 = await import("path");
|
|
35400
35371
|
const os30 = await import("os");
|
|
35401
|
-
const
|
|
35372
|
+
const key2 = typeof args?.key === "string" ? args.key.trim() : "";
|
|
35402
35373
|
const kind = args?.kind === "append" ? "append" : "override";
|
|
35403
35374
|
const content = typeof args?.content === "string" ? args.content : "";
|
|
35404
|
-
if (!
|
|
35375
|
+
if (!key2 || !/^[a-zA-Z0-9_.-]+$/.test(key2)) {
|
|
35405
35376
|
return { success: false, error: "key must match [a-zA-Z0-9_.-]+" };
|
|
35406
35377
|
}
|
|
35407
35378
|
const dir = path43.join(os30.homedir(), ".adhdev", "coordinator-prompts");
|
|
35408
|
-
const filename = kind === "append" ? `${
|
|
35379
|
+
const filename = kind === "append" ? `${key2}.append.md` : `${key2}.md`;
|
|
35409
35380
|
const full = path43.join(dir, filename);
|
|
35410
35381
|
try {
|
|
35411
35382
|
fs38.mkdirSync(dir, { recursive: true });
|
|
@@ -35414,7 +35385,7 @@ var coordinatorPromptHandlers = {
|
|
|
35414
35385
|
} else if (fs38.existsSync(full)) {
|
|
35415
35386
|
fs38.unlinkSync(full);
|
|
35416
35387
|
}
|
|
35417
|
-
return { success: true, path: full, kind, key };
|
|
35388
|
+
return { success: true, path: full, kind, key: key2 };
|
|
35418
35389
|
} catch (error) {
|
|
35419
35390
|
return { success: false, error: error?.message || String(error) };
|
|
35420
35391
|
}
|
|
@@ -36359,7 +36330,7 @@ var RULES = [
|
|
|
36359
36330
|
{
|
|
36360
36331
|
name: "key_value_secret",
|
|
36361
36332
|
pattern: /\b([A-Z0-9_]*(?:SECRET|TOKEN|API[_-]?KEY|PASSWORD|PASSWD|PRIVATE[_-]?KEY|CREDENTIAL|CLIENT[_-]?SECRET)[A-Z0-9_]*)(\s*[:=]\s*)(["']?)([^\s"',;]+)\3/gi,
|
|
36362
|
-
replace: (_m,
|
|
36333
|
+
replace: (_m, key2, delim, quote) => `${key2}${delim}${quote}${MASK}${quote}`
|
|
36363
36334
|
},
|
|
36364
36335
|
// Authorization: Bearer <token>
|
|
36365
36336
|
{
|
|
@@ -36709,7 +36680,7 @@ function realWorkspacePath(workingDir) {
|
|
|
36709
36680
|
}
|
|
36710
36681
|
function applyPreLaunchTrust(trust, workingDir) {
|
|
36711
36682
|
const settingsPath = expandHome2(trust.settings_path);
|
|
36712
|
-
const
|
|
36683
|
+
const key2 = trust.key;
|
|
36713
36684
|
const real = realWorkspacePath(workingDir);
|
|
36714
36685
|
try {
|
|
36715
36686
|
let parsed = {};
|
|
@@ -36722,18 +36693,18 @@ function applyPreLaunchTrust(trust, workingDir) {
|
|
|
36722
36693
|
}
|
|
36723
36694
|
}
|
|
36724
36695
|
}
|
|
36725
|
-
const existing = parsed[
|
|
36696
|
+
const existing = parsed[key2];
|
|
36726
36697
|
const list = Array.isArray(existing) ? existing.filter((v) => typeof v === "string") : [];
|
|
36727
36698
|
if (list.includes(real)) {
|
|
36728
36699
|
LOG.debug("pre-launch-trust", `[${trust.settings_path}] ${real} already trusted \u2014 no change`);
|
|
36729
36700
|
return null;
|
|
36730
36701
|
}
|
|
36731
36702
|
list.push(real);
|
|
36732
|
-
parsed[
|
|
36703
|
+
parsed[key2] = list;
|
|
36733
36704
|
fs14.mkdirSync(path22.dirname(settingsPath), { recursive: true });
|
|
36734
36705
|
fs14.writeFileSync(settingsPath, `${JSON.stringify(parsed, null, 2)}
|
|
36735
36706
|
`, "utf8");
|
|
36736
|
-
LOG.info("pre-launch-trust", `pre-trusted workspace in ${trust.settings_path} (key="${
|
|
36707
|
+
LOG.info("pre-launch-trust", `pre-trusted workspace in ${trust.settings_path} (key="${key2}")`);
|
|
36737
36708
|
return real;
|
|
36738
36709
|
} catch (err) {
|
|
36739
36710
|
LOG.warn("pre-launch-trust", `failed to pre-trust workspace in ${trust.settings_path}: ${err.message}`);
|
|
@@ -38344,8 +38315,8 @@ function jsonPathGet(record, expr) {
|
|
|
38344
38315
|
}
|
|
38345
38316
|
let end = i;
|
|
38346
38317
|
while (end < expr.length && expr[end] !== "." && expr[end] !== "[") end += 1;
|
|
38347
|
-
const
|
|
38348
|
-
cur = cur[
|
|
38318
|
+
const key2 = expr.slice(i, end);
|
|
38319
|
+
cur = cur[key2];
|
|
38349
38320
|
i = end;
|
|
38350
38321
|
}
|
|
38351
38322
|
return cur;
|
|
@@ -40320,8 +40291,8 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
40320
40291
|
/** Drop user-input ack entries older than the dedup window so the map can't grow unbounded. */
|
|
40321
40292
|
pruneRecentUserInputAcks(now) {
|
|
40322
40293
|
if (this.recentUserInputAcks.size <= 1) return;
|
|
40323
|
-
for (const [
|
|
40324
|
-
if (now - at > USER_INPUT_ACK_DEDUP_WINDOW_MS) this.recentUserInputAcks.delete(
|
|
40294
|
+
for (const [key2, at] of this.recentUserInputAcks) {
|
|
40295
|
+
if (now - at > USER_INPUT_ACK_DEDUP_WINDOW_MS) this.recentUserInputAcks.delete(key2);
|
|
40325
40296
|
}
|
|
40326
40297
|
}
|
|
40327
40298
|
dispose() {
|
|
@@ -41525,8 +41496,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41525
41496
|
};
|
|
41526
41497
|
const isRuntimeOverlay = (entry) => {
|
|
41527
41498
|
if (entry.source !== "runtime") return false;
|
|
41528
|
-
const
|
|
41529
|
-
if (
|
|
41499
|
+
const key2 = typeof entry.runtimeKey === "string" ? entry.runtimeKey.trim().toLowerCase() : "";
|
|
41500
|
+
if (key2.startsWith("auto_approval:")) return true;
|
|
41530
41501
|
return !isUserFacingChatMessage(entry.message);
|
|
41531
41502
|
};
|
|
41532
41503
|
const shouldKeepParsedBeforeUntimedRuntime = (message) => {
|
|
@@ -43136,16 +43107,16 @@ var DEFAULT_COORDINATOR_DELEGATED_ENV_UNSETS = [
|
|
|
43136
43107
|
function hasCliArg(args, flag) {
|
|
43137
43108
|
return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
|
|
43138
43109
|
}
|
|
43139
|
-
function hasConfigOverride(args,
|
|
43110
|
+
function hasConfigOverride(args, key2) {
|
|
43140
43111
|
for (let index = 0; index < args.length; index += 1) {
|
|
43141
43112
|
const arg = args[index];
|
|
43142
43113
|
const next = args[index + 1];
|
|
43143
43114
|
if ((arg === "-c" || arg === "--config") && typeof next === "string") {
|
|
43144
|
-
if (next ===
|
|
43115
|
+
if (next === key2 || next.startsWith(`${key2}=`) || next.startsWith(`${key2}.`)) return true;
|
|
43145
43116
|
}
|
|
43146
43117
|
if (arg.startsWith("--config=")) {
|
|
43147
43118
|
const value = arg.slice("--config=".length);
|
|
43148
|
-
if (value ===
|
|
43119
|
+
if (value === key2 || value.startsWith(`${key2}=`) || value.startsWith(`${key2}.`)) return true;
|
|
43149
43120
|
}
|
|
43150
43121
|
}
|
|
43151
43122
|
return false;
|
|
@@ -43162,10 +43133,10 @@ function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
|
43162
43133
|
const cliArgs = Array.isArray(input.cliArgs) ? [...input.cliArgs] : [];
|
|
43163
43134
|
const env = { ...input.env || {} };
|
|
43164
43135
|
const envUnsets = new Set(DEFAULT_COORDINATOR_DELEGATED_ENV_UNSETS);
|
|
43165
|
-
for (const
|
|
43166
|
-
if (typeof
|
|
43136
|
+
for (const key2 of input.isolation?.env?.unset || []) {
|
|
43137
|
+
if (typeof key2 === "string" && key2.trim()) envUnsets.add(key2.trim());
|
|
43167
43138
|
}
|
|
43168
|
-
for (const
|
|
43139
|
+
for (const key2 of envUnsets) env[key2] = "";
|
|
43169
43140
|
for (const rule of input.isolation?.args || []) {
|
|
43170
43141
|
if (!rule || typeof rule !== "object") continue;
|
|
43171
43142
|
if (rule.mode === "empty_mcp_config") {
|
|
@@ -43178,9 +43149,9 @@ function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
|
43178
43149
|
continue;
|
|
43179
43150
|
}
|
|
43180
43151
|
if (rule.mode === "config_override") {
|
|
43181
|
-
const
|
|
43152
|
+
const key2 = String(rule.dedupeKey || rule.key || "").trim();
|
|
43182
43153
|
const flag = String(rule.flag || "").trim();
|
|
43183
|
-
if (!
|
|
43154
|
+
if (!key2 || !flag || hasConfigOverride(cliArgs, key2)) continue;
|
|
43184
43155
|
cliArgs.unshift(flag, `${rule.key}=${rule.value}`);
|
|
43185
43156
|
}
|
|
43186
43157
|
}
|
|
@@ -43386,12 +43357,12 @@ var DaemonCliManager = class {
|
|
|
43386
43357
|
}
|
|
43387
43358
|
throw new Error(`No CLI provider found for '${cliType}'. Create a provider.js in providers/cli/${cliType}/`);
|
|
43388
43359
|
}
|
|
43389
|
-
startCliExitMonitor(
|
|
43360
|
+
startCliExitMonitor(key2, cliType) {
|
|
43390
43361
|
const sessionRegistry = this.deps.getSessionRegistry?.() || null;
|
|
43391
43362
|
const instanceManager = this.deps.getInstanceManager();
|
|
43392
43363
|
const checkStopped = setInterval(() => {
|
|
43393
43364
|
try {
|
|
43394
|
-
const adapter = this.adapters.get(
|
|
43365
|
+
const adapter = this.adapters.get(key2);
|
|
43395
43366
|
if (!adapter) {
|
|
43396
43367
|
clearInterval(checkStopped);
|
|
43397
43368
|
return;
|
|
@@ -43400,12 +43371,12 @@ var DaemonCliManager = class {
|
|
|
43400
43371
|
if (status?.status === "stopped" || status?.status === "error") {
|
|
43401
43372
|
clearInterval(checkStopped);
|
|
43402
43373
|
setTimeout(() => {
|
|
43403
|
-
if (this.adapters.has(
|
|
43404
|
-
this.adapters.delete(
|
|
43405
|
-
this.deps.removeAgentTracking(
|
|
43406
|
-
sessionRegistry?.unregisterByInstanceKey(
|
|
43407
|
-
instanceManager?.removeInstance(
|
|
43408
|
-
unregisterMeshCoordinator(
|
|
43374
|
+
if (this.adapters.has(key2)) {
|
|
43375
|
+
this.adapters.delete(key2);
|
|
43376
|
+
this.deps.removeAgentTracking(key2);
|
|
43377
|
+
sessionRegistry?.unregisterByInstanceKey(key2);
|
|
43378
|
+
instanceManager?.removeInstance(key2);
|
|
43379
|
+
unregisterMeshCoordinator(key2);
|
|
43409
43380
|
LOG.info("CLI", `\u{1F9F9} Auto-cleaned ${status.status} CLI: ${cliType}`);
|
|
43410
43381
|
this.deps.onStatusChange();
|
|
43411
43382
|
}
|
|
@@ -43415,21 +43386,21 @@ var DaemonCliManager = class {
|
|
|
43415
43386
|
}
|
|
43416
43387
|
}, 3e3);
|
|
43417
43388
|
}
|
|
43418
|
-
async registerCliInstance(
|
|
43389
|
+
async registerCliInstance(key2, normalizedType, cliType, resolvedDir, cliArgs, provider, settings, attachExisting = false, options) {
|
|
43419
43390
|
const instanceManager = this.deps.getInstanceManager();
|
|
43420
43391
|
const sessionRegistry = this.deps.getSessionRegistry?.() || null;
|
|
43421
43392
|
if (!instanceManager) throw new Error("InstanceManager not available");
|
|
43422
43393
|
const transportFactory = this.getTransportFactory(
|
|
43423
|
-
|
|
43394
|
+
key2,
|
|
43424
43395
|
normalizedType,
|
|
43425
43396
|
resolvedDir,
|
|
43426
43397
|
cliArgs,
|
|
43427
43398
|
options?.providerSessionId,
|
|
43428
43399
|
attachExisting
|
|
43429
43400
|
);
|
|
43430
|
-
const cliInstance = new CliProviderInstance(provider, resolvedDir, cliArgs,
|
|
43401
|
+
const cliInstance = new CliProviderInstance(provider, resolvedDir, cliArgs, key2, transportFactory, options);
|
|
43431
43402
|
try {
|
|
43432
|
-
await instanceManager.addInstance(
|
|
43403
|
+
await instanceManager.addInstance(key2, cliInstance, {
|
|
43433
43404
|
serverConn: this.deps.getServerConn(),
|
|
43434
43405
|
settings,
|
|
43435
43406
|
onPtyData: (data) => {
|
|
@@ -43441,8 +43412,8 @@ var DaemonCliManager = class {
|
|
|
43441
43412
|
parentSessionId: null,
|
|
43442
43413
|
providerType: normalizedType,
|
|
43443
43414
|
transport: "pty",
|
|
43444
|
-
adapterKey:
|
|
43445
|
-
instanceKey:
|
|
43415
|
+
adapterKey: key2,
|
|
43416
|
+
instanceKey: key2,
|
|
43446
43417
|
workspace: resolvedDir,
|
|
43447
43418
|
// attachExisting === true means we're restoring an already-spawned
|
|
43448
43419
|
// hosted runtime after a daemon restart, not starting a fresh PTY.
|
|
@@ -43458,10 +43429,10 @@ var DaemonCliManager = class {
|
|
|
43458
43429
|
});
|
|
43459
43430
|
} catch (spawnErr) {
|
|
43460
43431
|
LOG.error("CLI", `[${cliType}] Spawn failed: ${spawnErr?.message}`);
|
|
43461
|
-
instanceManager.removeInstance(
|
|
43432
|
+
instanceManager.removeInstance(key2);
|
|
43462
43433
|
throw new Error(`Failed to start ${provider.displayName || provider.name || cliType}: ${spawnErr?.message}`);
|
|
43463
43434
|
}
|
|
43464
|
-
this.adapters.set(
|
|
43435
|
+
this.adapters.set(key2, cliInstance.getAdapter());
|
|
43465
43436
|
const launchMeshNodeId = typeof settings?.meshNodeId === "string" ? settings.meshNodeId.trim() : "";
|
|
43466
43437
|
const launchMeshNodeFor = typeof settings?.meshNodeFor === "string" ? settings.meshNodeFor.trim() : "";
|
|
43467
43438
|
if (launchMeshNodeId || launchMeshNodeFor) {
|
|
@@ -43474,7 +43445,7 @@ var DaemonCliManager = class {
|
|
|
43474
43445
|
} catch {
|
|
43475
43446
|
}
|
|
43476
43447
|
}
|
|
43477
|
-
this.startCliExitMonitor(
|
|
43448
|
+
this.startCliExitMonitor(key2, cliType);
|
|
43478
43449
|
}
|
|
43479
43450
|
// ─── Session start/management ──────────────────────────────
|
|
43480
43451
|
async startSession(cliType, workingDir, cliArgs, initialModel, options) {
|
|
@@ -43491,11 +43462,11 @@ var DaemonCliManager = class {
|
|
|
43491
43462
|
Enable and detect this provider from the Machine Providers page before starting a runtime.`
|
|
43492
43463
|
);
|
|
43493
43464
|
}
|
|
43494
|
-
const
|
|
43465
|
+
const key2 = crypto5.randomUUID();
|
|
43495
43466
|
{
|
|
43496
43467
|
const coordinatorMeshId = options?.settingsOverride?.meshCoordinatorFor;
|
|
43497
43468
|
if (typeof coordinatorMeshId === "string" && coordinatorMeshId.trim()) {
|
|
43498
|
-
options = { ...options, extraEnv: { ...options?.extraEnv || {}, ADHDEV_COORDINATOR_SESSION_ID:
|
|
43469
|
+
options = { ...options, extraEnv: { ...options?.extraEnv || {}, ADHDEV_COORDINATOR_SESSION_ID: key2 } };
|
|
43499
43470
|
}
|
|
43500
43471
|
}
|
|
43501
43472
|
const sessionRegistry = this.deps.getSessionRegistry?.() || null;
|
|
@@ -43515,7 +43486,7 @@ ${installInfo}`
|
|
|
43515
43486
|
}
|
|
43516
43487
|
console.log(colorize("cyan", ` \u{1F50C} Starting ACP agent: ${provider.name} (${provider.type}) in ${resolvedDir}`));
|
|
43517
43488
|
const acpInstance = new AcpProviderInstance(resolvedProvider, resolvedDir, cliArgs);
|
|
43518
|
-
await instanceManager2.addInstance(
|
|
43489
|
+
await instanceManager2.addInstance(key2, acpInstance, {
|
|
43519
43490
|
settings: this.providerLoader.getSettings(normalizedType)
|
|
43520
43491
|
});
|
|
43521
43492
|
const sessionId = acpInstance.getInstanceId();
|
|
@@ -43524,11 +43495,11 @@ ${installInfo}`
|
|
|
43524
43495
|
parentSessionId: null,
|
|
43525
43496
|
providerType: normalizedType,
|
|
43526
43497
|
transport: "acp",
|
|
43527
|
-
adapterKey:
|
|
43528
|
-
instanceKey:
|
|
43498
|
+
adapterKey: key2,
|
|
43499
|
+
instanceKey: key2,
|
|
43529
43500
|
workspace: resolvedDir
|
|
43530
43501
|
});
|
|
43531
|
-
this.adapters.set(
|
|
43502
|
+
this.adapters.set(key2, {
|
|
43532
43503
|
cliType: normalizedType,
|
|
43533
43504
|
cliName: provider.name,
|
|
43534
43505
|
workingDir: resolvedDir,
|
|
@@ -43536,7 +43507,7 @@ ${installInfo}`
|
|
|
43536
43507
|
spawn: async () => {
|
|
43537
43508
|
},
|
|
43538
43509
|
shutdown: () => {
|
|
43539
|
-
instanceManager2.removeInstance(
|
|
43510
|
+
instanceManager2.removeInstance(key2);
|
|
43540
43511
|
},
|
|
43541
43512
|
sendMessage: async (text) => {
|
|
43542
43513
|
const input = normalizeInputEnvelope(text);
|
|
@@ -43552,7 +43523,7 @@ ${installInfo}`
|
|
|
43552
43523
|
},
|
|
43553
43524
|
getPartialResponse: () => "",
|
|
43554
43525
|
cancel: () => {
|
|
43555
|
-
instanceManager2.removeInstance(
|
|
43526
|
+
instanceManager2.removeInstance(key2);
|
|
43556
43527
|
},
|
|
43557
43528
|
isProcessing: () => false,
|
|
43558
43529
|
isReady: () => true,
|
|
@@ -43606,7 +43577,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
43606
43577
|
if (provider && instanceManager) {
|
|
43607
43578
|
const resolvedProvider = this.providerLoader.resolve(cliType, { version: cliInfo.version }) || provider;
|
|
43608
43579
|
await this.registerCliInstance(
|
|
43609
|
-
|
|
43580
|
+
key2,
|
|
43610
43581
|
normalizedType,
|
|
43611
43582
|
cliType,
|
|
43612
43583
|
resolvedDir,
|
|
@@ -43636,7 +43607,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
43636
43607
|
cliType,
|
|
43637
43608
|
resolvedDir,
|
|
43638
43609
|
resolvedCliArgs,
|
|
43639
|
-
|
|
43610
|
+
key2,
|
|
43640
43611
|
sessionBinding.providerSessionId,
|
|
43641
43612
|
false,
|
|
43642
43613
|
options?.extraEnv
|
|
@@ -43656,9 +43627,9 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
43656
43627
|
const status = adapter.getStatus?.();
|
|
43657
43628
|
if (status?.status === "stopped" || status?.status === "error") {
|
|
43658
43629
|
setTimeout(() => {
|
|
43659
|
-
if (this.adapters.get(
|
|
43660
|
-
this.adapters.delete(
|
|
43661
|
-
this.deps.removeAgentTracking(
|
|
43630
|
+
if (this.adapters.get(key2) === adapter) {
|
|
43631
|
+
this.adapters.delete(key2);
|
|
43632
|
+
this.deps.removeAgentTracking(key2);
|
|
43662
43633
|
LOG.info("CLI", `\u{1F9F9} Auto-cleaned ${status.status} CLI: ${adapter.cliType}`);
|
|
43663
43634
|
this.deps.onStatusChange();
|
|
43664
43635
|
}
|
|
@@ -43667,10 +43638,10 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
43667
43638
|
});
|
|
43668
43639
|
if (typeof adapter.setOnPtyData === "function") {
|
|
43669
43640
|
adapter.setOnPtyData((data) => {
|
|
43670
|
-
this.deps.getP2p()?.broadcastSessionOutput(
|
|
43641
|
+
this.deps.getP2p()?.broadcastSessionOutput(key2, data);
|
|
43671
43642
|
});
|
|
43672
43643
|
}
|
|
43673
|
-
this.adapters.set(
|
|
43644
|
+
this.adapters.set(key2, adapter);
|
|
43674
43645
|
console.log(colorize("green", ` \u2713 CLI started: ${cliInfo.displayName} v${cliInfo.version || "unknown"} in ${resolvedDir}`));
|
|
43675
43646
|
}
|
|
43676
43647
|
this.persistRecentActivity({
|
|
@@ -43680,20 +43651,20 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
43680
43651
|
providerSessionId: sessionBinding.providerSessionId,
|
|
43681
43652
|
workspace: resolvedDir,
|
|
43682
43653
|
summaryMetadata: buildLegacyModelModeSummaryMetadata({ model: initialModel }),
|
|
43683
|
-
sessionId:
|
|
43654
|
+
sessionId: key2,
|
|
43684
43655
|
title: provider?.displayName || provider?.name || normalizedType
|
|
43685
43656
|
});
|
|
43686
43657
|
this.deps.onStatusChange();
|
|
43687
43658
|
return {
|
|
43688
|
-
runtimeSessionId:
|
|
43659
|
+
runtimeSessionId: key2,
|
|
43689
43660
|
providerSessionId: sessionBinding.providerSessionId
|
|
43690
43661
|
};
|
|
43691
43662
|
}
|
|
43692
|
-
async stopSession(
|
|
43693
|
-
return this.stopSessionWithMode(
|
|
43663
|
+
async stopSession(key2) {
|
|
43664
|
+
return this.stopSessionWithMode(key2, "hard");
|
|
43694
43665
|
}
|
|
43695
|
-
async stopSessionWithMode(
|
|
43696
|
-
const adapter = this.adapters.get(
|
|
43666
|
+
async stopSessionWithMode(key2, mode) {
|
|
43667
|
+
const adapter = this.adapters.get(key2);
|
|
43697
43668
|
if (adapter) {
|
|
43698
43669
|
try {
|
|
43699
43670
|
if (mode === "save" && typeof adapter.saveAndStop === "function") {
|
|
@@ -43704,21 +43675,21 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
43704
43675
|
} catch (e) {
|
|
43705
43676
|
LOG.warn("CLI", `Shutdown error for ${adapter.cliType}: ${e?.message} (force-cleaning)`);
|
|
43706
43677
|
}
|
|
43707
|
-
this.adapters.delete(
|
|
43708
|
-
this.deps.removeAgentTracking(
|
|
43709
|
-
this.deps.getSessionRegistry?.()?.unregisterByInstanceKey(
|
|
43710
|
-
this.deps.getInstanceManager()?.removeInstance(
|
|
43711
|
-
unregisterMeshCoordinator(
|
|
43678
|
+
this.adapters.delete(key2);
|
|
43679
|
+
this.deps.removeAgentTracking(key2);
|
|
43680
|
+
this.deps.getSessionRegistry?.()?.unregisterByInstanceKey(key2);
|
|
43681
|
+
this.deps.getInstanceManager()?.removeInstance(key2);
|
|
43682
|
+
unregisterMeshCoordinator(key2);
|
|
43712
43683
|
LOG.info("CLI", `\u{1F6D1} Agent stopped: ${adapter.cliType} in ${adapter.workingDir}`);
|
|
43713
43684
|
this.deps.onStatusChange();
|
|
43714
43685
|
} else {
|
|
43715
43686
|
const im = this.deps.getInstanceManager();
|
|
43716
43687
|
if (im) {
|
|
43717
|
-
this.deps.getSessionRegistry?.()?.unregisterByInstanceKey(
|
|
43718
|
-
im.removeInstance(
|
|
43719
|
-
this.deps.removeAgentTracking(
|
|
43720
|
-
unregisterMeshCoordinator(
|
|
43721
|
-
LOG.warn("CLI", `\u{1F9F9} Force-removed orphan entry: ${
|
|
43688
|
+
this.deps.getSessionRegistry?.()?.unregisterByInstanceKey(key2);
|
|
43689
|
+
im.removeInstance(key2);
|
|
43690
|
+
this.deps.removeAgentTracking(key2);
|
|
43691
|
+
unregisterMeshCoordinator(key2);
|
|
43692
|
+
LOG.warn("CLI", `\u{1F9F9} Force-removed orphan entry: ${key2}`);
|
|
43722
43693
|
this.deps.onStatusChange();
|
|
43723
43694
|
}
|
|
43724
43695
|
}
|
|
@@ -43746,8 +43717,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
43746
43717
|
for (const r of sessions) {
|
|
43747
43718
|
if (!r?.runtimeId || !r?.cliType || !r?.workspace) continue;
|
|
43748
43719
|
restoredRuntimeIds.add(r.runtimeId);
|
|
43749
|
-
const
|
|
43750
|
-
workspaceTypeCounts.set(
|
|
43720
|
+
const key2 = `${r.workspace}::${r.cliType}`;
|
|
43721
|
+
workspaceTypeCounts.set(key2, (workspaceTypeCounts.get(key2) || 0) + 1);
|
|
43751
43722
|
}
|
|
43752
43723
|
for (const record of sessions) {
|
|
43753
43724
|
if (!record?.runtimeId || !record?.cliType || !record?.workspace) continue;
|
|
@@ -44101,7 +44072,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44101
44072
|
});
|
|
44102
44073
|
}
|
|
44103
44074
|
if (!found) throw new Error(`CLI agent not running: ${agentType}`);
|
|
44104
|
-
const { adapter, key } = found;
|
|
44075
|
+
const { adapter, key: key2 } = found;
|
|
44105
44076
|
if (action === "send_chat") {
|
|
44106
44077
|
let currentStatus = getEffectiveAgentSendStatus(adapter);
|
|
44107
44078
|
if (currentStatus === "starting" && await waitForZeroMessageStartingLaunch(adapter)) {
|
|
@@ -44111,7 +44082,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44111
44082
|
}
|
|
44112
44083
|
const meshContext = args?.meshContext;
|
|
44113
44084
|
if (meshContext && typeof meshContext === "object" && typeof meshContext.meshId === "string" && meshContext.meshId) {
|
|
44114
|
-
const targetInstanceId =
|
|
44085
|
+
const targetInstanceId = key2;
|
|
44115
44086
|
try {
|
|
44116
44087
|
this.deps.getInstanceManager()?.attachMeshAssignmentToInstance(targetInstanceId, {
|
|
44117
44088
|
meshId: meshContext.meshId,
|
|
@@ -44143,7 +44114,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44143
44114
|
} else {
|
|
44144
44115
|
await adapter.sendMessage(message);
|
|
44145
44116
|
}
|
|
44146
|
-
const targetInstance = this.deps.getInstanceManager()?.getInstance(
|
|
44117
|
+
const targetInstance = this.deps.getInstanceManager()?.getInstance(key2);
|
|
44147
44118
|
targetInstance?.recordAcknowledgedUserInput?.(input);
|
|
44148
44119
|
return {
|
|
44149
44120
|
success: true,
|
|
@@ -44155,7 +44126,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44155
44126
|
if (typeof adapter.clearHistory === "function") adapter.clearHistory();
|
|
44156
44127
|
return { success: true, cleared: true };
|
|
44157
44128
|
} else if (action === "stop") {
|
|
44158
|
-
await this.stopSession(
|
|
44129
|
+
await this.stopSession(key2);
|
|
44159
44130
|
return { success: true, stopped: true };
|
|
44160
44131
|
}
|
|
44161
44132
|
throw new Error(`Unknown action: ${action}`);
|
|
@@ -44427,9 +44398,9 @@ function validateProviderDefinition(raw) {
|
|
|
44427
44398
|
} else if (!["ide", "extension", "cli", "acp"].includes(String(provider.category))) {
|
|
44428
44399
|
errors.push(`Invalid category: ${String(provider.category)}`);
|
|
44429
44400
|
}
|
|
44430
|
-
for (const
|
|
44431
|
-
if (!KNOWN_PROVIDER_FIELDS.has(
|
|
44432
|
-
warnings.push(`Unknown provider field: ${
|
|
44401
|
+
for (const key2 of Object.keys(provider)) {
|
|
44402
|
+
if (!KNOWN_PROVIDER_FIELDS.has(key2)) {
|
|
44403
|
+
warnings.push(`Unknown provider field: ${key2}`);
|
|
44433
44404
|
}
|
|
44434
44405
|
}
|
|
44435
44406
|
if (provider.disableUpstream !== void 0) {
|
|
@@ -44574,10 +44545,10 @@ function validateNativeHistory(raw, errors) {
|
|
|
44574
44545
|
return;
|
|
44575
44546
|
}
|
|
44576
44547
|
const scriptConfig = scripts;
|
|
44577
|
-
for (const
|
|
44578
|
-
const value = scriptConfig[
|
|
44548
|
+
for (const key2 of ["readSession", "listSessions"]) {
|
|
44549
|
+
const value = scriptConfig[key2];
|
|
44579
44550
|
if (typeof value !== "string" || !value.trim()) {
|
|
44580
|
-
errors.push(`nativeHistory.scripts.${
|
|
44551
|
+
errors.push(`nativeHistory.scripts.${key2} must be a non-empty string`);
|
|
44581
44552
|
}
|
|
44582
44553
|
}
|
|
44583
44554
|
}
|
|
@@ -44612,10 +44583,10 @@ function validateMeshCoordinatorMcpConfig(mcpConfig, errors) {
|
|
|
44612
44583
|
if (format !== void 0 && !["claude_mcp_json", "hermes_config_yaml"].includes(String(format))) {
|
|
44613
44584
|
errors.push("meshCoordinator.mcpConfig.format must be one of: claude_mcp_json, hermes_config_yaml");
|
|
44614
44585
|
}
|
|
44615
|
-
for (const
|
|
44616
|
-
const value = config[
|
|
44586
|
+
for (const key2 of ["path", "serverName", "configPathCommand", "instructions", "template"]) {
|
|
44587
|
+
const value = config[key2];
|
|
44617
44588
|
if (value !== void 0 && (typeof value !== "string" || !value.trim())) {
|
|
44618
|
-
errors.push(`meshCoordinator.mcpConfig.${
|
|
44589
|
+
errors.push(`meshCoordinator.mcpConfig.${key2} must be a non-empty string when provided`);
|
|
44619
44590
|
}
|
|
44620
44591
|
}
|
|
44621
44592
|
if (config.requiresRestart !== void 0 && typeof config.requiresRestart !== "boolean") {
|
|
@@ -44651,7 +44622,7 @@ function validateMeshCoordinatorDelegatedWorkerIsolation(raw, errors) {
|
|
|
44651
44622
|
errors.push("meshCoordinator.delegatedWorkerIsolation.env must be an object");
|
|
44652
44623
|
} else {
|
|
44653
44624
|
const unset = env.unset;
|
|
44654
|
-
if (unset !== void 0 && (!Array.isArray(unset) || unset.some((
|
|
44625
|
+
if (unset !== void 0 && (!Array.isArray(unset) || unset.some((key2) => typeof key2 !== "string" || !key2.trim()))) {
|
|
44655
44626
|
errors.push("meshCoordinator.delegatedWorkerIsolation.env.unset must be an array of non-empty strings");
|
|
44656
44627
|
}
|
|
44657
44628
|
}
|
|
@@ -44674,16 +44645,16 @@ function validateMeshCoordinatorDelegatedWorkerIsolation(raw, errors) {
|
|
|
44674
44645
|
errors.push(`${prefix}.mode must be one of: empty_mcp_config, config_override`);
|
|
44675
44646
|
continue;
|
|
44676
44647
|
}
|
|
44677
|
-
for (const
|
|
44678
|
-
const value = item[
|
|
44648
|
+
for (const key2 of mode === "empty_mcp_config" ? ["flag"] : ["flag", "key", "value"]) {
|
|
44649
|
+
const value = item[key2];
|
|
44679
44650
|
if (typeof value !== "string" || !value.trim()) {
|
|
44680
|
-
errors.push(`${prefix}.${
|
|
44651
|
+
errors.push(`${prefix}.${key2} must be a non-empty string`);
|
|
44681
44652
|
}
|
|
44682
44653
|
}
|
|
44683
|
-
for (const
|
|
44684
|
-
const value = item[
|
|
44654
|
+
for (const key2 of ["strictFlag", "dedupeKey"]) {
|
|
44655
|
+
const value = item[key2];
|
|
44685
44656
|
if (value !== void 0 && (typeof value !== "string" || !value.trim())) {
|
|
44686
|
-
errors.push(`${prefix}.${
|
|
44657
|
+
errors.push(`${prefix}.${key2} must be a non-empty string when provided`);
|
|
44687
44658
|
}
|
|
44688
44659
|
}
|
|
44689
44660
|
}
|
|
@@ -46906,9 +46877,9 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
46906
46877
|
reload() {
|
|
46907
46878
|
this.log("Reloading all providers...");
|
|
46908
46879
|
this.scriptsCache.clear();
|
|
46909
|
-
for (const
|
|
46910
|
-
if (
|
|
46911
|
-
delete __require.cache[
|
|
46880
|
+
for (const key2 of Object.keys(__require.cache)) {
|
|
46881
|
+
if (key2.includes("providers") && (key2.endsWith(".js") || key2.endsWith(".json"))) {
|
|
46882
|
+
delete __require.cache[key2];
|
|
46912
46883
|
}
|
|
46913
46884
|
}
|
|
46914
46885
|
this.loadAll();
|
|
@@ -47216,7 +47187,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
47216
47187
|
*/
|
|
47217
47188
|
getPublicSettings(type) {
|
|
47218
47189
|
const settings = this.getSettingsSchema(type);
|
|
47219
|
-
return Object.entries(settings).filter(([, def]) => def.public === true).map(([
|
|
47190
|
+
return Object.entries(settings).filter(([, def]) => def.public === true).map(([key2, def]) => ({ key: key2, ...def }));
|
|
47220
47191
|
}
|
|
47221
47192
|
/**
|
|
47222
47193
|
* Get public settings schema for all providers
|
|
@@ -47232,23 +47203,23 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
47232
47203
|
/**
|
|
47233
47204
|
* Resolved setting value for a provider (default + user override)
|
|
47234
47205
|
*/
|
|
47235
|
-
getSettingValue(type,
|
|
47206
|
+
getSettingValue(type, key2) {
|
|
47236
47207
|
const providerType = this.resolveAlias(type);
|
|
47237
47208
|
const machineConfig = this.getMachineProviderConfig(providerType);
|
|
47238
|
-
if (
|
|
47209
|
+
if (key2 === "enabled") {
|
|
47239
47210
|
return machineConfig.enabled === true;
|
|
47240
47211
|
}
|
|
47241
|
-
if (
|
|
47212
|
+
if (key2 === "executablePath") {
|
|
47242
47213
|
return machineConfig.executable || "";
|
|
47243
47214
|
}
|
|
47244
|
-
if (
|
|
47215
|
+
if (key2 === "executableArgs") {
|
|
47245
47216
|
const args = machineConfig.args;
|
|
47246
47217
|
return args ? args.map((arg) => /\s/.test(arg) ? JSON.stringify(arg) : arg).join(" ") : "";
|
|
47247
47218
|
}
|
|
47248
|
-
const schemaDef = this.getSettingsSchema(providerType)[
|
|
47219
|
+
const schemaDef = this.getSettingsSchema(providerType)[key2];
|
|
47249
47220
|
const defaultVal = schemaDef ? schemaDef.default : void 0;
|
|
47250
47221
|
const config = this.readConfig();
|
|
47251
|
-
const userVal = config?.providerSettings?.[providerType]?.[
|
|
47222
|
+
const userVal = config?.providerSettings?.[providerType]?.[key2];
|
|
47252
47223
|
return userVal !== void 0 ? userVal : defaultVal;
|
|
47253
47224
|
}
|
|
47254
47225
|
/**
|
|
@@ -47258,17 +47229,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
47258
47229
|
const providerType = this.resolveAlias(type);
|
|
47259
47230
|
const settings = this.getSettingsSchema(providerType);
|
|
47260
47231
|
const result = {};
|
|
47261
|
-
for (const [
|
|
47262
|
-
result[
|
|
47232
|
+
for (const [key2] of Object.entries(settings)) {
|
|
47233
|
+
result[key2] = this.getSettingValue(providerType, key2);
|
|
47263
47234
|
}
|
|
47264
47235
|
return result;
|
|
47265
47236
|
}
|
|
47266
47237
|
/**
|
|
47267
47238
|
* Save provider setting value (writes to config.json)
|
|
47268
47239
|
*/
|
|
47269
|
-
setSetting(type,
|
|
47240
|
+
setSetting(type, key2, value) {
|
|
47270
47241
|
const providerType = this.resolveAlias(type);
|
|
47271
|
-
const schemaDef = this.getSettingsSchema(providerType)[
|
|
47242
|
+
const schemaDef = this.getSettingsSchema(providerType)[key2];
|
|
47272
47243
|
if (!schemaDef) return false;
|
|
47273
47244
|
if (!schemaDef.public) return false;
|
|
47274
47245
|
if (schemaDef.type === "boolean" && typeof value !== "boolean") return false;
|
|
@@ -47279,13 +47250,13 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
47279
47250
|
if (schemaDef.max !== void 0 && value > schemaDef.max) return false;
|
|
47280
47251
|
}
|
|
47281
47252
|
if (schemaDef.type === "select" && schemaDef.options && !schemaDef.options.includes(value)) return false;
|
|
47282
|
-
if (
|
|
47253
|
+
if (key2 === "enabled") {
|
|
47283
47254
|
return this.setMachineProviderEnabled(providerType, value);
|
|
47284
47255
|
}
|
|
47285
|
-
if (
|
|
47256
|
+
if (key2 === "executablePath") {
|
|
47286
47257
|
return this.setMachineProviderConfig(providerType, { executable: value });
|
|
47287
47258
|
}
|
|
47288
|
-
if (
|
|
47259
|
+
if (key2 === "executableArgs") {
|
|
47289
47260
|
return this.setMachineProviderConfig(providerType, {
|
|
47290
47261
|
args: value.trim() ? this.parseArgsSetting(value) : void 0
|
|
47291
47262
|
});
|
|
@@ -47295,17 +47266,17 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
47295
47266
|
try {
|
|
47296
47267
|
if (!config.providerSettings) config.providerSettings = {};
|
|
47297
47268
|
if (!config.providerSettings[providerType]) config.providerSettings[providerType] = {};
|
|
47298
|
-
config.providerSettings[providerType][
|
|
47269
|
+
config.providerSettings[providerType][key2] = value;
|
|
47299
47270
|
this.writeConfig(config);
|
|
47300
|
-
this.log(`Setting updated: ${providerType}.${
|
|
47271
|
+
this.log(`Setting updated: ${providerType}.${key2} = ${JSON.stringify(value)}`);
|
|
47301
47272
|
return true;
|
|
47302
47273
|
} catch (e) {
|
|
47303
47274
|
this.log(`Failed to save setting: ${e.message}`);
|
|
47304
47275
|
return false;
|
|
47305
47276
|
}
|
|
47306
47277
|
}
|
|
47307
|
-
getOptionalStringSetting(type,
|
|
47308
|
-
const value = this.getSettingValue(type,
|
|
47278
|
+
getOptionalStringSetting(type, key2) {
|
|
47279
|
+
const value = this.getSettingValue(type, key2);
|
|
47309
47280
|
if (typeof value !== "string") return null;
|
|
47310
47281
|
const trimmed = value.trim();
|
|
47311
47282
|
return trimmed ? trimmed : null;
|
|
@@ -47485,7 +47456,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
47485
47456
|
try {
|
|
47486
47457
|
let content = fs25.readFileSync(filePath, "utf-8");
|
|
47487
47458
|
if (args[0] && typeof args[0] === "object") {
|
|
47488
|
-
for (const [
|
|
47459
|
+
for (const [key2, val] of Object.entries(args[0])) {
|
|
47489
47460
|
let v = val;
|
|
47490
47461
|
if (typeof v === "string") {
|
|
47491
47462
|
if (!v.startsWith('"') && !v.startsWith("'") && !v.startsWith("`")) {
|
|
@@ -47494,7 +47465,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
47494
47465
|
} else {
|
|
47495
47466
|
v = JSON.stringify(v);
|
|
47496
47467
|
}
|
|
47497
|
-
const re = new RegExp(`\\$\\{\\s*${
|
|
47468
|
+
const re = new RegExp(`\\$\\{\\s*${key2}\\s*\\}`, "g");
|
|
47498
47469
|
content = content.replace(re, String(v));
|
|
47499
47470
|
}
|
|
47500
47471
|
} else if (typeof args[0] === "string") {
|
|
@@ -48283,6 +48254,21 @@ init_mesh_host_ownership();
|
|
|
48283
48254
|
init_worktree_bootstrap_config();
|
|
48284
48255
|
init_mesh_events();
|
|
48285
48256
|
init_config();
|
|
48257
|
+
async function decideOssCloneSync(ossCtx, worktreeOssSha, sourceSha, rg) {
|
|
48258
|
+
if (!worktreeOssSha || !sourceSha || worktreeOssSha === sourceSha) return "noop";
|
|
48259
|
+
const isAncestor = async (ancestor, descendant) => {
|
|
48260
|
+
try {
|
|
48261
|
+
await rg(ossCtx, ["merge-base", "--is-ancestor", ancestor, descendant], { timeoutMs: 1e4 });
|
|
48262
|
+
return true;
|
|
48263
|
+
} catch (err) {
|
|
48264
|
+
if (err?.exitCode === 1 || err?.code === 1) return false;
|
|
48265
|
+
throw err;
|
|
48266
|
+
}
|
|
48267
|
+
};
|
|
48268
|
+
if (await isAncestor(sourceSha, worktreeOssSha)) return "skip_rewind";
|
|
48269
|
+
if (await isAncestor(worktreeOssSha, sourceSha)) return "advance";
|
|
48270
|
+
return "skip_diverged";
|
|
48271
|
+
}
|
|
48286
48272
|
var meshCrudHandlers = {
|
|
48287
48273
|
list_meshes: async (_ctx, _args) => {
|
|
48288
48274
|
try {
|
|
@@ -48373,7 +48359,8 @@ var meshCrudHandlers = {
|
|
|
48373
48359
|
// entry. This is an export scaffold for the operator to review and commit to
|
|
48374
48360
|
// the repo, NOT an automatic data migration: nothing is written to disk and
|
|
48375
48361
|
// meshes.json is untouched. The returned `scaffold` (object) + `scaffoldJson`
|
|
48376
|
-
// (2-space text) capture the
|
|
48362
|
+
// (2-space text) capture the coordinator prompt override/append (policy is
|
|
48363
|
+
// machine-local and is intentionally NOT exported into mesh.json).
|
|
48377
48364
|
export_mesh_json_config: async (_ctx, args) => {
|
|
48378
48365
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
48379
48366
|
if (!meshId) return { success: false, error: "meshId required" };
|
|
@@ -48744,7 +48731,7 @@ var meshCrudHandlers = {
|
|
|
48744
48731
|
}
|
|
48745
48732
|
};
|
|
48746
48733
|
const initSubmodules = sourceNode.policy?.initSubmodulesOnClone !== false;
|
|
48747
|
-
const loadedBootstrap =
|
|
48734
|
+
const loadedBootstrap = loadRepoSettings({ workspace: result.worktreePath, mesh }).worktreeBootstrap;
|
|
48748
48735
|
const runningBootstrapState = {
|
|
48749
48736
|
status: "running",
|
|
48750
48737
|
required: loadedBootstrap.config?.required !== false,
|
|
@@ -48778,12 +48765,25 @@ var meshCrudHandlers = {
|
|
|
48778
48765
|
const ossCtx = { workspace: `${result.worktreePath}/oss`, repoRoot: `${result.worktreePath}/oss`, isGitRepo: true };
|
|
48779
48766
|
const worktreeOssHeadOut = await rg(ossCtx, ["rev-parse", "HEAD"], { timeoutMs: 1e4 });
|
|
48780
48767
|
const worktreeOssSha = (typeof worktreeOssHeadOut === "string" ? worktreeOssHeadOut : worktreeOssHeadOut?.stdout ?? "").trim();
|
|
48781
|
-
if (worktreeOssSha !== sourceSha) {
|
|
48768
|
+
if (worktreeOssSha && worktreeOssSha !== sourceSha) {
|
|
48782
48769
|
await rg(ossCtx, ["fetch", `${sourceWorkspace}/oss`, "HEAD"], { timeoutMs: 6e4 });
|
|
48783
|
-
|
|
48784
|
-
|
|
48785
|
-
|
|
48786
|
-
|
|
48770
|
+
let ossAction;
|
|
48771
|
+
try {
|
|
48772
|
+
ossAction = await decideOssCloneSync(ossCtx, worktreeOssSha, sourceSha, rg);
|
|
48773
|
+
} catch (decideErr) {
|
|
48774
|
+
ossAction = "skip_diverged";
|
|
48775
|
+
console.warn(`[mesh] oss submodule sync guard could not resolve ancestry (kept fresh worktree HEAD): ${decideErr?.message ?? decideErr}`);
|
|
48776
|
+
}
|
|
48777
|
+
if (ossAction === "advance") {
|
|
48778
|
+
await rg(ossCtx, ["checkout", sourceSha], { timeoutMs: 1e4 });
|
|
48779
|
+
await rg(worktreeCtx, ["add", "oss"], { timeoutMs: 1e4 });
|
|
48780
|
+
await rg(worktreeCtx, ["commit", "-m", "chore: sync oss to source node HEAD on clone"], { timeoutMs: 1e4 });
|
|
48781
|
+
console.log(`[mesh] Advanced oss submodule to newer source HEAD ${sourceSha.slice(0, 8)} in worktree`);
|
|
48782
|
+
} else if (ossAction === "skip_rewind") {
|
|
48783
|
+
console.warn(`[mesh] Skipped oss submodule rewind on clone: source node oss ${sourceSha.slice(0, 8)} is an ancestor of the fresh worktree oss ${worktreeOssSha.slice(0, 8)} \u2014 kept fresher worktree HEAD`);
|
|
48784
|
+
} else if (ossAction === "skip_diverged") {
|
|
48785
|
+
console.warn(`[mesh] Skipped oss submodule sync on clone: source node oss ${sourceSha.slice(0, 8)} diverged from the fresh worktree oss ${worktreeOssSha.slice(0, 8)} \u2014 kept worktree HEAD (coordinator reconciles)`);
|
|
48786
|
+
}
|
|
48787
48787
|
}
|
|
48788
48788
|
}
|
|
48789
48789
|
} catch (ossErr) {
|
|
@@ -49217,9 +49217,20 @@ var meshQueueHandlers = {
|
|
|
49217
49217
|
targetNodeId: typeof args?.targetNodeId === "string" ? args.targetNodeId.trim() : void 0,
|
|
49218
49218
|
targetSessionId: typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : void 0,
|
|
49219
49219
|
clearTargetNode: args?.clearTargetNode === true,
|
|
49220
|
-
clearTargetSession: args?.clearTargetSession !== false
|
|
49220
|
+
clearTargetSession: args?.clearTargetSession !== false,
|
|
49221
|
+
// CANON-IDENTITY: an in-flight (actively-generating) task is refused by
|
|
49222
|
+
// default to avoid a duplicate second dispatch; an explicit operator
|
|
49223
|
+
// force overrides that guard (and the retry cap).
|
|
49224
|
+
force: args?.force === true
|
|
49221
49225
|
});
|
|
49222
49226
|
if (!task) return { success: false, error: `Queue task '${taskId}' not found` };
|
|
49227
|
+
if (task.status === "assigned" && args?.force !== true) {
|
|
49228
|
+
return {
|
|
49229
|
+
success: false,
|
|
49230
|
+
error: `Task '${taskId}' is actively dispatched/generating; requeue refused to avoid a duplicate second dispatch. Pass force:true to override, or cancel and re-enqueue.`,
|
|
49231
|
+
task
|
|
49232
|
+
};
|
|
49233
|
+
}
|
|
49223
49234
|
return { success: true, task };
|
|
49224
49235
|
} catch (e) {
|
|
49225
49236
|
return { success: false, error: e.message };
|
|
@@ -50750,15 +50761,15 @@ var SENSITIVE_KEYS = /* @__PURE__ */ new Set([
|
|
|
50750
50761
|
function maskArgs(args) {
|
|
50751
50762
|
if (!args || typeof args !== "object") return void 0;
|
|
50752
50763
|
const masked = {};
|
|
50753
|
-
for (const [
|
|
50754
|
-
if (SENSITIVE_KEYS.has(
|
|
50755
|
-
masked[
|
|
50756
|
-
} else if (
|
|
50757
|
-
masked[
|
|
50764
|
+
for (const [key2, value] of Object.entries(args)) {
|
|
50765
|
+
if (SENSITIVE_KEYS.has(key2)) {
|
|
50766
|
+
masked[key2] = typeof value === "string" ? `[${value.length} chars]` : "[masked]";
|
|
50767
|
+
} else if (key2.startsWith("_")) {
|
|
50768
|
+
masked[key2] = value;
|
|
50758
50769
|
} else if (typeof value === "object" && value !== null) {
|
|
50759
|
-
masked[
|
|
50770
|
+
masked[key2] = Array.isArray(value) ? `[Array(${value.length})]` : `[Object]`;
|
|
50760
50771
|
} else {
|
|
50761
|
-
masked[
|
|
50772
|
+
masked[key2] = value;
|
|
50762
50773
|
}
|
|
50763
50774
|
}
|
|
50764
50775
|
return masked;
|
|
@@ -51855,23 +51866,23 @@ var MeshGitProbeCache = class {
|
|
|
51855
51866
|
* neither gate is satisfied.
|
|
51856
51867
|
*/
|
|
51857
51868
|
async probe(daemonId, workspace, probe) {
|
|
51858
|
-
const
|
|
51859
|
-
const cached3 = this.recent.get(
|
|
51869
|
+
const key2 = this.key(daemonId, workspace);
|
|
51870
|
+
const cached3 = this.recent.get(key2);
|
|
51860
51871
|
if (cached3 && this.now() - cached3.at < this.reuseMs) {
|
|
51861
51872
|
return cached3.value;
|
|
51862
51873
|
}
|
|
51863
|
-
const existing = this.inflight.get(
|
|
51874
|
+
const existing = this.inflight.get(key2);
|
|
51864
51875
|
if (existing) return existing;
|
|
51865
51876
|
const pending = (async () => {
|
|
51866
51877
|
const result = await probe();
|
|
51867
|
-
if (result) this.recent.set(
|
|
51878
|
+
if (result) this.recent.set(key2, { at: this.now(), value: result });
|
|
51868
51879
|
return result;
|
|
51869
51880
|
})();
|
|
51870
|
-
this.inflight.set(
|
|
51881
|
+
this.inflight.set(key2, pending);
|
|
51871
51882
|
try {
|
|
51872
51883
|
return await pending;
|
|
51873
51884
|
} finally {
|
|
51874
|
-
if (this.inflight.get(
|
|
51885
|
+
if (this.inflight.get(key2) === pending) this.inflight.delete(key2);
|
|
51875
51886
|
}
|
|
51876
51887
|
}
|
|
51877
51888
|
};
|
|
@@ -54569,8 +54580,8 @@ var DaemonCommandRouter = class {
|
|
|
54569
54580
|
if (source !== "refine_mesh_node_async_job") continue;
|
|
54570
54581
|
const jobId = e.payload?.refineJob?.jobId;
|
|
54571
54582
|
if (!jobId || terminal.has(`${e.nodeId}:${jobId}`)) continue;
|
|
54572
|
-
const
|
|
54573
|
-
if (this.runningRefineJobs.has(
|
|
54583
|
+
const key2 = this.buildRefineJobKey(meshId, e.nodeId);
|
|
54584
|
+
if (this.runningRefineJobs.has(key2)) continue;
|
|
54574
54585
|
const coordinatorDaemonId = e.payload?.refineJob?.targetCoordinatorDaemonId;
|
|
54575
54586
|
LOG.info("Mesh", `[Refinery] Auto-resuming interrupted refine job for node ${e.nodeId} (jobId=${jobId})`);
|
|
54576
54587
|
void this.startMeshRefineJob(meshId, e.nodeId, {
|
|
@@ -55653,7 +55664,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
55653
55664
|
}
|
|
55654
55665
|
}
|
|
55655
55666
|
async finishMeshRefineBatchJob(handle, orderedNodes, ordering, args) {
|
|
55656
|
-
const
|
|
55667
|
+
const key2 = this.buildRefineBatchJobKey(handle.meshId);
|
|
55657
55668
|
let result;
|
|
55658
55669
|
try {
|
|
55659
55670
|
result = await this.runMeshRefineBatchConvergence(handle.meshId, orderedNodes, ordering, args);
|
|
@@ -55685,8 +55696,8 @@ ${hintLines.join("\n")}` : "",
|
|
|
55685
55696
|
coordinatorDaemonId: handle.targetCoordinatorDaemonId
|
|
55686
55697
|
});
|
|
55687
55698
|
const terminal = { ...terminalHandle, result: normalizedResult };
|
|
55688
|
-
this.terminalRefineBatchJobs.set(
|
|
55689
|
-
this.runningRefineBatchJobs.delete(
|
|
55699
|
+
this.terminalRefineBatchJobs.set(key2, terminal);
|
|
55700
|
+
this.runningRefineBatchJobs.delete(key2);
|
|
55690
55701
|
this.invalidateAggregateMeshStatus(handle.meshId);
|
|
55691
55702
|
await this.appendRefineBatchJobLedger(isTerminalSuccess ? "task_completed" : "task_failed", terminalHandle, normalizedResult);
|
|
55692
55703
|
this.queueRefineBatchJobEvent(isTerminalSuccess ? "refine:completed" : "refine:failed", terminalHandle, normalizedResult);
|
|
@@ -55710,8 +55721,8 @@ ${hintLines.join("\n")}` : "",
|
|
|
55710
55721
|
if (nodeIds.length === 0) {
|
|
55711
55722
|
return { ...planRecord, success: true, batch: true, dryRun: false, async: false };
|
|
55712
55723
|
}
|
|
55713
|
-
const
|
|
55714
|
-
const running = this.runningRefineBatchJobs.get(
|
|
55724
|
+
const key2 = this.buildRefineBatchJobKey(meshId);
|
|
55725
|
+
const running = this.runningRefineBatchJobs.get(key2);
|
|
55715
55726
|
if (running) return { ...running, duplicate: true };
|
|
55716
55727
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
55717
55728
|
const mesh = meshRecord?.mesh;
|
|
@@ -55726,7 +55737,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
55726
55737
|
};
|
|
55727
55738
|
const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
55728
55739
|
const handle = this.buildRefineBatchJobHandle({ meshId, nodeIds, order, coordinatorDaemonId });
|
|
55729
|
-
this.runningRefineBatchJobs.set(
|
|
55740
|
+
this.runningRefineBatchJobs.set(key2, handle);
|
|
55730
55741
|
await this.appendRefineBatchJobLedger("task_dispatched", handle);
|
|
55731
55742
|
this.queueRefineBatchJobEvent("refine:accepted", handle);
|
|
55732
55743
|
setImmediate(() => {
|
|
@@ -55741,7 +55752,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
55741
55752
|
};
|
|
55742
55753
|
}
|
|
55743
55754
|
async finishMeshRefineJob(handle, args) {
|
|
55744
|
-
const
|
|
55755
|
+
const key2 = this.buildRefineJobKey(handle.meshId, handle.targetNodeId);
|
|
55745
55756
|
let result;
|
|
55746
55757
|
try {
|
|
55747
55758
|
result = await this.executeMeshRefineNodeSynchronously(handle.meshId, handle.targetNodeId, args);
|
|
@@ -55809,17 +55820,17 @@ ${hintLines.join("\n")}` : "",
|
|
|
55809
55820
|
coordinatorDaemonId: handle.targetCoordinatorDaemonId
|
|
55810
55821
|
});
|
|
55811
55822
|
const terminal = { ...terminalHandle, result: normalizedResult };
|
|
55812
|
-
this.terminalRefineJobs.set(
|
|
55813
|
-
this.runningRefineJobs.delete(
|
|
55823
|
+
this.terminalRefineJobs.set(key2, terminal);
|
|
55824
|
+
this.runningRefineJobs.delete(key2);
|
|
55814
55825
|
this.invalidateAggregateMeshStatus(handle.meshId);
|
|
55815
55826
|
await this.appendRefineJobLedger(isTerminalSuccess ? "task_completed" : "task_failed", terminalHandle, normalizedResult);
|
|
55816
55827
|
this.queueRefineJobEvent(isTerminalSuccess ? "refine:completed" : "refine:failed", terminalHandle, normalizedResult);
|
|
55817
55828
|
}
|
|
55818
55829
|
async startMeshRefineJob(meshId, nodeId, args) {
|
|
55819
|
-
const
|
|
55820
|
-
const running = this.runningRefineJobs.get(
|
|
55830
|
+
const key2 = this.buildRefineJobKey(meshId, nodeId);
|
|
55831
|
+
const running = this.runningRefineJobs.get(key2);
|
|
55821
55832
|
if (running) return { ...running, duplicate: true };
|
|
55822
|
-
const terminal = this.terminalRefineJobs.get(
|
|
55833
|
+
const terminal = this.terminalRefineJobs.get(key2);
|
|
55823
55834
|
const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh, { preferInline: true });
|
|
55824
55835
|
const mesh = meshRecord?.mesh;
|
|
55825
55836
|
const node = mesh?.nodes?.find((n) => meshNodeIdMatches(n, nodeId));
|
|
@@ -55827,7 +55838,7 @@ ${hintLines.join("\n")}` : "",
|
|
|
55827
55838
|
if (!node.isLocalWorktree || !node.workspace) return { success: false, error: `Refinery requires a local worktree node` };
|
|
55828
55839
|
const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
55829
55840
|
const handle = this.buildRefineJobHandle({ meshId, nodeId, node, retryOfJobId: terminal?.jobId, coordinatorDaemonId });
|
|
55830
|
-
this.runningRefineJobs.set(
|
|
55841
|
+
this.runningRefineJobs.set(key2, handle);
|
|
55831
55842
|
await this.appendRefineJobLedger("task_dispatched", handle);
|
|
55832
55843
|
this.queueRefineJobEvent("refine:accepted", handle);
|
|
55833
55844
|
setImmediate(() => {
|
|
@@ -55883,27 +55894,27 @@ ${hintLines.join("\n")}` : "",
|
|
|
55883
55894
|
*/
|
|
55884
55895
|
async stopIde(ideType, killProcess = false) {
|
|
55885
55896
|
const cdpKeysToRemove = [];
|
|
55886
|
-
for (const
|
|
55887
|
-
if (
|
|
55888
|
-
cdpKeysToRemove.push(
|
|
55897
|
+
for (const key2 of this.deps.cdpManagers.keys()) {
|
|
55898
|
+
if (key2 === ideType || key2.startsWith(`${ideType}_`)) {
|
|
55899
|
+
cdpKeysToRemove.push(key2);
|
|
55889
55900
|
}
|
|
55890
55901
|
}
|
|
55891
|
-
for (const
|
|
55892
|
-
const cdp = this.deps.cdpManagers.get(
|
|
55902
|
+
for (const key2 of cdpKeysToRemove) {
|
|
55903
|
+
const cdp = this.deps.cdpManagers.get(key2);
|
|
55893
55904
|
if (cdp) {
|
|
55894
55905
|
try {
|
|
55895
55906
|
cdp.disconnect();
|
|
55896
55907
|
} catch {
|
|
55897
55908
|
}
|
|
55898
|
-
this.deps.cdpManagers.delete(
|
|
55899
|
-
this.deps.sessionRegistry.unregisterByManagerKey(
|
|
55900
|
-
LOG.info("StopIDE", `CDP disconnected: ${
|
|
55909
|
+
this.deps.cdpManagers.delete(key2);
|
|
55910
|
+
this.deps.sessionRegistry.unregisterByManagerKey(key2);
|
|
55911
|
+
LOG.info("StopIDE", `CDP disconnected: ${key2}`);
|
|
55901
55912
|
}
|
|
55902
55913
|
}
|
|
55903
55914
|
const keysToRemove = [];
|
|
55904
|
-
for (const
|
|
55905
|
-
if (
|
|
55906
|
-
keysToRemove.push(
|
|
55915
|
+
for (const key2 of this.deps.instanceManager.listInstanceIds()) {
|
|
55916
|
+
if (key2 === `ide:${ideType}` || typeof key2 === "string" && key2.startsWith(`ide:${ideType}_`)) {
|
|
55917
|
+
keysToRemove.push(key2);
|
|
55907
55918
|
}
|
|
55908
55919
|
}
|
|
55909
55920
|
for (const instanceKey of keysToRemove) {
|
|
@@ -60596,9 +60607,9 @@ async function handleAutoImplement(ctx, type, req, res) {
|
|
|
60596
60607
|
}
|
|
60597
60608
|
if (Date.now() - lastApprovalTime < 2e3) return;
|
|
60598
60609
|
if (approvalPatterns.some((p) => p.test(approvalBuffer))) {
|
|
60599
|
-
const
|
|
60600
|
-
writeFn(
|
|
60601
|
-
ctx.log(`Auto-Implement auto-approved prompt! Sending: ${JSON.stringify(
|
|
60610
|
+
const key2 = approvalKeys[1] || approvalKeys[0] || "a\r";
|
|
60611
|
+
writeFn(key2);
|
|
60612
|
+
ctx.log(`Auto-Implement auto-approved prompt! Sending: ${JSON.stringify(key2)}`);
|
|
60602
60613
|
sendAutoImplSSE(ctx, { event: "output", data: { chunk: `
|
|
60603
60614
|
[\u{1F916} ADHDev Auto-Approve] CLI Action Approved
|
|
60604
60615
|
`, stream: "stdout" } });
|
|
@@ -61850,8 +61861,8 @@ var DevServer = class _DevServer {
|
|
|
61850
61861
|
category: p.category
|
|
61851
61862
|
}));
|
|
61852
61863
|
const cdpStatus = {};
|
|
61853
|
-
for (const [
|
|
61854
|
-
cdpStatus[
|
|
61864
|
+
for (const [key2, cdp] of this.cdpManagers.entries()) {
|
|
61865
|
+
cdpStatus[key2] = { connected: cdp.isConnected };
|
|
61855
61866
|
}
|
|
61856
61867
|
this.json(res, 200, {
|
|
61857
61868
|
devMode: true,
|
|
@@ -62171,16 +62182,16 @@ var DevServer = class _DevServer {
|
|
|
62171
62182
|
errors.push(...validation.errors);
|
|
62172
62183
|
warnings.push(...validation.warnings);
|
|
62173
62184
|
if (config.settings) {
|
|
62174
|
-
for (const [
|
|
62185
|
+
for (const [key2, val] of Object.entries(config.settings)) {
|
|
62175
62186
|
const s2 = val;
|
|
62176
|
-
if (!s2.type) errors.push(`settings.${
|
|
62187
|
+
if (!s2.type) errors.push(`settings.${key2}: missing type`);
|
|
62177
62188
|
else if (!["boolean", "number", "string", "select"].includes(s2.type))
|
|
62178
|
-
errors.push(`settings.${
|
|
62179
|
-
if (s2.default === void 0) warnings.push(`settings.${
|
|
62189
|
+
errors.push(`settings.${key2}: invalid type '${s2.type}'`);
|
|
62190
|
+
if (s2.default === void 0) warnings.push(`settings.${key2}: no default value`);
|
|
62180
62191
|
if (s2.type === "number" && s2.min !== void 0 && s2.max !== void 0 && s2.min > s2.max)
|
|
62181
|
-
errors.push(`settings.${
|
|
62192
|
+
errors.push(`settings.${key2}: min (${s2.min}) > max (${s2.max})`);
|
|
62182
62193
|
if (s2.type === "select" && (!s2.options || !Array.isArray(s2.options) || s2.options.length === 0))
|
|
62183
|
-
errors.push(`settings.${
|
|
62194
|
+
errors.push(`settings.${key2}: select type requires options[]`);
|
|
62184
62195
|
}
|
|
62185
62196
|
}
|
|
62186
62197
|
if (config.cdpPorts && Array.isArray(config.cdpPorts)) {
|
|
@@ -62968,21 +62979,21 @@ function isLowercaseLetter(value) {
|
|
|
62968
62979
|
function encodeControlLetter(letter) {
|
|
62969
62980
|
return String.fromCharCode(letter.charCodeAt(0) - 96);
|
|
62970
62981
|
}
|
|
62971
|
-
function encodeShiftedKey(
|
|
62972
|
-
if (isLowercaseLetter(
|
|
62973
|
-
if (
|
|
62974
|
-
return encodeControlLetter(
|
|
62982
|
+
function encodeShiftedKey(key2) {
|
|
62983
|
+
if (isLowercaseLetter(key2)) return key2.toUpperCase();
|
|
62984
|
+
if (key2.startsWith("ctrl+") && isLowercaseLetter(key2.slice(5))) {
|
|
62985
|
+
return encodeControlLetter(key2.slice(5));
|
|
62975
62986
|
}
|
|
62976
|
-
if (
|
|
62977
|
-
return `\x1B${
|
|
62987
|
+
if (key2.startsWith("alt+") && isLowercaseLetter(key2.slice(4))) {
|
|
62988
|
+
return `\x1B${key2.slice(4).toUpperCase()}`;
|
|
62978
62989
|
}
|
|
62979
|
-
if (
|
|
62980
|
-
if (
|
|
62981
|
-
if (
|
|
62982
|
-
throw new Error(`Unsupported named key: shift+${
|
|
62990
|
+
if (key2 === "tab") return "\x1B[Z";
|
|
62991
|
+
if (key2 in SHIFTED_CSI_KEYS) return SHIFTED_CSI_KEYS[key2];
|
|
62992
|
+
if (key2 in BASE_KEY_SEQUENCES) return BASE_KEY_SEQUENCES[key2];
|
|
62993
|
+
throw new Error(`Unsupported named key: shift+${key2}`);
|
|
62983
62994
|
}
|
|
62984
|
-
function namedKeyToAnsi(
|
|
62985
|
-
const normalized = String(
|
|
62995
|
+
function namedKeyToAnsi(key2) {
|
|
62996
|
+
const normalized = String(key2 || "").trim().toLowerCase();
|
|
62986
62997
|
if (normalized in BASE_KEY_SEQUENCES) return BASE_KEY_SEQUENCES[normalized];
|
|
62987
62998
|
if (normalized.startsWith("ctrl+") && isLowercaseLetter(normalized.slice(5))) {
|
|
62988
62999
|
return encodeControlLetter(normalized.slice(5));
|
|
@@ -62991,7 +63002,7 @@ function namedKeyToAnsi(key) {
|
|
|
62991
63002
|
return `\x1B${normalized.slice(4)}`;
|
|
62992
63003
|
}
|
|
62993
63004
|
if (normalized.startsWith("shift+")) return encodeShiftedKey(normalized.slice(6));
|
|
62994
|
-
throw new Error(`Unsupported named key: ${
|
|
63005
|
+
throw new Error(`Unsupported named key: ${key2}`);
|
|
62995
63006
|
}
|
|
62996
63007
|
function namedKeysToAnsi(keys) {
|
|
62997
63008
|
if (!Array.isArray(keys)) throw new Error("keys must be an array");
|
|
@@ -63472,19 +63483,19 @@ var SessionRegistry = class {
|
|
|
63472
63483
|
if (!ids) return [];
|
|
63473
63484
|
return [...ids].map((id) => this.bySessionId.get(id)).filter(Boolean);
|
|
63474
63485
|
}
|
|
63475
|
-
addIndex(index,
|
|
63476
|
-
let set = index.get(
|
|
63486
|
+
addIndex(index, key2, sessionId) {
|
|
63487
|
+
let set = index.get(key2);
|
|
63477
63488
|
if (!set) {
|
|
63478
63489
|
set = /* @__PURE__ */ new Set();
|
|
63479
|
-
index.set(
|
|
63490
|
+
index.set(key2, set);
|
|
63480
63491
|
}
|
|
63481
63492
|
set.add(sessionId);
|
|
63482
63493
|
}
|
|
63483
|
-
removeIndex(index,
|
|
63484
|
-
const set = index.get(
|
|
63494
|
+
removeIndex(index, key2, sessionId) {
|
|
63495
|
+
const set = index.get(key2);
|
|
63485
63496
|
if (!set) return;
|
|
63486
63497
|
set.delete(sessionId);
|
|
63487
|
-
if (set.size === 0) index.delete(
|
|
63498
|
+
if (set.size === 0) index.delete(key2);
|
|
63488
63499
|
}
|
|
63489
63500
|
};
|
|
63490
63501
|
|
|
@@ -64144,6 +64155,7 @@ export {
|
|
|
64144
64155
|
buildToolChatMessage,
|
|
64145
64156
|
buildUserChatMessage,
|
|
64146
64157
|
cancelTask,
|
|
64158
|
+
canonicalDaemonId,
|
|
64147
64159
|
claimNextTask,
|
|
64148
64160
|
classifyChatMessageVisibility,
|
|
64149
64161
|
classifyHotChatSessionsForSubscriptionFlush,
|
|
@@ -64272,6 +64284,7 @@ export {
|
|
|
64272
64284
|
loadMeshCoordinatorRegistry,
|
|
64273
64285
|
loadMeshRefineConfig,
|
|
64274
64286
|
loadMeshWorktreeBootstrapConfig,
|
|
64287
|
+
loadRepoSettings,
|
|
64275
64288
|
loadState,
|
|
64276
64289
|
logCommand,
|
|
64277
64290
|
machineCoreFromDaemonId,
|