@adhdev/daemon-core 0.9.63 → 0.9.65

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.
Files changed (35) hide show
  1. package/dist/chat/chat-signatures.d.ts +0 -4
  2. package/dist/chat/chat-signatures.js +0 -4
  3. package/dist/chat/chat-signatures.js.map +1 -1
  4. package/dist/chat/chat-signatures.mjs +0 -4
  5. package/dist/chat/chat-signatures.mjs.map +1 -1
  6. package/dist/chat/subscription-updates.d.ts +0 -2
  7. package/dist/cli-adapters/provider-cli-adapter.d.ts +2 -30
  8. package/dist/cli-adapters/provider-cli-parse.d.ts +1 -8
  9. package/dist/cli-adapters/provider-cli-shared.d.ts +8 -3
  10. package/dist/commands/chat-commands.d.ts +0 -2
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.js +646 -1687
  13. package/dist/index.js.map +1 -1
  14. package/dist/index.mjs +646 -1687
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/shared-types.d.ts +0 -7
  17. package/node_modules/@adhdev/session-host-core/package.json +1 -1
  18. package/package.json +1 -1
  19. package/src/chat/chat-signatures.ts +0 -8
  20. package/src/chat/subscription-updates.ts +7 -46
  21. package/src/cli-adapters/provider-cli-adapter.d.ts +2 -10
  22. package/src/cli-adapters/provider-cli-adapter.ts +66 -692
  23. package/src/cli-adapters/provider-cli-parse.d.ts +0 -7
  24. package/src/cli-adapters/provider-cli-parse.ts +2 -226
  25. package/src/cli-adapters/provider-cli-shared.d.ts +0 -1
  26. package/src/cli-adapters/provider-cli-shared.ts +8 -3
  27. package/src/commands/chat-commands.ts +54 -338
  28. package/src/daemon/dev-auto-implement.ts +3 -3
  29. package/src/daemon/dev-server.ts +3 -3
  30. package/src/index.d.ts +1 -1
  31. package/src/index.ts +0 -1
  32. package/src/launch.ts +10 -3
  33. package/src/providers/cli-provider-instance.ts +2 -39
  34. package/src/shared-types.d.ts +0 -7
  35. package/src/shared-types.ts +0 -8
@@ -5,14 +5,7 @@ export interface TurnParseScope {
5
5
  bufferStart: number;
6
6
  rawBufferStart: number;
7
7
  }
