@sumicom/quicksave 0.5.1 → 0.6.0

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 (50) hide show
  1. package/dist/ai/asyncQueue.d.ts +16 -0
  2. package/dist/ai/asyncQueue.d.ts.map +1 -0
  3. package/dist/ai/asyncQueue.js +39 -0
  4. package/dist/ai/asyncQueue.js.map +1 -0
  5. package/dist/ai/asyncQueue.test.d.ts +2 -0
  6. package/dist/ai/asyncQueue.test.d.ts.map +1 -0
  7. package/dist/ai/asyncQueue.test.js +56 -0
  8. package/dist/ai/asyncQueue.test.js.map +1 -0
  9. package/dist/ai/cardBuilder.d.ts +64 -0
  10. package/dist/ai/cardBuilder.d.ts.map +1 -0
  11. package/dist/ai/cardBuilder.js +503 -0
  12. package/dist/ai/cardBuilder.js.map +1 -0
  13. package/dist/ai/claudeCodeService.d.ts +65 -32
  14. package/dist/ai/claudeCodeService.d.ts.map +1 -1
  15. package/dist/ai/claudeCodeService.js +534 -267
  16. package/dist/ai/claudeCodeService.js.map +1 -1
  17. package/dist/connection/connection.d.ts +24 -1
  18. package/dist/connection/connection.d.ts.map +1 -1
  19. package/dist/connection/connection.js +92 -6
  20. package/dist/connection/connection.js.map +1 -1
  21. package/dist/connection/pubsub.d.ts +41 -0
  22. package/dist/connection/pubsub.d.ts.map +1 -0
  23. package/dist/connection/pubsub.js +101 -0
  24. package/dist/connection/pubsub.js.map +1 -0
  25. package/dist/connection/pubsub.test.d.ts +2 -0
  26. package/dist/connection/pubsub.test.d.ts.map +1 -0
  27. package/dist/connection/pubsub.test.js +96 -0
  28. package/dist/connection/pubsub.test.js.map +1 -0
  29. package/dist/connection/relay.d.ts +4 -0
  30. package/dist/connection/relay.d.ts.map +1 -1
  31. package/dist/connection/relay.js +30 -0
  32. package/dist/connection/relay.js.map +1 -1
  33. package/dist/handlers/messageHandler.d.ts +22 -2
  34. package/dist/handlers/messageHandler.d.ts.map +1 -1
  35. package/dist/handlers/messageHandler.js +207 -16
  36. package/dist/handlers/messageHandler.js.map +1 -1
  37. package/dist/handlers/messageHandler.test.js +1 -1
  38. package/dist/index.js +192 -4
  39. package/dist/index.js.map +1 -1
  40. package/dist/service/ipc.test.js +6 -6
  41. package/dist/service/ipcClient.js +1 -1
  42. package/dist/service/run.d.ts.map +1 -1
  43. package/dist/service/run.js +125 -13
  44. package/dist/service/run.js.map +1 -1
  45. package/dist/service/singleton.test.js +1 -1
  46. package/dist/service/types.d.ts +29 -0
  47. package/dist/service/types.d.ts.map +1 -1
  48. package/dist/service/types.js +11 -0
  49. package/dist/service/types.js.map +1 -1
  50. package/package.json +2 -2
