@adhdev/daemon-core 0.9.82-rc.465 → 0.9.82-rc.466
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 +149 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +149 -10
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-events-pending.d.ts +8 -0
- package/dist/mesh/mesh-runtime-store.d.ts +26 -0
- package/dist/providers/cli-provider-instance.d.ts +40 -0
- package/package.json +3 -3
- package/src/mesh/mesh-event-forwarding.ts +16 -1
- package/src/mesh/mesh-events-pending.ts +36 -0
- package/src/mesh/mesh-ledger.ts +10 -0
- package/src/mesh/mesh-runtime-store.ts +53 -0
- package/src/providers/cli-provider-instance.ts +116 -3
package/dist/index.mjs
CHANGED
|
@@ -404,10 +404,10 @@ function readInjected(value) {
|
|
|
404
404
|
}
|
|
405
405
|
function getDaemonBuildInfo() {
|
|
406
406
|
if (cached) return cached;
|
|
407
|
-
const commit = readInjected(true ? "
|
|
408
|
-
const commitShort = readInjected(true ? "
|
|
409
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
410
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
407
|
+
const commit = readInjected(true ? "e0f04b7d54855e0f0d5ed4200078d95596ab9f6f" : void 0) ?? "unknown";
|
|
408
|
+
const commitShort = readInjected(true ? "e0f04b7d" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
409
|
+
const version = readInjected(true ? "0.9.82-rc.466" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
410
|
+
const builtAt = readInjected(true ? "2026-07-05T08:18:54.364Z" : void 0);
|
|
411
411
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
412
412
|
return cached;
|
|
413
413
|
}
|
|
@@ -5144,7 +5144,8 @@ var init_mesh_ledger = __esm({
|
|
|
5144
5144
|
"task_completed",
|
|
5145
5145
|
"task_failed",
|
|
5146
5146
|
"task_stalled",
|
|
5147
|
-
"recovery_attempted"
|
|
5147
|
+
"recovery_attempted",
|
|
5148
|
+
"session_auto_launch"
|
|
5148
5149
|
]);
|
|
5149
5150
|
DEFAULT_LEDGER_SLICE_LIMIT = 100;
|
|
5150
5151
|
MAX_LEDGER_SLICE_LIMIT = 500;
|
|
@@ -7337,6 +7338,10 @@ var init_mesh_runtime_store = __esm({
|
|
|
7337
7338
|
}
|
|
7338
7339
|
// ── G2: Event Ledger ────────────────────────────────────────────────────
|
|
7339
7340
|
appendLedgerEntry(entry) {
|
|
7341
|
+
if (!entry.kind || !String(entry.kind).trim()) {
|
|
7342
|
+
LOG.warn("MeshRuntimeStore", `Refusing to append ledger entry with empty kind for mesh ${entry.meshId} (id ${entry.id})`);
|
|
7343
|
+
return;
|
|
7344
|
+
}
|
|
7340
7345
|
this.db.prepare(
|
|
7341
7346
|
`INSERT OR IGNORE INTO mesh_event_ledger
|
|
7342
7347
|
(id, mesh_id, timestamp, kind, node_id, session_id, provider_type, payload)
|
|
@@ -7471,6 +7476,7 @@ var init_mesh_runtime_store = __esm({
|
|
|
7471
7476
|
);
|
|
7472
7477
|
this.db.transaction(() => {
|
|
7473
7478
|
for (const e of entries) {
|
|
7479
|
+
if (!e.kind || !String(e.kind).trim()) continue;
|
|
7474
7480
|
const result = stmt.run(
|
|
7475
7481
|
e.id,
|
|
7476
7482
|
e.meshId,
|
|
@@ -7765,6 +7771,41 @@ var init_mesh_runtime_store = __esm({
|
|
|
7765
7771
|
`DELETE FROM mesh_pending_events WHERE id IN (${idList.map(() => "?").join(",")})`
|
|
7766
7772
|
).run(...idList).changes;
|
|
7767
7773
|
}
|
|
7774
|
+
/**
|
|
7775
|
+
* Retention prune for mesh_pending_events. This table has no lifecycle GC of its
|
|
7776
|
+
* own: a drained row is soft-marked (drained=1) and RETAINED — deliberately, so
|
|
7777
|
+
* drainedEventIdsForMesh() has a durable v2-eventId dedup baseline — and an
|
|
7778
|
+
* undrained row queued for a coordinator that never returned (a dead/evicted
|
|
7779
|
+
* coordinator identity) stays drained=0 forever. Both accumulate without bound
|
|
7780
|
+
* (observed: tens of thousands of rows, mostly stale). This is the missing
|
|
7781
|
+
* retention step. Two independent windows:
|
|
7782
|
+
*
|
|
7783
|
+
* - drained rows older than `drainedOlderThanMs`: the coordinator consumed them
|
|
7784
|
+
* long ago; the only thing they still back is the eventId re-delivery guard,
|
|
7785
|
+
* which is only meaningful for the recent past (a re-delivery of a week-old
|
|
7786
|
+
* event cannot occur — its producer session is long gone). Safe to delete.
|
|
7787
|
+
* - UNDRAINED rows older than `undrainedOlderThanMs` (a much wider window):
|
|
7788
|
+
* these are orphaned events for a coordinator identity that never drained
|
|
7789
|
+
* them. Kept wide so a genuinely-offline-but-returning coordinator still
|
|
7790
|
+
* receives its backlog; only genuinely unrecoverable orphans are swept.
|
|
7791
|
+
*
|
|
7792
|
+
* Both windows key off `queued_at` (always present) — `drained_at` can be NULL on
|
|
7793
|
+
* legacy rows. Returns the number of rows deleted. Best-effort / idempotent:
|
|
7794
|
+
* running it repeatedly with nothing to prune is a cheap no-op.
|
|
7795
|
+
*/
|
|
7796
|
+
prunePendingEvents(opts) {
|
|
7797
|
+
const now = Date.now();
|
|
7798
|
+
const drainedCutoff = now - Math.max(0, opts.drainedOlderThanMs);
|
|
7799
|
+
const undrainedCutoff = now - Math.max(0, opts.undrainedOlderThanMs);
|
|
7800
|
+
let removed = 0;
|
|
7801
|
+
removed += this.db.prepare(
|
|
7802
|
+
"DELETE FROM mesh_pending_events WHERE drained = 1 AND queued_at < ?"
|
|
7803
|
+
).run(drainedCutoff).changes;
|
|
7804
|
+
removed += this.db.prepare(
|
|
7805
|
+
"DELETE FROM mesh_pending_events WHERE drained = 0 AND queued_at < ?"
|
|
7806
|
+
).run(undrainedCutoff).changes;
|
|
7807
|
+
return removed;
|
|
7808
|
+
}
|
|
7768
7809
|
};
|
|
7769
7810
|
}
|
|
7770
7811
|
});
|
|
@@ -11764,6 +11805,21 @@ function reconcilePendingMeshCoordinatorEvents(meshId, events) {
|
|
|
11764
11805
|
const reconciled = terminalJobIds.size === 0 ? events : events.filter((event) => !(event.event === "refine:accepted" && terminalJobIds.has(readRefineJobId2(event))));
|
|
11765
11806
|
return backfilled.length === 0 ? reconciled : [...reconciled, ...backfilled];
|
|
11766
11807
|
}
|
|
11808
|
+
function prunePendingMeshCoordinatorEventsRetention() {
|
|
11809
|
+
try {
|
|
11810
|
+
const removed = MeshRuntimeStore.getInstance().prunePendingEvents({
|
|
11811
|
+
drainedOlderThanMs: PENDING_EVENTS_DRAINED_RETENTION_MS,
|
|
11812
|
+
undrainedOlderThanMs: PENDING_EVENTS_UNDRAINED_RETENTION_MS
|
|
11813
|
+
});
|
|
11814
|
+
if (removed > 0) {
|
|
11815
|
+
LOG.info("MeshEvents", `Pruned ${removed} stale pending-event row(s) (drained >7d / undrained >30d)`);
|
|
11816
|
+
}
|
|
11817
|
+
return removed;
|
|
11818
|
+
} catch (e) {
|
|
11819
|
+
LOG.warn("MeshEvents", `Pending-event retention prune failed: ${e?.message || e}`);
|
|
11820
|
+
return 0;
|
|
11821
|
+
}
|
|
11822
|
+
}
|
|
11767
11823
|
function trimPendingEventsIfNeeded(path45) {
|
|
11768
11824
|
try {
|
|
11769
11825
|
if (!existsSync15(path45)) return;
|
|
@@ -12134,7 +12190,7 @@ function clearPendingMeshCoordinatorEvents(meshId, coordinatorDaemonId) {
|
|
|
12134
12190
|
}
|
|
12135
12191
|
}
|
|
12136
12192
|
}
|
|
12137
|
-
var REFINE_TERMINAL_EVENTS, meshV2DrainCounters, warnedV2Violations, TERMINAL_COMPLETION_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP;
|
|
12193
|
+
var REFINE_TERMINAL_EVENTS, meshV2DrainCounters, warnedV2Violations, TERMINAL_COMPLETION_EVENTS, MAX_PENDING_EVENTS_BYTES, MAX_PENDING_EVENTS_KEEP, PENDING_EVENTS_DRAINED_RETENTION_MS, PENDING_EVENTS_UNDRAINED_RETENTION_MS;
|
|
12138
12194
|
var init_mesh_events_pending = __esm({
|
|
12139
12195
|
"src/mesh/mesh-events-pending.ts"() {
|
|
12140
12196
|
"use strict";
|
|
@@ -12175,6 +12231,8 @@ var init_mesh_events_pending = __esm({
|
|
|
12175
12231
|
TERMINAL_COMPLETION_EVENTS = /* @__PURE__ */ new Set(["agent:generating_completed", "agent:stopped"]);
|
|
12176
12232
|
MAX_PENDING_EVENTS_BYTES = 100 * 1024;
|
|
12177
12233
|
MAX_PENDING_EVENTS_KEEP = 50;
|
|
12234
|
+
PENDING_EVENTS_DRAINED_RETENTION_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
12235
|
+
PENDING_EVENTS_UNDRAINED_RETENTION_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
12178
12236
|
}
|
|
12179
12237
|
});
|
|
12180
12238
|
|
|
@@ -17235,6 +17293,11 @@ function sweepExpiredRemoteIdleSessions() {
|
|
|
17235
17293
|
MeshRuntimeStore.getInstance().pruneExpiredRemoteIdleSessions();
|
|
17236
17294
|
} catch {
|
|
17237
17295
|
}
|
|
17296
|
+
const now = Date.now();
|
|
17297
|
+
if (now - lastPendingEventsPruneAt >= PENDING_EVENTS_PRUNE_INTERVAL_MS) {
|
|
17298
|
+
lastPendingEventsPruneAt = now;
|
|
17299
|
+
prunePendingMeshCoordinatorEventsRetention();
|
|
17300
|
+
}
|
|
17238
17301
|
}
|
|
17239
17302
|
function isIntentionalCleanupStopMetadata(event) {
|
|
17240
17303
|
return event.intentional === true || event.intentionalStop === true || event.operatorCleanup === true || event.reason === "operator_cleanup" || event.stopReason === "operator_cleanup" || event.cleanupReason === "operator_cleanup" || event.source === "mesh_cleanup_sessions" || event.source === "mesh_remove_node";
|
|
@@ -18293,7 +18356,7 @@ function setupMeshEventForwarding(components) {
|
|
|
18293
18356
|
flushPendingForMeshIdleCoordinators(components, routing.meshId);
|
|
18294
18357
|
});
|
|
18295
18358
|
}
|
|
18296
|
-
var REMOTE_IDLE_SESSION_TTL_MS, meshByWorkspaceCache, MESH_WORKSPACE_CACHE_TTL_MS, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, RECONCILED_COMPLETION_SOURCES, coordinatorForwardLanes;
|
|
18359
|
+
var REMOTE_IDLE_SESSION_TTL_MS, meshByWorkspaceCache, MESH_WORKSPACE_CACHE_TTL_MS, lastPendingEventsPruneAt, PENDING_EVENTS_PRUNE_INTERVAL_MS, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, RECONCILED_COMPLETION_SOURCES, coordinatorForwardLanes;
|
|
18297
18360
|
var init_mesh_event_forwarding = __esm({
|
|
18298
18361
|
"src/mesh/mesh-event-forwarding.ts"() {
|
|
18299
18362
|
"use strict";
|
|
@@ -18320,6 +18383,8 @@ var init_mesh_event_forwarding = __esm({
|
|
|
18320
18383
|
REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
|
|
18321
18384
|
meshByWorkspaceCache = /* @__PURE__ */ new Map();
|
|
18322
18385
|
MESH_WORKSPACE_CACHE_TTL_MS = 5e3;
|
|
18386
|
+
lastPendingEventsPruneAt = 0;
|
|
18387
|
+
PENDING_EVENTS_PRUNE_INTERVAL_MS = 60 * 60 * 1e3;
|
|
18323
18388
|
INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS = 30 * 60 * 1e3;
|
|
18324
18389
|
RECENT_COMPLETION_FINGERPRINT_TTL_MS = 10 * 60 * 1e3;
|
|
18325
18390
|
RECONCILED_COMPLETION_SOURCES = /* @__PURE__ */ new Set([
|
|
@@ -42299,6 +42364,33 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
42299
42364
|
* from scratch rather than firing on a stale timestamp.
|
|
42300
42365
|
*/
|
|
42301
42366
|
static AUTO_APPROVE_GATE_HYSTERESIS_MS = 1500;
|
|
42367
|
+
/**
|
|
42368
|
+
* AUTOAPPROVE-FLAP-RECUR (Fix B): extended busy-side continuity window for a
|
|
42369
|
+
* DELEGATED-WORKER auto-approve episode that is genuinely still cycling.
|
|
42370
|
+
*
|
|
42371
|
+
* The default AUTO_APPROVE_GATE_HYSTERESIS_MS (1500) absorbs a *momentary*
|
|
42372
|
+
* `generating` blip. But a delegated worker running a Bash approval observed
|
|
42373
|
+
* the FSM cycle the FULL state waiting_approval → busy → waiting_approval on a
|
|
42374
|
+
* 2–5s period (the button set scrolls in/out AND the modal question repaints,
|
|
42375
|
+
* so the adapter genuinely reports status=generating for whole seconds between
|
|
42376
|
+
* approval frames). Each busy phase outran the 1500ms hysteresis, so the
|
|
42377
|
+
* settle clock was WIPED (the genuine-resolution branch), the 600ms settle
|
|
42378
|
+
* window never accumulated across the flap, resolveModal never fired
|
|
42379
|
+
* (resolveModal count 0), and the mask-stall clock instead tripped at 4500ms →
|
|
42380
|
+
* coordinator nudge → the flap the coordinator observed.
|
|
42381
|
+
*
|
|
42382
|
+
* A genuine resolution and a flap both start with a busy phase; they diverge
|
|
42383
|
+
* only in whether waiting_approval RETURNS. So we cannot simply lengthen the
|
|
42384
|
+
* blanket hysteresis (that would make every real resolution hold the gate
|
|
42385
|
+
* open for seconds). Instead this longer window applies ONLY while an active
|
|
42386
|
+
* mask episode is alive (autoApproveMaskSince > 0) AND the session is a
|
|
42387
|
+
* delegated worker — i.e. exactly the never-resolving-flap case. A foreground
|
|
42388
|
+
* / attended session keeps the tight 1500ms window unchanged. The mask-stall
|
|
42389
|
+
* bound below still caps the episode, so a worker whose approval truly never
|
|
42390
|
+
* returns is surfaced to the coordinator within AUTO_APPROVE_MASK_STALL_MS
|
|
42391
|
+
* rather than held forever.
|
|
42392
|
+
*/
|
|
42393
|
+
static AUTO_APPROVE_FLAP_CONTINUITY_MS = 4e3;
|
|
42302
42394
|
/**
|
|
42303
42395
|
* STATUS-MISMATCH: upper bound on how long the auto-approve→`generating` SURFACE
|
|
42304
42396
|
* mask may hide a worker's `waiting_approval` (status + activeModal) before we give
|
|
@@ -42373,9 +42465,22 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
42373
42465
|
pendingAutoApprovalSince = 0;
|
|
42374
42466
|
autoApproveSettleTimer = null;
|
|
42375
42467
|
// Wall-clock when auto-approve first observed status!=waiting_approval while
|
|
42376
|
-
// a settle gate was in progress. Drives AUTO_APPROVE_GATE_HYSTERESIS_MS
|
|
42468
|
+
// a settle gate was in progress. Drives AUTO_APPROVE_GATE_HYSTERESIS_MS (or,
|
|
42469
|
+
// for a delegated-worker flap episode, AUTO_APPROVE_FLAP_CONTINUITY_MS) so a
|
|
42377
42470
|
// brief generating flip does not immediately wipe the settle clock.
|
|
42378
42471
|
autoApproveInactiveSince = 0;
|
|
42472
|
+
// AUTOAPPROVE-FLAP-RECUR (Fix A): wall-clock when the CURRENT waiting_approval
|
|
42473
|
+
// episode last presented a concrete, captured modal (buttons.length > 0). The
|
|
42474
|
+
// Claude TUI momentarily reports status=waiting_approval with activeModal=null
|
|
42475
|
+
// / an empty button block while the button block scrolls out of the captured
|
|
42476
|
+
// frame; the raw guard below (buttons.length===0) used to bail on that frame,
|
|
42477
|
+
// never advancing the settle gate and leaving no re-check armed — so a modal
|
|
42478
|
+
// that flapped modal=none ↔ N-buttons around the settle boundary never
|
|
42479
|
+
// accumulated its 600ms. This tracks the last GOOD-modal frame so a short
|
|
42480
|
+
// scroll-out blip is absorbed (settle keeps running against the last captured
|
|
42481
|
+
// signature) while a genuinely closed modal — buttons empty continuously past
|
|
42482
|
+
// the continuity window — is still recognised and resets the gate.
|
|
42483
|
+
autoApproveLastModalSeenAt = 0;
|
|
42379
42484
|
// STATUS-MISMATCH: wall-clock when the CURRENT auto-approve episode (waiting_approval
|
|
42380
42485
|
// + shouldAutoApprove) first began wanting to mask. Unlike pendingAutoApprovalSince it
|
|
42381
42486
|
// is NOT reset when the modal signature changes (a still-streaming/flapping prompt) and
|
|
@@ -43338,6 +43443,20 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
43338
43443
|
isMeshWorkerSession() {
|
|
43339
43444
|
return !!(this.settings.meshNodeFor || this.settings.meshActiveTaskId || this.settings.meshNodeId || this.settings.launchedByCoordinator);
|
|
43340
43445
|
}
|
|
43446
|
+
/**
|
|
43447
|
+
* AUTOAPPROVE-FLAP-RECUR (Fix A+B): how long a busy blip / modal scroll-out may
|
|
43448
|
+
* persist before the in-progress settle gate is torn down. For a delegated
|
|
43449
|
+
* worker whose auto-approve episode is genuinely still cycling (mask clock
|
|
43450
|
+
* alive), the FSM's full waiting_approval → busy → waiting_approval flap runs
|
|
43451
|
+
* on a multi-second period, so the settle continuity window is extended to
|
|
43452
|
+
* AUTO_APPROVE_FLAP_CONTINUITY_MS to bridge it (still bounded, and still capped
|
|
43453
|
+
* by AUTO_APPROVE_MASK_STALL_MS). Every other case — foreground/attended
|
|
43454
|
+
* session, or no active mask episode — keeps the tight default hysteresis so a
|
|
43455
|
+
* genuine resolution frees the gate promptly.
|
|
43456
|
+
*/
|
|
43457
|
+
autoApproveContinuityWindowMs() {
|
|
43458
|
+
return this.autoApproveMaskSince > 0 && this.isMeshWorkerSession() ? _CliProviderInstance.AUTO_APPROVE_FLAP_CONTINUITY_MS : _CliProviderInstance.AUTO_APPROVE_GATE_HYSTERESIS_MS;
|
|
43459
|
+
}
|
|
43341
43460
|
// FALSE-IDLE (self-coordinator settle): an autonomously-progressing mesh session
|
|
43342
43461
|
// is either a delegated worker (isMeshWorkerSession) OR the coordinator's OWN
|
|
43343
43462
|
// claude-cli session (meshCoordinatorFor). Both run auto-approved tool turns whose
|
|
@@ -43573,6 +43692,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
43573
43692
|
this.autoApproveInactiveSince = 0;
|
|
43574
43693
|
this.autoApproveMaskSince = 0;
|
|
43575
43694
|
this.stalledApprovalNudgeEpisode = 0;
|
|
43695
|
+
this.autoApproveLastModalSeenAt = 0;
|
|
43576
43696
|
if (this.autoApproveSettleTimer) clearTimeout(this.autoApproveSettleTimer);
|
|
43577
43697
|
this.autoApproveSettleTimer = setTimeout(() => {
|
|
43578
43698
|
this.autoApproveSettleTimer = null;
|
|
@@ -43586,12 +43706,13 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
43586
43706
|
if (this.pendingAutoApprovalSince) {
|
|
43587
43707
|
if (!this.autoApproveInactiveSince) this.autoApproveInactiveSince = now;
|
|
43588
43708
|
const goneForMs = now - this.autoApproveInactiveSince;
|
|
43589
|
-
|
|
43709
|
+
const continuityMs = this.autoApproveContinuityWindowMs();
|
|
43710
|
+
if (goneForMs < continuityMs) {
|
|
43590
43711
|
if (this.autoApproveSettleTimer) clearTimeout(this.autoApproveSettleTimer);
|
|
43591
43712
|
this.autoApproveSettleTimer = setTimeout(() => {
|
|
43592
43713
|
this.autoApproveSettleTimer = null;
|
|
43593
43714
|
this.recheckAutoApproveSettled();
|
|
43594
|
-
},
|
|
43715
|
+
}, continuityMs - goneForMs + 20);
|
|
43595
43716
|
return autoApproveActive;
|
|
43596
43717
|
}
|
|
43597
43718
|
}
|
|
@@ -43600,6 +43721,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
43600
43721
|
this.autoApproveInactiveSince = 0;
|
|
43601
43722
|
this.autoApproveMaskSince = 0;
|
|
43602
43723
|
this.stalledApprovalNudgeEpisode = 0;
|
|
43724
|
+
this.autoApproveLastModalSeenAt = 0;
|
|
43603
43725
|
if (this.autoApproveSettleTimer) {
|
|
43604
43726
|
clearTimeout(this.autoApproveSettleTimer);
|
|
43605
43727
|
this.autoApproveSettleTimer = null;
|
|
@@ -43612,8 +43734,22 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
43612
43734
|
const modal = adapterStatus.activeModal;
|
|
43613
43735
|
const buttons = Array.isArray(modal?.buttons) ? modal.buttons.map((b) => String(b || "").trim()).filter(Boolean) : [];
|
|
43614
43736
|
if (!modal || buttons.length === 0) {
|
|
43737
|
+
const blipForMs = this.autoApproveLastModalSeenAt ? now - this.autoApproveLastModalSeenAt : Infinity;
|
|
43738
|
+
if (this.pendingAutoApprovalSince && blipForMs < this.autoApproveContinuityWindowMs()) {
|
|
43739
|
+
if (this.autoApproveSettleTimer) clearTimeout(this.autoApproveSettleTimer);
|
|
43740
|
+
this.autoApproveSettleTimer = setTimeout(() => {
|
|
43741
|
+
this.autoApproveSettleTimer = null;
|
|
43742
|
+
this.recheckAutoApproveSettled();
|
|
43743
|
+
}, this.autoApproveContinuityWindowMs() - blipForMs + 20);
|
|
43744
|
+
return autoApproveActive;
|
|
43745
|
+
}
|
|
43746
|
+
if (blipForMs >= this.autoApproveContinuityWindowMs()) {
|
|
43747
|
+
this.pendingAutoApprovalSignature = "";
|
|
43748
|
+
this.pendingAutoApprovalSince = 0;
|
|
43749
|
+
}
|
|
43615
43750
|
return autoApproveActive;
|
|
43616
43751
|
}
|
|
43752
|
+
this.autoApproveLastModalSeenAt = now;
|
|
43617
43753
|
const modalKind = typeof modal?.kind === "string" ? modal.kind : "approval";
|
|
43618
43754
|
if (modalKind !== "approval") {
|
|
43619
43755
|
return autoApproveActive;
|
|
@@ -43657,6 +43793,7 @@ var CliProviderInstance = class _CliProviderInstance {
|
|
|
43657
43793
|
this.autoApproveInactiveSince = 0;
|
|
43658
43794
|
this.autoApproveMaskSince = 0;
|
|
43659
43795
|
this.stalledApprovalNudgeEpisode = 0;
|
|
43796
|
+
this.autoApproveLastModalSeenAt = 0;
|
|
43660
43797
|
if (this.autoApproveBusyTimer) clearTimeout(this.autoApproveBusyTimer);
|
|
43661
43798
|
this.autoApproveBusyTimer = setTimeout(() => {
|
|
43662
43799
|
this.autoApproveBusy = false;
|
|
@@ -44302,6 +44439,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
44302
44439
|
if (!this.isMeshWorkerSession()) return;
|
|
44303
44440
|
if (adapterStatus?.status !== "waiting_approval") return;
|
|
44304
44441
|
if (!this.autoApproveMaskStalled(now)) return;
|
|
44442
|
+
const modalButtons = Array.isArray(adapterStatus.activeModal?.buttons) ? adapterStatus.activeModal.buttons.map((b) => String(b || "").trim()).filter(Boolean) : [];
|
|
44443
|
+
if (this.pendingAutoApprovalSince && modalButtons.length > 0) return;
|
|
44305
44444
|
if (this.stalledApprovalNudgeEpisode === this.autoApproveMaskSince) return;
|
|
44306
44445
|
this.stalledApprovalNudgeEpisode = this.autoApproveMaskSince;
|
|
44307
44446
|
const modal = adapterStatus.activeModal;
|