8
- export declare function hydrateCliParsedMessages(parsedMessages: any[], options: {
9
- committedMessages: CliChatMessage[];
10
- scope?: TurnParseScope | null;
11
- lastOutputAt: number;
12
- now?: number;
13
- }): any[];
14
8
  export declare function normalizeCliParsedMessages(parsedMessages: any[], options: {
15
- committedMessages: CliChatMessage[];
16
9
  scope?: TurnParseScope | null;
17
10
  lastOutputAt: number;
18
11
  now?: number;
@@ -1,6 +1,5 @@
1
1
  import {
2
2
  buildCliScreenSnapshot,
3
- normalizeComparableMessageContent,
4
3
  sanitizeTerminalText,
5
4
  type CliChatMessage,
6
5
  type CliScriptInput,
@@ -20,238 +19,15 @@ function sliceFromOffset(text: string, start: number): string {
20
19
  return text.slice(start);
21
20
  }
22
21
 
23
- export function hydrateCliParsedMessages(
24
- parsedMessages: any[],
25
- options: {
26
- committedMessages: CliChatMessage[];
27
- scope?: TurnParseScope | null;
28
- lastOutputAt: number;
29
- now?: number;
30
- },
31
- ): any[] {
32
- const { committedMessages, scope, lastOutputAt } = options;
33
- const referenceMessages = [...committedMessages];
34
- const referenceComparables: Array<string | undefined> = new Array(referenceMessages.length);
35
- const usedReferenceIndexes = new Set<number>();
36
- const now = options.now ?? Date.now();
37
- let exactReferenceIndexesByKey: Map<string, number[]> | null = null;
38
- const exactReferenceCursorByKey = new Map<string, number>();
39
-
40
- const hasFiniteTimestamp = (message: any): message is { timestamp: number } => (
41
- typeof message?.timestamp === 'number' && Number.isFinite(message.timestamp)
42
- );
43
-
44
- const getReferenceComparable = (index: number): string => {
45
- if (typeof referenceComparables[index] === 'string') return referenceComparables[index] || '';
46
- const comparable = normalizeComparableMessageContent(referenceMessages[index]?.content || '');
47
- referenceComparables[index] = comparable;
48
- return comparable;
49
- };
50
-
51
- const messagesShareStableIdentity = (parsed: any, reference: any): boolean => {
52
- if (!parsed || !reference) return false;
53
- const parsedId = typeof parsed.id === 'string' ? parsed.id.trim() : '';
54
- const referenceId = typeof reference.id === 'string' ? reference.id.trim() : '';
55
- if (parsedId && referenceId && parsedId === referenceId) return true;
56
- return typeof parsed.index === 'number'
57
- && Number.isFinite(parsed.index)
58
- && typeof reference.index === 'number'
59
- && Number.isFinite(reference.index)
60
- && parsed.index === reference.index;
61
- };
62
-
63
- const exactReferenceKey = (role: 'user' | 'assistant', comparable: string): string => `${role}\u0000${comparable}`;
64
-
65
- const ensureExactReferenceIndex = (): Map<string, number[]> => {
66
- if (exactReferenceIndexesByKey) return exactReferenceIndexesByKey;
67
- const byKey = new Map<string, number[]>();
68
- for (let i = 0; i < referenceMessages.length; i++) {
69
- const candidate = referenceMessages[i];
70
- if (!candidate || (candidate.role !== 'user' && candidate.role !== 'assistant') || !hasFiniteTimestamp(candidate)) continue;
71
- const comparable = getReferenceComparable(i);
72
- if (!comparable) continue;
73
- const key = exactReferenceKey(candidate.role, comparable);
74
- const indexes = byKey.get(key);
75
- if (indexes) {
76
- indexes.push(i);
77
- } else {
78
- byKey.set(key, [i]);
79
- }
80
- }
81
- exactReferenceIndexesByKey = byKey;
82
- return byKey;
83
- };
84
-
85
- const takeExactReferenceTimestamp = (role: 'user' | 'assistant', normalizedContent: string): number | undefined => {
86
- const key = exactReferenceKey(role, normalizedContent);
87
- const indexes = ensureExactReferenceIndex().get(key);
88
- if (!indexes) return undefined;
89
- let cursor = exactReferenceCursorByKey.get(key) || 0;
90
- while (cursor < indexes.length) {
91
- const candidateIndex = indexes[cursor];
92
- cursor += 1;
93
- if (usedReferenceIndexes.has(candidateIndex)) continue;
94
- const candidate = referenceMessages[candidateIndex];
95
- if (!candidate || candidate.role !== role || !hasFiniteTimestamp(candidate)) continue;
96
- usedReferenceIndexes.add(candidateIndex);
97
- exactReferenceCursorByKey.set(key, cursor);
98
- return candidate.timestamp;
99
- }
100
- exactReferenceCursorByKey.set(key, cursor);
101
- return undefined;
102
- };
103
-
104
- const findReferenceTimestamp = (message: any, role: 'user' | 'assistant', content: string, parsedIndex: number): number | undefined => {
105
- const sameIndex = referenceMessages[parsedIndex];
106
- if (
107
- sameIndex
108
- && !usedReferenceIndexes.has(parsedIndex)
109
- && sameIndex.role === role
110
- && hasFiniteTimestamp(sameIndex)
111
- && messagesShareStableIdentity(message, sameIndex)
112
- ) {
113
- usedReferenceIndexes.add(parsedIndex);
114
- return sameIndex.timestamp;
115
- }
116
-
117
- const normalizedContent = normalizeComparableMessageContent(content);
118
- if (!normalizedContent) return undefined;
119
-
120
- if (
121
- sameIndex
122
- && !usedReferenceIndexes.has(parsedIndex)
123
- && sameIndex.role === role
124
- && getReferenceComparable(parsedIndex) === normalizedContent
125
- && hasFiniteTimestamp(sameIndex)
126
- ) {
127
- usedReferenceIndexes.add(parsedIndex);
128
- return sameIndex.timestamp;
129
- }
130
-
131
- const exactTimestamp = takeExactReferenceTimestamp(role, normalizedContent);
132
- if (typeof exactTimestamp === 'number') return exactTimestamp;
133
-
134
- for (let i = 0; i < referenceMessages.length; i++) {
135
- if (usedReferenceIndexes.has(i)) continue;
136
- const candidate = referenceMessages[i];
137
- if (!candidate || candidate.role !== role) continue;
138
- const candidateContent = getReferenceComparable(i);
139
- if (!candidateContent) continue;
140
- const fuzzyMatch = candidateContent.includes(normalizedContent) || normalizedContent.includes(candidateContent);
141
- if (!fuzzyMatch) continue;
142
- if (hasFiniteTimestamp(candidate)) {
143
- usedReferenceIndexes.add(i);
144
- return candidate.timestamp;
145
- }
146
- }
147
-
148
- return undefined;
149
- };
150
-
151
- return parsedMessages
152
- .filter((message) => message && (message.role === 'user' || message.role === 'assistant'))
153
- .map((message, index) => {
154
- const role = message.role as 'user' | 'assistant';
155
- const content = typeof message.content === 'string' ? message.content : String(message.content || '');
156
- const parsedTimestamp = typeof message.timestamp === 'number' && Number.isFinite(message.timestamp)
157
- ? message.timestamp
158
- : undefined;
159
- const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(message, role, content, index);
160
- const fallbackTimestamp = role === 'user'
161
- ? (scope?.startedAt || now)
162
- : (lastOutputAt || scope?.startedAt || now);
163
- const timestamp = referenceTimestamp ?? fallbackTimestamp;
164
- return {
165
- ...message,
166
- role,
167
- content,
168
- timestamp,
169
- receivedAt: typeof message.receivedAt === 'number' && Number.isFinite(message.receivedAt)
170
- ? message.receivedAt
171
- : timestamp,
172
- };
173
- });
174
- }
175
-
176
- function chooseMoreComparableCliMessage(
177
- left: CliChatMessage,
178
- right: CliChatMessage,
179
- leftComparable = normalizeComparableMessageContent(left.content || ''),
180
- rightComparable = normalizeComparableMessageContent(right.content || ''),
181
- ): CliChatMessage {
182
- if (leftComparable && leftComparable === rightComparable) {
183
- const leftNewlines = String(left.content || '').split(/\r\n|\n|\r/g).length - 1;
184
- const rightNewlines = String(right.content || '').split(/\r\n|\n|\r/g).length - 1;
185
- return rightNewlines < leftNewlines ? right : left;
186
- }
187
-
188
- return rightComparable.length > leftComparable.length ? right : left;
189
- }
190
-
191
- function dedupeConsecutiveComparableCliMessages(messages: CliChatMessage[]): CliChatMessage[] {
192
- const deduped: Array<{ message: CliChatMessage; comparable: string }> = [];
193
-
194
- for (const message of messages) {
195
- const current = {
196
- ...message,
197
- content: typeof message.content === 'string' ? message.content : String(message.content || ''),
198
- } as CliChatMessage;
199
- const currentComparable = normalizeComparableMessageContent(current.content || '');
200
- const previous = deduped[deduped.length - 1];
201
- if (!previous) {
202
- deduped.push({ message: current, comparable: currentComparable });
203
- continue;
204
- }
205
-
206
- const sameRole = previous.message.role === current.role;
207
- const sameKind = (previous.message.kind || 'standard') === (current.kind || 'standard');
208
- const sameSender = (previous.message.senderName || '') === (current.senderName || '');
209
- const comparableMatch = previous.comparable && previous.comparable === currentComparable;
210
-
211
- if (sameRole && sameKind && sameSender && comparableMatch) {
212
- const selected = chooseMoreComparableCliMessage(
213
- previous.message,
214
- current,
215
- previous.comparable,
216
- currentComparable,
217
- );
218
- deduped[deduped.length - 1] = {
219
- message: selected,
220
- comparable: selected === current ? currentComparable : previous.comparable,
221
- };
222
- continue;
223
- }
224
-
225
- deduped.push({ message: current, comparable: currentComparable });
226
- }
227
-
228
- return deduped.map((entry) => entry.message);
229
- }
230
-
231
22
  export function normalizeCliParsedMessages(
232
23
  parsedMessages: any[],
233
- options: {
234
- committedMessages: CliChatMessage[];
24
+ _options: {
235
25
  scope?: TurnParseScope | null;
236
26
  lastOutputAt: number;
237
27
  now?: number;
238
28
  },
239
29
  ): CliChatMessage[] {
240
- return dedupeConsecutiveComparableCliMessages(hydrateCliParsedMessages(parsedMessages, options).map((message) => ({
241
- role: message.role,
242
- content: message.content,
243
- timestamp: message.timestamp,
244
- receivedAt: message.receivedAt,
245
- kind: message.kind,
246
- id: message.id,
247
- index: message.index,
248
- providerUnitKey: message.providerUnitKey,
249
- bubbleId: message.bubbleId,
250
- bubbleState: message.bubbleState,
251
- _turnKey: message._turnKey,
252
- meta: message.meta,
253
- senderName: message.senderName,
254
- })));
30
+ return Array.isArray(parsedMessages) ? parsedMessages as CliChatMessage[] : [];
255
31
  }
256
32
 
257
33
  export function buildCliParseInput(options: {
@@ -20,7 +20,6 @@ export interface CliSessionStatus {
20
20
  errorReason?: string;
21
21
  }
22
22
  export interface CliScripts {
23
- parseOutput?: (input: CliScriptInput) => any;
24
23
  detectStatus?: (input: CliStatusInput) => string | null;
25
24
  parseApproval?: (input: CliApprovalInput) => {
26
25
  message: string;
@@ -3,18 +3,24 @@ import * as path from 'path';
3
3
  import { execSync } from 'child_process';
4
4
  import type { ProviderResumeCapability } from '../providers/contracts.js';
5
5
  import type { ChatMessageKind } from '../providers/chat-message-normalization.js';
6
+ import type { ChatBubbleState } from '../types.js';
6
7
  import { sanitizeSpawnEnv } from './spawn-env.js';
7
8
 
8
9
  export interface CliChatMessage {
9
- role: 'user' | 'assistant';
10
- content: string;
10
+ role: string;
11
+ content: any;
11
12
  timestamp?: number;
12
13
  receivedAt?: number;
13
14
  kind?: ChatMessageKind;
14
15
  id?: string;
15
16
  index?: number;
17
+ providerUnitKey?: string;
18
+ bubbleId?: string;
19
+ bubbleState?: ChatBubbleState;
20
+ _turnKey?: string;
16
21
  meta?: Record<string, unknown>;
17
22
  senderName?: string;
23
+ [key: string]: any;
18
24
  }
19
25
 
20
26
  export interface CliSessionStatus {
@@ -43,7 +49,6 @@ export interface ParsedSession {
43
49
 
44
50
  export interface CliScripts {
45
51
  parseSession?: (input: CliScriptInput & { tail?: string; tailScreen?: CliScreenSnapshot }) => ParsedSession | null;
46
- parseOutput?: (input: CliScriptInput) => any;
47
52
  detectStatus?: (input: CliStatusInput) => string | null;
48
53
  parseApproval?: (input: CliApprovalInput) => { message: string; buttons: string[] } | null;
49
54
  resolveAction?: (data: any) => string;