@adhdev/daemon-core 0.9.82-rc.539 → 0.9.82-rc.540
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 +32 -0
- package/dist/index.js +63 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +63 -15
- package/dist/index.mjs.map +1 -1
- package/dist/providers/approval-utils.d.ts +1 -0
- package/package.json +3 -3
- package/src/cli-adapters/provider-cli-adapter.ts +47 -1
- package/src/commands/chat-commands-write.ts +7 -2
- package/src/providers/approval-utils.ts +38 -11
|
@@ -121,6 +121,38 @@ export declare class ProviderCliAdapter implements CliAdapter {
|
|
|
121
121
|
private getFreshParsedStatusCache;
|
|
122
122
|
private providerOwnsTranscript;
|
|
123
123
|
private shouldUseFullProviderTranscriptContext;
|
|
124
|
+
/**
|
|
125
|
+
* MULTI-TURN TRANSCRIPT FLICKER (kimi): whether this provider reconstructs
|
|
126
|
+
* its ENTIRE transcript from the rendered PTY buffer on every read and so
|
|
127
|
+
* must be fed the full accumulated buffer rather than the current-turn slice.
|
|
128
|
+
*
|
|
129
|
+
* The turn-scope slice (buildCliParseInput → sliceFromOffset(accumulatedBuffer,
|
|
130
|
+
* scope.bufferStart)) exists so a mid-turn parse only sees the fresh output of
|
|
131
|
+
* the CURRENT turn — correct for status/streaming detection and for providers
|
|
132
|
+
* that reassemble prior history elsewhere (native-history on disk, or a
|
|
133
|
+
* provider-owned full-context parser). But a pure-PTY provider with NO native
|
|
134
|
+
* history and NO provider transcript authority, whose tui parser walks the
|
|
135
|
+
* whole buffer for its per-turn bubble markers (kimi's `●`/`✨` bullets),
|
|
136
|
+
* loses every prior turn's bubbles the instant a new turn starts: bufferStart
|
|
137
|
+
* jumps to the new turn's offset, the slice drops turns 1..n-1, and until the
|
|
138
|
+
* new turn emits its first bullet parseSession returns zero messages — so
|
|
139
|
+
* read_chat momentarily goes EMPTY and the dashboard clears every bubble,
|
|
140
|
+
* then restores them once output arrives (the observed flicker).
|
|
141
|
+
*
|
|
142
|
+
* accumulatedBuffer is the terminal-EMULATED rendered scrollback (overwritten
|
|
143
|
+
* cells collapsed), not raw PTY append, so parsing it in full yields the clean
|
|
144
|
+
* cumulative transcript with no repaint duplication. Scope to exactly this
|
|
145
|
+
* class (tui transcriptPty scope 'buffer' + no native history + not
|
|
146
|
+
* provider-owned) so no other provider's turn-scoped parse changes.
|
|
147
|
+
*/
|
|
148
|
+
private parsesFullPtyTranscriptFromBuffer;
|
|
149
|
+
/**
|
|
150
|
+
* The turn scope to feed the transcript parser. Normally the live turn scope
|
|
151
|
+
* (so a mid-turn parse is current-turn-only), but null (= full accumulated
|
|
152
|
+
* buffer) for pure-PTY full-transcript providers so prior turns never drop.
|
|
153
|
+
* See {@link parsesFullPtyTranscriptFromBuffer}.
|
|
154
|
+
*/
|
|
155
|
+
private transcriptParseScope;
|
|
124
156
|
private getIdleFinishConfirmMs;
|
|
125
157
|
private getStatusActivityHoldMs;
|
|
126
158
|
private isAutonomousMeshSession;
|
package/dist/index.js
CHANGED
|
@@ -419,10 +419,10 @@ function readInjected(value) {
|
|
|
419
419
|
}
|
|
420
420
|
function getDaemonBuildInfo() {
|
|
421
421
|
if (cached) return cached;
|
|
422
|
-
const commit = readInjected(true ? "
|
|
423
|
-
const commitShort = readInjected(true ? "
|
|
424
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
425
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
422
|
+
const commit = readInjected(true ? "0674080aa30d25acbfb5c295598d15f686d4cba3" : void 0) ?? "unknown";
|
|
423
|
+
const commitShort = readInjected(true ? "0674080a" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
424
|
+
const version = readInjected(true ? "0.9.82-rc.540" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
425
|
+
const builtAt = readInjected(true ? "2026-07-16T01:53:13.412Z" : void 0);
|
|
426
426
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
427
427
|
return cached;
|
|
428
428
|
}
|
|
@@ -23007,15 +23007,21 @@ function pickApprovalButton(buttons, provider) {
|
|
|
23007
23007
|
}
|
|
23008
23008
|
const normalizedButtons = labels.map((label) => normalizeApprovalLabel(label));
|
|
23009
23009
|
const hints = getApprovalPositiveHints(provider);
|
|
23010
|
-
|
|
23011
|
-
|
|
23012
|
-
|
|
23013
|
-
|
|
23014
|
-
|
|
23015
|
-
|
|
23016
|
-
|
|
23017
|
-
|
|
23018
|
-
|
|
23010
|
+
const includesWord = (label, hint) => {
|
|
23011
|
+
if (!label.includes(hint)) return false;
|
|
23012
|
+
const re = new RegExp(`(?:^|\\s)${hint.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?:\\s|$)`);
|
|
23013
|
+
return re.test(label);
|
|
23014
|
+
};
|
|
23015
|
+
const findMatch = (predicate) => {
|
|
23016
|
+
for (const hint of hints) {
|
|
23017
|
+
const idx = normalizedButtons.findIndex(
|
|
23018
|
+
(label, index) => predicate(label, hint) && !isNegativeApprovalLabel(labels[index])
|
|
23019
|
+
);
|
|
23020
|
+
if (idx >= 0) return { index: idx, label: labels[idx] };
|
|
23021
|
+
}
|
|
23022
|
+
return null;
|
|
23023
|
+
};
|
|
23024
|
+
return findMatch((label, hint) => label === hint) ?? findMatch((label, hint) => label.startsWith(hint)) ?? findMatch((label, hint) => includesWord(label, hint)) ?? { index: -1, label: "" };
|
|
23019
23025
|
}
|
|
23020
23026
|
function pickAutoApprovalButton(buttons) {
|
|
23021
23027
|
const labels = (buttons || []).map((button) => String(button || "").trim());
|
|
@@ -27019,6 +27025,45 @@ ${lastSnapshot}`;
|
|
|
27019
27025
|
shouldUseFullProviderTranscriptContext() {
|
|
27020
27026
|
return this.providerOwnsTranscript() && this.provider.transcriptContext === "full";
|
|
27021
27027
|
}
|
|
27028
|
+
/**
|
|
27029
|
+
* MULTI-TURN TRANSCRIPT FLICKER (kimi): whether this provider reconstructs
|
|
27030
|
+
* its ENTIRE transcript from the rendered PTY buffer on every read and so
|
|
27031
|
+
* must be fed the full accumulated buffer rather than the current-turn slice.
|
|
27032
|
+
*
|
|
27033
|
+
* The turn-scope slice (buildCliParseInput → sliceFromOffset(accumulatedBuffer,
|
|
27034
|
+
* scope.bufferStart)) exists so a mid-turn parse only sees the fresh output of
|
|
27035
|
+
* the CURRENT turn — correct for status/streaming detection and for providers
|
|
27036
|
+
* that reassemble prior history elsewhere (native-history on disk, or a
|
|
27037
|
+
* provider-owned full-context parser). But a pure-PTY provider with NO native
|
|
27038
|
+
* history and NO provider transcript authority, whose tui parser walks the
|
|
27039
|
+
* whole buffer for its per-turn bubble markers (kimi's `●`/`✨` bullets),
|
|
27040
|
+
* loses every prior turn's bubbles the instant a new turn starts: bufferStart
|
|
27041
|
+
* jumps to the new turn's offset, the slice drops turns 1..n-1, and until the
|
|
27042
|
+
* new turn emits its first bullet parseSession returns zero messages — so
|
|
27043
|
+
* read_chat momentarily goes EMPTY and the dashboard clears every bubble,
|
|
27044
|
+
* then restores them once output arrives (the observed flicker).
|
|
27045
|
+
*
|
|
27046
|
+
* accumulatedBuffer is the terminal-EMULATED rendered scrollback (overwritten
|
|
27047
|
+
* cells collapsed), not raw PTY append, so parsing it in full yields the clean
|
|
27048
|
+
* cumulative transcript with no repaint duplication. Scope to exactly this
|
|
27049
|
+
* class (tui transcriptPty scope 'buffer' + no native history + not
|
|
27050
|
+
* provider-owned) so no other provider's turn-scoped parse changes.
|
|
27051
|
+
*/
|
|
27052
|
+
parsesFullPtyTranscriptFromBuffer() {
|
|
27053
|
+
if (this.providerOwnsTranscript()) return false;
|
|
27054
|
+
if (this.provider.nativeHistory) return false;
|
|
27055
|
+
const transcriptPty = this.provider.tui?.transcriptPty;
|
|
27056
|
+
return transcriptPty?.scope === "buffer";
|
|
27057
|
+
}
|
|
27058
|
+
/**
|
|
27059
|
+
* The turn scope to feed the transcript parser. Normally the live turn scope
|
|
27060
|
+
* (so a mid-turn parse is current-turn-only), but null (= full accumulated
|
|
27061
|
+
* buffer) for pure-PTY full-transcript providers so prior turns never drop.
|
|
27062
|
+
* See {@link parsesFullPtyTranscriptFromBuffer}.
|
|
27063
|
+
*/
|
|
27064
|
+
transcriptParseScope() {
|
|
27065
|
+
return this.parsesFullPtyTranscriptFromBuffer() ? null : this.engine.currentTurnScope;
|
|
27066
|
+
}
|
|
27022
27067
|
getIdleFinishConfirmMs() {
|
|
27023
27068
|
return this.timeouts.idleFinishConfirm;
|
|
27024
27069
|
}
|
|
@@ -27372,7 +27417,10 @@ ${lastSnapshot}`;
|
|
|
27372
27417
|
baseMessages: [],
|
|
27373
27418
|
partialResponse: this.responseBuffer,
|
|
27374
27419
|
isWaitingForResponse: this.engine.isWaitingForResponse,
|
|
27375
|
-
scope
|
|
27420
|
+
// Full accumulated buffer (scope null) for pure-PTY full-transcript
|
|
27421
|
+
// providers so prior turns' bubbles never drop when a new turn starts;
|
|
27422
|
+
// the current-turn slice otherwise. See parsesFullPtyTranscriptFromBuffer.
|
|
27423
|
+
scope: this.transcriptParseScope(),
|
|
27376
27424
|
runtimeSettings: this.runtimeSettings,
|
|
27377
27425
|
spawnAt: this.spawnAt
|
|
27378
27426
|
});
|
|
@@ -39065,7 +39113,7 @@ async function handleResolveAction(h, args) {
|
|
|
39065
39113
|
buttonIndex = buttons.findIndex((b) => b.toLowerCase().includes(btnLower));
|
|
39066
39114
|
}
|
|
39067
39115
|
if (buttonIndex < 0 && (action === "reject" || action === "deny")) {
|
|
39068
|
-
buttonIndex = buttons.findIndex((b) =>
|
|
39116
|
+
buttonIndex = buttons.findIndex((b) => isNegativeApprovalLabel(b));
|
|
39069
39117
|
}
|
|
39070
39118
|
if (buttonIndex < 0 && (action === "always" || /always/i.test(button))) {
|
|
39071
39119
|
buttonIndex = buttons.findIndex((b) => /always/i.test(b));
|