@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.js
CHANGED
|
@@ -88,7 +88,10 @@ var init_repo_mesh_types = __esm({
|
|
|
88
88
|
requireApprovalForDestructiveGit: true,
|
|
89
89
|
dirtyWorkspaceBehavior: "warn",
|
|
90
90
|
maxParallelTasks: 2,
|
|
91
|
-
|
|
91
|
+
// Coordinator-spawned worker sessions default to hidden so the dashboard is not
|
|
92
|
+
// flooded with mesh noise tabs/notifications. Users can still surface or unmute
|
|
93
|
+
// any specific session manually; that override is preserved per-device.
|
|
94
|
+
spawnedSessionVisibility: "hidden",
|
|
92
95
|
delegatedWorkerAutoApprove: true,
|
|
93
96
|
sessionCleanupOnNodeRemove: "preserve",
|
|
94
97
|
autoFastForward: { enabled: true },
|
|
@@ -313,10 +316,10 @@ function readInjected(value) {
|
|
|
313
316
|
}
|
|
314
317
|
function getDaemonBuildInfo() {
|
|
315
318
|
if (cached) return cached;
|
|
316
|
-
const commit = readInjected(true ? "
|
|
317
|
-
const commitShort = readInjected(true ? "
|
|
318
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
319
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
319
|
+
const commit = readInjected(true ? "2466d8b001000d509eb9058a0c51ec6f383741ed" : void 0) ?? "unknown";
|
|
320
|
+
const commitShort = readInjected(true ? "2466d8b0" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
321
|
+
const version = readInjected(true ? "0.9.82-rc.332" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
322
|
+
const builtAt = readInjected(true ? "2026-06-20T01:55:54.421Z" : void 0);
|
|
320
323
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
321
324
|
return cached;
|
|
322
325
|
}
|
|
@@ -1940,7 +1943,7 @@ function mergeMeshPolicy(base, patch) {
|
|
|
1940
1943
|
policy.sessionCleanupOnNodeRemove = "preserve";
|
|
1941
1944
|
}
|
|
1942
1945
|
if (!SPAWNED_SESSION_VISIBILITY_MODES.has(String(policy.spawnedSessionVisibility))) {
|
|
1943
|
-
policy.spawnedSessionVisibility =
|
|
1946
|
+
policy.spawnedSessionVisibility = DEFAULT_MESH_POLICY.spawnedSessionVisibility;
|
|
1944
1947
|
}
|
|
1945
1948
|
const normalizedStrategy = normalizeMeshSchedulingStrategy(policy.schedulingStrategy);
|
|
1946
1949
|
if (normalizedStrategy === "first_eligible") {
|
|
@@ -10666,6 +10669,21 @@ function handleMeshForwardEvent(components, payload) {
|
|
|
10666
10669
|
targetSessionId: readNonEmptyString2(payload.targetSessionId) || readNonEmptyString2(payload.sessionId) || readNonEmptyString2(payload.instanceId),
|
|
10667
10670
|
providerType: readNonEmptyString2(payload.providerType),
|
|
10668
10671
|
providerSessionId: readNonEmptyString2(payload.providerSessionId),
|
|
10672
|
+
// Carry the session identity fields the worker provider event emits so the
|
|
10673
|
+
// coordinator's mirror (updateMeshOwnedSession) gets a real workspace/title/
|
|
10674
|
+
// settings. Without these the remote-relay hop reconstructs metadataEvent with
|
|
10675
|
+
// an empty workspace, and the dashboard flaps to the generic
|
|
10676
|
+
// "Terminal (Mesh Node)" title (and degrades the provider label) between live
|
|
10677
|
+
// events and the periodic get_status_metadata snapshot. The local in-process
|
|
10678
|
+
// forward path (onMeshCoordinatorEventForwarded) already preserves these; this
|
|
10679
|
+
// mirrors them for the remote-only relay path.
|
|
10680
|
+
workspace: readNonEmptyString2(payload.workspace) || readNonEmptyString2(payload.workspaceName),
|
|
10681
|
+
workspaceName: readNonEmptyString2(payload.workspaceName) || readNonEmptyString2(payload.workspace),
|
|
10682
|
+
sessionTitle: readNonEmptyString2(payload.sessionTitle),
|
|
10683
|
+
sessionStatus: readNonEmptyString2(payload.sessionStatus),
|
|
10684
|
+
sessionChatStatus: readNonEmptyString2(payload.sessionChatStatus),
|
|
10685
|
+
providerName: readNonEmptyString2(payload.providerName),
|
|
10686
|
+
...payload.sessionSettings && typeof payload.sessionSettings === "object" && !Array.isArray(payload.sessionSettings) ? { sessionSettings: payload.sessionSettings } : {},
|
|
10669
10687
|
finalSummary: readNonEmptyString2(payload.finalSummary) || readNonEmptyString2(payload.summary),
|
|
10670
10688
|
jobId: readNonEmptyString2(payload.jobId),
|
|
10671
10689
|
interactionId: readNonEmptyString2(payload.interactionId),
|
|
@@ -11546,7 +11564,8 @@ function findLiveCoordinators(components) {
|
|
|
11546
11564
|
const meshId = readNonEmptyString2(settings.meshCoordinatorFor);
|
|
11547
11565
|
if (!meshId) continue;
|
|
11548
11566
|
const status = readNonEmptyString2(state.status).toLowerCase();
|
|
11549
|
-
|
|
11567
|
+
const modalParked = status === "waiting_choice" || status === "waiting_approval";
|
|
11568
|
+
out.push({ meshId, instance: inst, idle: status === "idle", modalParked });
|
|
11550
11569
|
}
|
|
11551
11570
|
return out;
|
|
11552
11571
|
}
|
|
@@ -11635,9 +11654,16 @@ async function runMeshReconcileTick(components) {
|
|
|
11635
11654
|
}
|
|
11636
11655
|
for (const [meshId, meshCoordinators] of byMesh) {
|
|
11637
11656
|
const idleCoordinators = meshCoordinators.filter((c) => c.idle);
|
|
11638
|
-
const generatingCoordinators = meshCoordinators.filter((c) => !c.idle);
|
|
11657
|
+
const generatingCoordinators = meshCoordinators.filter((c) => !c.idle && !c.modalParked);
|
|
11658
|
+
const modalParkedCoordinators = meshCoordinators.filter((c) => !c.idle && c.modalParked);
|
|
11639
11659
|
const targetCoordinators = idleCoordinators.length > 0 ? idleCoordinators : generatingCoordinators;
|
|
11640
11660
|
const forceOnly = idleCoordinators.length === 0;
|
|
11661
|
+
if (targetCoordinators.length === 0) {
|
|
11662
|
+
if (modalParkedCoordinators.length > 0) {
|
|
11663
|
+
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)`);
|
|
11664
|
+
}
|
|
11665
|
+
continue;
|
|
11666
|
+
}
|
|
11641
11667
|
if (store) {
|
|
11642
11668
|
try {
|
|
11643
11669
|
if (store.pendingEventCount(meshId) === 0) continue;
|
|
@@ -15954,6 +15980,10 @@ ${lastSnapshot}`;
|
|
|
15954
15980
|
if (!this.ptyProcess) throw new Error(`${this.cliName} is not running`);
|
|
15955
15981
|
const content = String(text || "");
|
|
15956
15982
|
if (!content.trim()) return;
|
|
15983
|
+
if (this.engine.currentStatus === "waiting_approval" || this.engine.hasActionableApproval()) {
|
|
15984
|
+
LOG.info("CLI", `[${this.cliType}] force-send held \u2014 session parked on approval modal (status=${this.engine.currentStatus})`);
|
|
15985
|
+
return;
|
|
15986
|
+
}
|
|
15957
15987
|
LOG.info("CLI", `[${this.cliType}] force-sending prompt while status=${this.engine.currentStatus}`);
|
|
15958
15988
|
await this.writeToPty(content + this.sendKey);
|
|
15959
15989
|
this.onStatusChange?.();
|
|
@@ -34858,6 +34888,35 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
34858
34888
|
this.settings = rest;
|
|
34859
34889
|
this.adapter.updateRuntimeSettings?.(this.settings);
|
|
34860
34890
|
}
|
|
34891
|
+
/**
|
|
34892
|
+
* The resolved modal-park status of this session, or null when it is not
|
|
34893
|
+
* parked on a modal awaiting a human answer. Mirrors the overlay logic in
|
|
34894
|
+
* getState(): an active AskUserQuestion interactive prompt resolves to
|
|
34895
|
+
* waiting_choice; otherwise the adapter's waiting_approval (tool consent)
|
|
34896
|
+
* counts — UNLESS auto-approve will dismiss it, in which case the session is
|
|
34897
|
+
* effectively generating and is NOT modal-parked. This is the single signal
|
|
34898
|
+
* the mesh force-inject guard consults, and the same status string the
|
|
34899
|
+
* reconcile loop reads off get_status_metadata. Lowercase literals only —
|
|
34900
|
+
* the SessionStatus enum is forked across modules and waiting_choice is
|
|
34901
|
+
* absent from some of them.
|
|
34902
|
+
*/
|
|
34903
|
+
resolveModalParkStatus() {
|
|
34904
|
+
if (this.activeInteractivePrompt) return "waiting_choice";
|
|
34905
|
+
let adapterStatus;
|
|
34906
|
+
try {
|
|
34907
|
+
adapterStatus = this.adapter.getStatus({ allowParse: false });
|
|
34908
|
+
} catch {
|
|
34909
|
+
return null;
|
|
34910
|
+
}
|
|
34911
|
+
if (adapterStatus.status === "waiting_approval" && !this.shouldAutoApprove()) {
|
|
34912
|
+
return "waiting_approval";
|
|
34913
|
+
}
|
|
34914
|
+
return null;
|
|
34915
|
+
}
|
|
34916
|
+
/** True when this session is parked on a modal awaiting a human answer. */
|
|
34917
|
+
isModalParked() {
|
|
34918
|
+
return this.resolveModalParkStatus() !== null;
|
|
34919
|
+
}
|
|
34861
34920
|
onEvent(event, data) {
|
|
34862
34921
|
if (event === "send_message") {
|
|
34863
34922
|
const input = normalizeInputEnvelope(data);
|
|
@@ -34865,6 +34924,10 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
34865
34924
|
const promptText = buildCliStructuredInputPrompt(input);
|
|
34866
34925
|
if (promptText) {
|
|
34867
34926
|
const force = data?.force === true;
|
|
34927
|
+
if (force && this.isModalParked()) {
|
|
34928
|
+
LOG.info("CLI", `[${this.type}] force send_message held \u2014 coordinator parked on modal (${this.resolveModalParkStatus()})`);
|
|
34929
|
+
return;
|
|
34930
|
+
}
|
|
34868
34931
|
void this.adapter.sendMessage(promptText, force ? { force: true } : {}).catch((e) => {
|
|
34869
34932
|
LOG.warn("CLI", `[${this.type}] send_message failed: ${e?.message || e}`);
|
|
34870
34933
|
});
|
|
@@ -51220,7 +51283,10 @@ var DaemonStatusReporter = class {
|
|
|
51220
51283
|
title: session.title,
|
|
51221
51284
|
cdpConnected: session.cdpConnected,
|
|
51222
51285
|
summaryMetadata: session.summaryMetadata,
|
|
51223
|
-
settings: session.settings
|
|
51286
|
+
settings: session.settings,
|
|
51287
|
+
// Forward surfaceHidden so the server can gate push notifications for
|
|
51288
|
+
// coordinator-hidden sessions (the WS path is the only one the server sees).
|
|
51289
|
+
surfaceHidden: session.surfaceHidden
|
|
51224
51290
|
})),
|
|
51225
51291
|
p2p: payload.p2p,
|
|
51226
51292
|
timestamp: now
|