@@ -0,0 +1,503 @@
1
+ import { getSessionMessages, listSubagents, } from '@anthropic-ai/claude-agent-sdk';
2
+ import { readFile } from 'fs/promises';
3
+ import { join } from 'path';
4
+ const TOOL_RESULT_TRUNCATE_LENGTH = 500;
5
+ /** Extract readable text from tool_result content (string or array of blocks). */
6
+ function extractToolResultText(content) {
7
+ if (typeof content === 'string')
8
+ return content;
9
+ if (Array.isArray(content)) {
10
+ return content
11
+ .filter((b) => b.type === 'text')
12
+ .map((b) => b.text || '')
13
+ .join('\n');
14
+ }
15
+ return JSON.stringify(content);
16
+ }
17
+ // ============================================================================
18
+ // StreamCardBuilder — streaming session, emits CardEvents
19
+ // ============================================================================
20
+ export class StreamCardBuilder {
21
+ sessionId;
22
+ streamId;
23
+ seq = 0;
24
+ cards = new Map();
25
+ /** tool_use_id → CardId, for pairing tool_result to ToolCallCard */
26
+ toolUseIdToCardId = new Map();
27
+ /** agentId (task_id) → CardId, for matching subagent updates */
28
+ agentIdToCardId = new Map();
29
+ /** Cards created for subagent permissions — removed after resolution. */
30
+ ephemeralCards = new Set();
31
+ /** Current streaming assistant_text card (for append_text events) */
32
+ currentTextCardId = null;
33
+ constructor(sessionId, streamId) {
34
+ this.sessionId = sessionId;
35
+ this.streamId = streamId;
36
+ }
37
+ updateSessionId(sessionId) {
38
+ this.sessionId = sessionId;
39
+ }
40
+ /** Start a new turn: update streamId and reset per-turn state, keep accumulated cards. */
41
+ startNewTurn(streamId) {
42
+ this.streamId = streamId;
43
+ this.currentTextCardId = null;
44
+ }
45
+ nextId() {
46
+ return `${this.sessionId}:${this.streamId}:${++this.seq}`;
47
+ }
48
+ addEvent(card, afterCardId) {
49
+ this.cards.set(card.id, card);
50
+ return { type: 'add', streamId: this.streamId, sessionId: this.sessionId, card, afterCardId };
51
+ }
52
+ updateEvent(cardId, patch) {
53
+ const existing = this.cards.get(cardId);
54
+ if (existing) {
55
+ Object.assign(existing, patch);
56
+ }
57
+ return { type: 'update', streamId: this.streamId, sessionId: this.sessionId, cardId, patch };
58
+ }
59
+ appendTextEvent(cardId, text) {
60
+ const existing = this.cards.get(cardId);
61
+ if (existing && 'text' in existing) {
62
+ existing.text += text;
63
+ }
64
+ return { type: 'append_text', streamId: this.streamId, sessionId: this.sessionId, cardId, text };
65
+ }
66
+ removeEvent(cardId) {
67
+ this.cards.delete(cardId);
68
+ return { type: 'remove', streamId: this.streamId, sessionId: this.sessionId, cardId };
69
+ }
70
+ // ── Public: produce CardEvents from SDK data ────────────────────────────
71
+ userMessage(text) {
72
+ this.currentTextCardId = null;
73
+ const card = { type: 'user', id: this.nextId(), timestamp: Date.now(), text };
74
+ return this.addEvent(card);
75
+ }
76
+ thinkingBlock(text) {
77
+ this.currentTextCardId = null;
78
+ const card = { type: 'thinking', id: this.nextId(), timestamp: Date.now(), text };
79
+ return this.addEvent(card);
80
+ }
81
+ /**
82
+ * Append text to current assistant_text card, or create a new one.
83
+ * Returns append_text event (hot path) or add event (new card).
84
+ */
85
+ assistantText(text) {
86
+ if (this.currentTextCardId) {
87
+ return this.appendTextEvent(this.currentTextCardId, text);
88
+ }
89
+ const id = this.nextId();
90
+ const card = { type: 'assistant_text', id, timestamp: Date.now(), text, streaming: true };
91
+ this.currentTextCardId = id;
92
+ return this.addEvent(card);
93
+ }
94
+ /** Mark the current assistant_text card as done streaming. */
95
+ finalizeAssistantText() {
96
+ if (!this.currentTextCardId)
97
+ return null;
98
+ const id = this.currentTextCardId;
99
+ this.currentTextCardId = null;
100
+ return this.updateEvent(id, { streaming: false });
101
+ }
102
+ /**
103
+ * Handle tool_use block from SDK stream.
104
+ * If the card was already pre-created via `toolCallFromPermission()`, confirm it.
105
+ * Otherwise create a new ToolCallCard.
106
+ */
107
+ toolUse(toolName, toolInput, toolUseId) {
108
+ this.currentTextCardId = null;
109
+ // Check if card was pre-created from canUseTool
110
+ const existingCardId = this.toolUseIdToCardId.get(toolUseId);
111
+ if (existingCardId) {
112
+ // Confirm with real data (input may differ if updatedInput was returned)
113
+ return this.updateEvent(existingCardId, { toolInput });
114
+ }
115
+ const id = this.nextId();
116
+ const card = {
117
+ type: 'tool_call', id, timestamp: Date.now(),
118
+ toolName, toolInput, toolUseId,
119
+ };
120
+ this.toolUseIdToCardId.set(toolUseId, id);
121
+ return this.addEvent(card);
122
+ }
123
+ /**
124
+ * Pre-create a ToolCallCard from canUseTool (fires before tool_use stream event).
125
+ * This eliminates the synthetic message hack.
126
+ */
127
+ toolCallFromPermission(toolName, toolInput, toolUseId, pendingInput,
128
+ /** Ephemeral cards are removed after permission is resolved (subagent permissions). */
129
+ ephemeral = false) {
130
+ this.currentTextCardId = null;
131
+ // If the card was already created by the assistant message's tool_use block
132
+ // (which arrives in the stream BEFORE canUseTool fires), update it with pendingInput.
133
+ const existingCardId = this.toolUseIdToCardId.get(toolUseId);
134
+ if (existingCardId) {
135
+ if (ephemeral)
136
+ this.ephemeralCards.add(existingCardId);
137
+ return this.updateEvent(existingCardId, { pendingInput });
138
+ }
139
+ const id = this.nextId();
140
+ const card = {
141
+ type: 'tool_call', id, timestamp: Date.now(),
142
+ toolName, toolInput, toolUseId, pendingInput,
143
+ };
144
+ this.toolUseIdToCardId.set(toolUseId, id);
145
+ if (ephemeral)
146
+ this.ephemeralCards.add(id);
147
+ return this.addEvent(card);
148
+ }
149
+ /** Attach a pending input to a subagent card (subagent permission). */
150
+ attachPendingToSubagent(agentId, pendingInput) {
151
+ const cardId = this.agentIdToCardId.get(agentId);
152
+ if (!cardId)
153
+ return null;
154
+ return this.updateEvent(cardId, { pendingInput });
155
+ }
156
+ /** Clear pending input from a card. Ephemeral cards are removed entirely. */
157
+ clearPendingInput(requestId) {
158
+ for (const [, card] of this.cards) {
159
+ if (card.pendingInput?.requestId === requestId) {
160
+ if (this.ephemeralCards.has(card.id)) {
161
+ this.ephemeralCards.delete(card.id);
162
+ return this.removeEvent(card.id);
163
+ }
164
+ return this.updateEvent(card.id, { pendingInput: undefined });
165
+ }
166
+ }
167
+ return null;
168
+ }
169
+ /** Find the card ID for a given requestId. */
170
+ findCardByRequestId(requestId) {
171
+ for (const [, card] of this.cards) {
172
+ if (card.pendingInput?.requestId === requestId)
173
+ return card.id;
174
+ }
175
+ return undefined;
176
+ }
177
+ /** Check if a tool card already exists for the given tool_use_id. */
178
+ hasToolCard(toolUseId) {
179
+ return this.toolUseIdToCardId.has(toolUseId);
180
+ }
181
+ /** Return all live cards (insertion order). Cards carry pendingInput if set. */
182
+ getCards() {
183
+ return Array.from(this.cards.values());
184
+ }
185
+ toolResult(toolUseId, content, isError) {
186
+ const cardId = this.toolUseIdToCardId.get(toolUseId);
187
+ if (!cardId)
188
+ return null;
189
+ const truncated = content.length > TOOL_RESULT_TRUNCATE_LENGTH;
190
+ const resultContent = truncated
191
+ ? content.slice(0, TOOL_RESULT_TRUNCATE_LENGTH) + ' [truncated]'
192
+ : content;
193
+ return this.updateEvent(cardId, {
194
+ result: { content: resultContent, isError, truncated },
195
+ });
196
+ }
197
+ subagentStart(description, agentId, toolUseId) {
198
+ this.currentTextCardId = null;
199
+ const id = this.nextId();
200
+ const card = {
201
+ type: 'subagent', id, timestamp: Date.now(),
202
+ description,
203
+ toolUseId: toolUseId ?? agentId,
204
+ agentId,
205
+ status: 'running',
206
+ toolUseCount: 0,
207
+ };
208
+ this.agentIdToCardId.set(agentId, id);
209
+ // Position after the parent ToolCallCard if we have the toolUseId
210
+ const afterCardId = toolUseId ? this.toolUseIdToCardId.get(toolUseId) : undefined;
211
+ return this.addEvent(card, afterCardId);
212
+ }
213
+ subagentProgress(agentId, toolUseId, toolUseCount, lastToolName) {
214
+ const cardId = this.agentIdToCardId.get(agentId)
215
+ ?? (toolUseId ? this.agentIdToCardId.get(toolUseId) : undefined);
216
+ if (!cardId)
217
+ return null;
218
+ const patch = {};
219
+ if (toolUseCount !== undefined)
220
+ patch.toolUseCount = toolUseCount;
221
+ if (lastToolName !== undefined)
222
+ patch.lastToolName = lastToolName;
223
+ return this.updateEvent(cardId, patch);
224
+ }
225
+ subagentEnd(agentId, toolUseId, status, summary) {
226
+ const cardId = this.agentIdToCardId.get(agentId)
227
+ ?? (toolUseId ? this.agentIdToCardId.get(toolUseId) : undefined);
228
+ if (!cardId)
229
+ return null;
230
+ return this.updateEvent(cardId, { status, summary });
231
+ }
232
+ systemMessage(text, subtype) {
233
+ const card = { type: 'system', id: this.nextId(), timestamp: Date.now(), text, subtype };
234
+ return this.addEvent(card);
235
+ }
236
+ errorMessage(text) {
237
+ return this.systemMessage(`Error: ${text}`, 'error');
238
+ }
239
+ }
240
+ // ============================================================================
241
+ // buildCardsFromHistory — convert JSONL history into Card[]
242
+ // ============================================================================
243
+ export async function buildCardsFromHistory(sessionId, cwd, offset = 0, limit = 50) {
244
+ const allMessages = (await getSessionMessages(sessionId, { dir: cwd, includeSystemMessages: true }))
245
+ .filter((m) => !m.isSidechain);
246
+ const total = allMessages.length;
247
+ const tailStart = Math.max(0, total - offset - limit);
248
+ const tailEnd = Math.max(0, total - offset);
249
+ const sliced = allMessages.slice(tailStart, tailEnd);
250
+ // ── Pass 1: Build indexes from ALL messages ────────────────────────────
251
+ // toolUseId → toolName (for tool_result lookup across pages)
252
+ const agentToolUseIds = new Set();
253
+ // toolUseId → tool_result data (for pairing)
254
+ const toolResults = new Map();
255
+ for (const msg of allMessages) {
256
+ const rawMsg = msg.message;
257
+ if (!Array.isArray(rawMsg?.content))
258
+ continue;
259
+ for (const block of rawMsg.content) {
260
+ if (block.type === 'tool_use' && block.name === 'Agent' && block.id) {
261
+ agentToolUseIds.add(block.id);
262
+ }
263
+ if (block.type === 'tool_result' && block.tool_use_id) {
264
+ const text = extractToolResultText(block.content);
265
+ toolResults.set(block.tool_use_id, { content: text, isError: !!block.is_error });
266
+ }
267
+ }
268
+ }
269
+ // ── Get real agentIds from SDK listSubagents ───────────────────────────
270
+ // System messages (task_started) are NOT reliably present in the JSONL.
271
+ // Instead, read subagent meta.json files and match by description to the
272
+ // Agent tool_use input.description.
273
+ // Build description → toolUseId map from Agent tool_use blocks
274
+ const descToToolUseId = new Map();
275
+ for (const msg of allMessages) {
276
+ const rawMsg = msg.message;
277
+ if (!Array.isArray(rawMsg?.content))
278
+ continue;
279
+ for (const block of rawMsg.content) {
280
+ if (block.type === 'tool_use' && block.name === 'Agent' && block.id) {
281
+ const desc = block.input?.description ?? '';
282
+ if (desc)
283
+ descToToolUseId.set(desc, block.id);
284
+ }
285
+ }
286
+ }
287
+ const toolUseIdToAgentId = new Map();
288
+ try {
289
+ const agentIds = await listSubagents(sessionId, { dir: cwd });
290
+ // Read each subagent's meta.json to get description, then match to toolUseId
291
+ // SDK stores subagent meta at ~/.claude/projects/<cwd-hash>/<sessionId>/subagents/<agentId>.meta.json
292
+ const cwdHash = cwd.replace(/\//g, '-').replace(/^-/, '');
293
+ const subagentsDir = join(process.env.HOME ?? '', '.claude', 'projects', cwdHash, sessionId, 'subagents');
294
+ for (const agentId of agentIds) {
295
+ try {
296
+ const possiblePaths = [
297
+ join(subagentsDir, `${agentId}.meta.json`),
298
+ ];
299
+ let meta = null;
300
+ for (const p of possiblePaths) {
301
+ try {
302
+ meta = JSON.parse(await readFile(p, 'utf-8'));
303
+ break;
304
+ }
305
+ catch { /* try next */ }
306
+ }
307
+ if (meta?.description && descToToolUseId.has(meta.description)) {
308
+ toolUseIdToAgentId.set(descToToolUseId.get(meta.description), agentId);
309
+ }
310
+ }
311
+ catch { /* skip this agent */ }
312
+ }
313
+ // Fallback for any unmatched Agent tool_use IDs
314
+ for (const toolUseId of agentToolUseIds) {
315
+ if (!toolUseIdToAgentId.has(toolUseId)) {
316
+ toolUseIdToAgentId.set(toolUseId, toolUseId);
317
+ }
318
+ }
319
+ }
320
+ catch {
321
+ // No subagents or SDK error — fallback: agentId = toolUseId
322
+ for (const toolUseId of agentToolUseIds) {
323
+ toolUseIdToAgentId.set(toolUseId, toolUseId);
324
+ }
325
+ }
326
+ // ── Pass 2: Build Cards from sliced messages ───────────────────────────
327
+ let seq = tailStart;
328
+ const nextId = () => `${sessionId}:h:${++seq}`;
329
+ const cards = [];
330
+ for (const msg of sliced) {
331
+ // ── System messages ──
332
+ if (msg.type === 'system') {
333
+ const subtype = msg.subtype;
334
+ // Skip subagent lifecycle events (handled via subagentCards below)
335
+ if (subtype === 'task_started' || subtype === 'task_progress' || subtype === 'task_notification')
336
+ continue;
337
+ // Skip init and status messages (not useful in history)
338
+ if (subtype === 'init' || subtype === 'status' || subtype === 'session_state_changed')
339
+ continue;
340
+ if (subtype === 'compact_boundary') {
341
+ cards.push({ type: 'system', id: nextId(), timestamp: Date.now(), text: 'Context compacted', subtype: 'compacted' });
342
+ }
343
+ else {
344
+ // Unknown system subtype — show as info
345
+ cards.push({ type: 'system', id: nextId(), timestamp: Date.now(), text: subtype ?? 'System event', subtype: 'info' });
346
+ }
347
+ continue;
348
+ }
349
+ const rawMessage = msg.message;
350
+ if (!rawMessage?.content) {
351
+ // Empty message — skip
352
+ continue;
353
+ }
354
+ // ── User messages ──
355
+ if (msg.type === 'user') {
356
+ if (typeof rawMessage.content === 'string') {
357
+ cards.push({ type: 'user', id: nextId(), timestamp: Date.now(), text: rawMessage.content });
358
+ continue;
359
+ }
360
+ if (Array.isArray(rawMessage.content)) {
361
+ for (const block of rawMessage.content) {
362
+ if (block.type === 'text') {
363
+ cards.push({ type: 'user', id: nextId(), timestamp: Date.now(), text: block.text });
364
+ }
365
+ // tool_result blocks are paired into ToolCallCard.result (handled below)
366
+ // Skip them here — they don't need separate cards
367
+ }
368
+ continue;
369
+ }
370
+ continue;
371
+ }
372
+ // ── Assistant messages ──
373
+ if (msg.type === 'assistant') {
374
+ const blocks = rawMessage.content;
375
+ if (!Array.isArray(blocks))
376
+ continue;
377
+ for (const block of blocks) {
378
+ switch (block.type) {
379
+ case 'text':
380
+ if (block.text) {
381
+ cards.push({ type: 'assistant_text', id: nextId(), timestamp: Date.now(), text: block.text });
382
+ }
383
+ break;
384
+ case 'thinking':
385
+ if (block.thinking) {
386
+ cards.push({ type: 'thinking', id: nextId(), timestamp: Date.now(), text: block.thinking });
387
+ }
388
+ break;
389
+ case 'redacted_thinking':
390
+ cards.push({ type: 'thinking', id: nextId(), timestamp: Date.now(), text: '[Redacted thinking]' });
391
+ break;
392
+ case 'tool_use': {
393
+ if (agentToolUseIds.has(block.id)) {
394
+ // Agent tool_use → create a ToolCallCard as anchor, then SubagentCard
395
+ const agentId = toolUseIdToAgentId.get(block.id) ?? block.id;
396
+ const result = toolResults.get(block.id);
397
+ const description = block.input?.description ?? '';
398
+ const summary = result ? result.content.slice(0, 200) : undefined;
399
+ // Insert SubagentCard
400
+ const subagentCard = {
401
+ type: 'subagent',
402
+ id: nextId(),
403
+ timestamp: Date.now(),
404
+ description,
405
+ toolUseId: block.id,
406
+ agentId,
407
+ status: result ? 'completed' : 'running',
408
+ summary,
409
+ toolUseCount: 0,
410
+ };
411
+ cards.push(subagentCard);
412
+ }
413
+ else {
414
+ // Normal tool call
415
+ const toolInput = typeof block.input === 'object' && block.input !== null
416
+ ? block.input
417
+ : {};
418
+ const result = toolResults.get(block.id);
419
+ let pairedResult;
420
+ if (result) {
421
+ const truncated = result.content.length > TOOL_RESULT_TRUNCATE_LENGTH;
422
+ pairedResult = {
423
+ content: truncated
424
+ ? result.content.slice(0, TOOL_RESULT_TRUNCATE_LENGTH) + ' [truncated]'
425
+ : result.content,
426
+ isError: result.isError,
427
+ truncated,
428
+ };
429
+ }
430
+ cards.push({
431
+ type: 'tool_call',
432
+ id: nextId(),
433
+ timestamp: Date.now(),
434
+ toolName: block.name,
435
+ toolInput,
436
+ toolUseId: block.id,
437
+ result: pairedResult,
438
+ });
439
+ }
440
+ break;
441
+ }
442
+ // Server tool blocks — show as generic tool calls
443
+ case 'server_tool_use':
444
+ case 'mcp_tool_use': {
445
+ const toolInput = typeof block.input === 'object' && block.input !== null
446
+ ? block.input
447
+ : {};
448
+ cards.push({
449
+ type: 'tool_call',
450
+ id: nextId(),
451
+ timestamp: Date.now(),
452
+ toolName: block.name ?? block.type,
453
+ toolInput,
454
+ toolUseId: block.id ?? nextId(),
455
+ });
456
+ break;
457
+ }
458
+ // Server/MCP tool results — show as system info
459
+ case 'web_search_tool_result':
460
+ case 'web_fetch_tool_result':
461
+ case 'mcp_tool_result':
462
+ case 'code_execution_tool_result':
463
+ case 'bash_code_execution_tool_result':
464
+ case 'text_editor_code_execution_tool_result':
465
+ case 'tool_search_tool_result': {
466
+ const resultText = extractToolResultText(block.content ?? block.text ?? '');
467
+ const parentToolUseId = block.tool_use_id;
468
+ // Try to pair with a previously emitted tool_call card
469
+ if (parentToolUseId) {
470
+ const parentCard = cards.find((c) => c.type === 'tool_call' && c.toolUseId === parentToolUseId);
471
+ if (parentCard && !parentCard.result) {
472
+ const truncated = resultText.length > TOOL_RESULT_TRUNCATE_LENGTH;
473
+ parentCard.result = {
474
+ content: truncated ? resultText.slice(0, TOOL_RESULT_TRUNCATE_LENGTH) + ' [truncated]' : resultText,
475
+ isError: !!block.is_error,
476
+ truncated,
477
+ };
478
+ break;
479
+ }
480
+ }
481
+ // Fallback: show as system info
482
+ if (resultText) {
483
+ cards.push({ type: 'system', id: nextId(), timestamp: Date.now(), text: `${block.type}: ${resultText.slice(0, 200)}`, subtype: 'info' });
484
+ }
485
+ break;
486
+ }
487
+ case 'container_upload':
488
+ cards.push({ type: 'system', id: nextId(), timestamp: Date.now(), text: 'Container upload', subtype: 'info' });
489
+ break;
490
+ // Unknown block types — skip silently
491
+ default:
492
+ break;
493
+ }
494
+ }
495
+ }
496
+ }
497
+ return {
498
+ cards,
499
+ total,
500
+ hasMore: tailStart > 0,
501
+ };
502
+ }
503
+ //# sourceMappingURL=cardBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cardBuilder.js","sourceRoot":"","sources":["../../src/ai/cardBuilder.ts"],"names":[],"mappings":"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"}
@@ -1,50 +1,51 @@
1
1
  import { EventEmitter } from 'events';
2
- import type { ClaudeSessionSummary, ClaudeHistoryMessage, ClaudeStreamEventType, ClaudeUserInputRequestPayload, ClaudeUserInputResponsePayload } from '@sumicom/quicksave-shared';
3
- export interface StreamEvent {
4
- sessionId: string;
5
- streamId: string;
6
- eventType: ClaudeStreamEventType;
7
- content: string;
8
- toolName?: string;
9
- toolInput?: string;
10
- isPartial?: boolean;
11
- }
12
- export interface StreamEndResult {
13
- sessionId: string;
14
- streamId: string;
15
- success: boolean;
16
- error?: string;
17
- totalCostUsd?: number;
18
- tokenUsage?: {
19
- input: number;
20
- output: number;
21
- };
22
- }
2
+ import type { ClaudeSessionSummary, ClaudeUserInputRequestPayload, ClaudeUserInputResponsePayload, ClaudePreferences, ConfigValue, CardHistoryResponse } from '@sumicom/quicksave-shared';
3
+ import { StreamCardBuilder } from './cardBuilder.js';
23
4
  /**
24
5
  * Events emitted by ClaudeCodeService:
25
- * 'stream' (event: StreamEvent)
26
- * 'stream:end' (result: StreamEndResult)
27
- * 'user-input-request' (request: ClaudeUserInputRequestPayload)
6
+ * 'card-event' (event: CardEvent)
7
+ * 'card-stream-end' (result: CardStreamEnd)
8
+ * 'user-input-request' (request: ClaudeUserInputRequestPayload)
9
+ * 'user-input-resolved' ({ requestId, sessionId })
10
+ * 'session-updated' ({ sessionId, isActive, isStreaming, hasPendingInput, permissionMode })
11
+ * 'preferences-updated' (prefs: ClaudePreferences)
12
+ * 'session-config-updated' ({ sessionId, config: Record<string, ConfigValue> })
28
13
  */
29
14
  type PermissionLevel = 'bypassPermissions' | 'acceptEdits' | 'default' | 'plan';
30
15
  export declare class ClaudeCodeService extends EventEmitter {
31
16
  private sessions;
17
+ private sessionPermissions;
18
+ private sessionConfigs;
32
19
  private pendingInputRequests;
33
20
  private requestCounter;
21
+ private preferences;
34
22
  constructor();
23
+ /**
24
+ * Initialize preferences from the most recently used session.
25
+ * Uses SDK listSessions + getSessionMessages to read the last assistant message's model field.
26
+ */
27
+ initPreferences(): Promise<void>;
28
+ getPreferences(): ClaudePreferences;
29
+ /**
30
+ * Update preferences. Returns the applied preferences (may differ if validation fails).
31
+ * Emits 'preferences-updated' if any value actually changed.
32
+ */
33
+ setPreferences(prefs: Partial<ClaudePreferences>): ClaudePreferences;
34
+ getSessionConfig(sessionId: string): Record<string, ConfigValue>;
35
+ /**
36
+ * Set a single key on a session's config. Applies known keys immediately:
37
+ * model / reasoningEffort → updates global preferences (takes effect next turn)
38
+ * permissionMode → calls setPermissionLevel (immediate)
39
+ */
40
+ setSessionConfig(sessionId: string, key: string, value: ConfigValue): Record<string, ConfigValue>;
35
41
  /** Build and emit a session-updated event with current state. */
36
42
  private emitSessionUpdate;
37
43
  listAvailableSessions(cwd: string): Promise<ClaudeSessionSummary[]>;
38
44
  /**
39
- * Check if a session's last message in the SDK JSONL is an unanswered tool_use.
40
- * Reads only the last few messages to keep it fast.
45
+ * Check if a session's last message is an unanswered tool_use.
46
+ * Uses SDK getSessionMessages + listSubagents/getSubagentMessages.
41
47
  */
42
48
  private detectPendingFromJSONL;
43
- getMessages(sessionId: string, cwd: string, offset?: number, limit?: number): Promise<{
44
- messages: ClaudeHistoryMessage[];
45
- total: number;
46
- hasMore: boolean;
47
- }>;
48
49
  /**
49
50
  * Create a V2 session with the given cwd.
50
51
  * V2 SDKSessionOptions doesn't expose `cwd`, so we temporarily change
@@ -60,6 +61,23 @@ export declare class ClaudeCodeService extends EventEmitter {
60
61
  * Get all pending user input requests (for re-sending to a reconnected client).
61
62
  */
62
63
  getPendingInputRequests(): ClaudeUserInputRequestPayload[];
64
+ /** Debug snapshot of pending inputs and active sessions. */
65
+ getDebugState(): {
66
+ pendingInputs: Array<{
67
+ requestId: string;
68
+ sessionId: string;
69
+ toolName?: string;
70
+ agentId?: string;
71
+ inputType: string;
72
+ }>;
73
+ activeSessions: Array<{
74
+ sessionId: string;
75
+ cwd: string;
76
+ isStreaming: boolean;
77
+ hasPendingInput: boolean;
78
+ permissionMode: string;
79
+ }>;
80
+ };
63
81
  startSession(opts: {
64
82
  prompt: string;
65
83
  cwd: string;
@@ -78,12 +96,27 @@ export declare class ClaudeCodeService extends EventEmitter {
78
96
  cancelSession(sessionId: string): boolean;
79
97
  setPermissionLevel(sessionId: string, level: PermissionLevel): boolean;
80
98
  getPermissionLevel(sessionId: string): PermissionLevel;
99
+ getActiveSessions(): {
100
+ sessionId: string;
101
+ cwd: string;
102
+ isStreaming: boolean;
103
+ hasPendingInput: boolean;
104
+ permissionMode: string;
105
+ }[];
81
106
  closeSession(sessionId: string): boolean;
82
107
  isStreaming(sessionId: string): boolean;
83
108
  isOpen(sessionId: string): boolean;
84
109
  getActiveSessionCount(): number;
85
110
  cleanup(): void;
86
- private consumeStream;
111
+ /** Get the CardBuilder for a session (if streaming). Used by canUseTool. */
112
+ getCardBuilder(sessionId: string): StreamCardBuilder | null;
113
+ /** Get card-based history for a session. */
114
+ getCards(sessionId: string, cwd: string, offset?: number, limit?: number): Promise<CardHistoryResponse>;
115
+ /**
116
+ * Turn loop: dequeue prompt → send() → consume stream → on result, check queue → repeat.
117
+ * The first entry may have an empty prompt (already sent by startSession/resumeSession).
118
+ */
119
+ private processTurnLoop;
87
120
  }
88
121
  export {};
89
122
  //# sourceMappingURL=claudeCodeService.d.ts.map