@adhdev/daemon-core 0.9.82-rc.70 → 0.9.82-rc.71
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 +285 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +286 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/commands/chat-commands.ts +242 -7
- package/src/commands/cli-manager.ts +19 -0
- package/src/commands/router.ts +80 -13
- package/src/mesh/coordinator-prompt.ts +2 -1
- package/src/providers/cli-provider-instance.ts +3 -1
package/dist/index.mjs
CHANGED
|
@@ -1187,6 +1187,7 @@ function buildRulesSection(coordinatorCliType) {
|
|
|
1187
1187
|
- **Clean up worktree nodes.** After a worktree task completes and its changes are merged or checkpointed, call \`mesh_remove_node\` to free resources.
|
|
1188
1188
|
- **Do not strand completed branches.** A checkpointed or clean feature/worktree branch is not done by itself. Merge/refine it to the mesh default branch, fast-forward obvious clean behind-only branches with \`mesh_fast_forward_node\`, or explicitly report one of \`pushed_feature_branch_needs_merge\`, \`blocked_review\`, \`cleanup_candidate\`, or \`not_mergeable\` with the next action.
|
|
1189
1189
|
- **Keep Refinery validation project-configurable.** \`mesh_refine_node\` must execute validation from repo mesh/refine config (for example \`.adhdev/refine.{json,yaml,yml}\`, \`.adhdev/repo-mesh-refine.*\`, or \`repo-mesh.refine.*\`). Heuristics are suggestions/scaffolding only, not the execution path.
|
|
1190
|
+
- **Treat submodule reachability as publish-needed.** A \`submodule_reachability_failed\` refine result means the root gitlink points at a submodule commit that is not reachable from the configured submodule remote. Do not retry validation blindly or start code review first. Classify it as \`blocked_review\`, request user approval to push/publish the submodule commit, then rerun \`mesh_refine_node\`.
|
|
1190
1191
|
- **Name worktree branches meaningfully.** Use descriptive names like \`feat/auth-refactor\` or \`fix/build-123\`.${coordinatorNote}`;
|
|
1191
1192
|
}
|
|
1192
1193
|
var TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION;
|
|
@@ -1233,7 +1234,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
|
|
|
1233
1234
|
4. **Monitor** \u2014 Prefer event-driven completion/status notifications. Do **not** poll \`mesh_read_chat\` repeatedly. Use \`mesh_view_queue\` to see the status of all pending, assigned, completed, and failed tasks. Do not call \`mesh_read_chat\` again within a few seconds for the same generating session. Use at most one compact \`mesh_read_chat\` check after a completion/approval signal. Handle approvals via \`mesh_approve\`.
|
|
1234
1235
|
5. **Verify** \u2014 When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
|
|
1235
1236
|
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
1236
|
-
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. 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.
|
|
1237
|
+
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 its configured remote. If \`mesh_refine_node\` returns \`submodule_reachability_failed\` or publish-required evidence, keep the public convergence bucket as \`blocked_review\`, ask the user for explicit approval to push/publish the unreachable submodule commit(s), then rerun \`mesh_refine_node\`; do not merge the root branch until the submodule commit(s) are reachable. 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.
|
|
1237
1238
|
8. **Clean up** \u2014 Remove worktree nodes via \`mesh_remove_node\` after their work is merged or no longer needed.
|
|
1238
1239
|
9. **Report** \u2014 Summarize what was done, what changed, any issues, and the branch convergence state.
|
|
1239
1240
|
|
|
@@ -15560,6 +15561,7 @@ function buildSessionModalDeliverySignature(payload) {
|
|
|
15560
15561
|
var RECENT_SEND_WINDOW_MS = 1200;
|
|
15561
15562
|
var READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS = 25e3;
|
|
15562
15563
|
var HERMES_CLI_STARTING_SEND_SETTLE_MS = 2e3;
|
|
15564
|
+
var CODEX_NATIVE_HISTORY_FRESH_MS = 5 * 6e4;
|
|
15563
15565
|
var recentSendByTarget = /* @__PURE__ */ new Map();
|
|
15564
15566
|
function getCurrentProviderType(h, fallback = "") {
|
|
15565
15567
|
return h.currentSession?.providerType || h.currentProviderType || fallback;
|
|
@@ -15693,6 +15695,77 @@ function normalizeReadChatMessages(payload) {
|
|
|
15693
15695
|
const messages = Array.isArray(payload.messages) ? payload.messages : [];
|
|
15694
15696
|
return normalizeChatMessages(messages);
|
|
15695
15697
|
}
|
|
15698
|
+
function getMessageNewestReceivedAt(messages) {
|
|
15699
|
+
let newest = 0;
|
|
15700
|
+
for (const message of messages) {
|
|
15701
|
+
const receivedAt = Number(message?.receivedAt ?? message?.timestamp ?? 0);
|
|
15702
|
+
if (Number.isFinite(receivedAt) && receivedAt > newest) newest = receivedAt;
|
|
15703
|
+
}
|
|
15704
|
+
return newest;
|
|
15705
|
+
}
|
|
15706
|
+
function buildCliMessageSourceProvenance(args) {
|
|
15707
|
+
const sourceMtimeMs = Number(args.sourceMtimeMs || 0);
|
|
15708
|
+
const sourceMtimeAgeMs = sourceMtimeMs > 0 ? Math.max(0, Date.now() - sourceMtimeMs) : void 0;
|
|
15709
|
+
const nativeMessages = args.nativeMessages || [];
|
|
15710
|
+
const ptyMessages = args.ptyMessages || [];
|
|
15711
|
+
const returnedMessages = args.returnedMessages || [];
|
|
15712
|
+
return {
|
|
15713
|
+
selected: args.selected,
|
|
15714
|
+
provider: args.provider,
|
|
15715
|
+
...args.nativeHandle ? { nativeHandle: args.nativeHandle } : {},
|
|
15716
|
+
...args.fallbackReason ? { fallbackReason: args.fallbackReason } : {},
|
|
15717
|
+
...args.nativeSource ? { nativeSource: args.nativeSource } : {},
|
|
15718
|
+
...args.sourcePath ? { sourcePath: args.sourcePath } : {},
|
|
15719
|
+
ptyStatusApprovalOnly: args.ptyStatusApprovalOnly === true,
|
|
15720
|
+
staleness: {
|
|
15721
|
+
sourceMtimeMs: sourceMtimeMs || void 0,
|
|
15722
|
+
sourceMtimeAgeMs,
|
|
15723
|
+
nativeNewestMessageAt: getMessageNewestReceivedAt(nativeMessages),
|
|
15724
|
+
ptyNewestMessageAt: getMessageNewestReceivedAt(ptyMessages),
|
|
15725
|
+
freshEnough: args.freshEnough === true
|
|
15726
|
+
},
|
|
15727
|
+
coverage: {
|
|
15728
|
+
nativeMessageCount: nativeMessages.length,
|
|
15729
|
+
ptyMessageCount: ptyMessages.length,
|
|
15730
|
+
returnedMessageCount: returnedMessages.length,
|
|
15731
|
+
safeMapping: args.safeMapping === true
|
|
15732
|
+
}
|
|
15733
|
+
};
|
|
15734
|
+
}
|
|
15735
|
+
function buildNativeHistoryFallbackReason(args) {
|
|
15736
|
+
if (args.providerType !== "codex-cli") return "provider_not_codex_cli";
|
|
15737
|
+
if (args.nativeSource === "native-unavailable") return "native_history_unavailable";
|
|
15738
|
+
if (args.nativeSource && args.nativeSource !== "provider-native") return `native_history_source_${args.nativeSource}`;
|
|
15739
|
+
if (args.nativeMessageCount <= 0) return "native_history_empty";
|
|
15740
|
+
if (!args.safeMapping) return "native_history_not_safely_mapped";
|
|
15741
|
+
if (!args.freshEnough) return "native_history_stale";
|
|
15742
|
+
return "native_history_not_selected";
|
|
15743
|
+
}
|
|
15744
|
+
function isCodexCliProvider(providerType) {
|
|
15745
|
+
return providerType === "codex-cli";
|
|
15746
|
+
}
|
|
15747
|
+
function hasSafeNativeHistoryMapping(args) {
|
|
15748
|
+
const explicitSessionId = String(args.historySessionId || args.providerSessionId || "").trim();
|
|
15749
|
+
if (explicitSessionId) {
|
|
15750
|
+
const messageSessionIds = args.nativeMessages.map((message) => typeof message?.historySessionId === "string" ? message.historySessionId.trim() : "").filter(Boolean);
|
|
15751
|
+
if (messageSessionIds.length === 0) return true;
|
|
15752
|
+
return messageSessionIds.some((id) => id === explicitSessionId);
|
|
15753
|
+
}
|
|
15754
|
+
const workspace = String(args.workspace || "").trim();
|
|
15755
|
+
if (!workspace) return false;
|
|
15756
|
+
return args.nativeMessages.some((message) => String(message?.workspace || "").trim() === workspace);
|
|
15757
|
+
}
|
|
15758
|
+
function isNativeHistoryFreshEnough(args) {
|
|
15759
|
+
const nativeNewest = getMessageNewestReceivedAt(args.nativeMessages);
|
|
15760
|
+
const ptyNewest = getMessageNewestReceivedAt(args.ptyMessages);
|
|
15761
|
+
if (nativeNewest > 0 && nativeNewest >= ptyNewest) return true;
|
|
15762
|
+
const sourceMtimeMs = Number(args.sourceMtimeMs || 0);
|
|
15763
|
+
if (sourceMtimeMs > 0 && Date.now() - sourceMtimeMs <= CODEX_NATIVE_HISTORY_FRESH_MS) return true;
|
|
15764
|
+
return ptyNewest === 0 && nativeNewest > 0;
|
|
15765
|
+
}
|
|
15766
|
+
function shouldPreserveReadChatPayloadField(key) {
|
|
15767
|
+
return key === "messageSource" || key === "transcriptProvenance";
|
|
15768
|
+
}
|
|
15696
15769
|
function deriveHistoryDedupKey(message) {
|
|
15697
15770
|
const unitKey = typeof message._unitKey === "string" ? message._unitKey.trim() : "";
|
|
15698
15771
|
if (unitKey) return `read_chat:${unitKey}`;
|
|
@@ -15798,6 +15871,7 @@ function buildReadChatCommandResult(payload, args) {
|
|
|
15798
15871
|
return {
|
|
15799
15872
|
success: true,
|
|
15800
15873
|
...validatedPayload,
|
|
15874
|
+
...Object.fromEntries(Object.entries(payload).filter(([key]) => shouldPreserveReadChatPayloadField(key))),
|
|
15801
15875
|
messages: sync.messages,
|
|
15802
15876
|
totalMessages: sync.totalMessages,
|
|
15803
15877
|
...returnedDebugReadChat ? { debugReadChat: returnedDebugReadChat } : {}
|
|
@@ -15974,6 +16048,8 @@ function buildChatDebugBundleSummary(bundle) {
|
|
|
15974
16048
|
adapterStatus: debugReadChat.adapterStatus,
|
|
15975
16049
|
parsedStatus: debugReadChat.parsedStatus,
|
|
15976
16050
|
returnedStatus: debugReadChat.returnedStatus,
|
|
16051
|
+
selectedMessageSource: debugReadChat.selectedMessageSource,
|
|
16052
|
+
messageSource: debugReadChat.messageSource,
|
|
15977
16053
|
parsedMsgCount: debugReadChat.parsedMsgCount,
|
|
15978
16054
|
returnedMsgCount: debugReadChat.returnedMsgCount,
|
|
15979
16055
|
shouldPreferAdapterMessages: debugReadChat.shouldPreferAdapterMessages
|
|
@@ -16049,6 +16125,8 @@ async function handleGetChatDebugBundle(h, args) {
|
|
|
16049
16125
|
providerSessionId: readResult.providerSessionId,
|
|
16050
16126
|
transcriptAuthority: readResult.transcriptAuthority,
|
|
16051
16127
|
coverage: readResult.coverage,
|
|
16128
|
+
messageSource: readResult.messageSource,
|
|
16129
|
+
transcriptProvenance: readResult.transcriptProvenance,
|
|
16052
16130
|
activeModal: readResult.activeModal,
|
|
16053
16131
|
messagesTail: Array.isArray(readResult.messages) ? readResult.messages.slice(-20) : [],
|
|
16054
16132
|
debugReadChat: readResult.debugReadChat
|
|
@@ -16246,25 +16324,134 @@ async function handleReadChat(h, args) {
|
|
|
16246
16324
|
const runtimeMessageMerger = getTargetInstance(h, args);
|
|
16247
16325
|
const parsedMessages = finalizeStreamingMessagesWhenIdle(parsedRecord.messages, returnedStatus);
|
|
16248
16326
|
const returnedMessages = runtimeMessageMerger?.category === "cli" && runtimeMessageMerger.type === adapter.cliType && typeof runtimeMessageMerger.mergeRuntimeChatMessages === "function" ? runtimeMessageMerger.mergeRuntimeChatMessages(parsedMessages) : parsedMessages;
|
|
16327
|
+
const providerType = provider?.type || adapter.cliType;
|
|
16328
|
+
let selectedMessages = returnedMessages;
|
|
16329
|
+
let selectedTitle = title;
|
|
16330
|
+
let selectedProviderSessionId = providerSessionId;
|
|
16331
|
+
let selectedTranscriptAuthority = transcriptAuthority;
|
|
16332
|
+
let selectedCoverage = coverage;
|
|
16333
|
+
let messageSource = buildCliMessageSourceProvenance({
|
|
16334
|
+
selected: "pty-parser",
|
|
16335
|
+
provider: adapter.cliType,
|
|
16336
|
+
fallbackReason: isCodexCliProvider(providerType) ? "native_history_not_checked" : "provider_not_codex_cli",
|
|
16337
|
+
ptyMessages: returnedMessages,
|
|
16338
|
+
returnedMessages,
|
|
16339
|
+
ptyStatusApprovalOnly: false
|
|
16340
|
+
});
|
|
16341
|
+
if (isCodexCliProvider(providerType)) {
|
|
16342
|
+
const agentStr = provider?.type || args?.agentType || getCurrentProviderType(h, adapter.cliType);
|
|
16343
|
+
const workspace = typeof args?.workspace === "string" ? args.workspace : typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : typeof adapter.workingDir === "string" ? adapter.workingDir : void 0;
|
|
16344
|
+
const nativeHistoryLimit = Math.max(
|
|
16345
|
+
normalizeReadChatTailLimit(args) || 0,
|
|
16346
|
+
returnedMessages.length,
|
|
16347
|
+
200
|
|
16348
|
+
);
|
|
16349
|
+
let nativeHistory = null;
|
|
16350
|
+
try {
|
|
16351
|
+
nativeHistory = readProviderChatHistory(agentStr, {
|
|
16352
|
+
canonicalHistory: provider?.canonicalHistory,
|
|
16353
|
+
historySessionId,
|
|
16354
|
+
workspace,
|
|
16355
|
+
offset: 0,
|
|
16356
|
+
limit: nativeHistoryLimit,
|
|
16357
|
+
excludeRecentCount: 0,
|
|
16358
|
+
historyBehavior: provider?.historyBehavior,
|
|
16359
|
+
scripts: provider?.scripts
|
|
16360
|
+
});
|
|
16361
|
+
} catch (error) {
|
|
16362
|
+
const fallbackReason = `native_history_error:${error?.message || String(error)}`;
|
|
16363
|
+
messageSource = buildCliMessageSourceProvenance({
|
|
16364
|
+
selected: "pty-parser",
|
|
16365
|
+
provider: adapter.cliType,
|
|
16366
|
+
fallbackReason,
|
|
16367
|
+
ptyMessages: returnedMessages,
|
|
16368
|
+
returnedMessages,
|
|
16369
|
+
ptyStatusApprovalOnly: false
|
|
16370
|
+
});
|
|
16371
|
+
nativeHistory = null;
|
|
16372
|
+
}
|
|
16373
|
+
if (nativeHistory) {
|
|
16374
|
+
const nativeMessages = Array.isArray(nativeHistory.messages) ? normalizeChatMessages(nativeHistory.messages) : [];
|
|
16375
|
+
const historyProviderSessionId = typeof nativeHistory?.providerSessionId === "string" ? nativeHistory.providerSessionId : historySessionId;
|
|
16376
|
+
const safeMapping = hasSafeNativeHistoryMapping({
|
|
16377
|
+
historySessionId,
|
|
16378
|
+
providerSessionId,
|
|
16379
|
+
workspace,
|
|
16380
|
+
nativeMessages
|
|
16381
|
+
});
|
|
16382
|
+
const freshEnough = isNativeHistoryFreshEnough({
|
|
16383
|
+
sourceMtimeMs: nativeHistory.sourceMtimeMs,
|
|
16384
|
+
nativeMessages,
|
|
16385
|
+
ptyMessages: returnedMessages
|
|
16386
|
+
});
|
|
16387
|
+
if (nativeHistory.source === "provider-native" && nativeMessages.length > 0 && safeMapping && freshEnough) {
|
|
16388
|
+
selectedMessages = finalizeStreamingMessagesWhenIdle(nativeMessages, returnedStatus);
|
|
16389
|
+
selectedProviderSessionId = historyProviderSessionId || providerSessionId;
|
|
16390
|
+
selectedTranscriptAuthority = "provider";
|
|
16391
|
+
selectedCoverage = nativeHistory.hasMore ? "tail" : "full";
|
|
16392
|
+
messageSource = buildCliMessageSourceProvenance({
|
|
16393
|
+
selected: "native-history",
|
|
16394
|
+
provider: adapter.cliType,
|
|
16395
|
+
nativeHandle: selectedProviderSessionId || historySessionId,
|
|
16396
|
+
nativeSource: nativeHistory.source,
|
|
16397
|
+
sourcePath: nativeHistory.sourcePath,
|
|
16398
|
+
sourceMtimeMs: nativeHistory.sourceMtimeMs,
|
|
16399
|
+
nativeMessages,
|
|
16400
|
+
ptyMessages: returnedMessages,
|
|
16401
|
+
returnedMessages: selectedMessages,
|
|
16402
|
+
safeMapping,
|
|
16403
|
+
freshEnough,
|
|
16404
|
+
ptyStatusApprovalOnly: true
|
|
16405
|
+
});
|
|
16406
|
+
} else {
|
|
16407
|
+
const fallbackReason = buildNativeHistoryFallbackReason({
|
|
16408
|
+
providerType,
|
|
16409
|
+
nativeSource: nativeHistory.source,
|
|
16410
|
+
nativeMessageCount: nativeMessages.length,
|
|
16411
|
+
safeMapping,
|
|
16412
|
+
freshEnough
|
|
16413
|
+
});
|
|
16414
|
+
messageSource = buildCliMessageSourceProvenance({
|
|
16415
|
+
selected: "pty-parser",
|
|
16416
|
+
provider: adapter.cliType,
|
|
16417
|
+
nativeHandle: historyProviderSessionId || historySessionId,
|
|
16418
|
+
fallbackReason,
|
|
16419
|
+
nativeSource: nativeHistory.source,
|
|
16420
|
+
sourcePath: nativeHistory.sourcePath,
|
|
16421
|
+
sourceMtimeMs: nativeHistory.sourceMtimeMs,
|
|
16422
|
+
nativeMessages,
|
|
16423
|
+
ptyMessages: returnedMessages,
|
|
16424
|
+
returnedMessages,
|
|
16425
|
+
safeMapping,
|
|
16426
|
+
freshEnough,
|
|
16427
|
+
ptyStatusApprovalOnly: false
|
|
16428
|
+
});
|
|
16429
|
+
}
|
|
16430
|
+
}
|
|
16431
|
+
}
|
|
16249
16432
|
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}`);
|
|
16250
16433
|
return buildReadChatCommandResult({
|
|
16251
|
-
messages:
|
|
16434
|
+
messages: selectedMessages,
|
|
16252
16435
|
status: returnedStatus,
|
|
16253
16436
|
activeModal,
|
|
16437
|
+
messageSource,
|
|
16438
|
+
transcriptProvenance: messageSource,
|
|
16254
16439
|
debugReadChat: {
|
|
16255
16440
|
provider: adapter.cliType,
|
|
16256
16441
|
targetSessionId: String(args?.targetSessionId || ""),
|
|
16257
16442
|
adapterStatus: String(adapterStatus.status || ""),
|
|
16258
16443
|
parsedStatus: String(parsedRecord.status || ""),
|
|
16259
16444
|
returnedStatus: String(returnedStatus || ""),
|
|
16260
|
-
|
|
16445
|
+
selectedMessageSource: messageSource.selected,
|
|
16446
|
+
messageSource,
|
|
16447
|
+
shouldPreferAdapterMessages: messageSource.selected !== "native-history",
|
|
16261
16448
|
parsedMsgCount: parsedRecord.messages.length,
|
|
16262
|
-
returnedMsgCount:
|
|
16449
|
+
returnedMsgCount: selectedMessages.length
|
|
16263
16450
|
},
|
|
16264
|
-
...
|
|
16265
|
-
...
|
|
16266
|
-
...
|
|
16267
|
-
...
|
|
16451
|
+
...selectedTitle ? { title: selectedTitle } : {},
|
|
16452
|
+
...selectedProviderSessionId ? { providerSessionId: selectedProviderSessionId } : {},
|
|
16453
|
+
...selectedTranscriptAuthority ? { transcriptAuthority: selectedTranscriptAuthority } : {},
|
|
16454
|
+
...selectedCoverage ? { coverage: selectedCoverage } : {}
|
|
16268
16455
|
}, args);
|
|
16269
16456
|
}
|
|
16270
16457
|
const historyLimit = normalizeReadChatTailLimit(args);
|
|
@@ -19308,7 +19495,7 @@ var CliProviderInstance = class {
|
|
|
19308
19495
|
chatTitle: pending.chatTitle,
|
|
19309
19496
|
duration: pending.duration,
|
|
19310
19497
|
timestamp: pending.timestamp,
|
|
19311
|
-
finalSummary: extractFinalSummaryFromMessages(this.adapter?.getScriptParsedStatus()?.messages),
|
|
19498
|
+
finalSummary: blockReason.startsWith("parsed_status:") ? "" : extractFinalSummaryFromMessages(this.adapter?.getScriptParsedStatus()?.messages),
|
|
19312
19499
|
completionDiagnostic
|
|
19313
19500
|
});
|
|
19314
19501
|
this.completedDebouncePending = null;
|
|
@@ -21151,6 +21338,10 @@ function commandExists(command) {
|
|
|
21151
21338
|
return false;
|
|
21152
21339
|
}
|
|
21153
21340
|
}
|
|
21341
|
+
var BUSY_AGENT_STATUSES = /* @__PURE__ */ new Set(["generating", "running", "streaming", "starting", "busy", "waiting", "waiting_approval", "long_generating"]);
|
|
21342
|
+
function normalizeAgentStatus(value) {
|
|
21343
|
+
return typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
21344
|
+
}
|
|
21154
21345
|
var chalkModule = chalk;
|
|
21155
21346
|
var chalkApi = typeof chalkModule.yellow === "function" ? chalkModule : chalkModule.default || null;
|
|
21156
21347
|
function colorize(color, text) {
|
|
@@ -21925,6 +22116,19 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
21925
22116
|
if (!found) throw new Error(`CLI agent not running: ${agentType}`);
|
|
21926
22117
|
const { adapter, key } = found;
|
|
21927
22118
|
if (action === "send_chat") {
|
|
22119
|
+
const currentStatus = normalizeAgentStatus(adapter.getStatus?.()?.status);
|
|
22120
|
+
if (BUSY_AGENT_STATUSES.has(currentStatus)) {
|
|
22121
|
+
return {
|
|
22122
|
+
success: false,
|
|
22123
|
+
code: "agent_runtime_busy",
|
|
22124
|
+
reason: "agent_runtime_busy",
|
|
22125
|
+
retryable: true,
|
|
22126
|
+
retryRecommended: true,
|
|
22127
|
+
status: currentStatus,
|
|
22128
|
+
targetSessionId: args?.targetSessionId,
|
|
22129
|
+
error: `CLI agent '${agentType}' is currently ${currentStatus}; retry after the current turn finishes.`
|
|
22130
|
+
};
|
|
22131
|
+
}
|
|
21928
22132
|
const input = normalizeInputEnvelope(args?.input ? { input: args.input } : args);
|
|
21929
22133
|
const provider = this.providerLoader.resolve(agentType) || this.providerLoader.getMeta(agentType);
|
|
21930
22134
|
if (provider?.category === "acp") {
|
|
@@ -25257,7 +25461,7 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
|
|
|
25257
25461
|
|
|
25258
25462
|
// src/commands/router.ts
|
|
25259
25463
|
init_mesh_work_queue();
|
|
25260
|
-
import { homedir as homedir19 } from "os";
|
|
25464
|
+
import { homedir as homedir19, tmpdir as tmpdir5 } from "os";
|
|
25261
25465
|
import { join as pathJoin, resolve as pathResolve } from "path";
|
|
25262
25466
|
import * as fs11 from "fs";
|
|
25263
25467
|
var CHANNEL_NPM_TAG = { stable: "latest", preview: "next" };
|
|
@@ -26069,6 +26273,10 @@ function recordMeshRefineStage(stages, stage, status, startedAt, details) {
|
|
|
26069
26273
|
...details || {}
|
|
26070
26274
|
});
|
|
26071
26275
|
}
|
|
26276
|
+
function buildSubmodulePublishRequiredNextStep(entries) {
|
|
26277
|
+
const refs = entries.map((entry) => `${entry.path}@${entry.commit}`).join(", ");
|
|
26278
|
+
return `Ask the user for explicit approval to push/publish the unreachable submodule commit(s) (${refs}) to their configured submodule remote(s), then rerun mesh_refine_node. Do not merge the root branch until every submodule gitlink commit is reachable from its configured remote.`;
|
|
26279
|
+
}
|
|
26072
26280
|
async function computeGitPatchId(cwd, fromRef, toRef) {
|
|
26073
26281
|
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
26074
26282
|
const diff = execFileSync3("git", ["diff", "--patch", "--full-index", fromRef, toRef], {
|
|
@@ -26154,6 +26362,16 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree) {
|
|
|
26154
26362
|
});
|
|
26155
26363
|
return String(stdout || "");
|
|
26156
26364
|
};
|
|
26365
|
+
const verifyRemoteCommitReachable = async (remoteUrl, commit) => {
|
|
26366
|
+
const probeDir = fs11.mkdtempSync(pathJoin(tmpdir5(), "adhdev-submodule-reachability-"));
|
|
26367
|
+
try {
|
|
26368
|
+
await runGit2(probeDir, ["init", "-q"]);
|
|
26369
|
+
await runGit2(probeDir, ["-c", "protocol.file.allow=always", "fetch", "--depth=1", remoteUrl, commit]);
|
|
26370
|
+
await runGit2(probeDir, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
26371
|
+
} finally {
|
|
26372
|
+
fs11.rmSync(probeDir, { recursive: true, force: true });
|
|
26373
|
+
}
|
|
26374
|
+
};
|
|
26157
26375
|
const treeOutput = await runGit2(repoRoot, ["ls-tree", "-r", "-z", mergedTree]);
|
|
26158
26376
|
const gitlinks = treeOutput.split("\0").filter(Boolean).map((record) => {
|
|
26159
26377
|
const match = /^160000\s+commit\s+([0-9a-f]{40})\t(.+)$/.exec(record);
|
|
@@ -26169,27 +26387,43 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree) {
|
|
|
26169
26387
|
try {
|
|
26170
26388
|
if (!fs11.existsSync(submodulePath)) {
|
|
26171
26389
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
26390
|
+
entry.publishRequired = true;
|
|
26172
26391
|
entries.push(entry);
|
|
26173
26392
|
continue;
|
|
26174
26393
|
}
|
|
26175
26394
|
entry.checkedLocal = true;
|
|
26176
26395
|
try {
|
|
26177
26396
|
await runGit2(submodulePath, ["cat-file", "-e", `${gitlink.commit}^{commit}`]);
|
|
26178
|
-
entry.
|
|
26179
|
-
entries.push(entry);
|
|
26180
|
-
continue;
|
|
26397
|
+
entry.localReachable = true;
|
|
26181
26398
|
} catch {
|
|
26399
|
+
entry.localReachable = false;
|
|
26182
26400
|
}
|
|
26183
26401
|
try {
|
|
26184
|
-
|
|
26402
|
+
entry.remote = "origin";
|
|
26403
|
+
let remoteUrl = "";
|
|
26404
|
+
try {
|
|
26405
|
+
remoteUrl = (await runGit2(submodulePath, ["remote", "get-url", "origin"])).trim();
|
|
26406
|
+
if (!remoteUrl) throw new Error("origin remote has no URL");
|
|
26407
|
+
entry.remoteUrl = remoteUrl;
|
|
26408
|
+
} catch {
|
|
26409
|
+
entry.error = "Submodule remote reachability check failed: no configured origin remote";
|
|
26410
|
+
entry.publishRequired = true;
|
|
26411
|
+
entries.push(entry);
|
|
26412
|
+
continue;
|
|
26413
|
+
}
|
|
26414
|
+
await verifyRemoteCommitReachable(remoteUrl, gitlink.commit);
|
|
26185
26415
|
entry.fetchedFromOrigin = true;
|
|
26186
|
-
|
|
26416
|
+
entry.remoteReachable = true;
|
|
26187
26417
|
entry.reachable = true;
|
|
26188
26418
|
} catch (e) {
|
|
26189
|
-
entry.
|
|
26419
|
+
entry.remoteReachable = false;
|
|
26420
|
+
entry.publishRequired = true;
|
|
26421
|
+
const details = truncateValidationOutput(e?.stderr || e?.message || String(e));
|
|
26422
|
+
entry.error = `Submodule remote reachability check failed for origin: ${details}`;
|
|
26190
26423
|
}
|
|
26191
26424
|
} catch (e) {
|
|
26192
26425
|
entry.error = truncateValidationOutput(e?.message || String(e));
|
|
26426
|
+
entry.publishRequired = true;
|
|
26193
26427
|
}
|
|
26194
26428
|
entries.push(entry);
|
|
26195
26429
|
}
|
|
@@ -26197,16 +26431,17 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree) {
|
|
|
26197
26431
|
return {
|
|
26198
26432
|
status: unreachable.length ? "failed" : "passed",
|
|
26199
26433
|
checked: entries.length,
|
|
26200
|
-
unreachable,
|
|
26201
|
-
entries,
|
|
26434
|
+
unreachable: unreachable.map((entry) => ({ ...entry, publishRequired: entry.publishRequired !== false })),
|
|
26435
|
+
entries: entries.map((entry) => entry.reachable ? entry : { ...entry, publishRequired: entry.publishRequired !== false }),
|
|
26202
26436
|
durationMs: Date.now() - startedAt
|
|
26203
26437
|
};
|
|
26204
26438
|
} catch (e) {
|
|
26439
|
+
const unreachable = entries.filter((entry) => !entry.reachable).map((entry) => ({ ...entry, publishRequired: true }));
|
|
26205
26440
|
return {
|
|
26206
26441
|
status: "failed",
|
|
26207
26442
|
checked: entries.length,
|
|
26208
|
-
unreachable
|
|
26209
|
-
entries,
|
|
26443
|
+
unreachable,
|
|
26444
|
+
entries: entries.map((entry) => entry.reachable ? entry : { ...entry, publishRequired: true }),
|
|
26210
26445
|
durationMs: Date.now() - startedAt,
|
|
26211
26446
|
error: truncateValidationOutput(e?.message || String(e))
|
|
26212
26447
|
};
|
|
@@ -27325,15 +27560,41 @@ var DaemonCommandRouter = class {
|
|
|
27325
27560
|
const submoduleReachability = await runMeshRefineSubmoduleReachabilityGate(repoRoot, patchEquivalence.mergedTree || branchHead);
|
|
27326
27561
|
recordMeshRefineStage(refineStages, "submodule_reachability", submoduleReachability.status, submoduleReachabilityStarted, {
|
|
27327
27562
|
checked: submoduleReachability.checked,
|
|
27328
|
-
unreachable: submoduleReachability.unreachable.map((entry) => ({
|
|
27563
|
+
unreachable: submoduleReachability.unreachable.map((entry) => ({
|
|
27564
|
+
path: entry.path,
|
|
27565
|
+
commit: entry.commit,
|
|
27566
|
+
publishRequired: entry.publishRequired === true,
|
|
27567
|
+
remote: entry.remote,
|
|
27568
|
+
remoteUrl: entry.remoteUrl,
|
|
27569
|
+
remoteReachable: entry.remoteReachable,
|
|
27570
|
+
error: entry.error
|
|
27571
|
+
})),
|
|
27329
27572
|
error: submoduleReachability.error
|
|
27330
27573
|
});
|
|
27331
27574
|
if (submoduleReachability.status === "failed") {
|
|
27575
|
+
const nextStep = buildSubmodulePublishRequiredNextStep(submoduleReachability.unreachable);
|
|
27332
27576
|
return {
|
|
27333
27577
|
success: false,
|
|
27334
27578
|
code: "submodule_reachability_failed",
|
|
27335
27579
|
convergenceStatus: "blocked_review",
|
|
27336
|
-
|
|
27580
|
+
publishRequired: true,
|
|
27581
|
+
blockedReason: "submodule_publish_required",
|
|
27582
|
+
error: "Refinery submodule reachability preflight failed because one or more submodule gitlink commits are not reachable from their configured remote; merge/refine cleanup was not attempted.",
|
|
27583
|
+
nextStep,
|
|
27584
|
+
nextSteps: [
|
|
27585
|
+
"Ask the user for explicit approval before pushing or publishing any submodule commit.",
|
|
27586
|
+
"Push/publish each unreachable submodule commit to the configured submodule remote shown in the evidence.",
|
|
27587
|
+
"Rerun mesh_refine_node after remote reachability is confirmed.",
|
|
27588
|
+
"Do not merge the root branch until every submodule gitlink commit is reachable from its configured remote."
|
|
27589
|
+
],
|
|
27590
|
+
unreachableSubmoduleCommits: submoduleReachability.unreachable.map((entry) => ({
|
|
27591
|
+
path: entry.path,
|
|
27592
|
+
commit: entry.commit,
|
|
27593
|
+
remote: entry.remote,
|
|
27594
|
+
remoteUrl: entry.remoteUrl,
|
|
27595
|
+
remoteReachable: entry.remoteReachable,
|
|
27596
|
+
error: entry.error
|
|
27597
|
+
})),
|
|
27337
27598
|
branch,
|
|
27338
27599
|
into: baseBranch,
|
|
27339
27600
|
validationSummary,
|
|
@@ -27348,7 +27609,9 @@ var DaemonCommandRouter = class {
|
|
|
27348
27609
|
validation: "passed",
|
|
27349
27610
|
patchEquivalence: "passed",
|
|
27350
27611
|
submoduleReachability: "failed",
|
|
27351
|
-
status: "blocked_review"
|
|
27612
|
+
status: "blocked_review",
|
|
27613
|
+
reason: "submodule_publish_required",
|
|
27614
|
+
nextStep
|
|
27352
27615
|
}
|
|
27353
27616
|
};
|
|
27354
27617
|
}
|