@adhdev/daemon-core 0.9.82-rc.195 → 0.9.82-rc.196
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/cli-adapter-types.d.ts +1 -0
- package/dist/index.js +202 -70
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +205 -73
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/contracts.d.ts +1 -1
- package/dist/mesh/mesh-active-work.d.ts +1 -1
- package/dist/mesh/{beads-db.d.ts → mesh-runtime-store.d.ts} +2 -2
- package/dist/mesh/mesh-work-queue.d.ts +3 -3
- package/dist/providers/provider-instance.d.ts +1 -1
- package/dist/providers/spec/driver.d.ts +4 -1
- package/dist/providers/spec/schema.gen.d.ts +46 -0
- package/dist/providers/spec/types.d.ts +39 -0
- package/dist/shared-types-extra.d.ts +1 -1
- package/dist/status/normalize.d.ts +1 -1
- package/dist/status/normalize.js +1 -0
- package/dist/status/normalize.js.map +1 -1
- package/dist/status/normalize.mjs +1 -0
- package/dist/status/normalize.mjs.map +1 -1
- package/package.json +1 -1
- package/src/cli-adapter-types.ts +1 -0
- package/src/cli-adapters/cli-state-engine.ts +44 -2
- package/src/mesh/contracts.ts +1 -1
- package/src/mesh/mesh-active-work.ts +8 -8
- package/src/mesh/mesh-events.ts +12 -12
- package/src/mesh/{beads-db.ts → mesh-runtime-store.ts} +30 -7
- package/src/mesh/mesh-work-queue.ts +33 -33
- package/src/providers/cli-provider-instance.ts +31 -8
- package/src/providers/provider-instance.ts +1 -1
- package/src/providers/spec/driver.ts +34 -3
- package/src/providers/spec/evaluator.ts +32 -3
- package/src/providers/spec/schema.gen.ts +22 -2
- package/src/providers/spec/schema.json +1 -0
- package/src/providers/spec/types.ts +39 -0
- package/src/providers/types/interactive-prompt.ts +21 -7
- package/src/shared-types-extra.ts +1 -1
- package/src/status/normalize.ts +2 -0
package/dist/index.mjs
CHANGED
|
@@ -3290,8 +3290,8 @@ var init_mesh_fast_forward = __esm({
|
|
|
3290
3290
|
}
|
|
3291
3291
|
});
|
|
3292
3292
|
|
|
3293
|
-
// src/mesh/
|
|
3294
|
-
import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync9, statSync as statSync4 } from "fs";
|
|
3293
|
+
// src/mesh/mesh-runtime-store.ts
|
|
3294
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync9, renameSync as renameSync3, statSync as statSync4 } from "fs";
|
|
3295
3295
|
import { dirname as dirname2, join as join12 } from "path";
|
|
3296
3296
|
import { createRequire } from "module";
|
|
3297
3297
|
function loadDatabaseCtor() {
|
|
@@ -3306,13 +3306,31 @@ function safeMeshId(meshId) {
|
|
|
3306
3306
|
function legacyQueuePath(meshId) {
|
|
3307
3307
|
return join12(getLedgerDir(), `${safeMeshId(meshId)}.queue.json`);
|
|
3308
3308
|
}
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
"
|
|
3309
|
+
function meshRuntimeStorePath() {
|
|
3310
|
+
const dir = getLedgerDir();
|
|
3311
|
+
const nextPath = join12(dir, "mesh-runtime.db");
|
|
3312
|
+
if (existsSync11(nextPath)) return nextPath;
|
|
3313
|
+
const legacyPath = join12(dir, "beads.db");
|
|
3314
|
+
if (!existsSync11(legacyPath)) return nextPath;
|
|
3315
|
+
try {
|
|
3316
|
+
renameSync3(legacyPath, nextPath);
|
|
3317
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
3318
|
+
const legacyCompanion = `${legacyPath}${suffix}`;
|
|
3319
|
+
if (existsSync11(legacyCompanion)) {
|
|
3320
|
+
renameSync3(legacyCompanion, `${nextPath}${suffix}`);
|
|
3321
|
+
}
|
|
3322
|
+
}
|
|
3323
|
+
} catch {
|
|
3324
|
+
}
|
|
3325
|
+
return nextPath;
|
|
3326
|
+
}
|
|
3327
|
+
var DatabaseCtor, MeshRuntimeStore;
|
|
3328
|
+
var init_mesh_runtime_store = __esm({
|
|
3329
|
+
"src/mesh/mesh-runtime-store.ts"() {
|
|
3312
3330
|
"use strict";
|
|
3313
3331
|
init_mesh_ledger();
|
|
3314
3332
|
init_mesh_work_queue();
|
|
3315
|
-
|
|
3333
|
+
MeshRuntimeStore = class _MeshRuntimeStore {
|
|
3316
3334
|
static instance;
|
|
3317
3335
|
db;
|
|
3318
3336
|
dbPath;
|
|
@@ -3335,7 +3353,7 @@ var init_beads_db = __esm({
|
|
|
3335
3353
|
}
|
|
3336
3354
|
static getInstance() {
|
|
3337
3355
|
if (!this.instance) {
|
|
3338
|
-
this.instance = new
|
|
3356
|
+
this.instance = new _MeshRuntimeStore(meshRuntimeStorePath());
|
|
3339
3357
|
}
|
|
3340
3358
|
return this.instance;
|
|
3341
3359
|
}
|
|
@@ -3420,13 +3438,13 @@ var init_beads_db = __esm({
|
|
|
3420
3438
|
this.db.prepare("DELETE FROM mesh_completion_fingerprints WHERE expires_at <= ?").run(Date.now());
|
|
3421
3439
|
}
|
|
3422
3440
|
maybeCheckpointWal() {
|
|
3423
|
-
if (++this.walWriteCounter <
|
|
3441
|
+
if (++this.walWriteCounter < _MeshRuntimeStore.WAL_CHECK_INTERVAL) return;
|
|
3424
3442
|
this.walWriteCounter = 0;
|
|
3425
3443
|
try {
|
|
3426
3444
|
const walPath = `${this.dbPath}-wal`;
|
|
3427
3445
|
if (!existsSync11(walPath)) return;
|
|
3428
3446
|
const size = statSync4(walPath).size;
|
|
3429
|
-
if (size <
|
|
3447
|
+
if (size < _MeshRuntimeStore.WAL_MAX_BYTES) return;
|
|
3430
3448
|
process.stderr.write(
|
|
3431
3449
|
`[adhdev-mesh] WAL file ${Math.round(size / 1024 / 1024)}MB exceeds threshold; forcing checkpoint
|
|
3432
3450
|
`
|
|
@@ -3737,7 +3755,7 @@ __export(mesh_work_queue_exports, {
|
|
|
3737
3755
|
__clearDirectDispatchesForTests: () => __clearDirectDispatchesForTests,
|
|
3738
3756
|
__clearMeshQueueForTests: () => __clearMeshQueueForTests,
|
|
3739
3757
|
__replaceMeshQueueForTests: () => __replaceMeshQueueForTests,
|
|
3740
|
-
|
|
3758
|
+
__resetMeshRuntimeStoreForTests: () => __resetMeshRuntimeStoreForTests,
|
|
3741
3759
|
buildMeshNodeCapabilityTags: () => buildMeshNodeCapabilityTags,
|
|
3742
3760
|
cancelTask: () => cancelTask,
|
|
3743
3761
|
claimNextTask: () => claimNextTask,
|
|
@@ -3816,7 +3834,7 @@ function nodeSatisfiesRequiredTags(requiredTags, capabilityTags) {
|
|
|
3816
3834
|
return required.every((tag) => available.has(tag));
|
|
3817
3835
|
}
|
|
3818
3836
|
function withQueueLock(_meshId, fn) {
|
|
3819
|
-
return
|
|
3837
|
+
return MeshRuntimeStore.getInstance().transaction(fn);
|
|
3820
3838
|
}
|
|
3821
3839
|
function enqueueTask(meshId, message, opts) {
|
|
3822
3840
|
requireMeshHostQueueOwner(opts);
|
|
@@ -3836,55 +3854,55 @@ function enqueueTask(meshId, message, opts) {
|
|
|
3836
3854
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3837
3855
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3838
3856
|
};
|
|
3839
|
-
|
|
3857
|
+
MeshRuntimeStore.getInstance().insertQueueEntry(entry);
|
|
3840
3858
|
return entry;
|
|
3841
3859
|
}
|
|
3842
3860
|
function getQueue(meshId, opts) {
|
|
3843
|
-
return
|
|
3861
|
+
return MeshRuntimeStore.getInstance().getQueueEntries(meshId, opts?.status?.length ? opts.status : void 0);
|
|
3844
3862
|
}
|
|
3845
3863
|
function getMeshQueueRevision(meshId) {
|
|
3846
|
-
return
|
|
3864
|
+
return MeshRuntimeStore.getInstance().getQueueRevision(meshId);
|
|
3847
3865
|
}
|
|
3848
3866
|
function claimNextTask(meshId, nodeId, sessionId, capabilityTags) {
|
|
3849
|
-
return
|
|
3867
|
+
return MeshRuntimeStore.getInstance().claimNextQueueTask(meshId, nodeId, sessionId, capabilityTags);
|
|
3850
3868
|
}
|
|
3851
3869
|
function updateTaskStatus(meshId, taskId, status, opts) {
|
|
3852
3870
|
requireMeshHostQueueOwner(opts);
|
|
3853
3871
|
return withQueueLock(meshId, () => {
|
|
3854
|
-
const entry =
|
|
3872
|
+
const entry = MeshRuntimeStore.getInstance().findQueueEntryById(meshId, taskId);
|
|
3855
3873
|
if (!entry) return null;
|
|
3856
3874
|
entry.status = status;
|
|
3857
|
-
|
|
3875
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
3858
3876
|
return entry;
|
|
3859
3877
|
});
|
|
3860
3878
|
}
|
|
3861
3879
|
function recordTaskAutoLaunch(meshId, taskId, autoLaunch) {
|
|
3862
3880
|
return withQueueLock(meshId, () => {
|
|
3863
|
-
const entry =
|
|
3881
|
+
const entry = MeshRuntimeStore.getInstance().findQueueEntryById(meshId, taskId);
|
|
3864
3882
|
if (!entry) return null;
|
|
3865
3883
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3866
3884
|
entry.autoLaunch = { ...autoLaunch, updatedAt: now };
|
|
3867
|
-
|
|
3885
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
3868
3886
|
return entry;
|
|
3869
3887
|
});
|
|
3870
3888
|
}
|
|
3871
3889
|
function cancelTask(meshId, taskId, opts) {
|
|
3872
3890
|
requireMeshHostQueueOwner(opts);
|
|
3873
3891
|
return withQueueLock(meshId, () => {
|
|
3874
|
-
const entry =
|
|
3892
|
+
const entry = MeshRuntimeStore.getInstance().findQueueEntryById(meshId, taskId);
|
|
3875
3893
|
if (!entry) return null;
|
|
3876
3894
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3877
3895
|
entry.status = "cancelled";
|
|
3878
3896
|
entry.cancelledAt = now;
|
|
3879
3897
|
if (opts?.reason) entry.cancelReason = opts.reason;
|
|
3880
|
-
|
|
3898
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
3881
3899
|
return entry;
|
|
3882
3900
|
});
|
|
3883
3901
|
}
|
|
3884
3902
|
function requeueTask(meshId, taskId, opts) {
|
|
3885
3903
|
requireMeshHostQueueOwner(opts);
|
|
3886
3904
|
return withQueueLock(meshId, () => {
|
|
3887
|
-
const entry =
|
|
3905
|
+
const entry = MeshRuntimeStore.getInstance().findQueueEntryById(meshId, taskId);
|
|
3888
3906
|
if (!entry) return null;
|
|
3889
3907
|
entry.status = "pending";
|
|
3890
3908
|
delete entry.assignedNodeId;
|
|
@@ -3898,22 +3916,22 @@ function requeueTask(meshId, taskId, opts) {
|
|
|
3898
3916
|
entry.requeuedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
3899
3917
|
entry.requeueCount = (entry.requeueCount || 0) + 1;
|
|
3900
3918
|
if (opts?.reason) entry.requeueReason = opts.reason;
|
|
3901
|
-
|
|
3919
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
3902
3920
|
return entry;
|
|
3903
3921
|
});
|
|
3904
3922
|
}
|
|
3905
3923
|
function updateSessionTaskStatus(meshId, sessionId, status, opts) {
|
|
3906
3924
|
return withQueueLock(meshId, () => {
|
|
3907
3925
|
const occurredAtIso = opts?.occurredAt ? new Date(opts.occurredAt).toISOString() : void 0;
|
|
3908
|
-
const entry =
|
|
3926
|
+
const entry = MeshRuntimeStore.getInstance().findAssignedBySession(meshId, sessionId, occurredAtIso);
|
|
3909
3927
|
if (!entry) return null;
|
|
3910
3928
|
entry.status = status;
|
|
3911
|
-
|
|
3929
|
+
MeshRuntimeStore.getInstance().updateQueueEntry(entry);
|
|
3912
3930
|
return entry;
|
|
3913
3931
|
});
|
|
3914
3932
|
}
|
|
3915
3933
|
function getMeshQueueStats(meshId) {
|
|
3916
|
-
const rows =
|
|
3934
|
+
const rows = MeshRuntimeStore.getInstance().getQueueStatsByStatus(meshId);
|
|
3917
3935
|
const counts = {};
|
|
3918
3936
|
for (const r of rows) counts[r.status] = r.count;
|
|
3919
3937
|
const pending = counts["pending"] ?? 0;
|
|
@@ -3932,26 +3950,26 @@ function getMeshQueueStats(meshId) {
|
|
|
3932
3950
|
cancelled,
|
|
3933
3951
|
activeCounts: { pending, assigned },
|
|
3934
3952
|
historicalCounts: { completed, failed, cancelled },
|
|
3935
|
-
activeAssignments:
|
|
3953
|
+
activeAssignments: MeshRuntimeStore.getInstance().getActiveAssignmentDetails(meshId)
|
|
3936
3954
|
};
|
|
3937
3955
|
}
|
|
3938
3956
|
function __replaceMeshQueueForTests(meshId, queue) {
|
|
3939
|
-
|
|
3940
|
-
|
|
3957
|
+
MeshRuntimeStore.getInstance().transaction(() => {
|
|
3958
|
+
MeshRuntimeStore.getInstance().replaceQueue(meshId, queue);
|
|
3941
3959
|
});
|
|
3942
3960
|
}
|
|
3943
3961
|
function __clearMeshQueueForTests(meshId) {
|
|
3944
|
-
|
|
3962
|
+
MeshRuntimeStore.getInstance().deleteQueue(meshId);
|
|
3945
3963
|
}
|
|
3946
3964
|
function __clearDirectDispatchesForTests(meshId) {
|
|
3947
|
-
|
|
3965
|
+
MeshRuntimeStore.getInstance().deleteDirectDispatches(meshId);
|
|
3948
3966
|
}
|
|
3949
|
-
function
|
|
3950
|
-
|
|
3967
|
+
function __resetMeshRuntimeStoreForTests() {
|
|
3968
|
+
MeshRuntimeStore.resetForTests();
|
|
3951
3969
|
}
|
|
3952
3970
|
function insertDirectDispatch(meshId, data) {
|
|
3953
3971
|
try {
|
|
3954
|
-
|
|
3972
|
+
MeshRuntimeStore.getInstance().insertDirectDispatch({ ...data, meshId });
|
|
3955
3973
|
} catch (e) {
|
|
3956
3974
|
process.stderr.write(`[adhdev-mesh] insertDirectDispatch failed for task ${data.taskId}: ${e?.message || e}
|
|
3957
3975
|
`);
|
|
@@ -3959,26 +3977,26 @@ function insertDirectDispatch(meshId, data) {
|
|
|
3959
3977
|
}
|
|
3960
3978
|
function getActiveDirectDispatches(meshId) {
|
|
3961
3979
|
try {
|
|
3962
|
-
return
|
|
3980
|
+
return MeshRuntimeStore.getInstance().getActiveDirectDispatches(meshId);
|
|
3963
3981
|
} catch {
|
|
3964
3982
|
return [];
|
|
3965
3983
|
}
|
|
3966
3984
|
}
|
|
3967
3985
|
function updateDirectDispatchStatus(meshId, sessionId, status) {
|
|
3968
3986
|
try {
|
|
3969
|
-
|
|
3987
|
+
MeshRuntimeStore.getInstance().updateDirectDispatchStatus(meshId, sessionId, status);
|
|
3970
3988
|
} catch {
|
|
3971
3989
|
}
|
|
3972
3990
|
}
|
|
3973
3991
|
function cleanupTerminalDirectDispatches(olderThanMs = 7 * 24 * 60 * 6e4) {
|
|
3974
3992
|
try {
|
|
3975
|
-
|
|
3993
|
+
MeshRuntimeStore.getInstance().cleanupTerminalDirectDispatches(olderThanMs);
|
|
3976
3994
|
} catch {
|
|
3977
3995
|
}
|
|
3978
3996
|
}
|
|
3979
3997
|
function markStaleDirectDispatches(meshId, olderThanMs = 60 * 6e4) {
|
|
3980
3998
|
try {
|
|
3981
|
-
|
|
3999
|
+
MeshRuntimeStore.getInstance().markStaleDirectDispatches(meshId, olderThanMs);
|
|
3982
4000
|
} catch {
|
|
3983
4001
|
}
|
|
3984
4002
|
}
|
|
@@ -3987,7 +4005,7 @@ var init_mesh_work_queue = __esm({
|
|
|
3987
4005
|
"src/mesh/mesh-work-queue.ts"() {
|
|
3988
4006
|
"use strict";
|
|
3989
4007
|
init_mesh_host_ownership();
|
|
3990
|
-
|
|
4008
|
+
init_mesh_runtime_store();
|
|
3991
4009
|
ACTIVE_MESH_QUEUE_STATUSES = ["pending", "assigned"];
|
|
3992
4010
|
HISTORICAL_MESH_QUEUE_STATUSES = ["completed", "failed", "cancelled"];
|
|
3993
4011
|
MESH_TASK_MODES = ["code_change", "validation", "live_debug_readonly", "launch_app", "convergence"];
|
|
@@ -4151,7 +4169,7 @@ __export(mesh_events_exports, {
|
|
|
4151
4169
|
triggerMeshQueue: () => triggerMeshQueue,
|
|
4152
4170
|
tryAssignQueueTask: () => tryAssignQueueTask
|
|
4153
4171
|
});
|
|
4154
|
-
import { appendFileSync as appendFileSync2, existsSync as existsSync13, readFileSync as readFileSync10, renameSync as
|
|
4172
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync13, readFileSync as readFileSync10, renameSync as renameSync4, statSync as statSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync6 } from "fs";
|
|
4155
4173
|
import { join as join14 } from "path";
|
|
4156
4174
|
function getCachedMeshByWorkspace(workspace) {
|
|
4157
4175
|
const now = Date.now();
|
|
@@ -4169,7 +4187,7 @@ function __resetIdleAutoFastForwardForTests() {
|
|
|
4169
4187
|
}
|
|
4170
4188
|
function sweepExpiredRemoteIdleSessions() {
|
|
4171
4189
|
try {
|
|
4172
|
-
|
|
4190
|
+
MeshRuntimeStore.getInstance().pruneExpiredRemoteIdleSessions();
|
|
4173
4191
|
} catch {
|
|
4174
4192
|
}
|
|
4175
4193
|
}
|
|
@@ -4338,7 +4356,7 @@ function queuePendingMeshCoordinatorEvent(event) {
|
|
|
4338
4356
|
function atomicDrainFile(path40) {
|
|
4339
4357
|
const tmpPath = `${path40}.draining`;
|
|
4340
4358
|
try {
|
|
4341
|
-
|
|
4359
|
+
renameSync4(path40, tmpPath);
|
|
4342
4360
|
} catch {
|
|
4343
4361
|
return null;
|
|
4344
4362
|
}
|
|
@@ -4445,14 +4463,14 @@ function shouldSuppressIntentionalCleanupStop(args) {
|
|
|
4445
4463
|
}
|
|
4446
4464
|
function hasFingerprintSeen(fingerprint) {
|
|
4447
4465
|
try {
|
|
4448
|
-
return
|
|
4466
|
+
return MeshRuntimeStore.getInstance().hasCompletionFingerprint(fingerprint);
|
|
4449
4467
|
} catch {
|
|
4450
4468
|
return false;
|
|
4451
4469
|
}
|
|
4452
4470
|
}
|
|
4453
4471
|
function recordFingerprintSeen(fingerprint) {
|
|
4454
4472
|
try {
|
|
4455
|
-
const db =
|
|
4473
|
+
const db = MeshRuntimeStore.getInstance();
|
|
4456
4474
|
db.recordCompletionFingerprint(fingerprint, RECENT_COMPLETION_FINGERPRINT_TTL_MS);
|
|
4457
4475
|
db.sweepExpiredFingerprints();
|
|
4458
4476
|
} catch {
|
|
@@ -5072,7 +5090,7 @@ async function triggerMeshQueue(components, meshId) {
|
|
|
5072
5090
|
}
|
|
5073
5091
|
let remoteSessions = [];
|
|
5074
5092
|
try {
|
|
5075
|
-
remoteSessions =
|
|
5093
|
+
remoteSessions = MeshRuntimeStore.getInstance().getRemoteIdleSessions();
|
|
5076
5094
|
} catch {
|
|
5077
5095
|
}
|
|
5078
5096
|
for (const idle of remoteSessions) {
|
|
@@ -5082,7 +5100,7 @@ async function triggerMeshQueue(components, meshId) {
|
|
|
5082
5100
|
const assigned = tryAssignQueueTask(components, meshId, idle.nodeId, idle.sessionId, idle.providerType);
|
|
5083
5101
|
if (assigned) {
|
|
5084
5102
|
try {
|
|
5085
|
-
|
|
5103
|
+
MeshRuntimeStore.getInstance().deleteRemoteIdleSession(idle.nodeId, idle.sessionId);
|
|
5086
5104
|
} catch {
|
|
5087
5105
|
}
|
|
5088
5106
|
}
|
|
@@ -5284,7 +5302,7 @@ function injectMeshSystemMessage(components, args) {
|
|
|
5284
5302
|
if (intentionalCleanupStop) {
|
|
5285
5303
|
if (eventSessionId && eventNodeId) {
|
|
5286
5304
|
try {
|
|
5287
|
-
|
|
5305
|
+
MeshRuntimeStore.getInstance().deleteRemoteIdleSession(eventNodeId, eventSessionId);
|
|
5288
5306
|
} catch {
|
|
5289
5307
|
}
|
|
5290
5308
|
}
|
|
@@ -5452,14 +5470,14 @@ function injectMeshSystemMessage(components, args) {
|
|
|
5452
5470
|
if (sessionId && nodeId && providerType) {
|
|
5453
5471
|
sweepExpiredRemoteIdleSessions();
|
|
5454
5472
|
try {
|
|
5455
|
-
|
|
5473
|
+
MeshRuntimeStore.getInstance().setRemoteIdleSession(nodeId, sessionId, providerType, Date.now() + REMOTE_IDLE_SESSION_TTL_MS);
|
|
5456
5474
|
} catch {
|
|
5457
5475
|
}
|
|
5458
5476
|
setImmediate(() => {
|
|
5459
5477
|
maybeAutoFastForwardIdleNode(components, { meshId: args.meshId, nodeId, sessionId, providerType }).finally(() => {
|
|
5460
5478
|
try {
|
|
5461
5479
|
const assigned = tryAssignQueueTask(components, args.meshId, nodeId, sessionId, providerType);
|
|
5462
|
-
if (assigned)
|
|
5480
|
+
if (assigned) MeshRuntimeStore.getInstance().deleteRemoteIdleSession(nodeId, sessionId);
|
|
5463
5481
|
} catch (e) {
|
|
5464
5482
|
LOG.warn("MeshQueue", `Failed to assign idle queue task after maintenance for ${nodeId}: ${e?.message || e}`);
|
|
5465
5483
|
}
|
|
@@ -5471,7 +5489,7 @@ function injectMeshSystemMessage(components, args) {
|
|
|
5471
5489
|
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
5472
5490
|
if (sessionId && nodeId) {
|
|
5473
5491
|
try {
|
|
5474
|
-
|
|
5492
|
+
MeshRuntimeStore.getInstance().deleteRemoteIdleSession(nodeId, sessionId);
|
|
5475
5493
|
} catch {
|
|
5476
5494
|
}
|
|
5477
5495
|
}
|
|
@@ -5483,7 +5501,7 @@ function injectMeshSystemMessage(components, args) {
|
|
|
5483
5501
|
const nodeId = readNonEmptyString2(args.nodeId) || readNonEmptyString2(args.metadataEvent.meshNodeId);
|
|
5484
5502
|
if (sessionId && nodeId) {
|
|
5485
5503
|
try {
|
|
5486
|
-
|
|
5504
|
+
MeshRuntimeStore.getInstance().deleteRemoteIdleSession(nodeId, sessionId);
|
|
5487
5505
|
} catch {
|
|
5488
5506
|
}
|
|
5489
5507
|
}
|
|
@@ -5755,7 +5773,7 @@ var init_mesh_events = __esm({
|
|
|
5755
5773
|
init_logger();
|
|
5756
5774
|
init_mesh_ledger();
|
|
5757
5775
|
init_mesh_work_queue();
|
|
5758
|
-
|
|
5776
|
+
init_mesh_runtime_store();
|
|
5759
5777
|
init_mesh_fast_forward();
|
|
5760
5778
|
REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
|
|
5761
5779
|
meshByWorkspaceCache = /* @__PURE__ */ new Map();
|
|
@@ -8706,11 +8724,12 @@ var init_cli_state_engine = __esm({
|
|
|
8706
8724
|
}
|
|
8707
8725
|
applyGenerating(ctx) {
|
|
8708
8726
|
const { modal, parsedMessages, lastParsedAssistant, parsedStatus, prevStatus } = ctx;
|
|
8727
|
+
const noActiveTurn = !this.currentTurnScope;
|
|
8728
|
+
if (!this.isWaitingForResponse && noActiveTurn && !modal) return;
|
|
8709
8729
|
this.clearIdleFinishCandidate("generating");
|
|
8710
8730
|
this.cancelPendingIdleFinish("generating_signal_returned");
|
|
8711
8731
|
const snap = this.transport.getSnapshot();
|
|
8712
8732
|
const effectiveScreenText = snap.screenText || snap.accumulatedBuffer;
|
|
8713
|
-
const noActiveTurn = !this.currentTurnScope;
|
|
8714
8733
|
const looksIdleChrome = /(^|\n)\s*[❯›>]\s*(?:\n|$)/m.test(effectiveScreenText);
|
|
8715
8734
|
const parsedShowsLiveProgress = parsedStatus === "generating" && !!lastParsedAssistant;
|
|
8716
8735
|
if (prevStatus === "idle" && !this.isWaitingForResponse && noActiveTurn && !modal && looksIdleChrome && !parsedShowsLiveProgress) return;
|
|
@@ -8970,7 +8989,25 @@ var init_cli_state_engine = __esm({
|
|
|
8970
8989
|
const parsedStatus = typeof parsed?.status === "string" ? parsed.status.trim() : "";
|
|
8971
8990
|
if (parsedStatus !== "idle") return true;
|
|
8972
8991
|
if (parsed?.activeModal || parsed?.modal) return true;
|
|
8973
|
-
|
|
8992
|
+
const messages = Array.isArray(parsed?.messages) ? parsed.messages : [];
|
|
8993
|
+
let lastUserIdx = -1;
|
|
8994
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
8995
|
+
if (messages[i]?.role === "user") {
|
|
8996
|
+
lastUserIdx = i;
|
|
8997
|
+
break;
|
|
8998
|
+
}
|
|
8999
|
+
}
|
|
9000
|
+
if (lastUserIdx < 0) {
|
|
9001
|
+
if (messages.length === 0) return false;
|
|
9002
|
+
return !this.parsedStatusHasFinalStandardAssistantMessage(parsed);
|
|
9003
|
+
}
|
|
9004
|
+
const hasCurrentTurnAssistant = messages.slice(lastUserIdx + 1).some((m) => {
|
|
9005
|
+
if (!m || m.role !== "assistant") return false;
|
|
9006
|
+
if (typeof m.content !== "string" || !m.content.trim()) return false;
|
|
9007
|
+
const kind = typeof m.kind === "string" && m.kind.trim() ? m.kind.trim() : "standard";
|
|
9008
|
+
return kind === "standard" && m.meta?.streaming !== true;
|
|
9009
|
+
});
|
|
9010
|
+
return !hasCurrentTurnAssistant;
|
|
8974
9011
|
}
|
|
8975
9012
|
rescheduleTranscriptFinishCheck(reason) {
|
|
8976
9013
|
this.clearIdleFinishCandidate(reason);
|
|
@@ -11432,14 +11469,19 @@ function buildClaudeInteractiveTuiAnswerSteps(prompt, response) {
|
|
|
11432
11469
|
if (question.multiSelect) throw new Error("Claude TUI multi-select prompts are not supported yet");
|
|
11433
11470
|
const answer = response.answers[question.questionId];
|
|
11434
11471
|
if (!answer) throw new Error(`Missing answer for ${question.questionId}`);
|
|
11435
|
-
|
|
11436
|
-
if (
|
|
11437
|
-
|
|
11438
|
-
|
|
11439
|
-
|
|
11440
|
-
steps.push(
|
|
11472
|
+
const freeformText = answer.freeformText?.trim() ?? "";
|
|
11473
|
+
if (freeformText) {
|
|
11474
|
+
const typeOptionIndex = question.options.findIndex((o) => /^Type something\.?$/i.test(o.label));
|
|
11475
|
+
const optionNumber = typeOptionIndex >= 0 ? typeOptionIndex + 1 : question.options.length;
|
|
11476
|
+
steps.push(String(optionNumber));
|
|
11477
|
+
for (const ch of freeformText) steps.push(ch);
|
|
11478
|
+
steps.push("\r");
|
|
11479
|
+
} else {
|
|
11480
|
+
if (answer.selectedLabels.length !== 1) throw new Error(`Expected one selected label for ${question.questionId}`);
|
|
11481
|
+
const selectedIndex = question.options.findIndex((option) => option.label === answer.selectedLabels[0]);
|
|
11482
|
+
if (selectedIndex < 0) throw new Error(`Unknown option for ${question.questionId}: ${answer.selectedLabels[0]}`);
|
|
11483
|
+
steps.push(String(selectedIndex + 1));
|
|
11441
11484
|
}
|
|
11442
|
-
steps.push("\r");
|
|
11443
11485
|
}
|
|
11444
11486
|
steps.push("\r");
|
|
11445
11487
|
return steps;
|
|
@@ -19772,6 +19814,7 @@ function normalizeManagedStatus(status, opts) {
|
|
|
19772
19814
|
if (hasApprovalButtons(opts?.activeModal)) return "waiting_approval";
|
|
19773
19815
|
const normalized = String(status || "idle").trim().toLowerCase();
|
|
19774
19816
|
if (normalized === "waiting_approval") return "waiting_approval";
|
|
19817
|
+
if (normalized === "waiting_choice") return "waiting_choice";
|
|
19775
19818
|
if (WORKING_STATUSES.has(normalized)) return "generating";
|
|
19776
19819
|
if (normalized === "error") return "error";
|
|
19777
19820
|
if (normalized === "stopped") return "stopped";
|
|
@@ -25790,10 +25833,47 @@ function resolveSections(spec, lines) {
|
|
|
25790
25833
|
for (const sec of spec.layout.sections) {
|
|
25791
25834
|
let from = 0;
|
|
25792
25835
|
let to = total;
|
|
25793
|
-
if (sec.
|
|
25836
|
+
if (sec.anchor_regex !== void 0) {
|
|
25837
|
+
try {
|
|
25838
|
+
const re = new RegExp(sec.anchor_regex, sec.anchor_flags ?? "");
|
|
25839
|
+
const prevRe = sec.anchor_context?.prev !== void 0 ? new RegExp(sec.anchor_context.prev, sec.anchor_context.prev_flags ?? "") : null;
|
|
25840
|
+
const nextRe = sec.anchor_context?.next !== void 0 ? new RegExp(sec.anchor_context.next, sec.anchor_context.next_flags ?? "") : null;
|
|
25841
|
+
const matches = (i) => re.test(lines[i]) && (prevRe === null || i > 0 && prevRe.test(lines[i - 1])) && (nextRe === null || i < total - 1 && nextRe.test(lines[i + 1]));
|
|
25842
|
+
let idx = -1;
|
|
25843
|
+
if (sec.anchor_last) {
|
|
25844
|
+
for (let i = total - 1; i >= 0; i--) {
|
|
25845
|
+
if (matches(i)) {
|
|
25846
|
+
idx = i;
|
|
25847
|
+
break;
|
|
25848
|
+
}
|
|
25849
|
+
}
|
|
25850
|
+
} else {
|
|
25851
|
+
for (let i = 0; i < total; i++) {
|
|
25852
|
+
if (matches(i)) {
|
|
25853
|
+
idx = i;
|
|
25854
|
+
break;
|
|
25855
|
+
}
|
|
25856
|
+
}
|
|
25857
|
+
}
|
|
25858
|
+
if (idx !== -1) {
|
|
25859
|
+
from = idx;
|
|
25860
|
+
to = total;
|
|
25861
|
+
if (sec.until_regex !== void 0) {
|
|
25862
|
+
try {
|
|
25863
|
+
const ure = new RegExp(sec.until_regex, sec.until_regex_flags ?? "");
|
|
25864
|
+
const end = lines.findIndex((l, i) => i > idx && ure.test(l));
|
|
25865
|
+
if (end !== -1) to = end;
|
|
25866
|
+
} catch {
|
|
25867
|
+
}
|
|
25868
|
+
} else if (sec.lines !== void 0) {
|
|
25869
|
+
to = Math.min(total, from + sec.lines);
|
|
25870
|
+
}
|
|
25871
|
+
}
|
|
25872
|
+
} catch {
|
|
25873
|
+
}
|
|
25874
|
+
} else if (sec.from_top !== void 0) {
|
|
25794
25875
|
from = resolveSize(sec.from_top, total);
|
|
25795
|
-
}
|
|
25796
|
-
if (sec.from_bottom !== void 0) {
|
|
25876
|
+
} else if (sec.from_bottom !== void 0) {
|
|
25797
25877
|
const sz = resolveSize(sec.from_bottom, total);
|
|
25798
25878
|
from = total - sz;
|
|
25799
25879
|
to = total;
|
|
@@ -26111,6 +26191,9 @@ var SCHEMA = {
|
|
|
26111
26191
|
"type": "string",
|
|
26112
26192
|
"minLength": 1
|
|
26113
26193
|
},
|
|
26194
|
+
"requiresFinalAssistantBeforeIdle": {
|
|
26195
|
+
"type": "boolean"
|
|
26196
|
+
},
|
|
26114
26197
|
"debounce": {
|
|
26115
26198
|
"type": "object",
|
|
26116
26199
|
"additionalProperties": false,
|
|
@@ -26125,7 +26208,8 @@ var SCHEMA = {
|
|
|
26125
26208
|
"section": { "type": "string", "minLength": 1 },
|
|
26126
26209
|
"regex": { "type": "string", "minLength": 1 },
|
|
26127
26210
|
"flags": { "type": "string" },
|
|
26128
|
-
"hold_ms": { "type": "integer", "minimum": 0 }
|
|
26211
|
+
"hold_ms": { "type": "integer", "minimum": 0 },
|
|
26212
|
+
"force_after_ms": { "type": "integer", "minimum": 0 }
|
|
26129
26213
|
}
|
|
26130
26214
|
}
|
|
26131
26215
|
}
|
|
@@ -26173,7 +26257,23 @@ var SCHEMA = {
|
|
|
26173
26257
|
"type": "string"
|
|
26174
26258
|
}
|
|
26175
26259
|
}
|
|
26176
|
-
}
|
|
26260
|
+
},
|
|
26261
|
+
"anchor_regex": { "type": "string", "minLength": 1 },
|
|
26262
|
+
"anchor_flags": { "type": "string" },
|
|
26263
|
+
"anchor_last": { "type": "boolean" },
|
|
26264
|
+
"anchor_context": {
|
|
26265
|
+
"type": "object",
|
|
26266
|
+
"additionalProperties": false,
|
|
26267
|
+
"properties": {
|
|
26268
|
+
"prev": { "type": "string" },
|
|
26269
|
+
"prev_flags": { "type": "string" },
|
|
26270
|
+
"next": { "type": "string" },
|
|
26271
|
+
"next_flags": { "type": "string" }
|
|
26272
|
+
}
|
|
26273
|
+
},
|
|
26274
|
+
"lines": { "type": "integer", "minimum": 1 },
|
|
26275
|
+
"until_regex": { "type": "string", "minLength": 1 },
|
|
26276
|
+
"until_regex_flags": { "type": "string" }
|
|
26177
26277
|
}
|
|
26178
26278
|
},
|
|
26179
26279
|
"sectionRegex": {
|
|
@@ -26609,6 +26709,7 @@ function resolveSpecPath(providerDir) {
|
|
|
26609
26709
|
}
|
|
26610
26710
|
|
|
26611
26711
|
// src/providers/spec/driver.ts
|
|
26712
|
+
init_logger();
|
|
26612
26713
|
var STARTUP_GRACE_MS = 2500;
|
|
26613
26714
|
var BUSY_HOLD_MS = 6e3;
|
|
26614
26715
|
var SUBMIT_DELAY_FLOOR_MS = 200;
|
|
@@ -26636,9 +26737,16 @@ function matchesCompletionIdleRule(spec, ev, screen) {
|
|
|
26636
26737
|
return null;
|
|
26637
26738
|
}
|
|
26638
26739
|
}
|
|
26639
|
-
function matchesCompletionIdleTargetState(spec, ev, screen) {
|
|
26740
|
+
function matchesCompletionIdleTargetState(spec, ev, screen, cursor) {
|
|
26640
26741
|
const target = spec.states.find((state) => state.id === spec.default_state) ?? spec.states.find((state) => state.id === "idle");
|
|
26641
|
-
if (!target?.when
|
|
26742
|
+
if (!target?.when) return false;
|
|
26743
|
+
const hasCursorGuard = target.when.cursor_row_min !== void 0 || target.when.cursor_row_max !== void 0 || target.when.cursor_col_min !== void 0 || target.when.cursor_col_max !== void 0;
|
|
26744
|
+
if (hasCursorGuard && cursor !== void 0) {
|
|
26745
|
+
const { cursor_row_min, cursor_row_max, cursor_col_min, cursor_col_max } = target.when;
|
|
26746
|
+
const cursorOk = (cursor_row_min === void 0 || cursor.row >= cursor_row_min) && (cursor_row_max === void 0 || cursor.row <= cursor_row_max) && (cursor_col_min === void 0 || cursor.col >= cursor_col_min) && (cursor_col_max === void 0 || cursor.col <= cursor_col_max);
|
|
26747
|
+
if (cursorOk) return true;
|
|
26748
|
+
}
|
|
26749
|
+
if (!target.when.regex) return false;
|
|
26642
26750
|
const haystack = target.when.section ? ev.sections.find((section) => section.id === target.when.section)?.text ?? "" : screen;
|
|
26643
26751
|
if (!haystack) return false;
|
|
26644
26752
|
try {
|
|
@@ -26800,6 +26908,7 @@ var SpecDriver = class {
|
|
|
26800
26908
|
if (this.busyExpiryTimer) clearTimeout(this.busyExpiryTimer);
|
|
26801
26909
|
this.busyExpiryTimer = setTimeout(() => {
|
|
26802
26910
|
this.busyExpiryTimer = null;
|
|
26911
|
+
LOG.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] busyExpiry fired holdMs=${holdMs}`);
|
|
26803
26912
|
this.reevaluate();
|
|
26804
26913
|
}, Math.max(holdMs + 50, 100));
|
|
26805
26914
|
}
|
|
@@ -26824,11 +26933,16 @@ var SpecDriver = class {
|
|
|
26824
26933
|
if (completionKey !== this.completionIdleKey) {
|
|
26825
26934
|
this.completionIdleKey = completionKey;
|
|
26826
26935
|
this.completionIdleFirstSeenAt = now;
|
|
26936
|
+
LOG.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] completion_idle_after matched: key="${completionKey}"`);
|
|
26827
26937
|
}
|
|
26828
26938
|
const holdMs = Math.max(0, completionIdleRule.hold_ms || 0);
|
|
26939
|
+
const forceAfterMs = typeof completionIdleRule.force_after_ms === "number" ? completionIdleRule.force_after_ms : null;
|
|
26829
26940
|
const ageMs = now - this.completionIdleFirstSeenAt;
|
|
26830
26941
|
if (ageMs >= holdMs) {
|
|
26831
|
-
|
|
26942
|
+
const targetMatches = matchesCompletionIdleTargetState(this.spec, ev, screen, cursor);
|
|
26943
|
+
const forced = !targetMatches && forceAfterMs !== null && ageMs >= holdMs + forceAfterMs;
|
|
26944
|
+
LOG.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] completion_idle_after hold expired ageMs=${ageMs} targetState=${targetMatches} forced=${forced} screenTail="${screen.split(/\r?\n/).slice(-3).join("\\n").slice(-200)}"`);
|
|
26945
|
+
if (targetMatches || forced) {
|
|
26832
26946
|
const idle = this.spec.states.find((state) => state.id === this.spec.default_state) ?? this.spec.states.find((state) => state.id === "idle");
|
|
26833
26947
|
evState = idle ? { id: idle.id, label: idle.label, title: null } : { id: "idle", label: "Ready", title: null };
|
|
26834
26948
|
} else {
|
|
@@ -27969,16 +28083,19 @@ var CliProviderInstance = class {
|
|
|
27969
28083
|
controlValues: this.controlValues
|
|
27970
28084
|
});
|
|
27971
28085
|
const activeChatStatus = parseErrorMessage ? "error" : autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : adapterStatus.status !== "idle" ? visibleStatus : suppressStaleParsedBusyStatus ? visibleStatus : parsedChatStatus || visibleStatus;
|
|
28086
|
+
const hasInteractivePrompt = !!this.activeInteractivePrompt;
|
|
28087
|
+
const finalStatus = hasInteractivePrompt ? "waiting_choice" : visibleStatus;
|
|
28088
|
+
const finalChatStatus = hasInteractivePrompt ? "waiting_choice" : activeChatStatus;
|
|
27972
28089
|
return {
|
|
27973
28090
|
type: this.type,
|
|
27974
28091
|
name: this.provider.name,
|
|
27975
28092
|
category: "cli",
|
|
27976
|
-
status:
|
|
28093
|
+
status: finalStatus,
|
|
27977
28094
|
mode: this.presentationMode,
|
|
27978
28095
|
activeChat: {
|
|
27979
28096
|
id: activeChatId,
|
|
27980
28097
|
title: parsedStatus?.title || dirName,
|
|
27981
|
-
status:
|
|
28098
|
+
status: finalChatStatus,
|
|
27982
28099
|
messages: statusMessages,
|
|
27983
28100
|
activeModal: autoApproveActive ? null : parsedStatus?.activeModal ?? adapterStatus.activeModal,
|
|
27984
28101
|
activeInteractivePrompt: this.activeInteractivePrompt,
|
|
@@ -28449,6 +28566,7 @@ var CliProviderInstance = class {
|
|
|
28449
28566
|
const adapterOwnsMessagesElsewhere = this.adapter?.chatMessagesOwnedExternally === true;
|
|
28450
28567
|
const finalAssistantEvidence = this.completionFinalAssistantEvidence(parsed?.messages);
|
|
28451
28568
|
const allowMissingAssistantTimeout = !!(this.settings.meshNodeFor || this.settings.meshActiveTaskId || this.settings.launchedByCoordinator);
|
|
28569
|
+
LOG.debug("CLI", `[${this.type}] finalAssistantEvidence: present=${finalAssistantEvidence.present} source=${finalAssistantEvidence.source} adapterOwnsMessagesElsewhere=${adapterOwnsMessagesElsewhere} parsedStatus=${parsedStatus}`);
|
|
28452
28570
|
if (!finalAssistantEvidence.present) {
|
|
28453
28571
|
if (adapterOwnsMessagesElsewhere) {
|
|
28454
28572
|
if (finalAssistantEvidence.source === "external-native") {
|
|
@@ -28457,6 +28575,10 @@ var CliProviderInstance = class {
|
|
|
28457
28575
|
LOG.info("CLI", `[${this.type}] external transcript probe: msgCount=${probe.msgCount} lastRole=${probe.lastRole || "none"} lastKind=${probe.lastKind || "none"} contentLen=${probe.contentLen} sourceMtime=${probe.sourceMtimeMs ?? "unknown"} mtimeAge=${probe.mtimeAgeMs ?? "unknown"}ms`);
|
|
28458
28576
|
pending.loggedTranscriptProbe = true;
|
|
28459
28577
|
}
|
|
28578
|
+
LOG.debug("CLI", `[${this.type}] external-native probe result: lastRole=${probe?.lastRole} contentLen=${probe?.contentLen}`);
|
|
28579
|
+
if (probe?.lastRole === "assistant" && (probe.contentLen ?? 0) > 0) {
|
|
28580
|
+
return null;
|
|
28581
|
+
}
|
|
28460
28582
|
if (this.type === "antigravity-cli") {
|
|
28461
28583
|
return null;
|
|
28462
28584
|
}
|
|
@@ -28466,6 +28588,7 @@ var CliProviderInstance = class {
|
|
|
28466
28588
|
return { reason: "missing_final_assistant", terminal: true, allowTimeout: allowMissingAssistantTimeout };
|
|
28467
28589
|
}
|
|
28468
28590
|
} else {
|
|
28591
|
+
LOG.debug("CLI", `[${this.type}] missing_final_assistant (not ownsExternal) requiresFinalAssistant=${!!this.provider.requiresFinalAssistantBeforeIdle}`);
|
|
28469
28592
|
return {
|
|
28470
28593
|
reason: "missing_final_assistant",
|
|
28471
28594
|
terminal: this.provider.requiresFinalAssistantBeforeIdle === true,
|
|
@@ -28499,6 +28622,7 @@ var CliProviderInstance = class {
|
|
|
28499
28622
|
const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
28500
28623
|
const externalNativeFinal = this.getExternalNativeFinalReconciliation(void 0, latestStatus);
|
|
28501
28624
|
const latestVisibleStatus = externalNativeFinal && isCliGeneratingLikeStatus(latestStatus.status) ? "idle" : latestAutoApproveActive ? "generating" : latestStatus.status;
|
|
28625
|
+
LOG.debug("CLI", `[${this.type}] flush attempt: adapterStatus=${latestStatus.status} latestVisible=${latestVisibleStatus} externalNativeFinal=${!!externalNativeFinal} generatingStartedAt=${this.generatingStartedAt} isWaitingForResponse=${!!this.adapter?.isWaitingForResponse} hasPartial=${!!this.adapter.getPartialResponse?.()}`);
|
|
28502
28626
|
if (latestVisibleStatus !== "idle") {
|
|
28503
28627
|
LOG.info("CLI", `[${this.type}] cancelled pending completed (resumed ${latestVisibleStatus})`);
|
|
28504
28628
|
this.completedDebouncePending = null;
|
|
@@ -28509,6 +28633,7 @@ var CliProviderInstance = class {
|
|
|
28509
28633
|
if (block2) {
|
|
28510
28634
|
const blockReason = block2.reason;
|
|
28511
28635
|
const waitedMs = Date.now() - pending.firstObservedAt;
|
|
28636
|
+
LOG.debug("CLI", `[${this.type}] finalization block: reason=${blockReason} terminal=${block2.terminal} waitedMs=${waitedMs} maxWait=${COMPLETED_FINALIZATION_MAX_WAIT_MS}`);
|
|
28512
28637
|
if (block2.terminal && !block2.allowTimeout || waitedMs < COMPLETED_FINALIZATION_MAX_WAIT_MS) {
|
|
28513
28638
|
if (pending.loggedBlockReason !== blockReason) {
|
|
28514
28639
|
LOG.info("CLI", `[${this.type}] waiting to emit completed until transcript finalizes (${blockReason})`);
|
|
@@ -28623,9 +28748,13 @@ var CliProviderInstance = class {
|
|
|
28623
28748
|
if (newStatus !== this.lastStatus) {
|
|
28624
28749
|
LOG.info("CLI", `[${this.type}] status: ${this.lastStatus} \u2192 ${newStatus}`);
|
|
28625
28750
|
if (this.lastStatus === "idle" && newStatus === "generating") {
|
|
28751
|
+
if (this.completedDebouncePending && this.generatingStartedAt === 0) {
|
|
28752
|
+
LOG.debug("CLI", `[${this.type}] ignoring post-completion PTY generating blip (generatingStartedAt=0)`);
|
|
28753
|
+
return;
|
|
28754
|
+
}
|
|
28626
28755
|
this.suppressIdleHistoryReplay = false;
|
|
28627
28756
|
if (this.completedDebouncePending) {
|
|
28628
|
-
LOG.info("CLI", `[${this.type}] cancelled pending completed (resumed generating)`);
|
|
28757
|
+
LOG.info("CLI", `[${this.type}] cancelled pending completed (resumed generating) generatingStartedAt=${this.generatingStartedAt} isWaitingForResponse=${!!this.adapter?.isWaitingForResponse}`);
|
|
28629
28758
|
if (this.completedDebounceTimer) {
|
|
28630
28759
|
clearTimeout(this.completedDebounceTimer);
|
|
28631
28760
|
this.completedDebounceTimer = null;
|
|
@@ -28723,7 +28852,10 @@ var CliProviderInstance = class {
|
|
|
28723
28852
|
firstObservedAt: now,
|
|
28724
28853
|
previousStatus: this.lastStatus
|
|
28725
28854
|
};
|
|
28726
|
-
this.
|
|
28855
|
+
const ownsExternalHistory = !!this.adapter?.chatMessagesOwnedExternally;
|
|
28856
|
+
const flushDelay = ownsExternalHistory ? 0 : 3e3;
|
|
28857
|
+
LOG.debug("CLI", `[${this.type}] set completedDebouncePending duration=${duration}s ownsExternalHistory=${ownsExternalHistory} flushDelay=${flushDelay}ms generatingStartedAt=${this.generatingStartedAt}`);
|
|
28858
|
+
this.scheduleCompletedDebounceFlush(flushDelay);
|
|
28727
28859
|
}
|
|
28728
28860
|
} else if (newStatus === "idle" && this.lastStatus === "starting") {
|
|
28729
28861
|
this.pushEvent({ event: "agent:ready", chatTitle, timestamp: now });
|