@adhdev/daemon-core 0.9.82-rc.330 → 0.9.82-rc.332
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +75 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +75 -9
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +15 -0
- package/package.json +2 -2
- package/src/cli-adapters/provider-cli-adapter.ts +12 -0
- package/src/config/mesh-config.ts +1 -1
- package/src/mesh/mesh-events-coordinator.ts +15 -0
- package/src/mesh/mesh-reconcile-loop.ts +38 -2
- package/src/providers/cli-provider-instance.ts +45 -0
- package/src/repo-mesh-types.ts +4 -1
- package/src/status/reporter.ts +3 -0
package/dist/index.mjs
CHANGED
|
@@ -83,7 +83,10 @@ var init_repo_mesh_types = __esm({
|
|
|
83
83
|
requireApprovalForDestructiveGit: true,
|
|
84
84
|
dirtyWorkspaceBehavior: "warn",
|
|
85
85
|
maxParallelTasks: 2,
|
|
86
|
-
|
|
86
|
+
// Coordinator-spawned worker sessions default to hidden so the dashboard is not
|
|
87
|
+
// flooded with mesh noise tabs/notifications. Users can still surface or unmute
|
|
88
|
+
// any specific session manually; that override is preserved per-device.
|
|
89
|
+
spawnedSessionVisibility: "hidden",
|
|
87
90
|
delegatedWorkerAutoApprove: true,
|
|
88
91
|
sessionCleanupOnNodeRemove: "preserve",
|
|
89
92
|
autoFastForward: { enabled: true },
|
|
@@ -308,10 +311,10 @@ function readInjected(value) {
|
|
|
308
311
|
}
|
|
309
312
|
function getDaemonBuildInfo() {
|
|
310
313
|
if (cached) return cached;
|
|
311
|
-
const commit = readInjected(true ? "
|
|
312
|
-
const commitShort = readInjected(true ? "
|
|
313
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
314
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
314
|
+
const commit = readInjected(true ? "2466d8b001000d509eb9058a0c51ec6f383741ed" : void 0) ?? "unknown";
|
|
315
|
+
const commitShort = readInjected(true ? "2466d8b0" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
316
|
+
const version = readInjected(true ? "0.9.82-rc.332" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
317
|
+
const builtAt = readInjected(true ? "2026-06-20T01:55:54.421Z" : void 0);
|
|
315
318
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
316
319
|
return cached;
|
|
317
320
|
}
|
|
@@ -1938,7 +1941,7 @@ function mergeMeshPolicy(base, patch) {
|
|
|
1938
1941
|
policy.sessionCleanupOnNodeRemove = "preserve";
|
|
1939
1942
|
}
|
|
1940
1943
|
if (!SPAWNED_SESSION_VISIBILITY_MODES.has(String(policy.spawnedSessionVisibility))) {
|
|
1941
|
-
policy.spawnedSessionVisibility =
|
|
1944
|
+
policy.spawnedSessionVisibility = DEFAULT_MESH_POLICY.spawnedSessionVisibility;
|
|
1942
1945
|
}
|
|
1943
1946
|
const normalizedStrategy = normalizeMeshSchedulingStrategy(policy.schedulingStrategy);
|
|
1944
1947
|
if (normalizedStrategy === "first_eligible") {
|
|
@@ -10663,6 +10666,21 @@ function handleMeshForwardEvent(components, payload) {
|
|
|
10663
10666
|
targetSessionId: readNonEmptyString2(payload.targetSessionId) || readNonEmptyString2(payload.sessionId) || readNonEmptyString2(payload.instanceId),
|
|
10664
10667
|
providerType: readNonEmptyString2(payload.providerType),
|
|
10665
10668
|
providerSessionId: readNonEmptyString2(payload.providerSessionId),
|
|
10669
|
+
// Carry the session identity fields the worker provider event emits so the
|
|
10670
|
+
// coordinator's mirror (updateMeshOwnedSession) gets a real workspace/title/
|
|
10671
|
+
// settings. Without these the remote-relay hop reconstructs metadataEvent with
|
|
10672
|
+
// an empty workspace, and the dashboard flaps to the generic
|
|
10673
|
+
// "Terminal (Mesh Node)" title (and degrades the provider label) between live
|
|
10674
|
+
// events and the periodic get_status_metadata snapshot. The local in-process
|
|
10675
|
+
// forward path (onMeshCoordinatorEventForwarded) already preserves these; this
|
|
10676
|
+
// mirrors them for the remote-only relay path.
|
|
10677
|
+
workspace: readNonEmptyString2(payload.workspace) || readNonEmptyString2(payload.workspaceName),
|
|
10678
|
+
workspaceName: readNonEmptyString2(payload.workspaceName) || readNonEmptyString2(payload.workspace),
|
|
10679
|
+
sessionTitle: readNonEmptyString2(payload.sessionTitle),
|
|
10680
|
+
sessionStatus: readNonEmptyString2(payload.sessionStatus),
|
|
10681
|
+
sessionChatStatus: readNonEmptyString2(payload.sessionChatStatus),
|
|
10682
|
+
providerName: readNonEmptyString2(payload.providerName),
|
|
10683
|
+
...payload.sessionSettings && typeof payload.sessionSettings === "object" && !Array.isArray(payload.sessionSettings) ? { sessionSettings: payload.sessionSettings } : {},
|
|
10666
10684
|
finalSummary: readNonEmptyString2(payload.finalSummary) || readNonEmptyString2(payload.summary),
|
|
10667
10685
|
jobId: readNonEmptyString2(payload.jobId),
|
|
10668
10686
|
interactionId: readNonEmptyString2(payload.interactionId),
|
|
@@ -11542,7 +11560,8 @@ function findLiveCoordinators(components) {
|
|
|
11542
11560
|
const meshId = readNonEmptyString2(settings.meshCoordinatorFor);
|
|
11543
11561
|
if (!meshId) continue;
|
|
11544
11562
|
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
11545
|
-
|
|
11563
|
+
const modalParked = status === "waiting_choice" || status === "waiting_approval";
|
|
11564
|
+
out.push({ meshId, instance: inst, idle: status === "idle", modalParked });
|
|
11546
11565
|
}
|
|
11547
11566
|
return out;
|
|
11548
11567
|
}
|
|
@@ -11631,9 +11650,16 @@ async function runMeshReconcileTick(components) {
|
|
|
11631
11650
|
}
|
|
11632
11651
|
for (const [meshId, meshCoordinators] of byMesh) {
|
|
11633
11652
|
const idleCoordinators = meshCoordinators.filter((c) => c.idle);
|
|
11634
|
-
const generatingCoordinators = meshCoordinators.filter((c) => !c.idle);
|
|
11653
|
+
const generatingCoordinators = meshCoordinators.filter((c) => !c.idle && !c.modalParked);
|
|
11654
|
+
const modalParkedCoordinators = meshCoordinators.filter((c) => !c.idle && c.modalParked);
|
|
11635
11655
|
const targetCoordinators = idleCoordinators.length > 0 ? idleCoordinators : generatingCoordinators;
|
|
11636
11656
|
const forceOnly = idleCoordinators.length === 0;
|
|
11657
|
+
if (targetCoordinators.length === 0) {
|
|
11658
|
+
if (modalParkedCoordinators.length > 0) {
|
|
11659
|
+
LOG.info("MeshReconcile", `Reconcile skip \u2192 modal-parked: holding pending event(s) for mesh ${meshId} (${modalParkedCoordinators.length} coordinator(s) awaiting a modal answer; events left queued)`);
|
|
11660
|
+
}
|
|
11661
|
+
continue;
|
|
11662
|
+
}
|
|
11637
11663
|
if (store) {
|
|
11638
11664
|
try {
|
|
11639
11665
|
if (store.pendingEventCount(meshId) === 0) continue;
|
|
@@ -15949,6 +15975,10 @@ ${lastSnapshot}`;
|
|
|
15949
15975
|
if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
|
|
15950
15976
|
const content = String(text || "");
|
|
15951
15977
|
if (!content.trim()) return;
|
|
15978
|
+
if (this.engine.currentStatus === "waiting_approval" || this.engine.hasActionableApproval()) {
|
|
15979
|
+
LOG.info("CLI", `[${this.cliType}] force-send held \u2014 session parked on approval modal (status=${this.engine.currentStatus})`);
|
|
15980
|
+
return;
|
|
15981
|
+
}
|
|
15952
15982
|
LOG.info("CLI", `[${this.cliType}] force-sending prompt while status=${this.engine.currentStatus}`);
|
|
15953
15983
|
await this.writeToPty(content + this.sendKey);
|
|
15954
15984
|
this.onStatusChange?.();
|
|
@@ -34498,6 +34528,35 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
34498
34528
|
this.settings = rest;
|
|
34499
34529
|
this.adapter.updateRuntimeSettings?.(this.settings);
|
|
34500
34530
|
}
|
|
34531
|
+
/**
|
|
34532
|
+
* The resolved modal-park status of this session, or null when it is not
|
|
34533
|
+
* parked on a modal awaiting a human answer. Mirrors the overlay logic in
|
|
34534
|
+
* getState(): an active AskUserQuestion interactive prompt resolves to
|
|
34535
|
+
* waiting_choice; otherwise the adapter's waiting_approval (tool consent)
|
|
34536
|
+
* counts — UNLESS auto-approve will dismiss it, in which case the session is
|
|
34537
|
+
* effectively generating and is NOT modal-parked. This is the single signal
|
|
34538
|
+
* the mesh force-inject guard consults, and the same status string the
|
|
34539
|
+
* reconcile loop reads off get_status_metadata. Lowercase literals only —
|
|
34540
|
+
* the SessionStatus enum is forked across modules and waiting_choice is
|
|
34541
|
+
* absent from some of them.
|
|
34542
|
+
*/
|
|
34543
|
+
resolveModalParkStatus() {
|
|
34544
|
+
if (this.activeInteractivePrompt) return "waiting_choice";
|
|
34545
|
+
let adapterStatus;
|
|
34546
|
+
try {
|
|
34547
|
+
adapterStatus = this.adapter.getStatus({ allowParse: false });
|
|
34548
|
+
} catch {
|
|
34549
|
+
return null;
|
|
34550
|
+
}
|
|
34551
|
+
if (adapterStatus.status === "waiting_approval" && !this.shouldAutoApprove()) {
|
|
34552
|
+
return "waiting_approval";
|
|
34553
|
+
}
|
|
34554
|
+
return null;
|
|
34555
|
+
}
|
|
34556
|
+
/** True when this session is parked on a modal awaiting a human answer. */
|
|
34557
|
+
isModalParked() {
|
|
34558
|
+
return this.resolveModalParkStatus() !== null;
|
|
34559
|
+
}
|
|
34501
34560
|
onEvent(event, data) {
|
|
34502
34561
|
if (event === "send_message") {
|
|
34503
34562
|
const input = normalizeInputEnvelope(data);
|
|
@@ -34505,6 +34564,10 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
34505
34564
|
const promptText = buildCliStructuredInputPrompt(input);
|
|
34506
34565
|
if (promptText) {
|
|
34507
34566
|
const force = data?.force === true;
|
|
34567
|
+
if (force && this.isModalParked()) {
|
|
34568
|
+
LOG.info("CLI", `[${this.type}] force send_message held \u2014 coordinator parked on modal (${this.resolveModalParkStatus()})`);
|
|
34569
|
+
return;
|
|
34570
|
+
}
|
|
34508
34571
|
void this.adapter.sendMessage(promptText, force ? { force: true } : {}).catch((e) => {
|
|
34509
34572
|
LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
|
|
34510
34573
|
});
|
|
@@ -50865,7 +50928,10 @@ var DaemonStatusReporter = class {
|
|
|
50865
50928
|
title: session.title,
|
|
50866
50929
|
cdpConnected: session.cdpConnected,
|
|
50867
50930
|
summaryMetadata: session.summaryMetadata,
|
|
50868
|
-
settings: session.settings
|
|
50931
|
+
settings: session.settings,
|
|
50932
|
+
// Forward surfaceHidden so the server can gate push notifications for
|
|
50933
|
+
// coordinator-hidden sessions (the WS path is the only one the server sees).
|
|
50934
|
+
surfaceHidden: session.surfaceHidden
|
|
50869
50935
|
})),
|
|
50870
50936
|
p2p: payload.p2p,
|
|
50871
50937
|
timestamp: now
|