@adhdev/daemon-core 0.9.82-rc.187 → 0.9.82-rc.188
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/boot/daemon-lifecycle.d.ts +1 -0
- package/dist/commands/cli-manager.d.ts +2 -1
- package/dist/commands/router.d.ts +5 -1
- package/dist/git/git-commands.d.ts +2 -0
- package/dist/git/git-types.d.ts +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +401 -33
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +400 -33
- package/dist/index.mjs.map +1 -1
- package/dist/providers/cli-provider-instance.d.ts +4 -0
- package/dist/providers/contracts.d.ts +31 -0
- package/dist/providers/sdk/v1/types/common/index.d.ts +35 -1
- package/dist/providers/spec/driver.d.ts +6 -1
- package/dist/providers/spec/schema.gen.d.ts +22 -0
- package/dist/providers/spec/types.d.ts +10 -0
- package/dist/repo-mesh-types.d.ts +6 -0
- package/package.json +1 -1
- package/src/boot/daemon-lifecycle.ts +2 -0
- package/src/commands/chat-commands.ts +26 -0
- package/src/commands/cli-manager.ts +52 -14
- package/src/commands/router.ts +35 -4
- package/src/git/git-commands.ts +20 -2
- package/src/git/git-status.ts +35 -6
- package/src/git/git-types.ts +2 -0
- package/src/index.ts +1 -1
- package/src/providers/cli-provider-instance.ts +110 -9
- package/src/providers/contracts.d.ts +55 -0
- package/src/providers/contracts.ts +35 -0
- package/src/providers/provider-schema.ts +56 -1
- package/src/providers/sdk/v1/schemas/cli/provider.schema.json +46 -0
- package/src/providers/sdk/v1/types/common/index.ts +19 -0
- package/src/providers/spec/driver.ts +68 -1
- package/src/providers/spec/schema.gen.ts +12 -1
- package/src/providers/spec/schema.json +21 -1
- package/src/providers/spec/types.ts +10 -0
- package/src/repo-mesh-types.ts +6 -0
package/dist/index.mjs
CHANGED
|
@@ -270,6 +270,8 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
270
270
|
if (includeSubmodules) {
|
|
271
271
|
submodules = await getSubmoduleStatuses(repo, options);
|
|
272
272
|
}
|
|
273
|
+
const submoduleDirty = (submodules || []).some((submodule) => submodule.dirty || submodule.outOfSync || !!submodule.error);
|
|
274
|
+
const dirty = parsed.staged + parsed.modified + parsed.untracked + parsed.deleted + parsed.renamed > 0 || parsed.conflictFiles.length > 0 || stashCount > 0 || submoduleDirty;
|
|
273
275
|
return {
|
|
274
276
|
workspace: repo.workspace,
|
|
275
277
|
repoRoot: repo.repoRoot,
|
|
@@ -288,6 +290,7 @@ async function getGitRepoStatus(workspace, options = {}) {
|
|
|
288
290
|
untracked: parsed.untracked,
|
|
289
291
|
deleted: parsed.deleted,
|
|
290
292
|
renamed: parsed.renamed,
|
|
293
|
+
dirty,
|
|
291
294
|
hasConflicts: parsed.conflictFiles.length > 0,
|
|
292
295
|
conflictFiles: parsed.conflictFiles,
|
|
293
296
|
stashCount,
|
|
@@ -461,6 +464,7 @@ function emptyStatus(workspace, lastCheckedAt, error) {
|
|
|
461
464
|
untracked: 0,
|
|
462
465
|
deleted: 0,
|
|
463
466
|
renamed: 0,
|
|
467
|
+
dirty: false,
|
|
464
468
|
hasConflicts: false,
|
|
465
469
|
conflictFiles: [],
|
|
466
470
|
stashCount: 0,
|
|
@@ -473,17 +477,33 @@ async function getSubmoduleStatuses(repo, options) {
|
|
|
473
477
|
if (!repo.repoRoot) return [];
|
|
474
478
|
try {
|
|
475
479
|
const result = await runGit(repo, ["submodule", "status", "--recursive"], options);
|
|
476
|
-
|
|
480
|
+
const submodules = parseSubmoduleStatusOutput(result.stdout, repo.repoRoot, options.submoduleIgnorePaths);
|
|
481
|
+
await Promise.all(submodules.map((submodule) => enrichSubmoduleWorktreeStatus(repo, submodule, options)));
|
|
482
|
+
return submodules;
|
|
477
483
|
} catch {
|
|
478
484
|
return [];
|
|
479
485
|
}
|
|
480
486
|
}
|
|
487
|
+
async function enrichSubmoduleWorktreeStatus(repo, submodule, options) {
|
|
488
|
+
try {
|
|
489
|
+
const result = await runGit(repo, ["status", "--porcelain=v2", "--branch"], {
|
|
490
|
+
...options,
|
|
491
|
+
cwd: submodule.repoPath
|
|
492
|
+
});
|
|
493
|
+
const parsed = parsePorcelainV2Status(result.stdout);
|
|
494
|
+
const dirty = parsed.staged + parsed.modified + parsed.untracked + parsed.deleted + parsed.renamed > 0 || parsed.conflictFiles.length > 0;
|
|
495
|
+
submodule.dirty = submodule.dirty || dirty;
|
|
496
|
+
} catch (error) {
|
|
497
|
+
submodule.dirty = true;
|
|
498
|
+
submodule.error = formatGitError(error);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
481
501
|
function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
|
|
482
502
|
const submodules = [];
|
|
483
503
|
const ignoreSet = new Set(ignorePaths || []);
|
|
484
504
|
for (const line of output.split("\n")) {
|
|
485
505
|
if (!line.trim()) continue;
|
|
486
|
-
const match = line.match(/^([
|
|
506
|
+
const match = line.match(/^([\-+U\s])([0-9a-f]{40})\s+(\S+)(?:\s+\(([^)]+)\))?/);
|
|
487
507
|
if (!match) continue;
|
|
488
508
|
const prefix = match[1];
|
|
489
509
|
const commit = match[2];
|
|
@@ -493,8 +513,8 @@ function parseSubmoduleStatusOutput(output, repoRoot, ignorePaths) {
|
|
|
493
513
|
path: path40,
|
|
494
514
|
commit,
|
|
495
515
|
repoPath: repoRoot + "/" + path40,
|
|
496
|
-
dirty: prefix === "
|
|
497
|
-
outOfSync: prefix === "-",
|
|
516
|
+
dirty: prefix === "U",
|
|
517
|
+
outOfSync: prefix === "-" || prefix === "+",
|
|
498
518
|
lastCheckedAt: Date.now()
|
|
499
519
|
});
|
|
500
520
|
}
|
|
@@ -6150,6 +6170,52 @@ var init_provider_schema = __esm({
|
|
|
6150
6170
|
properties: { mode: { const: "env_var" }, name: { type: "string" } }
|
|
6151
6171
|
}
|
|
6152
6172
|
]
|
|
6173
|
+
},
|
|
6174
|
+
delegatedWorkerIsolation: {
|
|
6175
|
+
description: "Provider-declared launch isolation for coordinator-spawned worker sessions. Keeps worker-only sessions from inheriting coordinator MCP/tools/config.",
|
|
6176
|
+
type: "object",
|
|
6177
|
+
additionalProperties: false,
|
|
6178
|
+
properties: {
|
|
6179
|
+
env: {
|
|
6180
|
+
type: "object",
|
|
6181
|
+
additionalProperties: false,
|
|
6182
|
+
properties: {
|
|
6183
|
+
unset: {
|
|
6184
|
+
type: "array",
|
|
6185
|
+
items: { type: "string", minLength: 1 }
|
|
6186
|
+
}
|
|
6187
|
+
}
|
|
6188
|
+
},
|
|
6189
|
+
args: {
|
|
6190
|
+
type: "array",
|
|
6191
|
+
items: {
|
|
6192
|
+
oneOf: [
|
|
6193
|
+
{
|
|
6194
|
+
type: "object",
|
|
6195
|
+
additionalProperties: false,
|
|
6196
|
+
required: ["mode", "flag"],
|
|
6197
|
+
properties: {
|
|
6198
|
+
mode: { const: "empty_mcp_config" },
|
|
6199
|
+
flag: { type: "string", minLength: 1 },
|
|
6200
|
+
strictFlag: { type: "string", minLength: 1 }
|
|
6201
|
+
}
|
|
6202
|
+
},
|
|
6203
|
+
{
|
|
6204
|
+
type: "object",
|
|
6205
|
+
additionalProperties: false,
|
|
6206
|
+
required: ["mode", "flag", "key", "value"],
|
|
6207
|
+
properties: {
|
|
6208
|
+
mode: { const: "config_override" },
|
|
6209
|
+
flag: { type: "string", minLength: 1 },
|
|
6210
|
+
key: { type: "string", minLength: 1 },
|
|
6211
|
+
value: { type: "string", minLength: 1 },
|
|
6212
|
+
dedupeKey: { type: "string", minLength: 1 }
|
|
6213
|
+
}
|
|
6214
|
+
}
|
|
6215
|
+
]
|
|
6216
|
+
}
|
|
6217
|
+
}
|
|
6218
|
+
}
|
|
6153
6219
|
}
|
|
6154
6220
|
}
|
|
6155
6221
|
},
|
|
@@ -12025,7 +12091,14 @@ async function handleGitCommand(command, args, services = defaultGitCommandServi
|
|
|
12025
12091
|
switch (command) {
|
|
12026
12092
|
case "git_status": {
|
|
12027
12093
|
if (!services.getStatus) return serviceNotImplemented(command);
|
|
12028
|
-
const
|
|
12094
|
+
const submoduleIgnorePaths = Array.isArray(args?.submoduleIgnorePaths) ? args.submoduleIgnorePaths.filter((value) => typeof value === "string" && value.trim().length > 0) : void 0;
|
|
12095
|
+
const statusParams = { workspace };
|
|
12096
|
+
const refreshUpstream = optionalBoolean(args?.refreshUpstream);
|
|
12097
|
+
const includeSubmodules = optionalBoolean(args?.includeSubmodules);
|
|
12098
|
+
if (refreshUpstream !== void 0) statusParams.refreshUpstream = refreshUpstream;
|
|
12099
|
+
if (includeSubmodules !== void 0) statusParams.includeSubmodules = includeSubmodules;
|
|
12100
|
+
if (submoduleIgnorePaths && submoduleIgnorePaths.length > 0) statusParams.submoduleIgnorePaths = submoduleIgnorePaths;
|
|
12101
|
+
const status = await runService(() => services.getStatus(statusParams));
|
|
12029
12102
|
return "success" in status ? status : { success: true, status };
|
|
12030
12103
|
}
|
|
12031
12104
|
case "git_diff_summary": {
|
|
@@ -12158,6 +12231,14 @@ async function gitCheckpoint(workspace, message, includeUntracked) {
|
|
|
12158
12231
|
if (statusResult.hasConflicts) {
|
|
12159
12232
|
throw new GitCommandError("conflict", "Repository has conflicts \u2014 resolve before checkpointing");
|
|
12160
12233
|
}
|
|
12234
|
+
const dirtySubmodules = (statusResult.submodules || []).filter((submodule) => submodule.dirty);
|
|
12235
|
+
if (dirtySubmodules.length > 0) {
|
|
12236
|
+
const paths = dirtySubmodules.map((submodule) => submodule.path).join(", ");
|
|
12237
|
+
throw new GitCommandError(
|
|
12238
|
+
"dirty_index_required",
|
|
12239
|
+
`Repository has dirty submodules that must be checkpointed first: ${paths}. Checkpoint or commit each dirty submodule, then checkpoint this repository to record gitlink changes.`
|
|
12240
|
+
);
|
|
12241
|
+
}
|
|
12161
12242
|
const addArgs = includeUntracked ? ["-A"] : ["-u"];
|
|
12162
12243
|
await runGit(repo, ["add", ...addArgs], { cwd: repoRoot });
|
|
12163
12244
|
const fullMsg = `adhdev: checkpoint ${message}`;
|
|
@@ -21479,6 +21560,14 @@ function hasVisibleAssistantMessage(messages) {
|
|
|
21479
21560
|
return String(message.content || "").trim().length > 0;
|
|
21480
21561
|
});
|
|
21481
21562
|
}
|
|
21563
|
+
function hasFinalVisibleAssistantMessage(messages) {
|
|
21564
|
+
if (!Array.isArray(messages)) return false;
|
|
21565
|
+
const visible = filterUserFacingChatMessages(messages);
|
|
21566
|
+
const last = visible[visible.length - 1];
|
|
21567
|
+
const role = typeof last?.role === "string" ? last.role.trim().toLowerCase() : "";
|
|
21568
|
+
const content = last ? flattenContent(last.content).trim() : "";
|
|
21569
|
+
return (role === "assistant" || role === "model") && content.length > 0;
|
|
21570
|
+
}
|
|
21482
21571
|
function shouldTrustCliAdapterTerminalStatus(parsedStatus, activeModal, adapter, adapterStatus) {
|
|
21483
21572
|
if (!isGeneratingLikeStatus(parsedStatus)) return false;
|
|
21484
21573
|
if (hasNonEmptyModalButtons(activeModal)) return false;
|
|
@@ -22333,6 +22422,18 @@ async function handleReadChat(h, args) {
|
|
|
22333
22422
|
});
|
|
22334
22423
|
}
|
|
22335
22424
|
}
|
|
22425
|
+
if (isGeneratingLikeStatus(selectedStatus) && selectedTranscriptAuthority === "provider" && !hasNonEmptyModalButtons(activeModal) && hasFinalVisibleAssistantMessage(selectedMessages)) {
|
|
22426
|
+
selectedStatus = "idle";
|
|
22427
|
+
selectedMessages = finalizeStreamingMessagesWhenIdle(selectedMessages, selectedStatus);
|
|
22428
|
+
messageSource = {
|
|
22429
|
+
...messageSource,
|
|
22430
|
+
statusReconciled: {
|
|
22431
|
+
from: returnedStatus,
|
|
22432
|
+
to: "idle",
|
|
22433
|
+
reason: "provider_native_final_assistant"
|
|
22434
|
+
}
|
|
22435
|
+
};
|
|
22436
|
+
}
|
|
22336
22437
|
LOG.debug("Command", `[read_chat] cli-like parsed provider=${adapter.cliType} target=${String(args?.targetSessionId || "")} adapterStatus=${String(adapterStatus.status || "")} parsedStatus=${String(parsedRecord.status || "")} parsedMsgCount=${parsedRecord.messages.length} returnedMsgCount=${returnedMessages.length}`);
|
|
22337
22438
|
return buildReadChatCommandResult({
|
|
22338
22439
|
messages: selectedMessages,
|
|
@@ -25919,7 +26020,18 @@ var SCHEMA = {
|
|
|
25919
26020
|
"additionalProperties": false,
|
|
25920
26021
|
"properties": {
|
|
25921
26022
|
"busy_hold_ms": { "type": "integer", "minimum": 0 },
|
|
25922
|
-
"startup_grace_ms": { "type": "integer", "minimum": 0 }
|
|
26023
|
+
"startup_grace_ms": { "type": "integer", "minimum": 0 },
|
|
26024
|
+
"completion_idle_after": {
|
|
26025
|
+
"type": "object",
|
|
26026
|
+
"additionalProperties": false,
|
|
26027
|
+
"required": ["regex", "hold_ms"],
|
|
26028
|
+
"properties": {
|
|
26029
|
+
"section": { "type": "string", "minLength": 1 },
|
|
26030
|
+
"regex": { "type": "string", "minLength": 1 },
|
|
26031
|
+
"flags": { "type": "string" },
|
|
26032
|
+
"hold_ms": { "type": "integer", "minimum": 0 }
|
|
26033
|
+
}
|
|
26034
|
+
}
|
|
25923
26035
|
}
|
|
25924
26036
|
}
|
|
25925
26037
|
},
|
|
@@ -26399,6 +26511,30 @@ function resolveSubmitDelayMs(specBeforeSubmit, text) {
|
|
|
26399
26511
|
const spec = typeof specBeforeSubmit === "number" && specBeforeSubmit > 0 ? specBeforeSubmit : 0;
|
|
26400
26512
|
return Math.max(spec, SUBMIT_DELAY_FLOOR_MS + linesBonus);
|
|
26401
26513
|
}
|
|
26514
|
+
function matchesCompletionIdleRule(spec, ev, screen) {
|
|
26515
|
+
const rule = spec.debounce?.completion_idle_after;
|
|
26516
|
+
if (!rule?.regex) return null;
|
|
26517
|
+
const haystack = rule.section ? ev.sections.find((section) => section.id === rule.section)?.text ?? "" : screen;
|
|
26518
|
+
if (!haystack) return null;
|
|
26519
|
+
try {
|
|
26520
|
+
const regex = new RegExp(rule.regex, rule.flags || "");
|
|
26521
|
+
const match = haystack.match(regex);
|
|
26522
|
+
return match?.[0] || null;
|
|
26523
|
+
} catch {
|
|
26524
|
+
return null;
|
|
26525
|
+
}
|
|
26526
|
+
}
|
|
26527
|
+
function matchesCompletionIdleTargetState(spec, ev, screen) {
|
|
26528
|
+
const target = spec.states.find((state) => state.id === spec.default_state) ?? spec.states.find((state) => state.id === "idle");
|
|
26529
|
+
if (!target?.when?.regex) return false;
|
|
26530
|
+
const haystack = target.when.section ? ev.sections.find((section) => section.id === target.when.section)?.text ?? "" : screen;
|
|
26531
|
+
if (!haystack) return false;
|
|
26532
|
+
try {
|
|
26533
|
+
return new RegExp(target.when.regex, target.when.flags || "i").test(haystack);
|
|
26534
|
+
} catch {
|
|
26535
|
+
return false;
|
|
26536
|
+
}
|
|
26537
|
+
}
|
|
26402
26538
|
var SpecDriver = class {
|
|
26403
26539
|
constructor(opts) {
|
|
26404
26540
|
this.opts = opts;
|
|
@@ -26438,6 +26574,8 @@ var SpecDriver = class {
|
|
|
26438
26574
|
* because the evaluator already moved past busy by the time the hold
|
|
26439
26575
|
* kicks in. */
|
|
26440
26576
|
lastBusyState = null;
|
|
26577
|
+
completionIdleFirstSeenAt = 0;
|
|
26578
|
+
completionIdleKey = "";
|
|
26441
26579
|
/** Timer that re-runs evaluate() once the hold window expires. Needed
|
|
26442
26580
|
* because the PTY stops emitting once the agent finishes; without an
|
|
26443
26581
|
* explicit wake-up there's nothing to trigger the busy → idle
|
|
@@ -26561,10 +26699,40 @@ var SpecDriver = class {
|
|
|
26561
26699
|
evState = this.lastBusyState ?? evState;
|
|
26562
26700
|
}
|
|
26563
26701
|
}
|
|
26702
|
+
const completionIdleRule = this.spec.debounce?.completion_idle_after;
|
|
26703
|
+
let busyWakeMs = busyHoldMs;
|
|
26704
|
+
if (evState.id === "busy" && completionIdleRule) {
|
|
26705
|
+
const completionKey = matchesCompletionIdleRule(this.spec, ev, screen);
|
|
26706
|
+
if (completionKey) {
|
|
26707
|
+
const now = Date.now();
|
|
26708
|
+
if (completionKey !== this.completionIdleKey) {
|
|
26709
|
+
this.completionIdleKey = completionKey;
|
|
26710
|
+
this.completionIdleFirstSeenAt = now;
|
|
26711
|
+
}
|
|
26712
|
+
const holdMs = Math.max(0, completionIdleRule.hold_ms || 0);
|
|
26713
|
+
const ageMs = now - this.completionIdleFirstSeenAt;
|
|
26714
|
+
if (ageMs >= holdMs) {
|
|
26715
|
+
if (matchesCompletionIdleTargetState(this.spec, ev, screen)) {
|
|
26716
|
+
const idle = this.spec.states.find((state) => state.id === this.spec.default_state) ?? this.spec.states.find((state) => state.id === "idle");
|
|
26717
|
+
evState = idle ? { id: idle.id, label: idle.label, title: null } : { id: "idle", label: "Ready", title: null };
|
|
26718
|
+
} else {
|
|
26719
|
+
busyWakeMs = Math.min(busyWakeMs, 1e3);
|
|
26720
|
+
}
|
|
26721
|
+
} else {
|
|
26722
|
+
busyWakeMs = Math.min(busyWakeMs, Math.max(holdMs - ageMs, 0));
|
|
26723
|
+
}
|
|
26724
|
+
} else {
|
|
26725
|
+
this.completionIdleKey = "";
|
|
26726
|
+
this.completionIdleFirstSeenAt = 0;
|
|
26727
|
+
}
|
|
26728
|
+
} else if (evState.id !== "busy") {
|
|
26729
|
+
this.completionIdleKey = "";
|
|
26730
|
+
this.completionIdleFirstSeenAt = 0;
|
|
26731
|
+
}
|
|
26564
26732
|
if (evState.id === "busy") {
|
|
26565
26733
|
this.lastBusyAt = Date.now();
|
|
26566
26734
|
this.lastBusyState = evState;
|
|
26567
|
-
this.scheduleBusyExpiry(
|
|
26735
|
+
this.scheduleBusyExpiry(busyWakeMs);
|
|
26568
26736
|
}
|
|
26569
26737
|
const changed = forceEmit || evState.id !== this.currentStateId || !shallowSameModal(ev, this.currentEval) || !shallowSameControls(ev, this.currentEval);
|
|
26570
26738
|
if (this.pickerInProgress) this.tryAdvancePicker(screen);
|
|
@@ -27467,6 +27635,8 @@ var CliProviderInstance = class {
|
|
|
27467
27635
|
historyWriter;
|
|
27468
27636
|
runtimeMessages = [];
|
|
27469
27637
|
lastPersistedHistoryMessages = [];
|
|
27638
|
+
lastAcknowledgedUserInputAt = 0;
|
|
27639
|
+
externalBusyIdleFingerprint = "";
|
|
27470
27640
|
lastNativeSourceCanonicalCheckAt = 0;
|
|
27471
27641
|
lastNativeSourceCanonicalCacheKey = void 0;
|
|
27472
27642
|
cachedSqliteDb = null;
|
|
@@ -27595,7 +27765,11 @@ var CliProviderInstance = class {
|
|
|
27595
27765
|
typeof adapterStatus?.providerSessionId === "string" ? adapterStatus.providerSessionId : ""
|
|
27596
27766
|
);
|
|
27597
27767
|
const autoApproveActive = this.maybeAutoApproveStatus(adapterStatus, Date.now());
|
|
27598
|
-
|
|
27768
|
+
let visibleStatus = parseErrorMessage || parsedStatus?.status === "error" ? "error" : autoApproveActive ? "generating" : adapterStatus.status;
|
|
27769
|
+
const externalNativeFinal = this.getExternalNativeFinalReconciliation(parsedStatus?.messages, adapterStatus);
|
|
27770
|
+
if (externalNativeFinal && isCliGeneratingLikeStatus(visibleStatus)) {
|
|
27771
|
+
visibleStatus = "idle";
|
|
27772
|
+
}
|
|
27599
27773
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
27600
27774
|
this.maybeAppendRuntimeRecoveryMessage(runtime);
|
|
27601
27775
|
let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
|
|
@@ -27757,7 +27931,22 @@ var CliProviderInstance = class {
|
|
|
27757
27931
|
};
|
|
27758
27932
|
}
|
|
27759
27933
|
updateSettings(newSettings) {
|
|
27760
|
-
|
|
27934
|
+
const runtimeMeshSettings = {};
|
|
27935
|
+
for (const key of [
|
|
27936
|
+
"meshNodeFor",
|
|
27937
|
+
"meshNodeId",
|
|
27938
|
+
"meshActiveTaskId",
|
|
27939
|
+
"meshCoordinatorFor",
|
|
27940
|
+
"meshCoordinatorDaemonId",
|
|
27941
|
+
"meshCoordinatorNodeId",
|
|
27942
|
+
"spawnedSessionVisibility",
|
|
27943
|
+
"launchedByCoordinator"
|
|
27944
|
+
]) {
|
|
27945
|
+
if (this.settings[key] !== void 0 && newSettings[key] === void 0) {
|
|
27946
|
+
runtimeMeshSettings[key] = this.settings[key];
|
|
27947
|
+
}
|
|
27948
|
+
}
|
|
27949
|
+
this.settings = { ...newSettings, ...runtimeMeshSettings };
|
|
27761
27950
|
this.adapter.updateRuntimeSettings?.(this.settings);
|
|
27762
27951
|
this.monitor.updateConfig({
|
|
27763
27952
|
approvalAlert: this.settings.approvalAlert !== false,
|
|
@@ -27848,6 +28037,8 @@ var CliProviderInstance = class {
|
|
|
27848
28037
|
const content = typeof input === "string" ? input.trim() : buildCliStructuredInputPrompt(input).trim();
|
|
27849
28038
|
if (!content) return;
|
|
27850
28039
|
const receivedAt = Date.now();
|
|
28040
|
+
this.lastAcknowledgedUserInputAt = receivedAt;
|
|
28041
|
+
this.externalBusyIdleFingerprint = "";
|
|
27851
28042
|
const dedupKey = `user_input_ack:${crypto4.createHash("sha256").update(`${this.instanceId}:${content}:${receivedAt}`).digest("hex").slice(0, 24)}`;
|
|
27852
28043
|
this.appendRuntimeMessage(buildChatMessage({
|
|
27853
28044
|
role: "user",
|
|
@@ -27996,6 +28187,50 @@ var CliProviderInstance = class {
|
|
|
27996
28187
|
const evidence = this.completionFinalAssistantEvidence(parsedMessages);
|
|
27997
28188
|
return extractFinalSummaryFromMessages(evidence.messages);
|
|
27998
28189
|
}
|
|
28190
|
+
externalNativeFinalFingerprint(evidence) {
|
|
28191
|
+
const messages = Array.isArray(evidence.messages) ? evidence.messages : [];
|
|
28192
|
+
const visibleMessages = messages.filter((message) => isUserFacingChatMessage(message));
|
|
28193
|
+
const lastVisible = visibleMessages[visibleMessages.length - 1];
|
|
28194
|
+
const content = lastVisible ? flattenContent(lastVisible.content).trim() : "";
|
|
28195
|
+
const receivedAt = lastVisible ? getMessageTime(lastVisible) : 0;
|
|
28196
|
+
const probe = this.lastExternalCompletionProbe;
|
|
28197
|
+
return crypto4.createHash("sha256").update([
|
|
28198
|
+
this.type,
|
|
28199
|
+
this.providerSessionId || "",
|
|
28200
|
+
probe?.sourcePath || "",
|
|
28201
|
+
String(probe?.sourceMtimeMs || 0),
|
|
28202
|
+
String(receivedAt || 0),
|
|
28203
|
+
content.slice(-500)
|
|
28204
|
+
].join("\0")).digest("hex").slice(0, 24);
|
|
28205
|
+
}
|
|
28206
|
+
getExternalNativeFinalReconciliation(parsedMessages, adapterStatus) {
|
|
28207
|
+
const rawStatus = typeof adapterStatus?.status === "string" ? adapterStatus.status.trim() : "";
|
|
28208
|
+
if (!isCliGeneratingLikeStatus(rawStatus)) return null;
|
|
28209
|
+
if (hasNonEmptyCliModalButtons(adapterStatus?.activeModal ?? adapterStatus?.modal)) return null;
|
|
28210
|
+
const evidence = this.completionFinalAssistantEvidence(parsedMessages);
|
|
28211
|
+
if (evidence.source !== "external-native" || !evidence.present) return null;
|
|
28212
|
+
const messages = Array.isArray(evidence.messages) ? evidence.messages : [];
|
|
28213
|
+
const visibleMessages = messages.filter((message) => isUserFacingChatMessage(message));
|
|
28214
|
+
const lastVisible = visibleMessages[visibleMessages.length - 1];
|
|
28215
|
+
const lastMessageAt = lastVisible ? getMessageTime(lastVisible) : 0;
|
|
28216
|
+
const sourceMtimeMs = Number(this.lastExternalCompletionProbe?.sourceMtimeMs || 0);
|
|
28217
|
+
const minEvidenceAt = Math.max(
|
|
28218
|
+
this.startedAt > 0 ? this.startedAt - 5e3 : 0,
|
|
28219
|
+
this.generatingStartedAt > 0 ? this.generatingStartedAt - 5e3 : 0,
|
|
28220
|
+
this.lastAcknowledgedUserInputAt > 0 ? this.lastAcknowledgedUserInputAt - 1e3 : 0
|
|
28221
|
+
);
|
|
28222
|
+
if (minEvidenceAt > 0 && lastMessageAt > 0 && lastMessageAt < minEvidenceAt && sourceMtimeMs < minEvidenceAt) {
|
|
28223
|
+
return null;
|
|
28224
|
+
}
|
|
28225
|
+
const finalSummary = extractFinalSummaryFromMessages(evidence.messages);
|
|
28226
|
+
if (!finalSummary) return null;
|
|
28227
|
+
const fingerprint = this.externalNativeFinalFingerprint(evidence);
|
|
28228
|
+
if (fingerprint === this.externalBusyIdleFingerprint) {
|
|
28229
|
+
return { fingerprint, finalSummary, evidence };
|
|
28230
|
+
}
|
|
28231
|
+
this.externalBusyIdleFingerprint = fingerprint;
|
|
28232
|
+
return { fingerprint, finalSummary, evidence };
|
|
28233
|
+
}
|
|
27999
28234
|
buildCompletedFinalizationDiagnostic(args) {
|
|
28000
28235
|
let parsed = null;
|
|
28001
28236
|
let parseError;
|
|
@@ -28066,17 +28301,18 @@ var CliProviderInstance = class {
|
|
|
28066
28301
|
if (typeof adapterAny?.responseBuffer === "string" && adapterAny.responseBuffer.trim()) return false;
|
|
28067
28302
|
return true;
|
|
28068
28303
|
}
|
|
28069
|
-
getCompletedFinalizationBlock(latestVisibleStatus, pending) {
|
|
28304
|
+
getCompletedFinalizationBlock(latestVisibleStatus, pending, opts) {
|
|
28070
28305
|
if (latestVisibleStatus !== "idle") return { reason: `status:${latestVisibleStatus}`, terminal: true };
|
|
28071
28306
|
const adapterAny = this.adapter;
|
|
28072
28307
|
const approvalResolvedIdle = pending.previousStatus === "waiting_approval";
|
|
28073
|
-
|
|
28308
|
+
const externalNativeFinal = opts?.externalNativeFinal || null;
|
|
28309
|
+
if (!approvalResolvedIdle && !externalNativeFinal) {
|
|
28074
28310
|
if (adapterAny?.isWaitingForResponse === true) return { reason: "adapter_waiting_for_response", terminal: true };
|
|
28075
28311
|
if (adapterAny?.currentTurnScope) return { reason: "adapter_turn_scope_active", terminal: true };
|
|
28076
28312
|
if (this.hasAdapterPendingResponse()) return { reason: "adapter_pending_response", terminal: true };
|
|
28077
28313
|
}
|
|
28078
28314
|
const partial = typeof this.adapter.getPartialResponse === "function" ? this.adapter.getPartialResponse() : "";
|
|
28079
|
-
if (typeof partial === "string" && partial.trim()) return { reason: "partial_response_pending", terminal: true };
|
|
28315
|
+
if (!externalNativeFinal && typeof partial === "string" && partial.trim()) return { reason: "partial_response_pending", terminal: true };
|
|
28080
28316
|
let parsed;
|
|
28081
28317
|
try {
|
|
28082
28318
|
parsed = this.adapter.getScriptParsedStatus();
|
|
@@ -28086,6 +28322,7 @@ var CliProviderInstance = class {
|
|
|
28086
28322
|
const parsedStatus = typeof parsed?.status === "string" ? parsed.status : "unknown";
|
|
28087
28323
|
if (parsedStatus !== "idle") {
|
|
28088
28324
|
const adapterStatus = this.adapter.getStatus({ allowParse: false });
|
|
28325
|
+
if (externalNativeFinal && isCliGeneratingLikeStatus(parsedStatus)) return null;
|
|
28089
28326
|
if (this.shouldSuppressStaleParsedBusyStatus(parsed, adapterStatus)) return null;
|
|
28090
28327
|
return { reason: `parsed_status:${parsedStatus}`, terminal: isCliGeneratingLikeStatus(parsedStatus) };
|
|
28091
28328
|
}
|
|
@@ -28138,14 +28375,15 @@ var CliProviderInstance = class {
|
|
|
28138
28375
|
}
|
|
28139
28376
|
const latestStatus = this.adapter.getStatus({ allowParse: false });
|
|
28140
28377
|
const latestAutoApproveActive = latestStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
28141
|
-
const
|
|
28378
|
+
const externalNativeFinal = this.getExternalNativeFinalReconciliation(void 0, latestStatus);
|
|
28379
|
+
const latestVisibleStatus = externalNativeFinal && isCliGeneratingLikeStatus(latestStatus.status) ? "idle" : latestAutoApproveActive ? "generating" : latestStatus.status;
|
|
28142
28380
|
if (latestVisibleStatus !== "idle") {
|
|
28143
28381
|
LOG.info("CLI", `[${this.type}] cancelled pending completed (resumed ${latestVisibleStatus})`);
|
|
28144
28382
|
this.completedDebouncePending = null;
|
|
28145
28383
|
this.completedDebounceTimer = null;
|
|
28146
28384
|
return;
|
|
28147
28385
|
}
|
|
28148
|
-
const block2 = this.getCompletedFinalizationBlock(latestVisibleStatus, pending);
|
|
28386
|
+
const block2 = this.getCompletedFinalizationBlock(latestVisibleStatus, pending, { externalNativeFinal });
|
|
28149
28387
|
if (block2) {
|
|
28150
28388
|
const blockReason = block2.reason;
|
|
28151
28389
|
const waitedMs = Date.now() - pending.firstObservedAt;
|
|
@@ -28186,7 +28424,18 @@ var CliProviderInstance = class {
|
|
|
28186
28424
|
chatTitle: pending.chatTitle,
|
|
28187
28425
|
duration: pending.duration,
|
|
28188
28426
|
timestamp: pending.timestamp,
|
|
28189
|
-
finalSummary: this.completionFinalSummary(this.adapter?.getScriptParsedStatus()?.messages)
|
|
28427
|
+
finalSummary: externalNativeFinal?.finalSummary || this.completionFinalSummary(this.adapter?.getScriptParsedStatus()?.messages),
|
|
28428
|
+
...externalNativeFinal ? {
|
|
28429
|
+
completionDiagnostic: {
|
|
28430
|
+
providerType: this.type,
|
|
28431
|
+
sessionId: this.instanceId,
|
|
28432
|
+
providerSessionId: this.providerSessionId || null,
|
|
28433
|
+
reconciliationReason: "external_native_final_assistant_while_adapter_busy",
|
|
28434
|
+
finalAssistantPresent: true,
|
|
28435
|
+
finalAssistantEvidenceSource: externalNativeFinal.evidence.source,
|
|
28436
|
+
externalFinalFingerprint: externalNativeFinal.fingerprint
|
|
28437
|
+
}
|
|
28438
|
+
} : {}
|
|
28190
28439
|
});
|
|
28191
28440
|
this.completedDebouncePending = null;
|
|
28192
28441
|
this.completedDebounceTimer = null;
|
|
@@ -28242,7 +28491,8 @@ var CliProviderInstance = class {
|
|
|
28242
28491
|
const parsedStatus = null;
|
|
28243
28492
|
const rawStatus = adapterStatus.status;
|
|
28244
28493
|
const autoApproveActive = this.maybeAutoApproveStatus(adapterStatus, now);
|
|
28245
|
-
const
|
|
28494
|
+
const externalNativeFinal = this.getExternalNativeFinalReconciliation(void 0, adapterStatus);
|
|
28495
|
+
const newStatus = externalNativeFinal && isCliGeneratingLikeStatus(rawStatus) ? "idle" : autoApproveActive ? "generating" : rawStatus;
|
|
28246
28496
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
28247
28497
|
const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
|
|
28248
28498
|
const partial = this.adapter.getPartialResponse();
|
|
@@ -30248,15 +30498,29 @@ function colorize(color, text) {
|
|
|
30248
30498
|
const fn = chalkApi?.[color];
|
|
30249
30499
|
return typeof fn === "function" ? fn(text) : text;
|
|
30250
30500
|
}
|
|
30251
|
-
var
|
|
30252
|
-
ADHDEV_INLINE_MESH
|
|
30253
|
-
ADHDEV_MCP_TRANSPORT
|
|
30254
|
-
ADHDEV_MESH_ID
|
|
30255
|
-
HERMES_EPHEMERAL_SYSTEM_PROMPT
|
|
30256
|
-
|
|
30501
|
+
var DEFAULT_COORDINATOR_DELEGATED_ENV_UNSETS = [
|
|
30502
|
+
"ADHDEV_INLINE_MESH",
|
|
30503
|
+
"ADHDEV_MCP_TRANSPORT",
|
|
30504
|
+
"ADHDEV_MESH_ID",
|
|
30505
|
+
"HERMES_EPHEMERAL_SYSTEM_PROMPT"
|
|
30506
|
+
];
|
|
30257
30507
|
function hasCliArg(args, flag) {
|
|
30258
30508
|
return args.some((arg) => arg === flag || arg.startsWith(`${flag}=`));
|
|
30259
30509
|
}
|
|
30510
|
+
function hasConfigOverride(args, key) {
|
|
30511
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
30512
|
+
const arg = args[index];
|
|
30513
|
+
const next = args[index + 1];
|
|
30514
|
+
if ((arg === "-c" || arg === "--config") && typeof next === "string") {
|
|
30515
|
+
if (next === key || next.startsWith(`${key}=`) || next.startsWith(`${key}.`)) return true;
|
|
30516
|
+
}
|
|
30517
|
+
if (arg.startsWith("--config=")) {
|
|
30518
|
+
const value = arg.slice("--config=".length);
|
|
30519
|
+
if (value === key || value.startsWith(`${key}=`) || value.startsWith(`${key}.`)) return true;
|
|
30520
|
+
}
|
|
30521
|
+
}
|
|
30522
|
+
return false;
|
|
30523
|
+
}
|
|
30260
30524
|
function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
30261
30525
|
const baseDir = path23.join(os17.tmpdir(), "adhdev-delegated-agent-empty-mcp");
|
|
30262
30526
|
mkdirSync11(baseDir, { recursive: true });
|
|
@@ -30266,11 +30530,30 @@ function ensureEmptyDelegatedMcpConfig(workspace) {
|
|
|
30266
30530
|
return filePath;
|
|
30267
30531
|
}
|
|
30268
30532
|
function buildCoordinatorDelegatedCliLaunchOptions(input) {
|
|
30269
|
-
const cliType = String(input.cliType || "").trim();
|
|
30270
30533
|
const cliArgs = Array.isArray(input.cliArgs) ? [...input.cliArgs] : [];
|
|
30271
|
-
const env = { ...input.env || {}
|
|
30272
|
-
|
|
30273
|
-
|
|
30534
|
+
const env = { ...input.env || {} };
|
|
30535
|
+
const envUnsets = new Set(DEFAULT_COORDINATOR_DELEGATED_ENV_UNSETS);
|
|
30536
|
+
for (const key of input.isolation?.env?.unset || []) {
|
|
30537
|
+
if (typeof key === "string" && key.trim()) envUnsets.add(key.trim());
|
|
30538
|
+
}
|
|
30539
|
+
for (const key of envUnsets) env[key] = "";
|
|
30540
|
+
for (const rule of input.isolation?.args || []) {
|
|
30541
|
+
if (!rule || typeof rule !== "object") continue;
|
|
30542
|
+
if (rule.mode === "empty_mcp_config") {
|
|
30543
|
+
if (rule.flag && !hasCliArg(cliArgs, rule.flag)) {
|
|
30544
|
+
cliArgs.unshift(rule.flag, ensureEmptyDelegatedMcpConfig(input.workspace));
|
|
30545
|
+
}
|
|
30546
|
+
if (rule.strictFlag && !hasCliArg(cliArgs, rule.strictFlag)) {
|
|
30547
|
+
cliArgs.unshift(rule.strictFlag);
|
|
30548
|
+
}
|
|
30549
|
+
continue;
|
|
30550
|
+
}
|
|
30551
|
+
if (rule.mode === "config_override") {
|
|
30552
|
+
const key = String(rule.dedupeKey || rule.key || "").trim();
|
|
30553
|
+
const flag = String(rule.flag || "").trim();
|
|
30554
|
+
if (!key || !flag || hasConfigOverride(cliArgs, key)) continue;
|
|
30555
|
+
cliArgs.unshift(flag, `${rule.key}=${rule.value}`);
|
|
30556
|
+
}
|
|
30274
30557
|
}
|
|
30275
30558
|
return { cliArgs, env };
|
|
30276
30559
|
}
|
|
@@ -30933,22 +31216,25 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
30933
31216
|
const dir = resolved.path;
|
|
30934
31217
|
const launchSource = resolved.source;
|
|
30935
31218
|
if (!cliType) throw new Error("cliType required");
|
|
31219
|
+
const providerType = this.providerLoader.resolveAlias(cliType);
|
|
31220
|
+
const provLookup = this.providerLoader.getMeta(providerType);
|
|
30936
31221
|
const settingsOverride = args?.settings && typeof args.settings === "object" ? args.settings : void 0;
|
|
30937
31222
|
const delegatedLaunch = settingsOverride?.launchedByCoordinator === true ? buildCoordinatorDelegatedCliLaunchOptions({
|
|
30938
31223
|
cliType,
|
|
30939
31224
|
workspace: dir,
|
|
30940
31225
|
cliArgs: args?.cliArgs,
|
|
30941
|
-
env: args?.env
|
|
31226
|
+
env: args?.env,
|
|
31227
|
+
isolation: provLookup?.meshCoordinator?.delegatedWorkerIsolation
|
|
30942
31228
|
}) : null;
|
|
30943
|
-
const
|
|
30944
|
-
const provTrust =
|
|
31229
|
+
const provMeta = provLookup;
|
|
31230
|
+
const provTrust = provMeta?._sourceTrust;
|
|
30945
31231
|
if (provTrust === "external-untrusted" && args?.confirmExternalUntrusted !== true) {
|
|
30946
31232
|
return {
|
|
30947
31233
|
success: false,
|
|
30948
31234
|
error: "untrusted_external_provider",
|
|
30949
31235
|
provider: {
|
|
30950
31236
|
type: provLookup?.type ?? cliType,
|
|
30951
|
-
sourceName:
|
|
31237
|
+
sourceName: provMeta?._sourceName ?? null,
|
|
30952
31238
|
trust: provTrust
|
|
30953
31239
|
},
|
|
30954
31240
|
hint: "Resend launch_cli with confirmExternalUntrusted=true after the user explicitly approves running JavaScript from this 3rd-party source."
|
|
@@ -31420,7 +31706,10 @@ function validateMeshCoordinator(raw, errors) {
|
|
|
31420
31706
|
if (meshCoordinator.reason !== void 0 && (typeof meshCoordinator.reason !== "string" || !meshCoordinator.reason.trim())) {
|
|
31421
31707
|
errors.push("meshCoordinator.reason must be a non-empty string when provided");
|
|
31422
31708
|
}
|
|
31423
|
-
|
|
31709
|
+
validateMeshCoordinatorMcpConfig(meshCoordinator.mcpConfig, errors);
|
|
31710
|
+
validateMeshCoordinatorDelegatedWorkerIsolation(meshCoordinator.delegatedWorkerIsolation, errors);
|
|
31711
|
+
}
|
|
31712
|
+
function validateMeshCoordinatorMcpConfig(mcpConfig, errors) {
|
|
31424
31713
|
if (mcpConfig === void 0) return;
|
|
31425
31714
|
if (!mcpConfig || typeof mcpConfig !== "object" || Array.isArray(mcpConfig)) {
|
|
31426
31715
|
errors.push("meshCoordinator.mcpConfig must be an object");
|
|
@@ -31461,6 +31750,56 @@ function validateMeshCoordinator(raw, errors) {
|
|
|
31461
31750
|
}
|
|
31462
31751
|
}
|
|
31463
31752
|
}
|
|
31753
|
+
function validateMeshCoordinatorDelegatedWorkerIsolation(raw, errors) {
|
|
31754
|
+
if (raw === void 0) return;
|
|
31755
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
31756
|
+
errors.push("meshCoordinator.delegatedWorkerIsolation must be an object");
|
|
31757
|
+
return;
|
|
31758
|
+
}
|
|
31759
|
+
const isolation = raw;
|
|
31760
|
+
const env = isolation.env;
|
|
31761
|
+
if (env !== void 0) {
|
|
31762
|
+
if (!env || typeof env !== "object" || Array.isArray(env)) {
|
|
31763
|
+
errors.push("meshCoordinator.delegatedWorkerIsolation.env must be an object");
|
|
31764
|
+
} else {
|
|
31765
|
+
const unset = env.unset;
|
|
31766
|
+
if (unset !== void 0 && (!Array.isArray(unset) || unset.some((key) => typeof key !== "string" || !key.trim()))) {
|
|
31767
|
+
errors.push("meshCoordinator.delegatedWorkerIsolation.env.unset must be an array of non-empty strings");
|
|
31768
|
+
}
|
|
31769
|
+
}
|
|
31770
|
+
}
|
|
31771
|
+
const args = isolation.args;
|
|
31772
|
+
if (args === void 0) return;
|
|
31773
|
+
if (!Array.isArray(args)) {
|
|
31774
|
+
errors.push("meshCoordinator.delegatedWorkerIsolation.args must be an array");
|
|
31775
|
+
return;
|
|
31776
|
+
}
|
|
31777
|
+
for (const [index, rule] of args.entries()) {
|
|
31778
|
+
const prefix = `meshCoordinator.delegatedWorkerIsolation.args[${index}]`;
|
|
31779
|
+
if (!rule || typeof rule !== "object" || Array.isArray(rule)) {
|
|
31780
|
+
errors.push(`${prefix} must be an object`);
|
|
31781
|
+
continue;
|
|
31782
|
+
}
|
|
31783
|
+
const item = rule;
|
|
31784
|
+
const mode = item.mode;
|
|
31785
|
+
if (mode !== "empty_mcp_config" && mode !== "config_override") {
|
|
31786
|
+
errors.push(`${prefix}.mode must be one of: empty_mcp_config, config_override`);
|
|
31787
|
+
continue;
|
|
31788
|
+
}
|
|
31789
|
+
for (const key of mode === "empty_mcp_config" ? ["flag"] : ["flag", "key", "value"]) {
|
|
31790
|
+
const value = item[key];
|
|
31791
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
31792
|
+
errors.push(`${prefix}.${key} must be a non-empty string`);
|
|
31793
|
+
}
|
|
31794
|
+
}
|
|
31795
|
+
for (const key of ["strictFlag", "dedupeKey"]) {
|
|
31796
|
+
const value = item[key];
|
|
31797
|
+
if (value !== void 0 && (typeof value !== "string" || !value.trim())) {
|
|
31798
|
+
errors.push(`${prefix}.${key} must be a non-empty string when provided`);
|
|
31799
|
+
}
|
|
31800
|
+
}
|
|
31801
|
+
}
|
|
31802
|
+
}
|
|
31464
31803
|
function validateControl(control, errors) {
|
|
31465
31804
|
if (!control || typeof control !== "object") {
|
|
31466
31805
|
errors.push("controls: each control must be an object");
|
|
@@ -37122,9 +37461,14 @@ function readCachedInlineMeshActiveSessionDetails(node) {
|
|
|
37122
37461
|
node?.provider_type
|
|
37123
37462
|
),
|
|
37124
37463
|
state: readStringValue(fallbackSession.status, fallbackSession.state, fallbackSession.lifecycle),
|
|
37464
|
+
chatStatus: readStringValue(fallbackSession.chatStatus, fallbackSession.chat_status),
|
|
37125
37465
|
lifecycle: readStringValue(fallbackSession.lifecycle),
|
|
37126
37466
|
title: readStringValue(fallbackSession.title, fallbackSession.displayName, fallbackSession.display_name) ?? null,
|
|
37127
37467
|
workspace: readStringValue(fallbackSession.workspace, node?.workspace) ?? null,
|
|
37468
|
+
role: readStringValue(fallbackSession.role) ?? null,
|
|
37469
|
+
isSelfCoordinator: fallbackSession.isSelfCoordinator === true || fallbackSession.is_self_coordinator === true,
|
|
37470
|
+
createdAt: readStringValue(fallbackSession.createdAt, fallbackSession.created_at) ?? null,
|
|
37471
|
+
startedAt: readStringValue(fallbackSession.startedAt, fallbackSession.started_at) ?? null,
|
|
37128
37472
|
lastActivityAt: readStringValue(fallbackSession.lastActivityAt, fallbackSession.last_activity_at) ?? null,
|
|
37129
37473
|
recoveryState: readStringValue(fallbackSession.recoveryState, fallbackSession.recovery_state) ?? null,
|
|
37130
37474
|
isCached: true
|
|
@@ -37265,15 +37609,26 @@ async function hydrateInlineMeshDirectTruth(args) {
|
|
|
37265
37609
|
};
|
|
37266
37610
|
}
|
|
37267
37611
|
function summarizeMeshSessionRecord(record) {
|
|
37612
|
+
const meta = readObjectRecord(record?.meta);
|
|
37613
|
+
const isSelfCoordinator = Boolean(readStringValue(meta.meshCoordinatorFor));
|
|
37614
|
+
const chatStatus = readStringValue(record?.chatStatus, record?.activeChat?.status, meta.chatStatus, meta.sessionStatus);
|
|
37615
|
+
const state = readLiveMeshSessionState(record);
|
|
37616
|
+
const statusNote = isSelfCoordinator && (!chatStatus || chatStatus === "idle" || state === "idle") ? "Coordinator self status is sampled from the session host and may read idle while the coordinator is generating this response." : null;
|
|
37268
37617
|
return {
|
|
37269
37618
|
sessionId: readStringValue(record?.sessionId) || "unknown",
|
|
37270
37619
|
providerType: readStringValue(record?.providerType),
|
|
37271
|
-
state
|
|
37620
|
+
state,
|
|
37621
|
+
chatStatus,
|
|
37272
37622
|
lifecycle: readStringValue(record?.lifecycle),
|
|
37273
37623
|
surfaceKind: getSessionHostSurfaceKind(record),
|
|
37274
|
-
recoveryState: readStringValue(
|
|
37624
|
+
recoveryState: readStringValue(meta.runtimeRecoveryState) ?? null,
|
|
37275
37625
|
workspace: readStringValue(record?.workspace) ?? null,
|
|
37276
37626
|
title: readStringValue(record?.displayName, record?.workspaceLabel) ?? null,
|
|
37627
|
+
role: isSelfCoordinator ? "coordinator" : readStringValue(meta.meshRole, meta.role) ?? null,
|
|
37628
|
+
isSelfCoordinator,
|
|
37629
|
+
statusNote,
|
|
37630
|
+
createdAt: toIsoTimestamp(record?.createdAt ?? record?.created_at),
|
|
37631
|
+
startedAt: toIsoTimestamp(record?.startedAt ?? record?.started_at ?? record?.spawnedAtMs ?? record?.spawned_at_ms),
|
|
37277
37632
|
lastActivityAt: toIsoTimestamp(record?.updatedAt ?? record?.lastActivityAt ?? record?.last_activity_at),
|
|
37278
37633
|
isCached: false
|
|
37279
37634
|
};
|
|
@@ -38297,6 +38652,15 @@ var DaemonCommandRouter = class {
|
|
|
38297
38652
|
this.aggregateMeshStatusCache.set(meshId, { builtAt, snapshot: this.cloneJsonValue(next), queueRevision: getMeshQueueRevision(meshId) });
|
|
38298
38653
|
return next;
|
|
38299
38654
|
}
|
|
38655
|
+
getCachedInlineMeshNodes() {
|
|
38656
|
+
const nodes = [];
|
|
38657
|
+
for (const mesh of this.inlineMeshCache.values()) {
|
|
38658
|
+
if (Array.isArray(mesh?.nodes)) {
|
|
38659
|
+
nodes.push(...mesh.nodes);
|
|
38660
|
+
}
|
|
38661
|
+
}
|
|
38662
|
+
return nodes;
|
|
38663
|
+
}
|
|
38300
38664
|
getCachedInlineMesh(meshId, inlineMesh) {
|
|
38301
38665
|
if (inlineMesh && typeof inlineMesh === "object") {
|
|
38302
38666
|
return this.warmInlineMeshCache(meshId, inlineMesh);
|
|
@@ -38345,6 +38709,7 @@ var DaemonCommandRouter = class {
|
|
|
38345
38709
|
}
|
|
38346
38710
|
invalidateAggregateMeshStatus(meshId) {
|
|
38347
38711
|
this.aggregateMeshStatusCache.delete(meshId);
|
|
38712
|
+
this.deps.onMeshStateChange?.(meshId);
|
|
38348
38713
|
}
|
|
38349
38714
|
async requireMeshHostMutationOwner(meshId, inlineMesh, operation) {
|
|
38350
38715
|
const meshRecord = await this.getMeshForCommand(meshId, inlineMesh, { preferInline: true });
|
|
@@ -49837,6 +50202,7 @@ async function initDaemonComponents(config) {
|
|
|
49837
50202
|
},
|
|
49838
50203
|
onIdeConnected: () => poller?.start(),
|
|
49839
50204
|
onStatusChange: config.onStatusChange,
|
|
50205
|
+
onMeshStateChange: config.onMeshStateChange,
|
|
49840
50206
|
onPostChatCommand: config.onPostChatCommand,
|
|
49841
50207
|
sessionHostControl: config.sessionHostControl,
|
|
49842
50208
|
statusInstanceId: config.statusInstanceId,
|
|
@@ -50429,6 +50795,7 @@ export {
|
|
|
50429
50795
|
probeCdpPort,
|
|
50430
50796
|
queuePendingMeshCoordinatorEvent,
|
|
50431
50797
|
readSession3 as readAntigravityCliSession,
|
|
50798
|
+
readCachedInlineMeshActiveSessionDetails,
|
|
50432
50799
|
readChatHistory,
|
|
50433
50800
|
readSession as readClaudeCliSession,
|
|
50434
50801
|
readSession2 as readCodexCliSession,
|