@adhdev/daemon-standalone 0.9.82-rc.292 → 0.9.82-rc.294
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 +418 -54
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index-BTGrWIYY.js +113 -0
- package/public/assets/index-BmuvnK-s.js +113 -0
- package/public/assets/index-BrRKaNU2.css +1 -0
- package/public/assets/index-C6CBDz4G.css +1 -0
- package/public/index.html +2 -2
package/dist/index.js
CHANGED
|
@@ -29983,10 +29983,10 @@ var require_dist3 = __commonJS({
|
|
|
29983
29983
|
}
|
|
29984
29984
|
function getDaemonBuildInfo() {
|
|
29985
29985
|
if (cached2) return cached2;
|
|
29986
|
-
const commit = readInjected(true ? "
|
|
29987
|
-
const commitShort = readInjected(true ? "
|
|
29988
|
-
const version2 = readInjected(true ? "0.9.82-rc.
|
|
29989
|
-
const builtAt = readInjected(true ? "2026-06-
|
|
29986
|
+
const commit = readInjected(true ? "6ee0e52b0b7347870577ebe598054d87127078fe" : void 0) ?? "unknown";
|
|
29987
|
+
const commitShort = readInjected(true ? "6ee0e52b" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
29988
|
+
const version2 = readInjected(true ? "0.9.82-rc.294" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
29989
|
+
const builtAt = readInjected(true ? "2026-06-16T12:16:10.838Z" : void 0);
|
|
29990
29990
|
cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
|
|
29991
29991
|
return cached2;
|
|
29992
29992
|
}
|
|
@@ -30055,6 +30055,15 @@ var require_dist3 = __commonJS({
|
|
|
30055
30055
|
);
|
|
30056
30056
|
}
|
|
30057
30057
|
}
|
|
30058
|
+
function isNonRuntimeRootFile(file2) {
|
|
30059
|
+
const base = file2.slice(file2.lastIndexOf("/") + 1);
|
|
30060
|
+
if (/^\.(?:verify|marker|converge|ff-verify|patch-equiv|live-verify)\b/i.test(base)) return true;
|
|
30061
|
+
if (/(?:^|\/)docs\//i.test(file2)) return true;
|
|
30062
|
+
if (/^(?:README|CHANGELOG|LICENSE|NOTICE|AUTHORS|CONTRIBUTING|CODEOWNERS)(?:\.[A-Za-z0-9]+)?$/i.test(base)) {
|
|
30063
|
+
return true;
|
|
30064
|
+
}
|
|
30065
|
+
return false;
|
|
30066
|
+
}
|
|
30058
30067
|
async function classifyDaemonBuildChange(repoPath, buildCommit, options) {
|
|
30059
30068
|
try {
|
|
30060
30069
|
const diff = await runGit(repoPath, ["diff", "--name-only", `${buildCommit}..HEAD`], options);
|
|
@@ -30063,18 +30072,18 @@ var require_dist3 = __commonJS({
|
|
|
30063
30072
|
return { isDaemonAffecting: true, affectedPackages: [] };
|
|
30064
30073
|
}
|
|
30065
30074
|
const pkgs = /* @__PURE__ */ new Set();
|
|
30066
|
-
let
|
|
30075
|
+
let sawRuntimeAmbiguousNonPackage = false;
|
|
30067
30076
|
for (const file2 of files) {
|
|
30068
30077
|
const match = file2.match(/(?:^|\/)packages\/([^/]+)\//);
|
|
30069
30078
|
if (!match) {
|
|
30070
|
-
|
|
30079
|
+
if (!isNonRuntimeRootFile(file2)) sawRuntimeAmbiguousNonPackage = true;
|
|
30071
30080
|
continue;
|
|
30072
30081
|
}
|
|
30073
30082
|
pkgs.add(match[1]);
|
|
30074
30083
|
}
|
|
30075
30084
|
const affectedPackages = [...pkgs].sort();
|
|
30076
|
-
const
|
|
30077
|
-
return { isDaemonAffecting: !
|
|
30085
|
+
const allBenign = !sawRuntimeAmbiguousNonPackage && affectedPackages.every((p) => WEB_ONLY_PACKAGES.has(p) && !DAEMON_RUNTIME_PACKAGES.has(p));
|
|
30086
|
+
return { isDaemonAffecting: !allBenign, affectedPackages };
|
|
30078
30087
|
} catch {
|
|
30079
30088
|
return { isDaemonAffecting: true, affectedPackages: [] };
|
|
30080
30089
|
}
|
|
@@ -30101,7 +30110,8 @@ var require_dist3 = __commonJS({
|
|
|
30101
30110
|
options
|
|
30102
30111
|
);
|
|
30103
30112
|
const scopeLabel = scope === "root" ? "workspace" : scope;
|
|
30104
|
-
const
|
|
30113
|
+
const benignDetail = affectedPackages.length > 0 ? `only web packages changed (${affectedPackages.join(", ")})` : "only non-runtime files changed (markers/docs)";
|
|
30114
|
+
const warning = isDaemonAffecting ? `Live daemon was built from ${build.commitShort} which is behind ${scopeLabel} HEAD ${head.slice(0, 7)}. Merged code is NOT live until the daemon is rebuilt/redeployed and restarted \u2014 a local dist rebuild alone does not update a cloud daemon.` : `Live daemon was built from ${build.commitShort} which is behind ${scopeLabel} HEAD ${head.slice(0, 7)}, but ${benignDetail}. Daemon restart NOT required \u2014 redeploy the web app to reflect the change.`;
|
|
30105
30115
|
return {
|
|
30106
30116
|
buildCommit: build.commit,
|
|
30107
30117
|
buildCommitShort: build.commitShort,
|
|
@@ -31713,8 +31723,9 @@ ${rules.join("\n")}`;
|
|
|
31713
31723
|
- **Reuse idle sessions.** For follow-up, retry, commit/push, or cleanup on the same issue, send only the delta to the existing idle session. Start fresh only for independent work, provider mismatch, transcript contamination, or required worktree isolation.
|
|
31714
31724
|
- **Respect explicit provider requests.** Map: Hermes \u2192 \`hermes-cli\`, Claude/Claude Code \u2192 \`claude-cli\`, Codex \u2192 \`codex-cli\`, Gemini \u2192 \`gemini-cli\`, Antigravity \u2192 \`antigravity-cli\`. Never substitute the coordinator's own runtime.
|
|
31715
31725
|
- **Verify via git, not source.** Use \`mesh_git_status\` to confirm side effects. Treat agent summaries as self-reports, not verification.
|
|
31716
|
-
- **Limit parallelism.** Start with 1\u20132 tasks; scale only on success. Never duplicate a session because \`mesh_read_chat\` shows no final message while tool/terminal activity is ongoing.
|
|
31726
|
+
- **Limit parallelism.** Start with 1\u20132 tasks; scale only on success. Never duplicate a session because \`mesh_read_chat\` shows no final message while tool/terminal activity is ongoing. This caps *concurrent* load \u2014 it does not mean serialize independent work: when a new, independent request arrives and there is headroom under \`maxParallelTasks\`, dispatch it right away rather than waiting for an in-flight task or a user nudge (read-only diagnosis especially, since it has no merge cost).
|
|
31717
31727
|
- **Check history first.** Call \`mesh_task_history\` at session start to avoid duplicate work and inform recovery. On failure, read task history before retrying.
|
|
31728
|
+
- **Sequence shared-base-moving merges.** Parallel dispatch is encouraged, but merging one worktree can advance another in-flight worktree's base \u2014 especially the oss submodule pointer \u2014 turning a clean fast-forward into a diverged rebase (patch-equivalence correctly blocks this). Before merging an in-flight worktree while siblings are also in flight, land in an intentional order, re-clone long-running worktrees from the advanced base, or expect to manually rebase + ff-only the laggards; merging an independent fix mid-flight can strand siblings into a rebase.
|
|
31718
31729
|
- **Converge branches.** After worktree tasks: refine/fast-forward, or classify as \`pushed_feature_branch_needs_merge\` / \`blocked_review\` / \`cleanup_candidate\` / \`not_mergeable\`. Clean up with \`mesh_remove_node\`.
|
|
31719
31730
|
- **Refinery is config-driven.** \`mesh_refine_node\` must run validation from \`.adhdev/refine.{json,yaml,yml}\` or \`repo-mesh.refine.*\`. Heuristics are scaffolding only.
|
|
31720
31731
|
- **Submodule reachability = publish-needed.** \`submodule_reachability_failed\` \u2192 classify as \`blocked_review\`, request user approval to push to submodule main, then rerun \`mesh_refine_node\`.
|
|
@@ -31772,7 +31783,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
|
|
|
31772
31783
|
c. **Targeted Tasks**: Use \`mesh_send_task\` only when you need to bypass the queue and force a specific node to execute a task immediately.
|
|
31773
31784
|
d. For the first dispatch of a new task, provide a **complete, self-contained** instruction that includes all context the agent needs (file paths, line numbers, what to change, why). Do not send partial instructions expecting future follow-up.
|
|
31774
31785
|
e. For a continuation of the same issue in an existing session, send a concise **delta instruction**: current verified state, the exact failed/blocked step, the newly approved action, and final reporting requirements. Do not resend the full original task or open a new chat solely to continue the same work; that wastes coordinator and worker context.
|
|
31775
|
-
4. **Monitor** \u2014 Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly. Do **not** repeatedly call \`mesh_status\` or \`mesh_view_queue\` just to wait for assigned/generating work. After dispatching a direct or queued task, send one progress update with the task/session handle, then stop. Wait for \`pendingCoordinatorEvents\` or another completion/approval/status signal, an explicit user status request, or a real timeout/stall signal before reading status/chat/queue again. Use at most one compact \`mesh_read_chat\` check after a terminal signal. Handle approvals via \`mesh_approve\`.
|
|
31786
|
+
4. **Monitor** \u2014 Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly. Do **not** repeatedly call \`mesh_status\` or \`mesh_view_queue\` just to wait for assigned/generating work. After dispatching a direct or queued task, send one progress update with the task/session handle, then stop. Wait for \`pendingCoordinatorEvents\` or another completion/approval/status signal, an explicit user status request, or a real timeout/stall signal before reading status/chat/queue again. Use at most one compact \`mesh_read_chat\` check after a terminal signal. Handle approvals via \`mesh_approve\`. **Proactively parallelize new work.** When the user reports a new bug or asks for new work, start it immediately if it is independent of in-flight tasks and there is headroom under \`maxParallelTasks\` \u2014 do not wait for a current task to finish or for the user to prompt you to parallelize. Read-only diagnosis (\`live_debug_readonly\`) has no isolation or merge cost, so dispatch it in parallel right away. The no-polling / concurrency-limit rules constrain *re-checking or duplicating already-dispatched work*; they are **not** a reason to defer starting a new, independent task.
|
|
31776
31787
|
5. **Verify** \u2014 When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
|
|
31777
31788
|
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
31778
31789
|
7. **Converge branches** \u2014 Before marking any task complete, classify every touched node/branch into exactly one final state: \`merged_to_main\`, \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\`. Use \`mesh_status\` branchConvergenceSummary. For obvious clean branch catch-up (ahead 0, behind > 0, upstream fresh, no dirty/stash/submodule issues), use \`mesh_fast_forward_node\` dry-run first and execute only when explicitly safe/approved; this avoids consuming an agent session. Use \`mesh_refine_node\` for clean worktree branches when safe. Before/refine merging root commits that contain submodule gitlink changes, require each submodule commit to be reachable from the configured submodule remote main branch, not merely present on a feature ref or local checkout. If \`mesh_refine_node\` returns \`submodule_reachability_failed\` or publish-required evidence, keep the public convergence bucket as \`blocked_review\`; unless \`allowAutoPublishSubmoduleMainCommits\` is explicitly enabled and Refinery reports successful non-force publish plus post-publish verification, ask the user for explicit approval to push/publish the unreachable submodule commit(s) to submodule main, then rerun \`mesh_refine_node\`. Do not merge the root branch until the submodule commit(s) are reachable from submodule origin/main. A task that remains on a non-main branch is not fully complete unless the final report names the follow-up state and next step.
|
|
@@ -34138,11 +34149,40 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34138
34149
|
).get(meshId);
|
|
34139
34150
|
return row?.cnt ?? 0;
|
|
34140
34151
|
}
|
|
34152
|
+
/**
|
|
34153
|
+
* Mark specific pending-event rows drained by id (ack). Used by the
|
|
34154
|
+
* unresolved-delegate durable-forward outbox: an event is peeked (not drained)
|
|
34155
|
+
* while its push to the coordinator is unconfirmed, then marked drained ONLY
|
|
34156
|
+
* after the push is acked. A failed push leaves the row undrained so the next
|
|
34157
|
+
* reconcile tick retries it. Returns the number of rows newly marked drained.
|
|
34158
|
+
*/
|
|
34159
|
+
markPendingEventsDrainedById(ids) {
|
|
34160
|
+
const idList = ids.filter((id) => typeof id === "string" && id.length > 0);
|
|
34161
|
+
if (idList.length === 0) return 0;
|
|
34162
|
+
const now = Date.now();
|
|
34163
|
+
return this.db.prepare(
|
|
34164
|
+
`UPDATE mesh_pending_events SET drained = 1, drained_at = ? WHERE drained = 0 AND id IN (${idList.map(() => "?").join(",")})`
|
|
34165
|
+
).run(now, ...idList).changes;
|
|
34166
|
+
}
|
|
34167
|
+
/**
|
|
34168
|
+
* Hard-delete pending-event rows by id (including the dedup fingerprint history).
|
|
34169
|
+
* Used to expire an unresolved-delegate outbox entry that has exhausted its retry
|
|
34170
|
+
* budget — fully removing it frees the fingerprint so a genuinely new completion
|
|
34171
|
+
* for the same task could be re-queued later. Returns the number of rows deleted.
|
|
34172
|
+
*/
|
|
34173
|
+
deletePendingEventsById(ids) {
|
|
34174
|
+
const idList = ids.filter((id) => typeof id === "string" && id.length > 0);
|
|
34175
|
+
if (idList.length === 0) return 0;
|
|
34176
|
+
return this.db.prepare(
|
|
34177
|
+
`DELETE FROM mesh_pending_events WHERE id IN (${idList.map(() => "?").join(",")})`
|
|
34178
|
+
).run(...idList).changes;
|
|
34179
|
+
}
|
|
34141
34180
|
};
|
|
34142
34181
|
}
|
|
34143
34182
|
});
|
|
34144
34183
|
var mesh_missions_exports = {};
|
|
34145
34184
|
__export2(mesh_missions_exports, {
|
|
34185
|
+
GOAL_PREVIEW_MAX: () => GOAL_PREVIEW_MAX,
|
|
34146
34186
|
MESH_MISSION_STATUSES: () => MESH_MISSION_STATUSES,
|
|
34147
34187
|
buildMissionPromptSection: () => buildMissionPromptSection,
|
|
34148
34188
|
getActiveMeshMissionSummaries: () => getActiveMeshMissionSummaries,
|
|
@@ -34214,12 +34254,23 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34214
34254
|
function getActiveMeshMissionSummaries(meshId) {
|
|
34215
34255
|
return getMeshMissions(meshId, ["active"]).map((mission) => summarizeMeshMission(meshId, mission));
|
|
34216
34256
|
}
|
|
34257
|
+
function slimMissionSummary(summary) {
|
|
34258
|
+
const goal = typeof summary.goal === "string" ? summary.goal : "";
|
|
34259
|
+
const goalTruncated = goal.length > GOAL_PREVIEW_MAX;
|
|
34260
|
+
const { goal: _omitGoal, ...rest } = summary;
|
|
34261
|
+
return {
|
|
34262
|
+
...rest,
|
|
34263
|
+
goalPreview: goalTruncated ? goal.slice(0, GOAL_PREVIEW_MAX) : goal,
|
|
34264
|
+
goalTruncated
|
|
34265
|
+
};
|
|
34266
|
+
}
|
|
34217
34267
|
function getMeshStatusMissionSummaries(meshId, options) {
|
|
34218
34268
|
const historyLimit = Math.max(0, options?.historyLimit ?? 10);
|
|
34219
34269
|
const all = getMeshMissions(meshId);
|
|
34220
34270
|
const live = all.filter((m) => m.status === "active" || m.status === "paused");
|
|
34221
34271
|
const history = all.filter((m) => m.status === "completed" || m.status === "abandoned").sort((a, b) => (b.updatedAt || "").localeCompare(a.updatedAt || "")).slice(0, historyLimit);
|
|
34222
|
-
|
|
34272
|
+
const full = [...live, ...history].map((mission) => summarizeMeshMission(meshId, mission));
|
|
34273
|
+
return options?.verbose ? full : full.map(slimMissionSummary);
|
|
34223
34274
|
}
|
|
34224
34275
|
function buildMissionPromptSection(meshId) {
|
|
34225
34276
|
const summaries = getActiveMeshMissionSummaries(meshId);
|
|
@@ -34241,6 +34292,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34241
34292
|
}
|
|
34242
34293
|
var import_crypto6;
|
|
34243
34294
|
var MESH_MISSION_STATUSES;
|
|
34295
|
+
var GOAL_PREVIEW_MAX;
|
|
34244
34296
|
var init_mesh_missions = __esm2({
|
|
34245
34297
|
"src/mesh/mesh-missions.ts"() {
|
|
34246
34298
|
"use strict";
|
|
@@ -34248,6 +34300,7 @@ Valid status values: \`completed\` | \`failed\` | \`blocked\` | \`partial\`.`;
|
|
|
34248
34300
|
init_mesh_runtime_store();
|
|
34249
34301
|
init_mesh_work_queue();
|
|
34250
34302
|
MESH_MISSION_STATUSES = ["active", "paused", "completed", "abandoned"];
|
|
34303
|
+
GOAL_PREVIEW_MAX = 120;
|
|
34251
34304
|
}
|
|
34252
34305
|
});
|
|
34253
34306
|
function readString3(value) {
|
|
@@ -37363,6 +37416,111 @@ Next step: ${nextStep}`;
|
|
|
37363
37416
|
recentUnroutableDiagnostics = /* @__PURE__ */ new Map();
|
|
37364
37417
|
}
|
|
37365
37418
|
});
|
|
37419
|
+
function getStore() {
|
|
37420
|
+
try {
|
|
37421
|
+
return MeshRuntimeStore.getInstance();
|
|
37422
|
+
} catch {
|
|
37423
|
+
return void 0;
|
|
37424
|
+
}
|
|
37425
|
+
}
|
|
37426
|
+
function enqueueUnresolvedDelegateForward(coordinatorDaemonId, eventName, forwardPayload) {
|
|
37427
|
+
const target = readNonEmptyString2(coordinatorDaemonId);
|
|
37428
|
+
const event = readNonEmptyString2(eventName);
|
|
37429
|
+
if (!target || !event) return false;
|
|
37430
|
+
const store = getStore();
|
|
37431
|
+
if (!store) return false;
|
|
37432
|
+
const queuedAt = Date.now();
|
|
37433
|
+
const fingerprintSource = {
|
|
37434
|
+
event,
|
|
37435
|
+
meshId: UNRESOLVED_FORWARD_OUTBOX_MESH_ID,
|
|
37436
|
+
nodeLabel: readNonEmptyString2(forwardPayload.nodeId) || readNonEmptyString2(forwardPayload.workspace) || "unresolved-delegate",
|
|
37437
|
+
nodeId: readNonEmptyString2(forwardPayload.nodeId) || void 0,
|
|
37438
|
+
workspace: readNonEmptyString2(forwardPayload.workspace) || void 0,
|
|
37439
|
+
metadataEvent: forwardPayload,
|
|
37440
|
+
queuedAt,
|
|
37441
|
+
targetCoordinatorDaemonId: target
|
|
37442
|
+
};
|
|
37443
|
+
const fingerprint = `${target}::${buildPendingEventFingerprint(fingerprintSource)}`;
|
|
37444
|
+
try {
|
|
37445
|
+
const inserted = store.insertPendingEvent({
|
|
37446
|
+
id: (0, import_crypto9.randomUUID)(),
|
|
37447
|
+
meshId: UNRESOLVED_FORWARD_OUTBOX_MESH_ID,
|
|
37448
|
+
coordinatorDaemonId: target,
|
|
37449
|
+
event,
|
|
37450
|
+
// Store the flat forward payload + the queue timestamp so the retry tick can
|
|
37451
|
+
// rebuild the push args and apply age-based expiry without a schema change.
|
|
37452
|
+
payload: { forwardPayload, coordinatorDaemonId: target, queuedAt },
|
|
37453
|
+
fingerprint,
|
|
37454
|
+
queuedAt
|
|
37455
|
+
});
|
|
37456
|
+
if (inserted) {
|
|
37457
|
+
LOG2.info("MeshEvents", `Durably queued unresolved-delegate ${event} for coordinator ${target} (outbox)`);
|
|
37458
|
+
}
|
|
37459
|
+
return true;
|
|
37460
|
+
} catch (e) {
|
|
37461
|
+
LOG2.warn("MeshEvents", `Failed to persist unresolved-delegate forward to outbox: ${e?.message || e}`);
|
|
37462
|
+
return false;
|
|
37463
|
+
}
|
|
37464
|
+
}
|
|
37465
|
+
function peekUnresolvedDelegateForwards() {
|
|
37466
|
+
const store = getStore();
|
|
37467
|
+
if (!store) return [];
|
|
37468
|
+
let rows;
|
|
37469
|
+
try {
|
|
37470
|
+
rows = store.peekPendingEvents(UNRESOLVED_FORWARD_OUTBOX_MESH_ID);
|
|
37471
|
+
} catch {
|
|
37472
|
+
return [];
|
|
37473
|
+
}
|
|
37474
|
+
const out = [];
|
|
37475
|
+
for (const row of rows) {
|
|
37476
|
+
const stored = row.payload && typeof row.payload === "object" ? row.payload : {};
|
|
37477
|
+
const coordinatorDaemonId = readNonEmptyString2(stored.coordinatorDaemonId);
|
|
37478
|
+
const forwardPayload = stored.forwardPayload && typeof stored.forwardPayload === "object" ? stored.forwardPayload : void 0;
|
|
37479
|
+
if (!coordinatorDaemonId || !forwardPayload) continue;
|
|
37480
|
+
const queuedAt = typeof stored.queuedAt === "number" ? stored.queuedAt : 0;
|
|
37481
|
+
out.push({ id: row.id, coordinatorDaemonId, payload: forwardPayload, queuedAt });
|
|
37482
|
+
}
|
|
37483
|
+
return out;
|
|
37484
|
+
}
|
|
37485
|
+
function ackUnresolvedDelegateForward(id) {
|
|
37486
|
+
const store = getStore();
|
|
37487
|
+
if (!store) return;
|
|
37488
|
+
try {
|
|
37489
|
+
store.markPendingEventsDrainedById([id]);
|
|
37490
|
+
} catch {
|
|
37491
|
+
}
|
|
37492
|
+
}
|
|
37493
|
+
function expireStaleUnresolvedDelegateForwards(nowMs = Date.now()) {
|
|
37494
|
+
const entries = peekUnresolvedDelegateForwards();
|
|
37495
|
+
const staleIds = entries.filter((e) => e.queuedAt > 0 && nowMs - e.queuedAt >= UNRESOLVED_FORWARD_MAX_AGE_MS).map((e) => e.id);
|
|
37496
|
+
if (staleIds.length === 0) return 0;
|
|
37497
|
+
const store = getStore();
|
|
37498
|
+
if (!store) return 0;
|
|
37499
|
+
try {
|
|
37500
|
+
const removed = store.deletePendingEventsById(staleIds);
|
|
37501
|
+
if (removed > 0) {
|
|
37502
|
+
LOG2.warn("MeshEvents", `Expired ${removed} unresolved-delegate forward(s) after ${Math.round(UNRESOLVED_FORWARD_MAX_AGE_MS / 6e4)}m of failed retries \u2014 coordinator unreachable, completion dropped`);
|
|
37503
|
+
}
|
|
37504
|
+
return removed;
|
|
37505
|
+
} catch {
|
|
37506
|
+
return 0;
|
|
37507
|
+
}
|
|
37508
|
+
}
|
|
37509
|
+
var import_crypto9;
|
|
37510
|
+
var UNRESOLVED_FORWARD_OUTBOX_MESH_ID;
|
|
37511
|
+
var UNRESOLVED_FORWARD_MAX_AGE_MS;
|
|
37512
|
+
var init_mesh_unresolved_forward_outbox = __esm2({
|
|
37513
|
+
"src/mesh/mesh-unresolved-forward-outbox.ts"() {
|
|
37514
|
+
"use strict";
|
|
37515
|
+
import_crypto9 = require("crypto");
|
|
37516
|
+
init_logger();
|
|
37517
|
+
init_mesh_runtime_store();
|
|
37518
|
+
init_mesh_events_pending();
|
|
37519
|
+
init_mesh_events_utils();
|
|
37520
|
+
UNRESOLVED_FORWARD_OUTBOX_MESH_ID = "__unresolved_forward_outbox__";
|
|
37521
|
+
UNRESOLVED_FORWARD_MAX_AGE_MS = 30 * 60 * 1e3;
|
|
37522
|
+
}
|
|
37523
|
+
});
|
|
37366
37524
|
function resolveCoordinatorDrainDaemonIds(components) {
|
|
37367
37525
|
const ids = /* @__PURE__ */ new Set();
|
|
37368
37526
|
const statusInstanceId = readNonEmptyString2(components.statusInstanceId);
|
|
@@ -38496,12 +38654,25 @@ Next step: ${nextStep}`;
|
|
|
38496
38654
|
nodeId: readNonEmptyString2(routing.nodeId) || readNonEmptyString2(event.meshNodeId) || void 0,
|
|
38497
38655
|
workspace: readNonEmptyString2(routing.workspace) || readNonEmptyString2(event.workspace) || void 0
|
|
38498
38656
|
};
|
|
38499
|
-
|
|
38500
|
-
|
|
38657
|
+
const persisted = enqueueUnresolvedDelegateForward(coordinatorDaemonId, eventName, payload);
|
|
38658
|
+
Promise.resolve(components.dispatchMeshCommand(coordinatorDaemonId, "mesh_forward_event", payload)).then((result) => {
|
|
38659
|
+
if (result && result.success === false) {
|
|
38660
|
+
LOG2.warn("MeshEvents", `Immediate forward of ${eventName} to coordinator ${coordinatorDaemonId} rejected (${readNonEmptyString2(result.error) || "no reason"}) \u2014 left queued for retry`);
|
|
38661
|
+
return;
|
|
38662
|
+
}
|
|
38663
|
+
if (persisted) ackUnresolvedDelegateForwardByFingerprint(coordinatorDaemonId, eventName, payload);
|
|
38664
|
+
}).catch((e) => {
|
|
38665
|
+
LOG2.warn("MeshEvents", `Immediate forward of ${eventName} to coordinator ${coordinatorDaemonId} failed: ${e?.message || e} \u2014 left queued for retry`);
|
|
38501
38666
|
});
|
|
38502
|
-
LOG2.info("MeshEvents", `
|
|
38667
|
+
LOG2.info("MeshEvents", `Durably forwarded ${eventName} for unresolved-mesh worker at ${routing.workspace || "(no workspace)"} to coordinator daemon ${coordinatorDaemonId}`);
|
|
38503
38668
|
return true;
|
|
38504
38669
|
}
|
|
38670
|
+
function ackUnresolvedDelegateForwardByFingerprint(coordinatorDaemonId, eventName, payload) {
|
|
38671
|
+
const match = peekUnresolvedDelegateForwards().find(
|
|
38672
|
+
(entry) => entry.coordinatorDaemonId === coordinatorDaemonId && readNonEmptyString2(entry.payload.event) === eventName && readNonEmptyString2(entry.payload.targetSessionId || entry.payload.sessionId || entry.payload.instanceId) === readNonEmptyString2(payload.targetSessionId || payload.sessionId || payload.instanceId) && readNonEmptyString2(entry.payload.workspace) === readNonEmptyString2(payload.workspace)
|
|
38673
|
+
);
|
|
38674
|
+
if (match) ackUnresolvedDelegateForward(match.id);
|
|
38675
|
+
}
|
|
38505
38676
|
function setupMeshEventForwarding(components) {
|
|
38506
38677
|
components.instanceManager.onEvent((event) => {
|
|
38507
38678
|
if (event.event === "agent:ready" || event.event === "agent:generating_completed") {
|
|
@@ -38596,6 +38767,7 @@ Next step: ${nextStep}`;
|
|
|
38596
38767
|
init_mesh_runtime_store();
|
|
38597
38768
|
init_mesh_events_pending();
|
|
38598
38769
|
init_mesh_routing();
|
|
38770
|
+
init_mesh_unresolved_forward_outbox();
|
|
38599
38771
|
init_repo_mesh_types();
|
|
38600
38772
|
init_dist();
|
|
38601
38773
|
init_mesh_events_stale();
|
|
@@ -38709,6 +38881,13 @@ Next step: ${nextStep}`;
|
|
|
38709
38881
|
return void 0;
|
|
38710
38882
|
}
|
|
38711
38883
|
})();
|
|
38884
|
+
if (dispatchMeshCommand) {
|
|
38885
|
+
try {
|
|
38886
|
+
await retryUnresolvedDelegateForwards(components);
|
|
38887
|
+
} catch (e) {
|
|
38888
|
+
LOG2.warn("MeshReconcile", `Unresolved-delegate forward retry failed: ${e?.message || e}`);
|
|
38889
|
+
}
|
|
38890
|
+
}
|
|
38712
38891
|
if (dispatchMeshCommand) {
|
|
38713
38892
|
for (const mesh of listMeshes()) {
|
|
38714
38893
|
const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
|
|
@@ -38762,6 +38941,28 @@ Next step: ${nextStep}`;
|
|
|
38762
38941
|
}
|
|
38763
38942
|
}
|
|
38764
38943
|
}
|
|
38944
|
+
async function retryUnresolvedDelegateForwards(components) {
|
|
38945
|
+
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
38946
|
+
if (!dispatchMeshCommand) return;
|
|
38947
|
+
expireStaleUnresolvedDelegateForwards();
|
|
38948
|
+
const entries = peekUnresolvedDelegateForwards();
|
|
38949
|
+
if (entries.length === 0) return;
|
|
38950
|
+
for (const entry of entries) {
|
|
38951
|
+
let result;
|
|
38952
|
+
try {
|
|
38953
|
+
result = await dispatchMeshCommand(entry.coordinatorDaemonId, "mesh_forward_event", entry.payload);
|
|
38954
|
+
} catch (e) {
|
|
38955
|
+
LOG2.warn("MeshReconcile", `Retry forward to coordinator ${entry.coordinatorDaemonId} failed: ${e?.message || e} \u2014 left queued`);
|
|
38956
|
+
continue;
|
|
38957
|
+
}
|
|
38958
|
+
if (result && result.success === false) {
|
|
38959
|
+
LOG2.warn("MeshReconcile", `Retry forward to coordinator ${entry.coordinatorDaemonId} rejected (${readNonEmptyString2(result.error) || "no reason"}) \u2014 left queued`);
|
|
38960
|
+
continue;
|
|
38961
|
+
}
|
|
38962
|
+
ackUnresolvedDelegateForward(entry.id);
|
|
38963
|
+
LOG2.info("MeshReconcile", `Retried+delivered unresolved-delegate ${readNonEmptyString2(entry.payload.event)} to coordinator ${entry.coordinatorDaemonId}`);
|
|
38964
|
+
}
|
|
38965
|
+
}
|
|
38765
38966
|
async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDaemonIds) {
|
|
38766
38967
|
const dispatchMeshCommand = components.dispatchMeshCommand;
|
|
38767
38968
|
if (!dispatchMeshCommand) return;
|
|
@@ -38838,6 +39039,7 @@ Next step: ${nextStep}`;
|
|
|
38838
39039
|
init_mesh_events_pending();
|
|
38839
39040
|
init_mesh_runtime_store();
|
|
38840
39041
|
init_mesh_events_coordinator();
|
|
39042
|
+
init_mesh_unresolved_forward_outbox();
|
|
38841
39043
|
init_mesh_events_utils();
|
|
38842
39044
|
DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
|
|
38843
39045
|
}
|
|
@@ -51396,22 +51598,160 @@ ${cleanBody}`;
|
|
|
51396
51598
|
if (!Number.isFinite(numericOffset) || !Number.isFinite(numericExclude)) return false;
|
|
51397
51599
|
return true;
|
|
51398
51600
|
}
|
|
51601
|
+
var REVERSE_TAIL_SMALL_FILE_BYTES = 64 * 1024;
|
|
51602
|
+
var REVERSE_TAIL_CHUNK_BYTES = 64 * 1024;
|
|
51603
|
+
var TAIL_LINES_RETAINED = BOUNDED_TAIL_MAX_LIMIT + 2 * BOUNDED_TAIL_SLACK;
|
|
51604
|
+
var INCREMENTAL_TAIL_CACHE_MAX_ENTRIES = 64;
|
|
51605
|
+
var incrementalTailCache = /* @__PURE__ */ new Map();
|
|
51606
|
+
function evictIncrementalTailCache() {
|
|
51607
|
+
while (incrementalTailCache.size > INCREMENTAL_TAIL_CACHE_MAX_ENTRIES) {
|
|
51608
|
+
const oldest = incrementalTailCache.keys().next().value;
|
|
51609
|
+
if (oldest === void 0) break;
|
|
51610
|
+
incrementalTailCache.delete(oldest);
|
|
51611
|
+
}
|
|
51612
|
+
}
|
|
51613
|
+
function splitBufferLines(buf) {
|
|
51614
|
+
const lines = [];
|
|
51615
|
+
let lineEnd = buf.length;
|
|
51616
|
+
let firstNewline = -1;
|
|
51617
|
+
for (let i = buf.length - 1; i >= 0; i--) {
|
|
51618
|
+
if (buf[i] !== 10) continue;
|
|
51619
|
+
if (i + 1 < lineEnd) {
|
|
51620
|
+
lines.push(buf.toString("utf-8", i + 1, lineEnd));
|
|
51621
|
+
}
|
|
51622
|
+
lineEnd = i;
|
|
51623
|
+
firstNewline = i;
|
|
51624
|
+
}
|
|
51625
|
+
lines.reverse();
|
|
51626
|
+
const head = firstNewline >= 0 ? buf.subarray(0, firstNewline) : buf;
|
|
51627
|
+
return { head, lines };
|
|
51628
|
+
}
|
|
51629
|
+
function readReverseTailLines(filePath, needed) {
|
|
51630
|
+
const fd = fs52.openSync(filePath, "r");
|
|
51631
|
+
try {
|
|
51632
|
+
const stat2 = fs52.fstatSync(fd);
|
|
51633
|
+
const size = stat2.size;
|
|
51634
|
+
let position = size;
|
|
51635
|
+
let carry = Buffer.alloc(0);
|
|
51636
|
+
const collected = [];
|
|
51637
|
+
while (position > 0 && collected.length < needed) {
|
|
51638
|
+
const chunkSize = Math.min(REVERSE_TAIL_CHUNK_BYTES, position);
|
|
51639
|
+
position -= chunkSize;
|
|
51640
|
+
const chunk = Buffer.alloc(chunkSize);
|
|
51641
|
+
fs52.readSync(fd, chunk, 0, chunkSize, position);
|
|
51642
|
+
const combined = carry.length ? Buffer.concat([chunk, carry]) : chunk;
|
|
51643
|
+
const { head, lines } = splitBufferLines(combined);
|
|
51644
|
+
carry = head;
|
|
51645
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
51646
|
+
collected.push(lines[i]);
|
|
51647
|
+
}
|
|
51648
|
+
}
|
|
51649
|
+
const reachedStart = position <= 0;
|
|
51650
|
+
if (reachedStart && carry.length) {
|
|
51651
|
+
collected.push(carry.toString("utf-8"));
|
|
51652
|
+
}
|
|
51653
|
+
collected.reverse();
|
|
51654
|
+
return { lines: collected, coversWholeFile: reachedStart, size, mtimeMs: stat2.mtimeMs };
|
|
51655
|
+
} finally {
|
|
51656
|
+
fs52.closeSync(fd);
|
|
51657
|
+
}
|
|
51658
|
+
}
|
|
51659
|
+
function readFileTailLines(filePath, needed) {
|
|
51660
|
+
let stat2;
|
|
51661
|
+
try {
|
|
51662
|
+
stat2 = fs52.statSync(filePath);
|
|
51663
|
+
} catch {
|
|
51664
|
+
return { lines: [], coversWholeFile: true };
|
|
51665
|
+
}
|
|
51666
|
+
const size = stat2.size;
|
|
51667
|
+
const mtimeMs = stat2.mtimeMs;
|
|
51668
|
+
if (size === 0) {
|
|
51669
|
+
incrementalTailCache.delete(filePath);
|
|
51670
|
+
return { lines: [], coversWholeFile: true };
|
|
51671
|
+
}
|
|
51672
|
+
const cached22 = incrementalTailCache.get(filePath);
|
|
51673
|
+
if (cached22) {
|
|
51674
|
+
if (cached22.size === size && cached22.mtimeMs === mtimeMs) {
|
|
51675
|
+
incrementalTailCache.delete(filePath);
|
|
51676
|
+
incrementalTailCache.set(filePath, cached22);
|
|
51677
|
+
if (cached22.coversWholeFile || cached22.lines.length >= needed) {
|
|
51678
|
+
return { lines: cached22.lines, coversWholeFile: cached22.coversWholeFile };
|
|
51679
|
+
}
|
|
51680
|
+
} else if (size > cached22.size) {
|
|
51681
|
+
const incremental = tryIncrementalTailGrowth(filePath, cached22, size, mtimeMs, needed);
|
|
51682
|
+
if (incremental) return { lines: incremental.lines, coversWholeFile: incremental.coversWholeFile };
|
|
51683
|
+
}
|
|
51684
|
+
incrementalTailCache.delete(filePath);
|
|
51685
|
+
}
|
|
51686
|
+
if (size <= REVERSE_TAIL_SMALL_FILE_BYTES) {
|
|
51687
|
+
let content;
|
|
51688
|
+
try {
|
|
51689
|
+
content = fs52.readFileSync(filePath, "utf-8");
|
|
51690
|
+
} catch {
|
|
51691
|
+
return { lines: [], coversWholeFile: true };
|
|
51692
|
+
}
|
|
51693
|
+
const lines = content.split("\n");
|
|
51694
|
+
if (lines.length && lines[lines.length - 1] === "") lines.pop();
|
|
51695
|
+
storeIncrementalTailCache(filePath, size, mtimeMs, lines, true);
|
|
51696
|
+
return { lines, coversWholeFile: true };
|
|
51697
|
+
}
|
|
51698
|
+
let result;
|
|
51699
|
+
try {
|
|
51700
|
+
result = readReverseTailLines(filePath, needed);
|
|
51701
|
+
} catch {
|
|
51702
|
+
return { lines: [], coversWholeFile: true };
|
|
51703
|
+
}
|
|
51704
|
+
storeIncrementalTailCache(filePath, result.size, result.mtimeMs, result.lines, result.coversWholeFile);
|
|
51705
|
+
return { lines: result.lines, coversWholeFile: result.coversWholeFile };
|
|
51706
|
+
}
|
|
51707
|
+
function tryIncrementalTailGrowth(filePath, cached22, size, mtimeMs, needed) {
|
|
51708
|
+
const fd = fs52.openSync(filePath, "r");
|
|
51709
|
+
try {
|
|
51710
|
+
if (cached22.size > 0) {
|
|
51711
|
+
const boundary = Buffer.alloc(1);
|
|
51712
|
+
fs52.readSync(fd, boundary, 0, 1, cached22.size - 1);
|
|
51713
|
+
if (boundary[0] !== 10) return null;
|
|
51714
|
+
}
|
|
51715
|
+
const appendedLength = size - cached22.size;
|
|
51716
|
+
const appended = Buffer.alloc(appendedLength);
|
|
51717
|
+
fs52.readSync(fd, appended, 0, appendedLength, cached22.size);
|
|
51718
|
+
const newLines = appended.toString("utf-8").split("\n");
|
|
51719
|
+
if (newLines.length && newLines[newLines.length - 1] === "") newLines.pop();
|
|
51720
|
+
const merged = cached22.lines.concat(newLines);
|
|
51721
|
+
const trimmed = merged.length > TAIL_LINES_RETAINED ? merged.slice(merged.length - TAIL_LINES_RETAINED) : merged;
|
|
51722
|
+
const coversWholeFile = cached22.coversWholeFile && trimmed.length === merged.length;
|
|
51723
|
+
storeIncrementalTailCache(filePath, size, mtimeMs, trimmed, coversWholeFile);
|
|
51724
|
+
if (coversWholeFile || trimmed.length >= needed) {
|
|
51725
|
+
return { lines: trimmed, coversWholeFile };
|
|
51726
|
+
}
|
|
51727
|
+
return { lines: trimmed, coversWholeFile };
|
|
51728
|
+
} catch {
|
|
51729
|
+
return null;
|
|
51730
|
+
} finally {
|
|
51731
|
+
fs52.closeSync(fd);
|
|
51732
|
+
}
|
|
51733
|
+
}
|
|
51734
|
+
function storeIncrementalTailCache(filePath, size, mtimeMs, lines, coversWholeFile) {
|
|
51735
|
+
const retained = lines.length > TAIL_LINES_RETAINED ? lines.slice(lines.length - TAIL_LINES_RETAINED) : lines;
|
|
51736
|
+
const covers = coversWholeFile && retained.length === lines.length;
|
|
51737
|
+
incrementalTailCache.delete(filePath);
|
|
51738
|
+
incrementalTailCache.set(filePath, { size, mtimeMs, lines: retained, coversWholeFile: covers });
|
|
51739
|
+
evictIncrementalTailCache();
|
|
51740
|
+
}
|
|
51399
51741
|
function readBoundedTailRecords(agentType, dir, files, needed) {
|
|
51400
51742
|
const collected = [];
|
|
51401
51743
|
const seen = /* @__PURE__ */ new Set();
|
|
51402
51744
|
let readAllFiles = true;
|
|
51403
51745
|
for (let f = 0; f < files.length; f++) {
|
|
51404
51746
|
const filePath = path12.join(dir, files[f]);
|
|
51405
|
-
|
|
51406
|
-
|
|
51407
|
-
|
|
51408
|
-
} catch {
|
|
51409
|
-
continue;
|
|
51410
|
-
}
|
|
51411
|
-
const lines = content.trim().split("\n").filter(Boolean);
|
|
51747
|
+
const remaining = Math.max(0, needed - collected.length);
|
|
51748
|
+
const perFileNeeded = Math.min(needed, remaining + BOUNDED_TAIL_SLACK);
|
|
51749
|
+
const { lines, coversWholeFile } = readFileTailLines(filePath, perFileNeeded);
|
|
51412
51750
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
51751
|
+
const line = lines[i];
|
|
51752
|
+
if (!line) continue;
|
|
51413
51753
|
try {
|
|
51414
|
-
const parsed = JSON.parse(
|
|
51754
|
+
const parsed = JSON.parse(line);
|
|
51415
51755
|
const sanitizedMessage = sanitizeHistoryMessage(agentType, parsed);
|
|
51416
51756
|
if (!sanitizedMessage) continue;
|
|
51417
51757
|
const hash2 = buildHistoryMessageHash(agentType, sanitizedMessage);
|
|
@@ -51421,6 +51761,10 @@ ${cleanBody}`;
|
|
|
51421
51761
|
} catch {
|
|
51422
51762
|
}
|
|
51423
51763
|
}
|
|
51764
|
+
if (!coversWholeFile) {
|
|
51765
|
+
readAllFiles = false;
|
|
51766
|
+
break;
|
|
51767
|
+
}
|
|
51424
51768
|
if (collected.length >= needed && f < files.length - 1) {
|
|
51425
51769
|
readAllFiles = false;
|
|
51426
51770
|
break;
|
|
@@ -52018,7 +52362,7 @@ ${cleanBody}`;
|
|
|
52018
52362
|
this.runtimeMessages = [];
|
|
52019
52363
|
}
|
|
52020
52364
|
updateSettings(newSettings) {
|
|
52021
|
-
this.settings = { ...newSettings };
|
|
52365
|
+
this.settings = { ...this.settings, ...newSettings };
|
|
52022
52366
|
this.monitor.updateConfig({
|
|
52023
52367
|
approvalAlert: this.settings.approvalAlert !== false,
|
|
52024
52368
|
longGeneratingAlert: this.settings.longGeneratingAlert !== false,
|
|
@@ -52675,7 +53019,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
52675
53019
|
this.extensions.clear();
|
|
52676
53020
|
}
|
|
52677
53021
|
updateSettings(newSettings) {
|
|
52678
|
-
this.settings = { ...newSettings };
|
|
53022
|
+
this.settings = { ...this.settings, ...newSettings };
|
|
52679
53023
|
this.monitor.updateConfig({
|
|
52680
53024
|
approvalAlert: this.settings.approvalAlert !== false,
|
|
52681
53025
|
longGeneratingAlert: this.settings.longGeneratingAlert !== false,
|
|
@@ -61291,12 +61635,14 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
61291
61635
|
}
|
|
61292
61636
|
this.maybeClearResolvedClaudeTuiPrompt();
|
|
61293
61637
|
this.maybeCaptureClaudeTuiPrompt();
|
|
61638
|
+
this.maybeUpgradeClaudeTuiMultiSelect();
|
|
61294
61639
|
this.statusCallback?.();
|
|
61295
61640
|
return;
|
|
61296
61641
|
case "pty_data":
|
|
61297
61642
|
this.detectInteractivePromptFromPtyChunk(ev.chunk);
|
|
61298
61643
|
this.maybeClearResolvedClaudeTuiPrompt();
|
|
61299
61644
|
this.maybeCaptureClaudeTuiPrompt();
|
|
61645
|
+
this.maybeUpgradeClaudeTuiMultiSelect();
|
|
61300
61646
|
try {
|
|
61301
61647
|
this.ptyDataCallback?.(ev.chunk);
|
|
61302
61648
|
} catch {
|
|
@@ -61445,6 +61791,35 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
61445
61791
|
this.claudeTuiPromptCaptureInFlight = false;
|
|
61446
61792
|
});
|
|
61447
61793
|
}
|
|
61794
|
+
/**
|
|
61795
|
+
* The TUI prompt is captured on the FIRST frame that renders the
|
|
61796
|
+
* "Enter to select" footer. At that instant the option rows' checkbox
|
|
61797
|
+
* column may not have drawn yet, so `detectClaudeTuiMultiSelect` returns
|
|
61798
|
+
* false and the prompt is frozen as single-select — the dashboard then
|
|
61799
|
+
* renders radio buttons even though the picker is multi-select.
|
|
61800
|
+
*
|
|
61801
|
+
* While the same TUI prompt is still on screen, re-check the live snapshot:
|
|
61802
|
+
* if checkbox glyphs have since appeared, promote any single-select
|
|
61803
|
+
* question to multi-select and re-emit status. Promotion is one-way
|
|
61804
|
+
* (false→true only) — once a question is known multi-select we never demote
|
|
61805
|
+
* it, since the glyph column can scroll out of view on later frames.
|
|
61806
|
+
*/
|
|
61807
|
+
maybeUpgradeClaudeTuiMultiSelect() {
|
|
61808
|
+
if (this.cliType !== "claude-cli" || this.interactivePromptTransport !== "tui" || !this.activeInteractivePrompt) return;
|
|
61809
|
+
const questions = this.activeInteractivePrompt.questions;
|
|
61810
|
+
if (questions.length !== 1) return;
|
|
61811
|
+
if (questions[0].multiSelect) return;
|
|
61812
|
+
let screenText = "";
|
|
61813
|
+
try {
|
|
61814
|
+
screenText = this.driver.snapshot();
|
|
61815
|
+
} catch {
|
|
61816
|
+
return;
|
|
61817
|
+
}
|
|
61818
|
+
if (!screenText.includes("Enter to select")) return;
|
|
61819
|
+
if (!detectClaudeTuiMultiSelect(screenText)) return;
|
|
61820
|
+
questions[0].multiSelect = true;
|
|
61821
|
+
this.statusCallback?.();
|
|
61822
|
+
}
|
|
61448
61823
|
readClaudeTuiHeaders(screenText) {
|
|
61449
61824
|
const navLine = screenText.split(/\r?\n/).find((line) => line.includes("\u2714 Submit") && /[☐☒]/.test(line));
|
|
61450
61825
|
if (!navLine) return [];
|
|
@@ -61586,6 +61961,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
61586
61961
|
}
|
|
61587
61962
|
return normalizedId;
|
|
61588
61963
|
}
|
|
61964
|
+
var STATUS_HYDRATION_TAIL_LIMIT = 200;
|
|
61589
61965
|
function isIdleStatus(value) {
|
|
61590
61966
|
const status = typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
61591
61967
|
return !status || status === "idle" || status === "ready";
|
|
@@ -62145,22 +62521,7 @@ ${formatManifestValidationIssues2(validation.issues)}`,
|
|
|
62145
62521
|
};
|
|
62146
62522
|
}
|
|
62147
62523
|
updateSettings(newSettings) {
|
|
62148
|
-
|
|
62149
|
-
for (const key of [
|
|
62150
|
-
"meshNodeFor",
|
|
62151
|
-
"meshNodeId",
|
|
62152
|
-
"meshActiveTaskId",
|
|
62153
|
-
"meshCoordinatorFor",
|
|
62154
|
-
"meshCoordinatorDaemonId",
|
|
62155
|
-
"meshCoordinatorNodeId",
|
|
62156
|
-
"spawnedSessionVisibility",
|
|
62157
|
-
"launchedByCoordinator"
|
|
62158
|
-
]) {
|
|
62159
|
-
if (this.settings[key] !== void 0 && newSettings[key] === void 0) {
|
|
62160
|
-
runtimeMeshSettings[key] = this.settings[key];
|
|
62161
|
-
}
|
|
62162
|
-
}
|
|
62163
|
-
this.settings = { ...newSettings, ...runtimeMeshSettings };
|
|
62524
|
+
this.settings = { ...this.settings, ...newSettings };
|
|
62164
62525
|
this.adapter.updateRuntimeSettings?.(this.settings);
|
|
62165
62526
|
this.monitor.updateConfig({
|
|
62166
62527
|
approvalAlert: this.settings.approvalAlert !== false,
|
|
@@ -63263,12 +63624,14 @@ ${effect.notification.body || ""}`.trim();
|
|
|
63263
63624
|
const newestMessageAt = parsedMessages.reduce((newest, message) => Math.max(newest, getMessageTime(message)), 0);
|
|
63264
63625
|
return newestMessageAt === 0;
|
|
63265
63626
|
}
|
|
63266
|
-
syncCanonicalSavedHistoryIfNeeded() {
|
|
63627
|
+
syncCanonicalSavedHistoryIfNeeded(options = {}) {
|
|
63267
63628
|
if (!this.providerSessionId) return false;
|
|
63268
63629
|
const canonicalHistory = this.provider.nativeHistory;
|
|
63269
63630
|
if (!canonicalHistory) return false;
|
|
63631
|
+
const limit = options.full ? Number.MAX_SAFE_INTEGER : STATUS_HYDRATION_TAIL_LIMIT;
|
|
63632
|
+
const windowTag = options.full ? "full" : `tail:${STATUS_HYDRATION_TAIL_LIMIT}`;
|
|
63270
63633
|
if (isNativeSourceCanonicalHistory(canonicalHistory)) {
|
|
63271
|
-
const cacheKey = [this.type, this.providerSessionId, this.workingDir].join("\0");
|
|
63634
|
+
const cacheKey = [this.type, this.providerSessionId, this.workingDir, windowTag].join("\0");
|
|
63272
63635
|
const now = Date.now();
|
|
63273
63636
|
if (cacheKey === this.lastNativeSourceCanonicalCacheKey && now - this.lastNativeSourceCanonicalCheckAt < 2e3) {
|
|
63274
63637
|
return true;
|
|
@@ -63280,7 +63643,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
63280
63643
|
historySessionId: this.providerSessionId,
|
|
63281
63644
|
workspace: this.workingDir,
|
|
63282
63645
|
offset: 0,
|
|
63283
|
-
limit
|
|
63646
|
+
limit,
|
|
63284
63647
|
historyBehavior: this.provider.historyBehavior,
|
|
63285
63648
|
scripts: this.provider.scripts
|
|
63286
63649
|
});
|
|
@@ -63296,7 +63659,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
63296
63659
|
return true;
|
|
63297
63660
|
}
|
|
63298
63661
|
try {
|
|
63299
|
-
const cacheKey = [this.type, this.providerSessionId, this.workingDir, canonicalHistory.mode || "materialized-mirror"].join("\0");
|
|
63662
|
+
const cacheKey = [this.type, this.providerSessionId, this.workingDir, canonicalHistory.mode || "materialized-mirror", windowTag].join("\0");
|
|
63300
63663
|
const now = Date.now();
|
|
63301
63664
|
if (cacheKey === this.lastNativeSourceCanonicalCacheKey && now - this.lastNativeSourceCanonicalCheckAt < 2e3) {
|
|
63302
63665
|
return true;
|
|
@@ -63306,7 +63669,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
63306
63669
|
if (!materializeProviderNativeHistory(this.type, canonicalHistory, this.providerSessionId, this.workingDir, this.provider.scripts)) {
|
|
63307
63670
|
return false;
|
|
63308
63671
|
}
|
|
63309
|
-
const restoredHistory = readChatHistory(this.type, 0,
|
|
63672
|
+
const restoredHistory = readChatHistory(this.type, 0, limit, this.providerSessionId, 0, this.provider.historyBehavior);
|
|
63310
63673
|
this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
|
|
63311
63674
|
role: message.role,
|
|
63312
63675
|
content: message.content,
|
|
@@ -63321,7 +63684,7 @@ ${effect.notification.body || ""}`.trim();
|
|
|
63321
63684
|
}
|
|
63322
63685
|
restorePersistedHistoryFromCurrentSession() {
|
|
63323
63686
|
if (!this.providerSessionId) return;
|
|
63324
|
-
this.syncCanonicalSavedHistoryIfNeeded();
|
|
63687
|
+
this.syncCanonicalSavedHistoryIfNeeded({ full: true });
|
|
63325
63688
|
const restoredHistory = isNativeSourceCanonicalHistory(this.provider.nativeHistory) ? readProviderChatHistory(this.type, {
|
|
63326
63689
|
canonicalHistory: this.provider.nativeHistory,
|
|
63327
63690
|
historySessionId: this.providerSessionId,
|
|
@@ -76164,9 +76527,9 @@ ${hintLines.join("\n")}` : "",
|
|
|
76164
76527
|
});
|
|
76165
76528
|
let node;
|
|
76166
76529
|
if (meshRecord.inline) {
|
|
76167
|
-
const { randomUUID:
|
|
76530
|
+
const { randomUUID: randomUUID15 } = await import("crypto");
|
|
76168
76531
|
node = {
|
|
76169
|
-
id: `node_${
|
|
76532
|
+
id: `node_${randomUUID15().replace(/-/g, "")}`,
|
|
76170
76533
|
workspace: result.worktreePath,
|
|
76171
76534
|
repoRoot: result.worktreePath,
|
|
76172
76535
|
daemonId: sourceNode.daemonId,
|
|
@@ -76940,10 +77303,11 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
76940
77303
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
76941
77304
|
const meshHost = resolveMeshHostStatus(mesh);
|
|
76942
77305
|
const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
|
|
77306
|
+
const verboseMissions = args?.verbose === true || args?.compact === false;
|
|
76943
77307
|
const peekScope = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : this.deps.statusInstanceId || void 0;
|
|
76944
77308
|
const pendingCoordinatorEventCount = getPendingMeshCoordinatorEvents(meshId, peekScope).length;
|
|
76945
77309
|
const hadAggregateCache = this.aggregateMeshStatusCache.has(meshId);
|
|
76946
|
-
if (!refreshRequested && pendingCoordinatorEventCount === 0) {
|
|
77310
|
+
if (!refreshRequested && !verboseMissions && pendingCoordinatorEventCount === 0) {
|
|
76947
77311
|
const cachedStatus = this.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
|
|
76948
77312
|
if (cachedStatus) {
|
|
76949
77313
|
logRepoMeshStatusDebug("return_cached", {
|
|
@@ -77246,7 +77610,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
77246
77610
|
liveSessionRecords: liveMeshSessions
|
|
77247
77611
|
});
|
|
77248
77612
|
const { getMeshStatusMissionSummaries: getMeshStatusMissionSummaries2 } = await Promise.resolve().then(() => (init_mesh_missions(), mesh_missions_exports));
|
|
77249
|
-
const missions = getMeshStatusMissionSummaries2(meshId);
|
|
77613
|
+
const missions = getMeshStatusMissionSummaries2(meshId, { verbose: verboseMissions });
|
|
77250
77614
|
const statusResult = {
|
|
77251
77615
|
success: true,
|
|
77252
77616
|
meshId: mesh.id,
|
|
@@ -77300,7 +77664,7 @@ ${ptyResult.output.slice(-2e3)}`);
|
|
|
77300
77664
|
}))
|
|
77301
77665
|
};
|
|
77302
77666
|
const { pendingCoordinatorEvents: _pendingCoordinatorEvents, unroutableDeliveries: _unroutableDeliveries, ...cacheableStatusResult } = statusResult;
|
|
77303
|
-
const rememberedStatus = this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
|
|
77667
|
+
const rememberedStatus = verboseMissions ? cacheableStatusResult : this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
|
|
77304
77668
|
const returnedStatus = {
|
|
77305
77669
|
...rememberedStatus,
|
|
77306
77670
|
...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {},
|
|
@@ -84812,7 +85176,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
84812
85176
|
});
|
|
84813
85177
|
}
|
|
84814
85178
|
};
|
|
84815
|
-
var
|
|
85179
|
+
var import_crypto10 = require("crypto");
|
|
84816
85180
|
var import_session_host_core10 = require_dist();
|
|
84817
85181
|
var BASE_KEY_SEQUENCES = {
|
|
84818
85182
|
enter: "\r",
|
|
@@ -84910,7 +85274,7 @@ data: ${JSON.stringify(msg.data)}
|
|
|
84910
85274
|
const sessionId = String(options.sessionId || "").trim();
|
|
84911
85275
|
if (!sessionId) throw new Error("sessionId is required");
|
|
84912
85276
|
const mode = options.mode || "read";
|
|
84913
|
-
const clientId = options.clientId || `raw-terminal-${process.pid}-${(0,
|
|
85277
|
+
const clientId = options.clientId || `raw-terminal-${process.pid}-${(0, import_crypto10.randomUUID)().slice(0, 8)}`;
|
|
84914
85278
|
const client = options.client || new import_session_host_core10.SessionHostClient({ endpoint: options.endpoint });
|
|
84915
85279
|
await client.connect();
|
|
84916
85280
|
const attachResponse = await client.request({
|