@adhdev/daemon-core 0.8.82 → 0.8.83
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 +1 -0
- package/dist/index.js +132 -77
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +132 -77
- package/dist/index.mjs.map +1 -1
- package/dist/shared-types.d.ts +2 -0
- package/dist/status/chat-tail-hot-sessions.d.ts +2 -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 +94 -26
- package/src/cli-adapters/terminal-screen.ts +6 -4
- package/src/providers/cli-provider-instance.ts +1 -0
- package/src/shared-types.d.ts +3 -0
- package/src/shared-types.ts +2 -0
- package/src/status/chat-tail-hot-sessions.ts +15 -1
- package/src/status/snapshot.ts +2 -0
package/dist/shared-types.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export declare const DEFAULT_CHAT_TAIL_RECENT_MESSAGE_GRACE_MS = 8000;
|
|
|
3
3
|
export interface HotChatSessionLike {
|
|
4
4
|
id?: string | null;
|
|
5
5
|
status?: unknown;
|
|
6
|
+
unread?: unknown;
|
|
7
|
+
inboxBucket?: unknown;
|
|
6
8
|
lastMessageAt?: unknown;
|
|
7
9
|
runtimeLifecycle?: unknown;
|
|
8
10
|
runtimeSurfaceKind?: unknown;
|
package/package.json
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import * as os from 'os';
|
|
18
18
|
import type { CliAdapter } from '../cli-adapter-types.js';
|
|
19
19
|
import { LOG } from '../logging/logger.js';
|
|
20
|
+
import { getDebugRuntimeConfig } from '../logging/debug-config.js';
|
|
20
21
|
import { TerminalScreen } from './terminal-screen.js';
|
|
21
22
|
import {
|
|
22
23
|
NodePtyTransportFactory,
|
|
@@ -182,8 +183,23 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
182
183
|
private currentTurnScope: TurnParseScope | null = null;
|
|
183
184
|
private traceEntries: CliTraceEntry[] = [];
|
|
184
185
|
private traceSeq = 0;
|
|
185
|
-
private traceSessionId =
|
|
186
|
+
private traceSessionId = '';
|
|
187
|
+
private parsedStatusCache: {
|
|
188
|
+
committedMessagesRef: CliChatMessage[];
|
|
189
|
+
responseBuffer: string;
|
|
190
|
+
currentTurnScope: TurnParseScope | null;
|
|
191
|
+
recentOutputBuffer: string;
|
|
192
|
+
accumulatedBuffer: string;
|
|
193
|
+
accumulatedRawBuffer: string;
|
|
194
|
+
screenText: string;
|
|
195
|
+
currentStatus: CliSessionStatus['status'];
|
|
196
|
+
activeModal: { message: string; buttons: string[] } | null;
|
|
197
|
+
cliName: string;
|
|
198
|
+
lastOutputAt: number;
|
|
199
|
+
result: any;
|
|
200
|
+
} | null = null;
|
|
186
201
|
private static readonly MAX_TRACE_ENTRIES = 250;
|
|
202
|
+
|
|
187
203
|
private readonly providerResolutionMeta: ProviderResolutionMeta;
|
|
188
204
|
private static readonly FINISH_RETRY_DELAY_MS = 300;
|
|
189
205
|
private static readonly MAX_FINISH_RETRIES = 2;
|
|
@@ -323,7 +339,19 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
323
339
|
`[${this.cliType}] Provider resolution: providerDir=${this.providerResolutionMeta.providerDir || '-'} scriptDir=${this.providerResolutionMeta.scriptDir || '-'} scriptsPath=${this.providerResolutionMeta.scriptsPath || '-'} source=${this.providerResolutionMeta.scriptsSource || '-'} version=${this.providerResolutionMeta.resolvedVersion || '-'}`
|
|
324
340
|
);
|
|
325
341
|
} else {
|
|
326
|
-
|
|
342
|
+
const resolutionSummary = `providerDir=${this.providerResolutionMeta.providerDir || '-'} scriptDir=${this.providerResolutionMeta.scriptDir || '-'} scriptsPath=${this.providerResolutionMeta.scriptsPath || '-'} source=${this.providerResolutionMeta.scriptsSource || '-'} version=${this.providerResolutionMeta.resolvedVersion || '-'}`;
|
|
343
|
+
const hasResolvedProviderScripts = Boolean(
|
|
344
|
+
this.providerResolutionMeta.providerDir
|
|
345
|
+
|| this.providerResolutionMeta.scriptDir
|
|
346
|
+
|| this.providerResolutionMeta.scriptsPath
|
|
347
|
+
|| this.providerResolutionMeta.scriptsSource
|
|
348
|
+
|| this.providerResolutionMeta.resolvedVersion,
|
|
349
|
+
);
|
|
350
|
+
if (hasResolvedProviderScripts) {
|
|
351
|
+
LOG.warn('CLI', `[${this.cliType}] ⚠ No CLI scripts loaded! Provider needs scripts/{version}/scripts.js (${resolutionSummary})`);
|
|
352
|
+
} else {
|
|
353
|
+
LOG.info('CLI', `[${this.cliType}] CLI scripts not yet resolved (${resolutionSummary})`);
|
|
354
|
+
}
|
|
327
355
|
}
|
|
328
356
|
}
|
|
329
357
|
|
|
@@ -485,7 +513,8 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
485
513
|
this.terminalScreen.write(rawData);
|
|
486
514
|
const cleanData = sanitizeTerminalText(rawData);
|
|
487
515
|
const now = Date.now();
|
|
488
|
-
const
|
|
516
|
+
const screenText = this.terminalScreen.getText();
|
|
517
|
+
const normalizedScreenSnapshot = normalizeScreenSnapshot(screenText);
|
|
489
518
|
this.lastOutputAt = now;
|
|
490
519
|
if (cleanData.trim()) this.lastNonEmptyOutputAt = now;
|
|
491
520
|
if (normalizedScreenSnapshot !== this.lastScreenSnapshot) {
|
|
@@ -498,13 +527,14 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
498
527
|
if (this.idleFinishCandidate && (rawData.length > 0 || cleanData.length > 0)) {
|
|
499
528
|
this.clearIdleFinishCandidate('new_output');
|
|
500
529
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
530
|
+
if (getDebugRuntimeConfig().collectDebugTrace) {
|
|
531
|
+
this.recordTrace('output', {
|
|
532
|
+
rawLength: rawData.length,
|
|
533
|
+
cleanLength: cleanData.length,
|
|
534
|
+
rawPreview: summarizeCliTraceText(rawData, 300),
|
|
535
|
+
cleanPreview: summarizeCliTraceText(cleanData, 300),
|
|
536
|
+
});
|
|
537
|
+
}
|
|
508
538
|
|
|
509
539
|
if (this.startupParseGate) {
|
|
510
540
|
this.scheduleStartupSettleCheck();
|
|
@@ -1304,15 +1334,36 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1304
1334
|
* Called by command handler / dashboard for rich content rendering.
|
|
1305
1335
|
*/
|
|
1306
1336
|
getScriptParsedStatus(): any {
|
|
1337
|
+
const screenText = this.terminalScreen.getText();
|
|
1338
|
+
const cached = this.parsedStatusCache;
|
|
1339
|
+
if (
|
|
1340
|
+
cached
|
|
1341
|
+
&& cached.committedMessagesRef === this.committedMessages
|
|
1342
|
+
&& cached.responseBuffer === this.responseBuffer
|
|
1343
|
+
&& cached.currentTurnScope === this.currentTurnScope
|
|
1344
|
+
&& cached.recentOutputBuffer === this.recentOutputBuffer
|
|
1345
|
+
&& cached.accumulatedBuffer === this.accumulatedBuffer
|
|
1346
|
+
&& cached.accumulatedRawBuffer === this.accumulatedRawBuffer
|
|
1347
|
+
&& cached.screenText === screenText
|
|
1348
|
+
&& cached.currentStatus === this.currentStatus
|
|
1349
|
+
&& cached.activeModal === this.activeModal
|
|
1350
|
+
&& cached.cliName === this.cliName
|
|
1351
|
+
&& cached.lastOutputAt === this.lastOutputAt
|
|
1352
|
+
) {
|
|
1353
|
+
return cached.result;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1307
1356
|
const parsed = this.parseCurrentTranscript(
|
|
1308
1357
|
this.committedMessages,
|
|
1309
1358
|
this.responseBuffer,
|
|
1310
1359
|
this.currentTurnScope,
|
|
1360
|
+
screenText,
|
|
1311
1361
|
);
|
|
1312
1362
|
const shouldPreferCommittedMessages =
|
|
1313
1363
|
!this.currentTurnScope
|
|
1314
1364
|
&& this.currentStatus === 'idle'
|
|
1315
1365
|
&& !this.activeModal;
|
|
1366
|
+
let result: any;
|
|
1316
1367
|
if (parsed && Array.isArray(parsed.messages)) {
|
|
1317
1368
|
const hydratedMessages = shouldPreferCommittedMessages
|
|
1318
1369
|
? this.committedMessages.map((message, index) => buildChatMessage({
|
|
@@ -1328,7 +1379,7 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1328
1379
|
scope: this.currentTurnScope,
|
|
1329
1380
|
lastOutputAt: this.lastOutputAt,
|
|
1330
1381
|
});
|
|
1331
|
-
|
|
1382
|
+
result = {
|
|
1332
1383
|
id: parsed.id || 'cli_session',
|
|
1333
1384
|
status: parsed.status || this.currentStatus,
|
|
1334
1385
|
title: parsed.title || this.cliName,
|
|
@@ -1336,23 +1387,39 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1336
1387
|
activeModal: parsed.activeModal ?? this.activeModal,
|
|
1337
1388
|
providerSessionId: typeof parsed.providerSessionId === 'string' ? parsed.providerSessionId : undefined,
|
|
1338
1389
|
};
|
|
1390
|
+
} else {
|
|
1391
|
+
const messages = [...this.committedMessages];
|
|
1392
|
+
result = {
|
|
1393
|
+
id: 'cli_session',
|
|
1394
|
+
status: this.currentStatus,
|
|
1395
|
+
title: this.cliName,
|
|
1396
|
+
messages: messages.map((message, index) => buildChatMessage({
|
|
1397
|
+
...message,
|
|
1398
|
+
id: message.id || `msg_${index}`,
|
|
1399
|
+
index: typeof message.index === 'number' ? message.index : index,
|
|
1400
|
+
receivedAt: typeof message.receivedAt === 'number'
|
|
1401
|
+
? message.receivedAt
|
|
1402
|
+
: message.timestamp,
|
|
1403
|
+
})),
|
|
1404
|
+
activeModal: this.activeModal,
|
|
1405
|
+
};
|
|
1339
1406
|
}
|
|
1340
1407
|
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
receivedAt: typeof message.receivedAt === 'number'
|
|
1351
|
-
? message.receivedAt
|
|
1352
|
-
: message.timestamp,
|
|
1353
|
-
})),
|
|
1408
|
+
this.parsedStatusCache = {
|
|
1409
|
+
committedMessagesRef: this.committedMessages,
|
|
1410
|
+
responseBuffer: this.responseBuffer,
|
|
1411
|
+
currentTurnScope: this.currentTurnScope,
|
|
1412
|
+
recentOutputBuffer: this.recentOutputBuffer,
|
|
1413
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
1414
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
1415
|
+
screenText,
|
|
1416
|
+
currentStatus: this.currentStatus,
|
|
1354
1417
|
activeModal: this.activeModal,
|
|
1418
|
+
cliName: this.cliName,
|
|
1419
|
+
lastOutputAt: this.lastOutputAt,
|
|
1420
|
+
result,
|
|
1355
1421
|
};
|
|
1422
|
+
return result;
|
|
1356
1423
|
}
|
|
1357
1424
|
|
|
1358
1425
|
async invokeScript(scriptName: string, args?: Record<string, any>): Promise<any> {
|
|
@@ -1377,17 +1444,18 @@ export class ProviderCliAdapter implements CliAdapter {
|
|
|
1377
1444
|
}));
|
|
1378
1445
|
}
|
|
1379
1446
|
|
|
1380
|
-
private parseCurrentTranscript(baseMessages: CliChatMessage[], partialResponse: string, scope?: TurnParseScope | null): any {
|
|
1447
|
+
private parseCurrentTranscript(baseMessages: CliChatMessage[], partialResponse: string, scope?: TurnParseScope | null, screenTextOverride?: string): any {
|
|
1381
1448
|
if (!this.cliScripts?.parseOutput) {
|
|
1382
1449
|
this.parseErrorMessage = null;
|
|
1383
1450
|
return null;
|
|
1384
1451
|
}
|
|
1385
1452
|
try {
|
|
1453
|
+
const screenText = typeof screenTextOverride === 'string' ? screenTextOverride : this.terminalScreen.getText();
|
|
1386
1454
|
const input = buildCliParseInput({
|
|
1387
1455
|
accumulatedBuffer: this.accumulatedBuffer,
|
|
1388
1456
|
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
1389
1457
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
1390
|
-
terminalScreenText:
|
|
1458
|
+
terminalScreenText: screenText,
|
|
1391
1459
|
baseMessages,
|
|
1392
1460
|
partialResponse,
|
|
1393
1461
|
isWaitingForResponse: this.isWaitingForResponse,
|
|
@@ -67,10 +67,12 @@ function logTerminalBackendSelection(
|
|
|
67
67
|
if (loggedTerminalBackends.has(key)) return;
|
|
68
68
|
loggedTerminalBackends.add(key);
|
|
69
69
|
if (backendKind === 'xterm' && preference !== 'xterm' && !ghosttyAvailable) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
const message = `[terminal-screen] ghostty-vt unavailable; using xterm fallback (preference=${preference})`;
|
|
71
|
+
if (preference === 'auto') {
|
|
72
|
+
LOG.info('Terminal', message);
|
|
73
|
+
} else {
|
|
74
|
+
LOG.warn('Terminal', message);
|
|
75
|
+
}
|
|
74
76
|
return;
|
|
75
77
|
}
|
|
76
78
|
LOG.info(
|
|
@@ -231,6 +231,7 @@ export class CliProviderInstance implements ProviderInstance {
|
|
|
231
231
|
|
|
232
232
|
async onTick(): Promise<void> {
|
|
233
233
|
if (this.providerSessionId) return;
|
|
234
|
+
if (this.type === 'hermes-cli' && this.launchMode === 'new') return;
|
|
234
235
|
|
|
235
236
|
let probedSessionId: string | null = null;
|
|
236
237
|
|
package/src/shared-types.d.ts
CHANGED
|
@@ -190,10 +190,13 @@ export interface SessionEntry {
|
|
|
190
190
|
summaryMetadata?: ProviderSummaryMetadata;
|
|
191
191
|
errorMessage?: string;
|
|
192
192
|
errorReason?: _ProviderErrorReason;
|
|
193
|
+
lastMessageHash?: string;
|
|
193
194
|
lastUpdated?: number;
|
|
194
195
|
unread?: boolean;
|
|
195
196
|
lastSeenAt?: number;
|
|
196
197
|
inboxBucket?: RecentSessionBucket;
|
|
198
|
+
completionMarker?: string;
|
|
199
|
+
seenCompletionMarker?: string;
|
|
197
200
|
surfaceHidden?: boolean;
|
|
198
201
|
}
|
|
199
202
|
/**
|
package/src/shared-types.ts
CHANGED
|
@@ -13,6 +13,8 @@ const LIVE_RUNTIME_LIFECYCLES = new Set(['starting', 'running', 'stopping', 'int
|
|
|
13
13
|
export interface HotChatSessionLike {
|
|
14
14
|
id?: string | null;
|
|
15
15
|
status?: unknown;
|
|
16
|
+
unread?: unknown;
|
|
17
|
+
inboxBucket?: unknown;
|
|
16
18
|
lastMessageAt?: unknown;
|
|
17
19
|
runtimeLifecycle?: unknown;
|
|
18
20
|
runtimeSurfaceKind?: unknown;
|
|
@@ -79,10 +81,22 @@ export function classifyHotChatSessionsForSubscriptionFlush(
|
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
const status = String(session?.status || '').toLowerCase();
|
|
84
|
+
const unread = session?.unread === true;
|
|
85
|
+
const inboxBucket = String(session?.inboxBucket || '').toLowerCase();
|
|
86
|
+
const runtimeSurfaceKind = String(session?.runtimeSurfaceKind || '').toLowerCase();
|
|
87
|
+
const runtimeLifecycle = String(session?.runtimeLifecycle || '').toLowerCase();
|
|
88
|
+
const isLiveRuntime = runtimeSurfaceKind === 'live_runtime' || LIVE_RUNTIME_LIFECYCLES.has(runtimeLifecycle);
|
|
82
89
|
const lastMessageAt = parseMessageTimestamp(session?.lastMessageAt);
|
|
83
90
|
const recentlyUpdated = lastMessageAt > 0 && (now - lastMessageAt) <= recentMessageGraceMs;
|
|
91
|
+
const shouldKeepRecentTailHot = recentlyUpdated && (
|
|
92
|
+
unread
|
|
93
|
+
|| inboxBucket === 'task_complete'
|
|
94
|
+
|| inboxBucket === 'needs_attention'
|
|
95
|
+
|| isLiveRuntime
|
|
96
|
+
|| activeStatuses.has(status)
|
|
97
|
+
);
|
|
84
98
|
|
|
85
|
-
if (activeStatuses.has(status) ||
|
|
99
|
+
if (activeStatuses.has(status) || shouldKeepRecentTailHot) {
|
|
86
100
|
active.add(sessionId);
|
|
87
101
|
}
|
|
88
102
|
}
|
package/src/status/snapshot.ts
CHANGED
|
@@ -408,6 +408,8 @@ export function buildStatusSnapshot(options: StatusSnapshotOptions): StatusSnaps
|
|
|
408
408
|
session.lastSeenAt = lastSeenAt;
|
|
409
409
|
session.unread = overlayUnread;
|
|
410
410
|
session.inboxBucket = overlayInboxBucket;
|
|
411
|
+
session.completionMarker = completionMarker;
|
|
412
|
+
session.seenCompletionMarker = seenCompletionMarker;
|
|
411
413
|
if (READ_DEBUG_ENABLED && (session.unread || session.inboxBucket !== 'idle' || session.providerType.includes('codex'))) {
|
|
412
414
|
const recentReadSnapshot: RecentReadDebugSnapshot = {
|
|
413
415
|
sessionId: session.id,
|