@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.js
CHANGED
|
@@ -1192,6 +1192,7 @@ function buildRulesSection(coordinatorCliType) {
|
|
|
1192
1192
|
- **Clean up worktree nodes.** After a worktree task completes and its changes are merged or checkpointed, call \`mesh_remove_node\` to free resources.
|
|
1193
1193
|
- **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.
|
|
1194
1194
|
- **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.
|
|
1195
|
+
- **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\`.
|
|
1195
1196
|
- **Name worktree branches meaningfully.** Use descriptive names like \`feat/auth-refactor\` or \`fix/build-123\`.${coordinatorNote}`;
|
|
1196
1197
|
}
|
|
1197
1198
|
var TOOLS_SECTION, TOOL_EXPOSURE_PREFLIGHT_SECTION, WORKFLOW_SECTION;
|
|
@@ -1238,7 +1239,7 @@ Before doing any coordinator work, confirm that the actual callable tool list in
|
|
|
1238
1239
|
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\`.
|
|
1239
1240
|
5. **Verify** \u2014 When a task reports completion or git work is visible, call \`mesh_git_status\` to verify changes were made.
|
|
1240
1241
|
6. **Checkpoint** \u2014 Call \`mesh_checkpoint\` to save the work.
|
|
1241
|
-
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.
|
|
1242
|
+
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.
|
|
1242
1243
|
8. **Clean up** \u2014 Remove worktree nodes via \`mesh_remove_node\` after their work is merged or no longer needed.
|
|
1243
1244
|
9. **Report** \u2014 Summarize what was done, what changed, any issues, and the branch convergence state.
|
|
1244
1245
|
|
|
@@ -15819,6 +15820,7 @@ function buildSessionModalDeliverySignature(payload) {
|
|
|
15819
15820
|
var RECENT_SEND_WINDOW_MS = 1200;
|
|
15820
15821
|
var READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS = 25e3;
|
|
15821
15822
|
var HERMES_CLI_STARTING_SEND_SETTLE_MS = 2e3;
|
|
15823
|
+
var CODEX_NATIVE_HISTORY_FRESH_MS = 5 * 6e4;
|
|
15822
15824
|
var recentSendByTarget = /* @__PURE__ */ new Map();
|
|
15823
15825
|
function getCurrentProviderType(h, fallback = "") {
|
|
15824
15826
|
return h.currentSession?.providerType || h.currentProviderType || fallback;
|
|
@@ -15952,6 +15954,77 @@ function normalizeReadChatMessages(payload) {
|
|
|
15952
15954
|
const messages = Array.isArray(payload.messages) ? payload.messages : [];
|
|
15953
15955
|
return normalizeChatMessages(messages);
|
|
15954
15956
|
}
|
|
15957
|
+
function getMessageNewestReceivedAt(messages) {
|
|
15958
|
+
let newest = 0;
|
|
15959
|
+
for (const message of messages) {
|
|
15960
|
+
const receivedAt = Number(message?.receivedAt ?? message?.timestamp ?? 0);
|
|
15961
|
+
if (Number.isFinite(receivedAt) && receivedAt > newest) newest = receivedAt;
|
|
15962
|
+
}
|
|
15963
|
+
return newest;
|
|
15964
|
+
}
|
|
15965
|
+
function buildCliMessageSourceProvenance(args) {
|
|
15966
|
+
const sourceMtimeMs = Number(args.sourceMtimeMs || 0);
|
|
15967
|
+
const sourceMtimeAgeMs = sourceMtimeMs > 0 ? Math.max(0, Date.now() - sourceMtimeMs) : void 0;
|
|
15968
|
+
const nativeMessages = args.nativeMessages || [];
|
|
15969
|
+
const ptyMessages = args.ptyMessages || [];
|
|
15970
|
+
const returnedMessages = args.returnedMessages || [];
|
|
15971
|
+
return {
|
|
15972
|
+
selected: args.selected,
|
|
15973
|
+
provider: args.provider,
|
|
15974
|
+
...args.nativeHandle ? { nativeHandle: args.nativeHandle } : {},
|
|
15975
|
+
...args.fallbackReason ? { fallbackReason: args.fallbackReason } : {},
|
|
15976
|
+
...args.nativeSource ? { nativeSource: args.nativeSource } : {},
|
|
15977
|
+
...args.sourcePath ? { sourcePath: args.sourcePath } : {},
|
|
15978
|
+
ptyStatusApprovalOnly: args.ptyStatusApprovalOnly === true,
|
|
15979
|
+
staleness: {
|
|
15980
|
+
sourceMtimeMs: sourceMtimeMs || void 0,
|
|
15981
|
+
sourceMtimeAgeMs,
|
|
15982
|
+
nativeNewestMessageAt: getMessageNewestReceivedAt(nativeMessages),
|
|
15983
|
+
ptyNewestMessageAt: getMessageNewestReceivedAt(ptyMessages),
|
|
15984
|
+
freshEnough: args.freshEnough === true
|
|
15985
|
+
},
|
|
15986
|
+
coverage: {
|
|
15987
|
+
nativeMessageCount: nativeMessages.length,
|
|
15988
|
+
ptyMessageCount: ptyMessages.length,
|
|
15989
|
+
returnedMessageCount: returnedMessages.length,
|
|
15990
|
+
safeMapping: args.safeMapping === true
|
|
15991
|
+
}
|
|
15992
|
+
};
|
|
15993
|
+
}
|
|
15994
|
+
function buildNativeHistoryFallbackReason(args) {
|
|
15995
|
+
if (args.providerType !== "codex-cli") return "provider_not_codex_cli";
|
|
15996
|
+
if (args.nativeSource === "native-unavailable") return "native_history_unavailable";
|
|
15997
|
+
if (args.nativeSource && args.nativeSource !== "provider-native") return `native_history_source_${args.nativeSource}`;
|
|
15998
|
+
if (args.nativeMessageCount <= 0) return "native_history_empty";
|
|
15999
|
+
if (!args.safeMapping) return "native_history_not_safely_mapped";
|
|
16000
|
+
if (!args.freshEnough) return "native_history_stale";
|
|
16001
|
+
return "native_history_not_selected";
|
|
16002
|
+
}
|
|
16003
|
+
function isCodexCliProvider(providerType) {
|
|
16004
|
+
return providerType === "codex-cli";
|
|
16005
|
+
}
|
|
16006
|
+
function hasSafeNativeHistoryMapping(args) {
|
|
16007
|
+
const explicitSessionId = String(args.historySessionId || args.providerSessionId || "").trim();
|
|
16008
|
+
if (explicitSessionId) {
|
|
16009
|
+
const messageSessionIds = args.nativeMessages.map((message) => typeof message?.historySessionId === "string" ? message.historySessionId.trim() : "").filter(Boolean);
|
|
16010
|
+
if (messageSessionIds.length === 0) return true;
|
|
16011
|
+
return messageSessionIds.some((id) => id === explicitSessionId);
|
|
16012
|
+
}
|
|
16013
|
+
const workspace = String(args.workspace || "").trim();
|
|
16014
|
+
if (!workspace) return false;
|
|
16015
|
+
return args.nativeMessages.some((message) => String(message?.workspace || "").trim() === workspace);
|
|
16016
|
+
}
|
|
16017
|
+
function isNativeHistoryFreshEnough(args) {
|
|
16018
|
+
const nativeNewest = getMessageNewestReceivedAt(args.nativeMessages);
|
|
16019
|
+
const ptyNewest = getMessageNewestReceivedAt(args.ptyMessages);
|
|
16020
|
+
if (nativeNewest > 0 && nativeNewest >= ptyNewest) return true;
|
|
16021
|
+
const sourceMtimeMs = Number(args.sourceMtimeMs || 0);
|
|
16022
|
+
if (sourceMtimeMs > 0 && Date.now() - sourceMtimeMs <= CODEX_NATIVE_HISTORY_FRESH_MS) return true;
|
|
16023
|
+
return ptyNewest === 0 && nativeNewest > 0;
|
|
16024
|
+
}
|
|
16025
|
+
function shouldPreserveReadChatPayloadField(key) {
|
|
16026
|
+
return key === "messageSource" || key === "transcriptProvenance";
|
|
16027
|
+
}
|
|
15955
16028
|
function deriveHistoryDedupKey(message) {
|
|
15956
16029
|
const unitKey = typeof message._unitKey === "string" ? message._unitKey.trim() : "";
|
|
15957
16030
|
if (unitKey) return `read_chat:${unitKey}`;
|
|
@@ -16057,6 +16130,7 @@ function buildReadChatCommandResult(payload, args) {
|
|
|
16057
16130
|
return {
|
|
16058
16131
|
success: true,
|
|
16059
16132
|
...validatedPayload,
|
|
16133
|
+
...Object.fromEntries(Object.entries(payload).filter(([key]) => shouldPreserveReadChatPayloadField(key))),
|
|
16060
16134
|
messages: sync.messages,
|
|
16061
16135
|
totalMessages: sync.totalMessages,
|
|
16062
16136
|
...returnedDebugReadChat ? { debugReadChat: returnedDebugReadChat } : {}
|
|
@@ -16233,6 +16307,8 @@ function buildChatDebugBundleSummary(bundle) {
|
|
|
16233
16307
|
adapterStatus: debugReadChat.adapterStatus,
|
|
16234
16308
|
parsedStatus: debugReadChat.parsedStatus,
|
|
16235
16309
|
returnedStatus: debugReadChat.returnedStatus,
|
|
16310
|
+
selectedMessageSource: debugReadChat.selectedMessageSource,
|
|
16311
|
+
messageSource: debugReadChat.messageSource,
|
|
16236
16312
|
parsedMsgCount: debugReadChat.parsedMsgCount,
|
|
16237
16313
|
returnedMsgCount: debugReadChat.returnedMsgCount,
|
|
16238
16314
|
shouldPreferAdapterMessages: debugReadChat.shouldPreferAdapterMessages
|
|
@@ -16308,6 +16384,8 @@ async function handleGetChatDebugBundle(h, args) {
|
|
|
16308
16384
|
providerSessionId: readResult.providerSessionId,
|
|
16309
16385
|
transcriptAuthority: readResult.transcriptAuthority,
|
|
16310
16386
|
coverage: readResult.coverage,
|
|
16387
|
+
messageSource: readResult.messageSource,
|
|
16388
|
+
transcriptProvenance: readResult.transcriptProvenance,
|
|
16311
16389
|
activeModal: readResult.activeModal,
|
|
16312
16390
|
messagesTail: Array.isArray(readResult.messages) ? readResult.messages.slice(-20) : [],
|
|
16313
16391
|
debugReadChat: readResult.debugReadChat
|
|
@@ -16505,25 +16583,134 @@ async function handleReadChat(h, args) {
|
|
|
16505
16583
|
const runtimeMessageMerger = getTargetInstance(h, args);
|
|
16506
16584
|
const parsedMessages = finalizeStreamingMessagesWhenIdle(parsedRecord.messages, returnedStatus);
|
|
16507
16585
|
const returnedMessages = runtimeMessageMerger?.category === "cli" && runtimeMessageMerger.type === adapter.cliType && typeof runtimeMessageMerger.mergeRuntimeChatMessages === "function" ? runtimeMessageMerger.mergeRuntimeChatMessages(parsedMessages) : parsedMessages;
|
|
16586
|
+
const providerType = provider?.type || adapter.cliType;
|
|
16587
|
+
let selectedMessages = returnedMessages;
|
|
16588
|
+
let selectedTitle = title;
|
|
16589
|
+
let selectedProviderSessionId = providerSessionId;
|
|
16590
|
+
let selectedTranscriptAuthority = transcriptAuthority;
|
|
16591
|
+
let selectedCoverage = coverage;
|
|
16592
|
+
let messageSource = buildCliMessageSourceProvenance({
|
|
16593
|
+
selected: "pty-parser",
|
|
16594
|
+
provider: adapter.cliType,
|
|
16595
|
+
fallbackReason: isCodexCliProvider(providerType) ? "native_history_not_checked" : "provider_not_codex_cli",
|
|
16596
|
+
ptyMessages: returnedMessages,
|
|
16597
|
+
returnedMessages,
|
|
16598
|
+
ptyStatusApprovalOnly: false
|
|
16599
|
+
});
|
|
16600
|
+
if (isCodexCliProvider(providerType)) {
|
|
16601
|
+
const agentStr = provider?.type || args?.agentType || getCurrentProviderType(h, adapter.cliType);
|
|
16602
|
+
const workspace = typeof args?.workspace === "string" ? args.workspace : typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : typeof adapter.workingDir === "string" ? adapter.workingDir : void 0;
|
|
16603
|
+
const nativeHistoryLimit = Math.max(
|
|
16604
|
+
normalizeReadChatTailLimit(args) || 0,
|
|
16605
|
+
returnedMessages.length,
|
|
16606
|
+
200
|
|
16607
|
+
);
|
|
16608
|
+
let nativeHistory = null;
|
|
16609
|
+
try {
|
|
16610
|
+
nativeHistory = readProviderChatHistory(agentStr, {
|
|
16611
|
+
canonicalHistory: provider?.canonicalHistory,
|
|
16612
|
+
historySessionId,
|
|
16613
|
+
workspace,
|
|
16614
|
+
offset: 0,
|
|
16615
|
+
limit: nativeHistoryLimit,
|
|
16616
|
+
excludeRecentCount: 0,
|
|
16617
|
+
historyBehavior: provider?.historyBehavior,
|
|
16618
|
+
scripts: provider?.scripts
|
|
16619
|
+
});
|
|
16620
|
+
} catch (error) {
|
|
16621
|
+
const fallbackReason = `native_history_error:${error?.message || String(error)}`;
|
|
16622
|
+
messageSource = buildCliMessageSourceProvenance({
|
|
16623
|
+
selected: "pty-parser",
|
|
16624
|
+
provider: adapter.cliType,
|
|
16625
|
+
fallbackReason,
|
|
16626
|
+
ptyMessages: returnedMessages,
|
|
16627
|
+
returnedMessages,
|
|
16628
|
+
ptyStatusApprovalOnly: false
|
|
16629
|
+
});
|
|
16630
|
+
nativeHistory = null;
|
|
16631
|
+
}
|
|
16632
|
+
if (nativeHistory) {
|
|
16633
|
+
const nativeMessages = Array.isArray(nativeHistory.messages) ? normalizeChatMessages(nativeHistory.messages) : [];
|
|
16634
|
+
const historyProviderSessionId = typeof nativeHistory?.providerSessionId === "string" ? nativeHistory.providerSessionId : historySessionId;
|
|
16635
|
+
const safeMapping = hasSafeNativeHistoryMapping({
|
|
16636
|
+
historySessionId,
|
|
16637
|
+
providerSessionId,
|
|
16638
|
+
workspace,
|
|
16639
|
+
nativeMessages
|
|
16640
|
+
});
|
|
16641
|
+
const freshEnough = isNativeHistoryFreshEnough({
|
|
16642
|
+
sourceMtimeMs: nativeHistory.sourceMtimeMs,
|
|
16643
|
+
nativeMessages,
|
|
16644
|
+
ptyMessages: returnedMessages
|
|
16645
|
+
});
|
|
16646
|
+
if (nativeHistory.source === "provider-native" && nativeMessages.length > 0 && safeMapping && freshEnough) {
|
|
16647
|
+
selectedMessages = finalizeStreamingMessagesWhenIdle(nativeMessages, returnedStatus);
|
|
16648
|
+
selectedProviderSessionId = historyProviderSessionId || providerSessionId;
|
|
16649
|
+
selectedTranscriptAuthority = "provider";
|
|
16650
|
+
selectedCoverage = nativeHistory.hasMore ? "tail" : "full";
|
|
16651
|
+
messageSource = buildCliMessageSourceProvenance({
|
|
16652
|
+
selected: "native-history",
|
|
16653
|
+
provider: adapter.cliType,
|
|
16654
|
+
nativeHandle: selectedProviderSessionId || historySessionId,
|
|
16655
|
+
nativeSource: nativeHistory.source,
|
|
16656
|
+
sourcePath: nativeHistory.sourcePath,
|
|
16657
|
+
sourceMtimeMs: nativeHistory.sourceMtimeMs,
|
|
16658
|
+
nativeMessages,
|
|
16659
|
+
ptyMessages: returnedMessages,
|
|
16660
|
+
returnedMessages: selectedMessages,
|
|
16661
|
+
safeMapping,
|
|
16662
|
+
freshEnough,
|
|
16663
|
+
ptyStatusApprovalOnly: true
|
|
16664
|
+
});
|
|
16665
|
+
} else {
|
|
16666
|
+
const fallbackReason = buildNativeHistoryFallbackReason({
|
|
16667
|
+
providerType,
|
|
16668
|
+
nativeSource: nativeHistory.source,
|
|
16669
|
+
nativeMessageCount: nativeMessages.length,
|
|
16670
|
+
safeMapping,
|
|
16671
|
+
freshEnough
|
|
16672
|
+
});
|
|
16673
|
+
messageSource = buildCliMessageSourceProvenance({
|
|
16674
|
+
selected: "pty-parser",
|
|
16675
|
+
provider: adapter.cliType,
|
|
16676
|
+
nativeHandle: historyProviderSessionId || historySessionId,
|
|
16677
|
+
fallbackReason,
|
|
16678
|
+
nativeSource: nativeHistory.source,
|
|
16679
|
+
sourcePath: nativeHistory.sourcePath,
|
|
16680
|
+
sourceMtimeMs: nativeHistory.sourceMtimeMs,
|
|
16681
|
+
nativeMessages,
|
|
16682
|
+
ptyMessages: returnedMessages,
|
|
16683
|
+
returnedMessages,
|
|
16684
|
+
safeMapping,
|
|
16685
|
+
freshEnough,
|
|
16686
|
+
ptyStatusApprovalOnly: false
|
|
16687
|
+
});
|
|
16688
|
+
}
|
|
16689
|
+
}
|
|
16690
|
+
}
|
|
16508
16691
|
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}`);
|
|
16509
16692
|
return buildReadChatCommandResult({
|
|
16510
|
-
messages:
|
|
16693
|
+
messages: selectedMessages,
|
|
16511
16694
|
status: returnedStatus,
|
|
16512
16695
|
activeModal,
|
|
16696
|
+
messageSource,
|
|
16697
|
+
transcriptProvenance: messageSource,
|
|
16513
16698
|
debugReadChat: {
|
|
16514
16699
|
provider: adapter.cliType,
|
|
16515
16700
|
targetSessionId: String(args?.targetSessionId || ""),
|
|
16516
16701
|
adapterStatus: String(adapterStatus.status || ""),
|
|
16517
16702
|
parsedStatus: String(parsedRecord.status || ""),
|
|
16518
16703
|
returnedStatus: String(returnedStatus || ""),
|
|
16519
|
-
|
|
16704
|
+
selectedMessageSource: messageSource.selected,
|
|
16705
|
+
messageSource,
|
|
16706
|
+
shouldPreferAdapterMessages: messageSource.selected !== "native-history",
|
|
16520
16707
|
parsedMsgCount: parsedRecord.messages.length,
|
|
16521
|
-
returnedMsgCount:
|
|
16708
|
+
returnedMsgCount: selectedMessages.length
|
|
16522
16709
|
},
|
|
16523
|
-
...
|
|
16524
|
-
...
|
|
16525
|
-
...
|
|
16526
|
-
...
|
|
16710
|
+
...selectedTitle ? { title: selectedTitle } : {},
|
|
16711
|
+
...selectedProviderSessionId ? { providerSessionId: selectedProviderSessionId } : {},
|
|
16712
|
+
...selectedTranscriptAuthority ? { transcriptAuthority: selectedTranscriptAuthority } : {},
|
|
16713
|
+
...selectedCoverage ? { coverage: selectedCoverage } : {}
|
|
16527
16714
|
}, args);
|
|
16528
16715
|
}
|
|
16529
16716
|
const historyLimit = normalizeReadChatTailLimit(args);
|
|
@@ -19567,7 +19754,7 @@ var CliProviderInstance = class {
|
|
|
19567
19754
|
chatTitle: pending.chatTitle,
|
|
19568
19755
|
duration: pending.duration,
|
|
19569
19756
|
timestamp: pending.timestamp,
|
|
19570
|
-
finalSummary: extractFinalSummaryFromMessages(this.adapter?.getScriptParsedStatus()?.messages),
|
|
19757
|
+
finalSummary: blockReason.startsWith("parsed_status:") ? "" : extractFinalSummaryFromMessages(this.adapter?.getScriptParsedStatus()?.messages),
|
|
19571
19758
|
completionDiagnostic
|
|
19572
19759
|
});
|
|
19573
19760
|
this.completedDebouncePending = null;
|
|
@@ -21405,6 +21592,10 @@ function commandExists(command) {
|
|
|
21405
21592
|
return false;
|
|
21406
21593
|
}
|
|
21407
21594
|
}
|
|
21595
|
+
var BUSY_AGENT_STATUSES = /* @__PURE__ */ new Set(["generating", "running", "streaming", "starting", "busy", "waiting", "waiting_approval", "long_generating"]);
|
|
21596
|
+
function normalizeAgentStatus(value) {
|
|
21597
|
+
return typeof value === "string" ? value.trim().toLowerCase() : "";
|
|
21598
|
+
}
|
|
21408
21599
|
var chalkModule = import_chalk.default;
|
|
21409
21600
|
var chalkApi = typeof chalkModule.yellow === "function" ? chalkModule : chalkModule.default || null;
|
|
21410
21601
|
function colorize(color, text) {
|
|
@@ -22179,6 +22370,19 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
22179
22370
|
if (!found) throw new Error(`CLI agent not running: ${agentType}`);
|
|
22180
22371
|
const { adapter, key } = found;
|
|
22181
22372
|
if (action === "send_chat") {
|
|
22373
|
+
const currentStatus = normalizeAgentStatus(adapter.getStatus?.()?.status);
|
|
22374
|
+
if (BUSY_AGENT_STATUSES.has(currentStatus)) {
|
|
22375
|
+
return {
|
|
22376
|
+
success: false,
|
|
22377
|
+
code: "agent_runtime_busy",
|
|
22378
|
+
reason: "agent_runtime_busy",
|
|
22379
|
+
retryable: true,
|
|
22380
|
+
retryRecommended: true,
|
|
22381
|
+
status: currentStatus,
|
|
22382
|
+
targetSessionId: args?.targetSessionId,
|
|
22383
|
+
error: `CLI agent '${agentType}' is currently ${currentStatus}; retry after the current turn finishes.`
|
|
22384
|
+
};
|
|
22385
|
+
}
|
|
22182
22386
|
const input = normalizeInputEnvelope(args?.input ? { input: args.input } : args);
|
|
22183
22387
|
const provider = this.providerLoader.resolve(agentType) || this.providerLoader.getMeta(agentType);
|
|
22184
22388
|
if (provider?.category === "acp") {
|
|
@@ -26323,6 +26527,10 @@ function recordMeshRefineStage(stages, stage, status, startedAt, details) {
|
|
|
26323
26527
|
...details || {}
|
|
26324
26528
|
});
|
|
26325
26529
|
}
|
|
26530
|
+
function buildSubmodulePublishRequiredNextStep(entries) {
|
|
26531
|
+
const refs = entries.map((entry) => `${entry.path}@${entry.commit}`).join(", ");
|
|
26532
|
+
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.`;
|
|
26533
|
+
}
|
|
26326
26534
|
async function computeGitPatchId(cwd, fromRef, toRef) {
|
|
26327
26535
|
const { execFileSync: execFileSync3 } = await import("child_process");
|
|
26328
26536
|
const diff = execFileSync3("git", ["diff", "--patch", "--full-index", fromRef, toRef], {
|
|
@@ -26408,6 +26616,16 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree) {
|
|
|
26408
26616
|
});
|
|
26409
26617
|
return String(stdout || "");
|
|
26410
26618
|
};
|
|
26619
|
+
const verifyRemoteCommitReachable = async (remoteUrl, commit) => {
|
|
26620
|
+
const probeDir = fs11.mkdtempSync((0, import_path8.join)((0, import_os3.tmpdir)(), "adhdev-submodule-reachability-"));
|
|
26621
|
+
try {
|
|
26622
|
+
await runGit2(probeDir, ["init", "-q"]);
|
|
26623
|
+
await runGit2(probeDir, ["-c", "protocol.file.allow=always", "fetch", "--depth=1", remoteUrl, commit]);
|
|
26624
|
+
await runGit2(probeDir, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
26625
|
+
} finally {
|
|
26626
|
+
fs11.rmSync(probeDir, { recursive: true, force: true });
|
|
26627
|
+
}
|
|
26628
|
+
};
|
|
26411
26629
|
const treeOutput = await runGit2(repoRoot, ["ls-tree", "-r", "-z", mergedTree]);
|
|
26412
26630
|
const gitlinks = treeOutput.split("\0").filter(Boolean).map((record) => {
|
|
26413
26631
|
const match = /^160000\s+commit\s+([0-9a-f]{40})\t(.+)$/.exec(record);
|
|
@@ -26423,27 +26641,43 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree) {
|
|
|
26423
26641
|
try {
|
|
26424
26642
|
if (!fs11.existsSync(submodulePath)) {
|
|
26425
26643
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
26644
|
+
entry.publishRequired = true;
|
|
26426
26645
|
entries.push(entry);
|
|
26427
26646
|
continue;
|
|
26428
26647
|
}
|
|
26429
26648
|
entry.checkedLocal = true;
|
|
26430
26649
|
try {
|
|
26431
26650
|
await runGit2(submodulePath, ["cat-file", "-e", `${gitlink.commit}^{commit}`]);
|
|
26432
|
-
entry.
|
|
26433
|
-
entries.push(entry);
|
|
26434
|
-
continue;
|
|
26651
|
+
entry.localReachable = true;
|
|
26435
26652
|
} catch {
|
|
26653
|
+
entry.localReachable = false;
|
|
26436
26654
|
}
|
|
26437
26655
|
try {
|
|
26438
|
-
|
|
26656
|
+
entry.remote = "origin";
|
|
26657
|
+
let remoteUrl = "";
|
|
26658
|
+
try {
|
|
26659
|
+
remoteUrl = (await runGit2(submodulePath, ["remote", "get-url", "origin"])).trim();
|
|
26660
|
+
if (!remoteUrl) throw new Error("origin remote has no URL");
|
|
26661
|
+
entry.remoteUrl = remoteUrl;
|
|
26662
|
+
} catch {
|
|
26663
|
+
entry.error = "Submodule remote reachability check failed: no configured origin remote";
|
|
26664
|
+
entry.publishRequired = true;
|
|
26665
|
+
entries.push(entry);
|
|
26666
|
+
continue;
|
|
26667
|
+
}
|
|
26668
|
+
await verifyRemoteCommitReachable(remoteUrl, gitlink.commit);
|
|
26439
26669
|
entry.fetchedFromOrigin = true;
|
|
26440
|
-
|
|
26670
|
+
entry.remoteReachable = true;
|
|
26441
26671
|
entry.reachable = true;
|
|
26442
26672
|
} catch (e) {
|
|
26443
|
-
entry.
|
|
26673
|
+
entry.remoteReachable = false;
|
|
26674
|
+
entry.publishRequired = true;
|
|
26675
|
+
const details = truncateValidationOutput(e?.stderr || e?.message || String(e));
|
|
26676
|
+
entry.error = `Submodule remote reachability check failed for origin: ${details}`;
|
|
26444
26677
|
}
|
|
26445
26678
|
} catch (e) {
|
|
26446
26679
|
entry.error = truncateValidationOutput(e?.message || String(e));
|
|
26680
|
+
entry.publishRequired = true;
|
|
26447
26681
|
}
|
|
26448
26682
|
entries.push(entry);
|
|
26449
26683
|
}
|
|
@@ -26451,16 +26685,17 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree) {
|
|
|
26451
26685
|
return {
|
|
26452
26686
|
status: unreachable.length ? "failed" : "passed",
|
|
26453
26687
|
checked: entries.length,
|
|
26454
|
-
unreachable,
|
|
26455
|
-
entries,
|
|
26688
|
+
unreachable: unreachable.map((entry) => ({ ...entry, publishRequired: entry.publishRequired !== false })),
|
|
26689
|
+
entries: entries.map((entry) => entry.reachable ? entry : { ...entry, publishRequired: entry.publishRequired !== false }),
|
|
26456
26690
|
durationMs: Date.now() - startedAt
|
|
26457
26691
|
};
|
|
26458
26692
|
} catch (e) {
|
|
26693
|
+
const unreachable = entries.filter((entry) => !entry.reachable).map((entry) => ({ ...entry, publishRequired: true }));
|
|
26459
26694
|
return {
|
|
26460
26695
|
status: "failed",
|
|
26461
26696
|
checked: entries.length,
|
|
26462
|
-
unreachable
|
|
26463
|
-
entries,
|
|
26697
|
+
unreachable,
|
|
26698
|
+
entries: entries.map((entry) => entry.reachable ? entry : { ...entry, publishRequired: true }),
|
|
26464
26699
|
durationMs: Date.now() - startedAt,
|
|
26465
26700
|
error: truncateValidationOutput(e?.message || String(e))
|
|
26466
26701
|
};
|
|
@@ -27579,15 +27814,41 @@ var DaemonCommandRouter = class {
|
|
|
27579
27814
|
const submoduleReachability = await runMeshRefineSubmoduleReachabilityGate(repoRoot, patchEquivalence.mergedTree || branchHead);
|
|
27580
27815
|
recordMeshRefineStage(refineStages, "submodule_reachability", submoduleReachability.status, submoduleReachabilityStarted, {
|
|
27581
27816
|
checked: submoduleReachability.checked,
|
|
27582
|
-
unreachable: submoduleReachability.unreachable.map((entry) => ({
|
|
27817
|
+
unreachable: submoduleReachability.unreachable.map((entry) => ({
|
|
27818
|
+
path: entry.path,
|
|
27819
|
+
commit: entry.commit,
|
|
27820
|
+
publishRequired: entry.publishRequired === true,
|
|
27821
|
+
remote: entry.remote,
|
|
27822
|
+
remoteUrl: entry.remoteUrl,
|
|
27823
|
+
remoteReachable: entry.remoteReachable,
|
|
27824
|
+
error: entry.error
|
|
27825
|
+
})),
|
|
27583
27826
|
error: submoduleReachability.error
|
|
27584
27827
|
});
|
|
27585
27828
|
if (submoduleReachability.status === "failed") {
|
|
27829
|
+
const nextStep = buildSubmodulePublishRequiredNextStep(submoduleReachability.unreachable);
|
|
27586
27830
|
return {
|
|
27587
27831
|
success: false,
|
|
27588
27832
|
code: "submodule_reachability_failed",
|
|
27589
27833
|
convergenceStatus: "blocked_review",
|
|
27590
|
-
|
|
27834
|
+
publishRequired: true,
|
|
27835
|
+
blockedReason: "submodule_publish_required",
|
|
27836
|
+
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.",
|
|
27837
|
+
nextStep,
|
|
27838
|
+
nextSteps: [
|
|
27839
|
+
"Ask the user for explicit approval before pushing or publishing any submodule commit.",
|
|
27840
|
+
"Push/publish each unreachable submodule commit to the configured submodule remote shown in the evidence.",
|
|
27841
|
+
"Rerun mesh_refine_node after remote reachability is confirmed.",
|
|
27842
|
+
"Do not merge the root branch until every submodule gitlink commit is reachable from its configured remote."
|
|
27843
|
+
],
|
|
27844
|
+
unreachableSubmoduleCommits: submoduleReachability.unreachable.map((entry) => ({
|
|
27845
|
+
path: entry.path,
|
|
27846
|
+
commit: entry.commit,
|
|
27847
|
+
remote: entry.remote,
|
|
27848
|
+
remoteUrl: entry.remoteUrl,
|
|
27849
|
+
remoteReachable: entry.remoteReachable,
|
|
27850
|
+
error: entry.error
|
|
27851
|
+
})),
|
|
27591
27852
|
branch,
|
|
27592
27853
|
into: baseBranch,
|
|
27593
27854
|
validationSummary,
|
|
@@ -27602,7 +27863,9 @@ var DaemonCommandRouter = class {
|
|
|
27602
27863
|
validation: "passed",
|
|
27603
27864
|
patchEquivalence: "passed",
|
|
27604
27865
|
submoduleReachability: "failed",
|
|
27605
|
-
status: "blocked_review"
|
|
27866
|
+
status: "blocked_review",
|
|
27867
|
+
reason: "submodule_publish_required",
|
|
27868
|
+
nextStep
|
|
27606
27869
|
}
|
|
27607
27870
|
};
|
|
27608
27871
|
}
|