@adhdev/daemon-core 0.9.22 → 0.9.24
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 +42 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +42 -3
- package/dist/index.mjs.map +1 -1
- package/dist/shared-types.d.ts +1 -0
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/cli-adapters/provider-cli-adapter.ts +5 -1
- package/src/cli-adapters/session-host-transport.ts +2 -2
- package/src/commands/chat-commands.ts +42 -0
- package/src/providers/cli-provider-instance.ts +19 -0
- package/src/shared-types.ts +1 -0
package/dist/shared-types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -2414,8 +2414,12 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
2414
2414
|
if (buttonIndex in this.approvalKeys) {
|
|
2415
2415
|
this.ptyProcess.write(this.approvalKeys[buttonIndex]);
|
|
2416
2416
|
} else {
|
|
2417
|
+
const buttonCount = Array.isArray(modal?.buttons) ? modal.buttons.length : 0;
|
|
2418
|
+
const clampedIndex = buttonCount > 0
|
|
2419
|
+
? Math.min(Math.max(0, buttonIndex), buttonCount - 1)
|
|
2420
|
+
: Math.max(0, buttonIndex);
|
|
2417
2421
|
const DOWN = '\x1B[B';
|
|
2418
|
-
const keys = DOWN.repeat(
|
|
2422
|
+
const keys = DOWN.repeat(clampedIndex) + '\r';
|
|
2419
2423
|
this.ptyProcess.write(keys);
|
|
2420
2424
|
}
|
|
2421
2425
|
}
|
|
@@ -423,8 +423,8 @@ class SessionHostRuntimeTransport implements PtyRuntimeTransport {
|
|
|
423
423
|
} catch { /* noop */ }
|
|
424
424
|
try {
|
|
425
425
|
await this.client.close();
|
|
426
|
-
} catch {
|
|
427
|
-
if (destroy) throw new Error(`Failed to close session host client: ${this.options.runtimeId}`);
|
|
426
|
+
} catch (err) {
|
|
427
|
+
if (destroy) throw err instanceof Error ? err : new Error(`Failed to close session host client: ${this.options.runtimeId}`);
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
430
|
}
|
|
@@ -193,14 +193,52 @@ function shouldCollapseReadChatReplayDuplicate(message: ChatMessage | null | und
|
|
|
193
193
|
return role === 'assistant' || role === 'system';
|
|
194
194
|
}
|
|
195
195
|
|
|
196
|
+
function normalizeReadChatReplayText(message: ChatMessage | null | undefined): string {
|
|
197
|
+
return flattenContent(message?.content || '').replace(/\s+/g, ' ').trim();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function isStableReadChatAssistantAnswer(message: ChatMessage | null | undefined): boolean {
|
|
201
|
+
if (!message) return false;
|
|
202
|
+
const role = typeof message.role === 'string' ? message.role.trim().toLowerCase() : '';
|
|
203
|
+
const kind = typeof message.kind === 'string' ? message.kind.trim().toLowerCase() : 'standard';
|
|
204
|
+
if (role !== 'assistant') return false;
|
|
205
|
+
if (kind && kind !== 'standard') return false;
|
|
206
|
+
const content = normalizeReadChatReplayText(message);
|
|
207
|
+
if (content.length < 160) return false;
|
|
208
|
+
|
|
209
|
+
// A provider may surface expanded command output as a standard assistant bubble
|
|
210
|
+
// (for example Claude Code's "Bash command ..." block). That is live work output,
|
|
211
|
+
// not a stable final answer. Treating it as a terminal answer would hide the
|
|
212
|
+
// real final response and violate read_chat fidelity.
|
|
213
|
+
if (/^(bash|shell|terminal) command\b/i.test(content)) return false;
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function isReplayedAssistantAnswerAfterStableAnswer(
|
|
218
|
+
message: ChatMessage | null | undefined,
|
|
219
|
+
stableAnswer: ChatMessage | null,
|
|
220
|
+
): boolean {
|
|
221
|
+
if (!message || !stableAnswer) return false;
|
|
222
|
+
const role = typeof message.role === 'string' ? message.role.trim().toLowerCase() : '';
|
|
223
|
+
const kind = typeof message.kind === 'string' ? message.kind.trim().toLowerCase() : 'standard';
|
|
224
|
+
if (role !== 'assistant') return false;
|
|
225
|
+
if (kind && kind !== 'standard') return false;
|
|
226
|
+
const content = normalizeReadChatReplayText(message);
|
|
227
|
+
const stableContent = normalizeReadChatReplayText(stableAnswer);
|
|
228
|
+
if (content.length < 80 || stableContent.length < 80) return false;
|
|
229
|
+
return content === stableContent || content.startsWith(stableContent) || stableContent.startsWith(content);
|
|
230
|
+
}
|
|
231
|
+
|
|
196
232
|
function collapseReplayDuplicatesFromReadChat(messages: ChatMessage[]): ChatMessage[] {
|
|
197
233
|
const collapsed: ChatMessage[] = [];
|
|
198
234
|
const replaySignaturesInCurrentTurn = new Set<string>();
|
|
235
|
+
let stableAssistantAnswerInCurrentTurn: ChatMessage | null = null;
|
|
199
236
|
|
|
200
237
|
for (const message of messages) {
|
|
201
238
|
const role = typeof message.role === 'string' ? message.role.trim().toLowerCase() : '';
|
|
202
239
|
if (role === 'user') {
|
|
203
240
|
replaySignaturesInCurrentTurn.clear();
|
|
241
|
+
stableAssistantAnswerInCurrentTurn = null;
|
|
204
242
|
}
|
|
205
243
|
|
|
206
244
|
const signature = buildReadChatReplayCollapseSignature(message);
|
|
@@ -210,12 +248,16 @@ function collapseReplayDuplicatesFromReadChat(messages: ChatMessage[]): ChatMess
|
|
|
210
248
|
if (shouldCollapseReadChatReplayDuplicate(message) && signature) {
|
|
211
249
|
if (previousSignature === signature) continue;
|
|
212
250
|
if (replaySignaturesInCurrentTurn.has(signature)) continue;
|
|
251
|
+
if (isReplayedAssistantAnswerAfterStableAnswer(message, stableAssistantAnswerInCurrentTurn)) continue;
|
|
213
252
|
}
|
|
214
253
|
|
|
215
254
|
collapsed.push(message);
|
|
216
255
|
if (shouldCollapseReadChatReplayDuplicate(message) && signature) {
|
|
217
256
|
replaySignaturesInCurrentTurn.add(signature);
|
|
218
257
|
}
|
|
258
|
+
if (isStableReadChatAssistantAnswer(message)) {
|
|
259
|
+
stableAssistantAnswerInCurrentTurn = message;
|
|
260
|
+
}
|
|
219
261
|
}
|
|
220
262
|
|
|
221
263
|
return collapsed;
|
|
@@ -367,6 +367,25 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
367
367
|
? parsedMessages.slice(-historyMessageCount)
|
|
368
368
|
: [];
|
|
369
369
|
}
|
|
370
|
+
// committedMessages (adapterStatus.messages) is the adapter's accumulated
|
|
371
|
+
// conversation history — use it as a floor to prevent history from disappearing.
|
|
372
|
+
//
|
|
373
|
+
// waiting_approval: always override — the approval dialog fills the terminal,
|
|
374
|
+
// pushing prior conversation out of view; parsedMessages will be partial or empty
|
|
375
|
+
// regardless of historyMessageCount.
|
|
376
|
+
//
|
|
377
|
+
// Other active states (generating, long_generating, error): apply floor only
|
|
378
|
+
// when the script has not explicitly windowed via historyMessageCount, so
|
|
379
|
+
// intentional windowing is preserved. Excludes idle — scripts may legitimately
|
|
380
|
+
// return messages:[] when the CLI exits or a new session begins.
|
|
381
|
+
const committedMessages = Array.isArray(adapterStatus.messages) ? adapterStatus.messages : [];
|
|
382
|
+
const isActiveNonIdle = adapterStatus.status !== 'idle';
|
|
383
|
+
const shouldApplyCommittedFloor = parsedMessages.length < committedMessages.length
|
|
384
|
+
&& (adapterStatus.status === 'waiting_approval'
|
|
385
|
+
|| (isActiveNonIdle && historyMessageCount === null));
|
|
386
|
+
if (shouldApplyCommittedFloor) {
|
|
387
|
+
parsedMessages = normalizeChatMessages(committedMessages as any);
|
|
388
|
+
}
|
|
370
389
|
const mergedMessages = this.mergeConversationMessages(parsedMessages);
|
|
371
390
|
const canonicalBackedHistory = this.syncCanonicalSavedHistoryIfNeeded();
|
|
372
391
|
|