@adhdev/daemon-core 0.8.84 → 0.8.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-adapters/provider-cli-adapter.d.ts +3 -0
- package/dist/cli-adapters/session-host-transport.d.ts +2 -1
- package/dist/index.js +253 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +253 -22
- package/dist/index.mjs.map +1 -1
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +252 -21
- package/src/cli-adapters/session-host-transport.ts +9 -1
- package/src/commands/chat-commands.ts +35 -2
- package/src/providers/cli-provider-instance.ts +3 -1
- package/src/session-host/startup-restore-policy.js +2 -0
- package/src/session-host/startup-restore-policy.ts +2 -0
package/dist/index.mjs
CHANGED
|
@@ -2498,6 +2498,58 @@ var init_provider_cli_adapter = __esm({
|
|
|
2498
2498
|
`[${this.cliType}] Interactive prompt wait timed out after ${maxWaitMs}ms; proceeding with screen=${JSON.stringify(summarizeCliTraceText(finalScreenText, 240)).slice(0, 280)}`
|
|
2499
2499
|
);
|
|
2500
2500
|
}
|
|
2501
|
+
clearStaleIdleResponseGuard(reason) {
|
|
2502
|
+
const screenText = this.terminalScreen.getText() || "";
|
|
2503
|
+
const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
|
|
2504
|
+
const blockingModal = this.activeModal || this.getStartupConfirmationModal(screenText);
|
|
2505
|
+
if (!this.isWaitingForResponse || this.currentStatus !== "idle" || !visibleIdlePrompt || !!blockingModal) {
|
|
2506
|
+
return false;
|
|
2507
|
+
}
|
|
2508
|
+
if (this.responseTimeout) {
|
|
2509
|
+
clearTimeout(this.responseTimeout);
|
|
2510
|
+
this.responseTimeout = null;
|
|
2511
|
+
}
|
|
2512
|
+
if (this.idleTimeout) {
|
|
2513
|
+
clearTimeout(this.idleTimeout);
|
|
2514
|
+
this.idleTimeout = null;
|
|
2515
|
+
}
|
|
2516
|
+
if (this.approvalExitTimeout) {
|
|
2517
|
+
clearTimeout(this.approvalExitTimeout);
|
|
2518
|
+
this.approvalExitTimeout = null;
|
|
2519
|
+
}
|
|
2520
|
+
if (this.finishRetryTimer) {
|
|
2521
|
+
clearTimeout(this.finishRetryTimer);
|
|
2522
|
+
this.finishRetryTimer = null;
|
|
2523
|
+
}
|
|
2524
|
+
this.clearIdleFinishCandidate(reason);
|
|
2525
|
+
this.responseBuffer = "";
|
|
2526
|
+
this.isWaitingForResponse = false;
|
|
2527
|
+
this.responseSettleIgnoreUntil = 0;
|
|
2528
|
+
this.submitRetryUsed = false;
|
|
2529
|
+
this.submitRetryPromptSnippet = "";
|
|
2530
|
+
this.finishRetryCount = 0;
|
|
2531
|
+
this.currentTurnScope = null;
|
|
2532
|
+
this.activeModal = null;
|
|
2533
|
+
this.recordTrace("stale_idle_response_cleared", {
|
|
2534
|
+
reason,
|
|
2535
|
+
screenText: summarizeCliTraceText(screenText, 240)
|
|
2536
|
+
});
|
|
2537
|
+
return true;
|
|
2538
|
+
}
|
|
2539
|
+
hasMeaningfulResponseBuffer(promptSnippet) {
|
|
2540
|
+
const raw = String(this.responseBuffer || "").trim();
|
|
2541
|
+
if (!raw) return false;
|
|
2542
|
+
const normalizedPrompt = compactPromptText(promptSnippet);
|
|
2543
|
+
if (!normalizedPrompt) return true;
|
|
2544
|
+
const normalizedBuffer = compactPromptText(raw);
|
|
2545
|
+
if (!normalizedBuffer) return false;
|
|
2546
|
+
if (normalizedBuffer === normalizedPrompt) return false;
|
|
2547
|
+
if (normalizedBuffer.startsWith(normalizedPrompt)) {
|
|
2548
|
+
const remainder = normalizedBuffer.slice(normalizedPrompt.length).replace(/[─═\-]+/g, "").replace(/⏵⏵accepteditson\([^)]*\)/gi, "").replace(/accepteditson\([^)]*\)/gi, "").replace(/(?:◐|◑|◒|◓|◔|◕|◉|●|·)?(?:x?high|medium|low|max)·?\/effort/gi, "").replace(/updateavailable!run:[a-z0-9:._\-/]+/gi, "").replace(/esctointerrupt/gi, "").replace(/❯/g, "").replace(/^[\s\-–—:;,.!/?]+/, "").trim();
|
|
2549
|
+
return remainder.length > 0;
|
|
2550
|
+
}
|
|
2551
|
+
return true;
|
|
2552
|
+
}
|
|
2501
2553
|
evaluateSettled() {
|
|
2502
2554
|
const now = Date.now();
|
|
2503
2555
|
if (this.submitPendingUntil > now || this.responseSettleIgnoreUntil > now) {
|
|
@@ -2530,7 +2582,11 @@ var init_provider_cli_adapter = __esm({
|
|
|
2530
2582
|
scope: this.currentTurnScope,
|
|
2531
2583
|
lastOutputAt: this.lastOutputAt
|
|
2532
2584
|
}) : [];
|
|
2585
|
+
if (this.maybeCommitVisibleIdleTranscript(parsedTranscript)) {
|
|
2586
|
+
return;
|
|
2587
|
+
}
|
|
2533
2588
|
const lastParsedAssistant = [...parsedMessages].reverse().find((message) => message.role === "assistant");
|
|
2589
|
+
const normalizedPromptSnippet = normalizePromptText(this.submitRetryPromptSnippet || this.currentTurnScope?.prompt || "");
|
|
2534
2590
|
this.recordTrace("settled", {
|
|
2535
2591
|
tail: summarizeCliTraceText(tail, 500),
|
|
2536
2592
|
screenText: summarizeCliTraceText(screenText, 1200),
|
|
@@ -2548,6 +2604,24 @@ var init_provider_cli_adapter = __esm({
|
|
|
2548
2604
|
scope: this.currentTurnScope
|
|
2549
2605
|
})
|
|
2550
2606
|
});
|
|
2607
|
+
if (this.currentTurnScope && !lastParsedAssistant && !this.submitRetryUsed && this.ptyProcess && this.currentStatus !== "waiting_approval" && promptLikelyVisible(screenText, normalizedPromptSnippet) && !this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) {
|
|
2608
|
+
this.submitRetryUsed = true;
|
|
2609
|
+
this.responseSettleIgnoreUntil = Date.now() + this.timeouts.outputSettle + 400;
|
|
2610
|
+
LOG.info("CLI", `[${this.cliType}] Retrying submit key from settled parser (no assistant yet)`);
|
|
2611
|
+
this.recordTrace("submit_write", {
|
|
2612
|
+
mode: "settled_retry",
|
|
2613
|
+
sendKey: this.sendKey,
|
|
2614
|
+
screenText: summarizeCliTraceText(screenText, 500)
|
|
2615
|
+
});
|
|
2616
|
+
this.ptyProcess.write(this.sendKey);
|
|
2617
|
+
if (this.settleTimer) clearTimeout(this.settleTimer);
|
|
2618
|
+
this.settleTimer = setTimeout(() => {
|
|
2619
|
+
this.settleTimer = null;
|
|
2620
|
+
this.settledBuffer = this.recentOutputBuffer;
|
|
2621
|
+
this.evaluateSettled();
|
|
2622
|
+
}, this.timeouts.outputSettle + 150);
|
|
2623
|
+
return;
|
|
2624
|
+
}
|
|
2551
2625
|
if (this.currentTurnScope && !lastParsedAssistant) {
|
|
2552
2626
|
LOG.info(
|
|
2553
2627
|
"CLI",
|
|
@@ -2590,7 +2664,15 @@ var init_provider_cli_adapter = __esm({
|
|
|
2590
2664
|
}
|
|
2591
2665
|
const recentInteractiveActivity = this.hasRecentInteractiveActivity(now);
|
|
2592
2666
|
const statusActivityHoldMs = this.getStatusActivityHoldMs();
|
|
2593
|
-
const
|
|
2667
|
+
const visibleIdlePrompt = this.looksLikeVisibleIdlePrompt(screenText);
|
|
2668
|
+
const visibleAssistantCandidate = this.looksLikeVisibleAssistantCandidate(screenText);
|
|
2669
|
+
if (this.currentTurnScope && this.cliType === "claude-cli") {
|
|
2670
|
+
LOG.info(
|
|
2671
|
+
"CLI",
|
|
2672
|
+
`[${this.cliType}] settled diagnostics prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} scriptStatus=${String(scriptStatus || "")} parsedStatus=${String(parsedTranscript?.status || "")} parsedMsgCount=${parsedMessages.length} lastParsedAssistant=${JSON.stringify(summarizeCliTraceText(lastParsedAssistant?.content || "", 120)).slice(0, 160)} visibleIdlePrompt=${String(visibleIdlePrompt)} visibleAssistantCandidate=${String(visibleAssistantCandidate)} responseBuffer=${JSON.stringify(summarizeCliTraceText(this.responseBuffer, 160)).slice(0, 220)} screen=${JSON.stringify(summarizeCliTraceText(screenText, 160)).slice(0, 220)}`
|
|
2673
|
+
);
|
|
2674
|
+
}
|
|
2675
|
+
const shouldHoldGenerating = scriptStatus === "idle" && this.isWaitingForResponse && !modal && recentInteractiveActivity && !(visibleIdlePrompt && visibleAssistantCandidate);
|
|
2594
2676
|
if (shouldHoldGenerating) {
|
|
2595
2677
|
this.clearIdleFinishCandidate("hold_generating_recent_activity");
|
|
2596
2678
|
this.setStatus("generating", "recent_activity_hold");
|
|
@@ -2621,8 +2703,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
2621
2703
|
if (scriptStatus === "waiting_approval") {
|
|
2622
2704
|
this.clearIdleFinishCandidate("waiting_approval");
|
|
2623
2705
|
const inCooldown = this.lastApprovalResolvedAt && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
|
|
2624
|
-
const
|
|
2625
|
-
if ((inCooldown ||
|
|
2706
|
+
const visibleIdlePrompt2 = this.looksLikeVisibleIdlePrompt(screenText);
|
|
2707
|
+
if ((inCooldown || visibleIdlePrompt2) && !modal) {
|
|
2626
2708
|
if (this.approvalExitTimeout) {
|
|
2627
2709
|
clearTimeout(this.approvalExitTimeout);
|
|
2628
2710
|
this.approvalExitTimeout = null;
|
|
@@ -2694,7 +2776,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
2694
2776
|
this.lastApprovalResolvedAt = Date.now();
|
|
2695
2777
|
}
|
|
2696
2778
|
if (this.isWaitingForResponse) {
|
|
2697
|
-
const
|
|
2779
|
+
const visibleIdlePrompt2 = this.looksLikeVisibleIdlePrompt(screenText);
|
|
2698
2780
|
const quietForMs = this.lastNonEmptyOutputAt ? now - this.lastNonEmptyOutputAt : Number.MAX_SAFE_INTEGER;
|
|
2699
2781
|
const screenStableMs = this.lastScreenChangeAt ? now - this.lastScreenChangeAt : 0;
|
|
2700
2782
|
const hasAssistantTurn = !!lastParsedAssistant;
|
|
@@ -2702,12 +2784,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
2702
2784
|
const idleFinishConfirmMs = this.getIdleFinishConfirmMs();
|
|
2703
2785
|
const idleQuietThresholdMs = Math.max(idleFinishConfirmMs, this.timeouts.outputSettle);
|
|
2704
2786
|
const idleStableThresholdMs = idleFinishConfirmMs;
|
|
2705
|
-
const idleReady =
|
|
2787
|
+
const idleReady = visibleIdlePrompt2 && !modal && hasAssistantTurn && quietForMs >= idleQuietThresholdMs && screenStableMs >= idleStableThresholdMs;
|
|
2706
2788
|
const candidate = this.idleFinishCandidate;
|
|
2707
2789
|
const candidateQuiet = !!candidate && candidate.responseEpoch === this.responseEpoch && candidate.lastOutputAt === this.lastOutputAt && candidate.lastScreenChangeAt === this.lastScreenChangeAt && assistantLength >= candidate.assistantLength && now - candidate.armedAt >= idleFinishConfirmMs;
|
|
2708
2790
|
const canFinishImmediately = idleReady && candidateQuiet;
|
|
2709
2791
|
this.recordTrace("idle_decision", {
|
|
2710
|
-
visibleIdlePrompt,
|
|
2792
|
+
visibleIdlePrompt: visibleIdlePrompt2,
|
|
2711
2793
|
quietForMs,
|
|
2712
2794
|
screenStableMs,
|
|
2713
2795
|
hasAssistantTurn,
|
|
@@ -2827,6 +2909,70 @@ var init_provider_cli_adapter = __esm({
|
|
|
2827
2909
|
this.setStatus("idle", "response_finished");
|
|
2828
2910
|
this.onStatusChange?.();
|
|
2829
2911
|
}
|
|
2912
|
+
maybeCommitVisibleIdleTranscript(parsed, options) {
|
|
2913
|
+
const allowImmediateScriptIdleCommit = this.provider.allowInputDuringGeneration === true;
|
|
2914
|
+
if (!allowImmediateScriptIdleCommit) return false;
|
|
2915
|
+
if (!parsed || !Array.isArray(parsed.messages) || parsed.status !== "idle" || !this.isWaitingForResponse || !this.currentTurnScope || this.activeModal || parsed.activeModal) {
|
|
2916
|
+
return false;
|
|
2917
|
+
}
|
|
2918
|
+
if (options?.requireVisibleAssistantCandidate) {
|
|
2919
|
+
const candidateText = options.screenText || this.terminalScreen.getText() || "";
|
|
2920
|
+
if (!this.looksLikeVisibleAssistantCandidate(candidateText)) {
|
|
2921
|
+
return false;
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
const hydratedForIdleCommit = normalizeCliParsedMessages(parsed.messages, {
|
|
2925
|
+
committedMessages: this.committedMessages,
|
|
2926
|
+
scope: this.currentTurnScope,
|
|
2927
|
+
lastOutputAt: this.lastOutputAt
|
|
2928
|
+
});
|
|
2929
|
+
const visibleAssistant = [...hydratedForIdleCommit].reverse().find((message) => message.role === "assistant" && message.content.trim());
|
|
2930
|
+
if (!visibleAssistant) return false;
|
|
2931
|
+
this.committedMessages = hydratedForIdleCommit;
|
|
2932
|
+
const promptForTrim = this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages);
|
|
2933
|
+
if (promptForTrim) {
|
|
2934
|
+
const lastAssistantForTrim = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
|
|
2935
|
+
if (lastAssistantForTrim) {
|
|
2936
|
+
lastAssistantForTrim.content = trimPromptEchoPrefix(lastAssistantForTrim.content, promptForTrim);
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
if (this.responseTimeout) {
|
|
2940
|
+
clearTimeout(this.responseTimeout);
|
|
2941
|
+
this.responseTimeout = null;
|
|
2942
|
+
}
|
|
2943
|
+
if (this.idleTimeout) {
|
|
2944
|
+
clearTimeout(this.idleTimeout);
|
|
2945
|
+
this.idleTimeout = null;
|
|
2946
|
+
}
|
|
2947
|
+
if (this.approvalExitTimeout) {
|
|
2948
|
+
clearTimeout(this.approvalExitTimeout);
|
|
2949
|
+
this.approvalExitTimeout = null;
|
|
2950
|
+
}
|
|
2951
|
+
if (this.submitRetryTimer) {
|
|
2952
|
+
clearTimeout(this.submitRetryTimer);
|
|
2953
|
+
this.submitRetryTimer = null;
|
|
2954
|
+
}
|
|
2955
|
+
if (this.finishRetryTimer) {
|
|
2956
|
+
clearTimeout(this.finishRetryTimer);
|
|
2957
|
+
this.finishRetryTimer = null;
|
|
2958
|
+
}
|
|
2959
|
+
this.syncMessageViews();
|
|
2960
|
+
this.responseBuffer = "";
|
|
2961
|
+
this.isWaitingForResponse = false;
|
|
2962
|
+
this.responseSettleIgnoreUntil = 0;
|
|
2963
|
+
this.submitRetryUsed = false;
|
|
2964
|
+
this.submitRetryPromptSnippet = "";
|
|
2965
|
+
this.finishRetryCount = 0;
|
|
2966
|
+
this.currentTurnScope = null;
|
|
2967
|
+
this.activeModal = null;
|
|
2968
|
+
this.setStatus("idle", "script_idle_commit");
|
|
2969
|
+
this.onStatusChange?.();
|
|
2970
|
+
this.recordTrace("script_idle_commit", {
|
|
2971
|
+
messageCount: this.committedMessages.length,
|
|
2972
|
+
lastAssistant: summarizeCliTraceText(visibleAssistant.content, 320)
|
|
2973
|
+
});
|
|
2974
|
+
return true;
|
|
2975
|
+
}
|
|
2830
2976
|
commitCurrentTranscript() {
|
|
2831
2977
|
const parsed = this.parseCurrentTranscript(
|
|
2832
2978
|
this.committedMessages,
|
|
@@ -2848,6 +2994,12 @@ var init_provider_cli_adapter = __esm({
|
|
|
2848
2994
|
}
|
|
2849
2995
|
this.syncMessageViews();
|
|
2850
2996
|
const lastAssistant = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
|
|
2997
|
+
if (this.currentTurnScope) {
|
|
2998
|
+
LOG.info(
|
|
2999
|
+
"CLI",
|
|
3000
|
+
`[${this.cliType}] commitCurrentTranscript committedMessages=${this.committedMessages.length} finalLastAssistant=${JSON.stringify(summarizeCliTraceText(lastAssistant?.content || "", 220)).slice(0, 260)}`
|
|
3001
|
+
);
|
|
3002
|
+
}
|
|
2851
3003
|
this.recordTrace("commit_transcript", {
|
|
2852
3004
|
parsedStatus: parsed.status || null,
|
|
2853
3005
|
messageCount: this.committedMessages.length,
|
|
@@ -2867,11 +3019,18 @@ var init_provider_cli_adapter = __esm({
|
|
|
2867
3019
|
`[${this.cliType}] Commit without assistant turn: prompt=${JSON.stringify(this.currentTurnScope.prompt).slice(0, 140)} responseBuffer=${JSON.stringify(summarizeCliTraceText(this.responseBuffer, 220)).slice(0, 260)} providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"} scriptsPath=${this.providerResolutionMeta.scriptsPath || "-"}`
|
|
2868
3020
|
);
|
|
2869
3021
|
}
|
|
3022
|
+
const hasAssistant = !!lastAssistant;
|
|
2870
3023
|
return {
|
|
2871
|
-
hasAssistant
|
|
3024
|
+
hasAssistant,
|
|
2872
3025
|
assistantContent: lastAssistant?.content || ""
|
|
2873
3026
|
};
|
|
2874
3027
|
}
|
|
3028
|
+
if (this.currentTurnScope) {
|
|
3029
|
+
LOG.info(
|
|
3030
|
+
"CLI",
|
|
3031
|
+
`[${this.cliType}] commitCurrentTranscript parsed.messages=none responseBufferLen=${this.responseBuffer.length} accumulatedBufferLen=${this.accumulatedBuffer.length} parsedStatus=${parsed?.status || "-"} providerDir=${this.providerResolutionMeta.providerDir || "-"} scriptDir=${this.providerResolutionMeta.scriptDir || "-"}`
|
|
3032
|
+
);
|
|
3033
|
+
}
|
|
2875
3034
|
return {
|
|
2876
3035
|
hasAssistant: false,
|
|
2877
3036
|
assistantContent: ""
|
|
@@ -2957,19 +3116,25 @@ var init_provider_cli_adapter = __esm({
|
|
|
2957
3116
|
this.currentTurnScope,
|
|
2958
3117
|
screenText
|
|
2959
3118
|
);
|
|
2960
|
-
|
|
3119
|
+
if (this.maybeCommitVisibleIdleTranscript(parsed)) {
|
|
3120
|
+
return this.getScriptParsedStatus();
|
|
3121
|
+
}
|
|
3122
|
+
const shouldPreferCommittedMessages = !this.currentTurnScope && !this.activeModal && this.currentStatus === "idle";
|
|
2961
3123
|
let result;
|
|
2962
3124
|
if (parsed && Array.isArray(parsed.messages)) {
|
|
2963
|
-
const
|
|
2964
|
-
...message,
|
|
2965
|
-
id: message.id || `msg_${index}`,
|
|
2966
|
-
index: typeof message.index === "number" ? message.index : index,
|
|
2967
|
-
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
2968
|
-
})) : hydrateCliParsedMessages(parsed.messages, {
|
|
3125
|
+
const parsedHydratedMessages = hydrateCliParsedMessages(parsed.messages, {
|
|
2969
3126
|
committedMessages: this.committedMessages,
|
|
2970
3127
|
scope: this.currentTurnScope,
|
|
2971
3128
|
lastOutputAt: this.lastOutputAt
|
|
2972
3129
|
});
|
|
3130
|
+
const committedHydratedMessages = this.committedMessages.map((message, index) => buildChatMessage({
|
|
3131
|
+
...message,
|
|
3132
|
+
id: message.id || `msg_${index}`,
|
|
3133
|
+
index: typeof message.index === "number" ? message.index : index,
|
|
3134
|
+
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
3135
|
+
}));
|
|
3136
|
+
const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && committedHydratedMessages.length > parsedHydratedMessages.length;
|
|
3137
|
+
const hydratedMessages = shouldPreferCommittedMessages || shouldPreferCommittedHistoryReplay ? committedHydratedMessages : parsedHydratedMessages;
|
|
2973
3138
|
result = {
|
|
2974
3139
|
id: parsed.id || "cli_session",
|
|
2975
3140
|
status: parsed.status || this.currentStatus,
|
|
@@ -2993,6 +3158,23 @@ var init_provider_cli_adapter = __esm({
|
|
|
2993
3158
|
activeModal: this.activeModal
|
|
2994
3159
|
};
|
|
2995
3160
|
}
|
|
3161
|
+
const hasVisibleAssistantMessage = Array.isArray(result?.messages) && result.messages.some((message) => message?.role === "assistant" && typeof message?.content === "string" && message.content.trim());
|
|
3162
|
+
const shouldClampStaleGeneratingToIdle = result?.status === "generating" && this.currentStatus === "idle" && !this.currentTurnScope && !result?.activeModal && hasVisibleAssistantMessage;
|
|
3163
|
+
if (shouldClampStaleGeneratingToIdle) {
|
|
3164
|
+
result = {
|
|
3165
|
+
...result,
|
|
3166
|
+
status: "idle",
|
|
3167
|
+
messages: Array.isArray(result.messages) ? result.messages.map((message) => {
|
|
3168
|
+
if (message?.role !== "assistant" || !message?.meta?.streaming) return message;
|
|
3169
|
+
const nextMeta = { ...message.meta || {} };
|
|
3170
|
+
delete nextMeta.streaming;
|
|
3171
|
+
return {
|
|
3172
|
+
...message,
|
|
3173
|
+
...Object.keys(nextMeta).length > 0 ? { meta: nextMeta } : { meta: void 0 }
|
|
3174
|
+
};
|
|
3175
|
+
}) : result.messages
|
|
3176
|
+
};
|
|
3177
|
+
}
|
|
2996
3178
|
this.parsedStatusCache = {
|
|
2997
3179
|
committedMessagesRef: this.committedMessages,
|
|
2998
3180
|
responseBuffer: this.responseBuffer,
|
|
@@ -3125,9 +3307,27 @@ ${data.message || ""}`.trim();
|
|
|
3125
3307
|
}
|
|
3126
3308
|
}
|
|
3127
3309
|
if (!this.ready) throw new Error(`${this.cliName} not ready (status: ${this.currentStatus})`);
|
|
3128
|
-
|
|
3310
|
+
const parsedStatusBeforeSend = !allowInputDuringGeneration ? (() => {
|
|
3311
|
+
try {
|
|
3312
|
+
return this.getScriptParsedStatus?.() || null;
|
|
3313
|
+
} catch {
|
|
3314
|
+
return null;
|
|
3315
|
+
}
|
|
3316
|
+
})() : null;
|
|
3317
|
+
const parsedSessionStatus = typeof parsedStatusBeforeSend?.status === "string" ? String(parsedStatusBeforeSend.status) : "";
|
|
3318
|
+
const parsedMessagesBeforeSend = Array.isArray(parsedStatusBeforeSend?.messages) ? parsedStatusBeforeSend.messages.filter((message) => message && (message.role === "user" || message.role === "assistant")) : [];
|
|
3319
|
+
const shouldCommitParsedIdleBeforeSend = !allowInputDuringGeneration && parsedSessionStatus === "idle" && parsedMessagesBeforeSend.length > this.committedMessages.length && parsedMessagesBeforeSend.some((message) => message?.role === "assistant" && typeof message?.content === "string" && message.content.trim());
|
|
3320
|
+
if (shouldCommitParsedIdleBeforeSend) {
|
|
3321
|
+
this.commitCurrentTranscript();
|
|
3322
|
+
}
|
|
3323
|
+
if (!allowInputDuringGeneration && (parsedSessionStatus === "generating" || parsedSessionStatus === "long_generating")) {
|
|
3129
3324
|
throw new Error(`${this.cliName} is still processing the previous prompt`);
|
|
3130
3325
|
}
|
|
3326
|
+
if (this.isWaitingForResponse && !allowInputDuringGeneration) {
|
|
3327
|
+
if (!this.clearStaleIdleResponseGuard("send_message_guard")) {
|
|
3328
|
+
throw new Error(`${this.cliName} is still processing the previous prompt`);
|
|
3329
|
+
}
|
|
3330
|
+
}
|
|
3131
3331
|
const blockingModal = this.activeModal || this.getStartupConfirmationModal(this.terminalScreen.getText() || "");
|
|
3132
3332
|
if (blockingModal || this.currentStatus === "waiting_approval") {
|
|
3133
3333
|
throw new Error(`${this.cliName} is awaiting confirmation before it can accept a prompt`);
|
|
@@ -3207,7 +3407,7 @@ ${data.message || ""}`.trim();
|
|
|
3207
3407
|
this.submitRetryTimer = null;
|
|
3208
3408
|
if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
|
|
3209
3409
|
if (this.currentStatus === "waiting_approval") return;
|
|
3210
|
-
if (
|
|
3410
|
+
if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
|
|
3211
3411
|
const screenText2 = this.terminalScreen.getText();
|
|
3212
3412
|
if (!promptLikelyVisible(screenText2, normalizedPromptSnippet)) return;
|
|
3213
3413
|
if (/Esc to interrupt|Do you want to proceed|This command requires approval|Allow Codex to|Approve and run now|Always approve this session|Running…|Running\.\.\./i.test(screenText2)) return;
|
|
@@ -3244,7 +3444,7 @@ ${data.message || ""}`.trim();
|
|
|
3244
3444
|
this.submitRetryTimer = null;
|
|
3245
3445
|
if (!this.ptyProcess || !this.isWaitingForResponse || this.submitRetryUsed) return;
|
|
3246
3446
|
if (this.currentStatus === "waiting_approval") return;
|
|
3247
|
-
if (
|
|
3447
|
+
if (this.hasMeaningfulResponseBuffer(normalizedPromptSnippet)) return;
|
|
3248
3448
|
const screenText = this.terminalScreen.getText();
|
|
3249
3449
|
if (!promptLikelyVisible(screenText, normalizedPromptSnippet)) return;
|
|
3250
3450
|
LOG.info("CLI", `[${this.cliType}] Retrying submit key for stuck prompt (attempt 1)`);
|
|
@@ -9609,6 +9809,7 @@ function normalizeReadChatCommandStatus(status, activeModal) {
|
|
|
9609
9809
|
}
|
|
9610
9810
|
function buildReadChatCommandResult(payload, args) {
|
|
9611
9811
|
let validatedPayload;
|
|
9812
|
+
const debugReadChat = payload?.debugReadChat && typeof payload.debugReadChat === "object" ? payload.debugReadChat : void 0;
|
|
9612
9813
|
try {
|
|
9613
9814
|
validatedPayload = validateReadChatResultPayload({
|
|
9614
9815
|
...payload,
|
|
@@ -9629,7 +9830,8 @@ function buildReadChatCommandResult(payload, args) {
|
|
|
9629
9830
|
syncMode: "full",
|
|
9630
9831
|
replaceFrom: 0,
|
|
9631
9832
|
totalMessages: messages.length,
|
|
9632
|
-
lastMessageSignature
|
|
9833
|
+
lastMessageSignature,
|
|
9834
|
+
...debugReadChat ? { debugReadChat } : {}
|
|
9633
9835
|
};
|
|
9634
9836
|
}
|
|
9635
9837
|
const sync = computeReadChatSync(messages, cursor);
|
|
@@ -9640,7 +9842,8 @@ function buildReadChatCommandResult(payload, args) {
|
|
|
9640
9842
|
syncMode: sync.syncMode,
|
|
9641
9843
|
replaceFrom: sync.replaceFrom,
|
|
9642
9844
|
totalMessages: sync.totalMessages,
|
|
9643
|
-
lastMessageSignature: sync.lastMessageSignature
|
|
9845
|
+
lastMessageSignature: sync.lastMessageSignature,
|
|
9846
|
+
...debugReadChat ? { debugReadChat } : {}
|
|
9644
9847
|
};
|
|
9645
9848
|
}
|
|
9646
9849
|
function didProviderConfirmSend(result) {
|
|
@@ -9731,14 +9934,33 @@ async function handleReadChat(h, args) {
|
|
|
9731
9934
|
}
|
|
9732
9935
|
}
|
|
9733
9936
|
const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
|
|
9734
|
-
const
|
|
9937
|
+
const adapterStatus = adapter.getStatus();
|
|
9938
|
+
const shouldPreferAdapterMessages = Array.isArray(adapterStatus.messages) && adapterStatus.messages.length > 0 && Array.isArray(parsedRecord?.messages) && adapterStatus.messages.length > parsedRecord.messages.length;
|
|
9939
|
+
const status = parsedRecord ? {
|
|
9940
|
+
...parsedRecord,
|
|
9941
|
+
messages: shouldPreferAdapterMessages ? adapterStatus.messages : parsedRecord.messages,
|
|
9942
|
+
status: adapterStatus.status !== "idle" ? adapterStatus.status : parsedRecord.status || adapterStatus.status,
|
|
9943
|
+
activeModal: parsedRecord.activeModal || adapterStatus.activeModal
|
|
9944
|
+
} : adapterStatus;
|
|
9735
9945
|
const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
|
|
9736
9946
|
const providerSessionId = typeof parsedRecord?.providerSessionId === "string" ? parsedRecord.providerSessionId : void 0;
|
|
9737
9947
|
if (status) {
|
|
9948
|
+
LOG.info("Command", `[read_chat] cli-like resolved provider=${adapter.cliType} target=${String(args?.targetSessionId || "")} adapterStatus=${String(adapterStatus.status || "")} parsedStatus=${String(parsedRecord?.status || "")} shouldPreferAdapterMessages=${String(shouldPreferAdapterMessages)} adapterMsgCount=${Array.isArray(adapterStatus.messages) ? adapterStatus.messages.length : 0} parsedMsgCount=${Array.isArray(parsedRecord?.messages) ? parsedRecord.messages.length : 0} returnedMsgCount=${Array.isArray(status.messages) ? status.messages.length : 0}`);
|
|
9738
9949
|
return buildReadChatCommandResult({
|
|
9739
9950
|
messages: status.messages || [],
|
|
9740
9951
|
status: status.status,
|
|
9741
9952
|
activeModal: status.activeModal,
|
|
9953
|
+
debugReadChat: {
|
|
9954
|
+
provider: adapter.cliType,
|
|
9955
|
+
targetSessionId: String(args?.targetSessionId || ""),
|
|
9956
|
+
adapterStatus: String(adapterStatus.status || ""),
|
|
9957
|
+
parsedStatus: String(parsedRecord?.status || ""),
|
|
9958
|
+
returnedStatus: String(status.status || ""),
|
|
9959
|
+
shouldPreferAdapterMessages,
|
|
9960
|
+
adapterMsgCount: Array.isArray(adapterStatus.messages) ? adapterStatus.messages.length : 0,
|
|
9961
|
+
parsedMsgCount: Array.isArray(parsedRecord?.messages) ? parsedRecord.messages.length : 0,
|
|
9962
|
+
returnedMsgCount: Array.isArray(status.messages) ? status.messages.length : 0
|
|
9963
|
+
},
|
|
9742
9964
|
...title ? { title } : {},
|
|
9743
9965
|
...providerSessionId ? { providerSessionId } : {}
|
|
9744
9966
|
}, args);
|
|
@@ -12297,7 +12519,7 @@ var CliProviderInstance = class {
|
|
|
12297
12519
|
activeChat: {
|
|
12298
12520
|
id: `${this.type}_${this.workingDir}`,
|
|
12299
12521
|
title: parsedStatus?.title || dirName,
|
|
12300
|
-
status: parseErrorMessage ? "error" : autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : parsedStatus?.status || visibleStatus,
|
|
12522
|
+
status: parseErrorMessage ? "error" : autoApproveActive && parsedStatus?.status === "waiting_approval" ? "generating" : adapterStatus.status !== "idle" ? visibleStatus : parsedStatus?.status || visibleStatus,
|
|
12301
12523
|
messages: mergedMessages,
|
|
12302
12524
|
activeModal: autoApproveActive ? null : parsedStatus?.activeModal ?? adapterStatus.activeModal,
|
|
12303
12525
|
inputContent: ""
|
|
@@ -24744,6 +24966,13 @@ init_logger();
|
|
|
24744
24966
|
import {
|
|
24745
24967
|
SessionHostClient
|
|
24746
24968
|
} from "@adhdev/session-host-core";
|
|
24969
|
+
function shouldResumeAttachedSession(record) {
|
|
24970
|
+
if (!record) return false;
|
|
24971
|
+
if (record.lifecycle === "interrupted") return true;
|
|
24972
|
+
if (record.lifecycle !== "stopped") return false;
|
|
24973
|
+
if (record.meta?.restoredFromStorage === true) return true;
|
|
24974
|
+
return typeof record.meta?.runtimeRecoveryState === "string" && String(record.meta.runtimeRecoveryState).trim().length > 0;
|
|
24975
|
+
}
|
|
24747
24976
|
var SessionHostRuntimeTransport = class {
|
|
24748
24977
|
constructor(options) {
|
|
24749
24978
|
this.options = options;
|
|
@@ -24917,7 +25146,7 @@ var SessionHostRuntimeTransport = class {
|
|
|
24917
25146
|
payload: {}
|
|
24918
25147
|
});
|
|
24919
25148
|
const existingRecord = existingRecords.success && existingRecords.result ? existingRecords.result.find((item) => item.sessionId === this.options.runtimeId) || null : null;
|
|
24920
|
-
if (existingRecord
|
|
25149
|
+
if (shouldResumeAttachedSession(existingRecord)) {
|
|
24921
25150
|
const resumeResponse = await this.client.request({
|
|
24922
25151
|
type: "resume_session",
|
|
24923
25152
|
payload: {
|
|
@@ -25216,6 +25445,8 @@ async function listHostedCliRuntimes(endpoint) {
|
|
|
25216
25445
|
// src/session-host/startup-restore-policy.js
|
|
25217
25446
|
function shouldAutoRestoreHostedSessionsOnStartup(env = process.env) {
|
|
25218
25447
|
const raw = typeof env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP === "string" ? env.ADHDEV_RESTORE_HOSTED_SESSIONS_ON_STARTUP.trim().toLowerCase() : "";
|
|
25448
|
+
if (!raw) return true;
|
|
25449
|
+
if (raw === "0" || raw === "false" || raw === "no") return false;
|
|
25219
25450
|
return raw === "1" || raw === "true" || raw === "yes";
|
|
25220
25451
|
}
|
|
25221
25452
|
|