@sumicom/quicksave 0.4.0 → 0.5.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 (75) hide show
  1. package/dist/ai/claudeCodeService.d.ts +89 -0
  2. package/dist/ai/claudeCodeService.d.ts.map +1 -0
  3. package/dist/ai/claudeCodeService.js +602 -0
  4. package/dist/ai/claudeCodeService.js.map +1 -0
  5. package/dist/ai/sessionStore.d.ts +31 -0
  6. package/dist/ai/sessionStore.d.ts.map +1 -0
  7. package/dist/ai/sessionStore.js +72 -0
  8. package/dist/ai/sessionStore.js.map +1 -0
  9. package/dist/ai/sessionStore.test.d.ts +2 -0
  10. package/dist/ai/sessionStore.test.d.ts.map +1 -0
  11. package/dist/ai/sessionStore.test.js +99 -0
  12. package/dist/ai/sessionStore.test.js.map +1 -0
  13. package/dist/config.d.ts +7 -0
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/config.js +39 -0
  16. package/dist/config.js.map +1 -1
  17. package/dist/connection/connection.d.ts +2 -0
  18. package/dist/connection/connection.d.ts.map +1 -1
  19. package/dist/connection/connection.js +14 -5
  20. package/dist/connection/connection.js.map +1 -1
  21. package/dist/connection/relay.d.ts.map +1 -1
  22. package/dist/connection/relay.js +2 -0
  23. package/dist/connection/relay.js.map +1 -1
  24. package/dist/git/operations.d.ts +8 -1
  25. package/dist/git/operations.d.ts.map +1 -1
  26. package/dist/git/operations.js +71 -4
  27. package/dist/git/operations.js.map +1 -1
  28. package/dist/handlers/messageHandler.d.ts +18 -1
  29. package/dist/handlers/messageHandler.d.ts.map +1 -1
  30. package/dist/handlers/messageHandler.js +231 -11
  31. package/dist/handlers/messageHandler.js.map +1 -1
  32. package/dist/handlers/messageHandler.test.js +1 -1
  33. package/dist/index.js +228 -94
  34. package/dist/index.js.map +1 -1
  35. package/dist/service/ensureDaemon.d.ts +23 -0
  36. package/dist/service/ensureDaemon.d.ts.map +1 -0
  37. package/dist/service/ensureDaemon.js +138 -0
  38. package/dist/service/ensureDaemon.js.map +1 -0
  39. package/dist/service/index.d.ts +8 -0
  40. package/dist/service/index.d.ts.map +1 -0
  41. package/dist/service/index.js +8 -0
  42. package/dist/service/index.js.map +1 -0
  43. package/dist/service/ipc.test.d.ts +2 -0
  44. package/dist/service/ipc.test.d.ts.map +1 -0
  45. package/dist/service/ipc.test.js +140 -0
  46. package/dist/service/ipc.test.js.map +1 -0
  47. package/dist/service/ipcClient.d.ts +36 -0
  48. package/dist/service/ipcClient.d.ts.map +1 -0
  49. package/dist/service/ipcClient.js +167 -0
  50. package/dist/service/ipcClient.js.map +1 -0
  51. package/dist/service/ipcServer.d.ts +53 -0
  52. package/dist/service/ipcServer.d.ts.map +1 -0
  53. package/dist/service/ipcServer.js +245 -0
  54. package/dist/service/ipcServer.js.map +1 -0
  55. package/dist/service/run.d.ts +13 -0
  56. package/dist/service/run.d.ts.map +1 -0
  57. package/dist/service/run.js +292 -0
  58. package/dist/service/run.js.map +1 -0
  59. package/dist/service/singleton.d.ts +31 -0
  60. package/dist/service/singleton.d.ts.map +1 -0
  61. package/dist/service/singleton.js +96 -0
  62. package/dist/service/singleton.js.map +1 -0
  63. package/dist/service/singleton.test.d.ts +2 -0
  64. package/dist/service/singleton.test.d.ts.map +1 -0
  65. package/dist/service/singleton.test.js +39 -0
  66. package/dist/service/singleton.test.js.map +1 -0
  67. package/dist/service/stateStore.d.ts +11 -0
  68. package/dist/service/stateStore.d.ts.map +1 -0
  69. package/dist/service/stateStore.js +35 -0
  70. package/dist/service/stateStore.js.map +1 -0
  71. package/dist/service/types.d.ts +111 -0
  72. package/dist/service/types.d.ts.map +1 -0
  73. package/dist/service/types.js +76 -0
  74. package/dist/service/types.js.map +1 -0
  75. package/package.json +3 -2
@@ -0,0 +1,602 @@
1
+ import { EventEmitter } from 'events';
2
+ import { unstable_v2_createSession, unstable_v2_resumeSession, listSessions, getSessionMessages, } from '@anthropic-ai/claude-agent-sdk';
3
+ const TOOL_RESULT_TRUNCATE_LENGTH = 500;
4
+ const DEFAULT_MODEL = 'claude-sonnet-4-6';
5
+ /** Tools auto-approved at each permission level (no user prompt).
6
+ * Read/Glob/Grep are always auto-approved at SDK level (allowedTools).
7
+ * Tools NOT listed here go through canUseTool → permission prompt.
8
+ *
9
+ * Risk tiers:
10
+ * - Safe: Edit, Write, NotebookEdit, TodoWrite, Agent, EnterWorktree, ExitWorktree
11
+ * - Network: WebFetch, WebSearch
12
+ * - Execute: Bash
13
+ * - Code/Control: Skill, ToolSearch, Config
14
+ * - Schedule: CronCreate, CronDelete (arbitrary scheduled execution)
15
+ * - Remote: RemoteTrigger (triggers remote agents)
16
+ * - Workflow: EnterPlanMode, ExitPlanMode (ExitPlanMode has its own interactive UI)
17
+ */
18
+ const AUTO_APPROVE = {
19
+ bypassPermissions: new Set([
20
+ // Safe
21
+ 'Edit', 'Write', 'NotebookEdit', 'TodoWrite', 'Agent', 'EnterWorktree', 'ExitWorktree',
22
+ // Network
23
+ 'WebFetch', 'WebSearch',
24
+ // Execute
25
+ 'Bash',
26
+ // Code/Control
27
+ 'Skill', 'ToolSearch', 'Config',
28
+ // Schedule + Remote
29
+ 'CronCreate', 'CronDelete', 'CronList', 'RemoteTrigger',
30
+ // Workflow
31
+ 'EnterPlanMode', 'ExitPlanMode',
32
+ // Background tasks
33
+ 'TaskOutput', 'TaskStop',
34
+ ]),
35
+ acceptEdits: new Set(['Edit', 'Write', 'NotebookEdit', 'TodoWrite', 'Agent', 'EnterWorktree', 'ExitWorktree']),
36
+ default: new Set(['TodoWrite', 'EnterWorktree', 'ExitWorktree', 'Agent']),
37
+ plan: new Set(),
38
+ };
39
+ /** Extract readable text from tool_result content (which may be a string or array of blocks). */
40
+ function extractToolResultText(content) {
41
+ if (typeof content === 'string')
42
+ return content;
43
+ if (Array.isArray(content)) {
44
+ return content
45
+ .filter((b) => b.type === 'text')
46
+ .map((b) => b.text || '')
47
+ .join('\n');
48
+ }
49
+ return JSON.stringify(content);
50
+ }
51
+ export class ClaudeCodeService extends EventEmitter {
52
+ sessions = new Map();
53
+ pendingInputRequests = new Map();
54
+ requestCounter = 0;
55
+ constructor() {
56
+ super();
57
+ }
58
+ /** Build and emit a session-updated event with current state. */
59
+ emitSessionUpdate(sessionId) {
60
+ const ps = this.sessions.get(sessionId);
61
+ const hasPendingInput = Array.from(this.pendingInputRequests.values())
62
+ .some((p) => p.request.sessionId === sessionId);
63
+ this.emit('session-updated', {
64
+ sessionId,
65
+ isActive: !!ps,
66
+ isStreaming: ps?.streaming ?? false,
67
+ hasPendingInput,
68
+ });
69
+ }
70
+ async listAvailableSessions(cwd) {
71
+ const sessions = await listSessions({ dir: cwd, limit: 50 });
72
+ // Enrich with live state + detect pending from JSONL
73
+ const pendingSessionIds = new Set(Array.from(this.pendingInputRequests.values()).map((p) => p.request.sessionId));
74
+ // Check JSONL for sessions not in memory (cold pending detection)
75
+ const enriched = await Promise.all(sessions.map(async (s) => {
76
+ const isActive = this.sessions.has(s.sessionId);
77
+ const isStreaming = this.sessions.get(s.sessionId)?.streaming ?? false;
78
+ let hasPendingInput = pendingSessionIds.has(s.sessionId);
79
+ // If not already known as pending from memory, check JSONL tail
80
+ if (!hasPendingInput) {
81
+ hasPendingInput = await this.detectPendingFromJSONL(s.sessionId, cwd);
82
+ }
83
+ return {
84
+ sessionId: s.sessionId,
85
+ summary: s.summary,
86
+ lastModified: s.lastModified,
87
+ createdAt: s.createdAt,
88
+ cwd: s.cwd,
89
+ gitBranch: s.gitBranch,
90
+ isActive,
91
+ isStreaming,
92
+ hasPendingInput,
93
+ };
94
+ }));
95
+ // Sort: pending first, then active, then by lastModified
96
+ enriched.sort((a, b) => {
97
+ if (a.hasPendingInput !== b.hasPendingInput)
98
+ return a.hasPendingInput ? -1 : 1;
99
+ if (a.isActive !== b.isActive)
100
+ return a.isActive ? -1 : 1;
101
+ return b.lastModified - a.lastModified;
102
+ });
103
+ return enriched;
104
+ }
105
+ /**
106
+ * Check if a session's last message in the SDK JSONL is an unanswered tool_use.
107
+ * Reads only the last few messages to keep it fast.
108
+ */
109
+ async detectPendingFromJSONL(sessionId, cwd) {
110
+ try {
111
+ const allMessages = await getSessionMessages(sessionId, { dir: cwd });
112
+ if (allMessages.length === 0)
113
+ return false;
114
+ const last = allMessages[allMessages.length - 1];
115
+ // Last message is assistant with a tool_use block and no following user/tool_result
116
+ if (last.type !== 'assistant')
117
+ return false;
118
+ const content = last.message?.content;
119
+ if (!Array.isArray(content))
120
+ return false;
121
+ return content.some((block) => block.type === 'tool_use');
122
+ }
123
+ catch {
124
+ return false;
125
+ }
126
+ }
127
+ async getMessages(sessionId, cwd, offset = 0, limit = 50) {
128
+ // Read directly from SDK JSONL — the single source of truth.
129
+ // SDK writes messages immediately and retains full, un-truncated data.
130
+ // Messages are chronological (old→new). We paginate from the tail:
131
+ // offset=0 → last `limit` messages (most recent)
132
+ // offset=50 → the `limit` messages before those, etc.
133
+ const allMessages = await getSessionMessages(sessionId, { dir: cwd });
134
+ const total = allMessages.length;
135
+ const tailStart = Math.max(0, total - offset - limit);
136
+ const tailEnd = Math.max(0, total - offset);
137
+ const sliced = allMessages.slice(tailStart, tailEnd);
138
+ const messages = sliced.map((msg, i) => {
139
+ const role = msg.type;
140
+ let content = '';
141
+ let toolName;
142
+ let toolInput;
143
+ let toolResult;
144
+ let truncated = false;
145
+ const rawMessage = msg.message;
146
+ if (rawMessage?.content) {
147
+ if (typeof rawMessage.content === 'string') {
148
+ content = rawMessage.content;
149
+ }
150
+ else if (Array.isArray(rawMessage.content)) {
151
+ const parts = [];
152
+ for (const block of rawMessage.content) {
153
+ if (block.type === 'text') {
154
+ parts.push(block.text);
155
+ }
156
+ else if (block.type === 'tool_use') {
157
+ toolName = block.name;
158
+ toolInput = JSON.stringify(block.input);
159
+ }
160
+ else if (block.type === 'tool_result') {
161
+ const resultStr = extractToolResultText(block.content);
162
+ if (resultStr.length > TOOL_RESULT_TRUNCATE_LENGTH) {
163
+ toolResult = resultStr.slice(0, TOOL_RESULT_TRUNCATE_LENGTH) + ' [truncated]';
164
+ truncated = true;
165
+ }
166
+ else {
167
+ toolResult = resultStr;
168
+ }
169
+ }
170
+ }
171
+ content = parts.join('\n');
172
+ }
173
+ }
174
+ return {
175
+ index: tailStart + i,
176
+ role,
177
+ content,
178
+ toolName,
179
+ toolInput,
180
+ toolResult,
181
+ truncated,
182
+ };
183
+ });
184
+ return {
185
+ messages,
186
+ total,
187
+ hasMore: tailStart > 0,
188
+ };
189
+ }
190
+ /**
191
+ * Create a V2 session with the given cwd.
192
+ * V2 SDKSessionOptions doesn't expose `cwd`, so we temporarily change
193
+ * process.cwd() around the synchronous createSession() call.
194
+ */
195
+ createSessionWithCwd(cwd, sessionId, opts) {
196
+ const originalCwd = process.cwd();
197
+ try {
198
+ process.chdir(cwd);
199
+ // allowedTools = SDK auto-approve list (bypasses canUseTool entirely).
200
+ // Only list tools that should NEVER prompt at ANY permission level.
201
+ // Everything else goes through permissionMode → canUseTool for dynamic control.
202
+ const sessionOpts = {
203
+ model: opts.model ?? DEFAULT_MODEL,
204
+ allowedTools: opts.allowedTools ?? ['Read', 'Glob', 'Grep'],
205
+ permissionMode: 'default',
206
+ settingSources: ['user', 'project', 'local'],
207
+ canUseTool: async (toolName, input, options) => {
208
+ const resolvedSessionId = sessionId ?? 'unknown';
209
+ // Check runtime permission level — auto-approve if tool is in the allow set
210
+ const ps = resolvedSessionId !== 'unknown' ? this.sessions.get(resolvedSessionId) : undefined;
211
+ const level = ps?.permissionLevel ?? 'acceptEdits';
212
+ if (AUTO_APPROVE[level].has(toolName)) {
213
+ return { behavior: 'allow', updatedInput: input };
214
+ }
215
+ const requestId = `perm-${++this.requestCounter}`;
216
+ // AskUserQuestion: forward as question type with options
217
+ const isQuestion = toolName === 'AskUserQuestion';
218
+ const questions = isQuestion ? input.questions : undefined;
219
+ // Forward request to PWA
220
+ const request = {
221
+ sessionId: resolvedSessionId,
222
+ requestId,
223
+ inputType: isQuestion ? 'question' : 'permission',
224
+ title: isQuestion
225
+ ? questions?.[0]?.question ?? 'Question from Claude'
226
+ : (options.title ?? `Allow ${toolName}?`),
227
+ message: isQuestion
228
+ ? undefined
229
+ : (options.description ?? JSON.stringify(input).slice(0, 500)),
230
+ toolName,
231
+ toolInput: input,
232
+ // Include structured options for question type
233
+ ...(isQuestion && questions ? {
234
+ options: questions.flatMap((q) => (q.options ?? []).map((opt) => ({
235
+ key: opt.label,
236
+ label: opt.label,
237
+ description: opt.description,
238
+ }))),
239
+ } : {}),
240
+ };
241
+ this.emit('user-input-request', request);
242
+ this.emitSessionUpdate(resolvedSessionId);
243
+ // Wait for explicit user response (no timeout — user must act)
244
+ const response = await this.waitForUserInput(requestId, request, options.signal);
245
+ if (response.action === 'deny') {
246
+ return { behavior: 'deny', message: 'User denied permission' };
247
+ }
248
+ // For AskUserQuestion, inject user's answer into the tool input
249
+ if (isQuestion && response.response) {
250
+ const answers = {};
251
+ if (questions?.[0]?.question) {
252
+ answers[questions[0].question] = response.response;
253
+ }
254
+ return {
255
+ behavior: 'allow',
256
+ updatedInput: { ...input, answers },
257
+ };
258
+ }
259
+ return { behavior: 'allow', updatedInput: input };
260
+ },
261
+ };
262
+ if (opts.resumeSessionId) {
263
+ return unstable_v2_resumeSession(opts.resumeSessionId, sessionOpts);
264
+ }
265
+ return unstable_v2_createSession(sessionOpts);
266
+ }
267
+ finally {
268
+ process.chdir(originalCwd);
269
+ }
270
+ }
271
+ waitForUserInput(requestId, request, signal) {
272
+ return new Promise((resolve) => {
273
+ this.pendingInputRequests.set(requestId, { resolve, request });
274
+ // Only auto-resolve if the SDK itself aborts (e.g. session closed)
275
+ signal?.addEventListener('abort', () => {
276
+ this.pendingInputRequests.delete(requestId);
277
+ resolve({ sessionId: '', requestId, action: 'allow' });
278
+ }, { once: true });
279
+ });
280
+ }
281
+ /**
282
+ * Called by message handler when PWA sends a user input response.
283
+ */
284
+ resolveUserInput(response) {
285
+ const pending = this.pendingInputRequests.get(response.requestId);
286
+ if (!pending)
287
+ return false;
288
+ this.pendingInputRequests.delete(response.requestId);
289
+ pending.resolve(response);
290
+ this.emit('user-input-resolved', { requestId: response.requestId, sessionId: pending.request.sessionId });
291
+ this.emitSessionUpdate(pending.request.sessionId);
292
+ return true;
293
+ }
294
+ /**
295
+ * Get all pending user input requests (for re-sending to a reconnected client).
296
+ */
297
+ getPendingInputRequests() {
298
+ return Array.from(this.pendingInputRequests.values()).map((p) => p.request);
299
+ }
300
+ async startSession(opts) {
301
+ const validModes = ['default', 'acceptEdits', 'bypassPermissions', 'plan'];
302
+ const level = validModes.includes(opts.permissionMode)
303
+ ? opts.permissionMode : 'acceptEdits';
304
+ const session = this.createSessionWithCwd(opts.cwd, null, {
305
+ allowedTools: opts.allowedTools,
306
+ model: opts.model,
307
+ permissionMode: opts.permissionMode,
308
+ });
309
+ const prompt = opts.systemPrompt
310
+ ? `[System context: ${opts.systemPrompt}]\n\n${opts.prompt}`
311
+ : opts.prompt;
312
+ await session.send(prompt);
313
+ this.emit('stream', {
314
+ sessionId: '', streamId: opts.streamId,
315
+ eventType: 'user_message',
316
+ content: opts.prompt,
317
+ });
318
+ const sessionId = await new Promise((resolve) => {
319
+ this.consumeStream(session, opts.streamId, (id) => {
320
+ this.sessions.set(id, {
321
+ session,
322
+ sessionId: id,
323
+ cwd: opts.cwd,
324
+ streaming: true,
325
+ cancelStreaming: null,
326
+ permissionLevel: level,
327
+ });
328
+ this.emitSessionUpdate(id);
329
+ resolve(id);
330
+ });
331
+ });
332
+ return sessionId;
333
+ }
334
+ async resumeSession(opts) {
335
+ const existing = this.sessions.get(opts.sessionId);
336
+ if (existing) {
337
+ console.log(`[v2] hot resume session=${opts.sessionId}`);
338
+ existing.streaming = true;
339
+ this.emitSessionUpdate(opts.sessionId);
340
+ this.emit('stream', {
341
+ sessionId: opts.sessionId, streamId: opts.streamId,
342
+ eventType: 'user_message',
343
+ content: opts.prompt,
344
+ });
345
+ await existing.session.send(opts.prompt);
346
+ this.consumeStream(existing.session, opts.streamId, () => {
347
+ // Session ID already captured
348
+ });
349
+ return opts.sessionId;
350
+ }
351
+ console.log(`[v2] cold resume session=${opts.sessionId}`);
352
+ const session = this.createSessionWithCwd(opts.cwd, opts.sessionId, {
353
+ resumeSessionId: opts.sessionId,
354
+ });
355
+ this.emit('stream', {
356
+ sessionId: opts.sessionId, streamId: opts.streamId,
357
+ eventType: 'user_message',
358
+ content: opts.prompt,
359
+ });
360
+ await session.send(opts.prompt);
361
+ const actualSessionId = await new Promise((resolve) => {
362
+ this.consumeStream(session, opts.streamId, (id) => {
363
+ if (id !== opts.sessionId) {
364
+ this.emit('stream', {
365
+ sessionId: id, streamId: opts.streamId,
366
+ eventType: 'system',
367
+ content: `Warning: SDK created new session ${id} instead of resuming ${opts.sessionId}`,
368
+ });
369
+ }
370
+ this.sessions.set(id, {
371
+ session,
372
+ sessionId: id,
373
+ cwd: opts.cwd,
374
+ streaming: true,
375
+ cancelStreaming: null,
376
+ permissionLevel: 'acceptEdits',
377
+ });
378
+ this.emitSessionUpdate(id);
379
+ resolve(id);
380
+ });
381
+ });
382
+ return actualSessionId;
383
+ }
384
+ cancelSession(sessionId) {
385
+ const ps = this.sessions.get(sessionId);
386
+ if (!ps)
387
+ return false;
388
+ // Stop streaming but keep the session process alive
389
+ if (ps.cancelStreaming) {
390
+ ps.cancelStreaming();
391
+ }
392
+ ps.streaming = false;
393
+ return true;
394
+ }
395
+ setPermissionLevel(sessionId, level) {
396
+ const ps = this.sessions.get(sessionId);
397
+ if (!ps)
398
+ return false;
399
+ ps.permissionLevel = level;
400
+ this.emitSessionUpdate(sessionId);
401
+ return true;
402
+ }
403
+ getPermissionLevel(sessionId) {
404
+ return this.sessions.get(sessionId)?.permissionLevel ?? 'acceptEdits';
405
+ }
406
+ closeSession(sessionId) {
407
+ const ps = this.sessions.get(sessionId);
408
+ if (!ps)
409
+ return false;
410
+ // Stop streaming if active
411
+ if (ps.cancelStreaming) {
412
+ ps.cancelStreaming();
413
+ }
414
+ // Terminate the subprocess
415
+ ps.session.close();
416
+ this.sessions.delete(sessionId);
417
+ this.emitSessionUpdate(sessionId);
418
+ return true;
419
+ }
420
+ isStreaming(sessionId) {
421
+ return this.sessions.get(sessionId)?.streaming ?? false;
422
+ }
423
+ isOpen(sessionId) {
424
+ return this.sessions.has(sessionId);
425
+ }
426
+ getActiveSessionCount() {
427
+ return this.sessions.size;
428
+ }
429
+ cleanup() {
430
+ // Force-resolve any pending inputs on daemon shutdown
431
+ for (const [requestId, pending] of this.pendingInputRequests) {
432
+ pending.resolve({ sessionId: '', requestId, action: 'allow' });
433
+ }
434
+ this.pendingInputRequests.clear();
435
+ for (const [, ps] of this.sessions) {
436
+ try {
437
+ ps.session.close();
438
+ }
439
+ catch {
440
+ // Ignore errors during cleanup
441
+ }
442
+ }
443
+ this.sessions.clear();
444
+ }
445
+ async consumeStream(session, streamId, onSessionId) {
446
+ let textBuffer = '';
447
+ let bufferTimer = null;
448
+ let capturedSessionId = null;
449
+ let cancelled = false;
450
+ const emitStream = (event) => {
451
+ this.emit('stream', { ...event, sessionId: capturedSessionId ?? '', streamId });
452
+ };
453
+ const flushText = () => {
454
+ if (textBuffer) {
455
+ emitStream({ eventType: 'assistant_text', content: textBuffer });
456
+ textBuffer = '';
457
+ }
458
+ if (bufferTimer) {
459
+ clearTimeout(bufferTimer);
460
+ bufferTimer = null;
461
+ }
462
+ };
463
+ const markStreamingDone = () => {
464
+ if (capturedSessionId) {
465
+ const ps = this.sessions.get(capturedSessionId);
466
+ if (ps) {
467
+ ps.streaming = false;
468
+ ps.cancelStreaming = null;
469
+ }
470
+ this.emitSessionUpdate(capturedSessionId);
471
+ }
472
+ };
473
+ const bufferText = (text) => {
474
+ textBuffer += text;
475
+ if (!bufferTimer) {
476
+ bufferTimer = setTimeout(flushText, 150);
477
+ }
478
+ if (textBuffer.length > 2048) {
479
+ flushText();
480
+ }
481
+ };
482
+ // Wire up cancel function for this streaming turn
483
+ const setCancelFn = () => {
484
+ if (capturedSessionId) {
485
+ const ps = this.sessions.get(capturedSessionId);
486
+ if (ps) {
487
+ ps.cancelStreaming = () => { cancelled = true; };
488
+ }
489
+ }
490
+ };
491
+ try {
492
+ for await (const message of session.stream()) {
493
+ if (cancelled)
494
+ break;
495
+ // Capture session ID from init message
496
+ if (message.type === 'system' && message.subtype === 'init') {
497
+ capturedSessionId = message.session_id;
498
+ console.log(`[stream] init session=${message.session_id}`);
499
+ onSessionId(message.session_id);
500
+ setCancelFn();
501
+ continue;
502
+ }
503
+ // Session state changed — 'idle' means turn is over
504
+ if (message.type === 'system' && message.subtype === 'session_state_changed') {
505
+ const state = message.state;
506
+ if (state === 'idle') {
507
+ flushText();
508
+ console.log(`[stream] session_state_changed=idle session=${capturedSessionId}`);
509
+ // Don't call onEnd here — the result message will follow
510
+ }
511
+ continue;
512
+ }
513
+ // Streaming partial events
514
+ if (message.type === 'stream_event') {
515
+ const event = message.event;
516
+ if (event?.type === 'content_block_delta') {
517
+ const delta = event.delta;
518
+ if (delta?.type === 'text_delta' && delta.text) {
519
+ bufferText(delta.text);
520
+ }
521
+ }
522
+ continue;
523
+ }
524
+ // Complete assistant messages
525
+ if (message.type === 'assistant') {
526
+ flushText();
527
+ const betaMessage = message.message;
528
+ if (betaMessage?.content) {
529
+ for (const block of betaMessage.content) {
530
+ if (block.type === 'text' && block.text) {
531
+ emitStream({
532
+ eventType: 'assistant_text',
533
+ content: block.text,
534
+ });
535
+ }
536
+ else if (block.type === 'tool_use') {
537
+ const toolInput = JSON.stringify(block.input);
538
+ emitStream({
539
+ eventType: 'tool_use',
540
+ content: '',
541
+ toolName: block.name,
542
+ toolInput,
543
+ });
544
+ }
545
+ }
546
+ }
547
+ continue;
548
+ }
549
+ // User messages contain tool results
550
+ if (message.type === 'user') {
551
+ const userMsg = message.message;
552
+ if (userMsg?.content && Array.isArray(userMsg.content)) {
553
+ for (const block of userMsg.content) {
554
+ if (block.type === 'tool_result') {
555
+ const resultContent = extractToolResultText(block.content);
556
+ const truncated = resultContent.length > TOOL_RESULT_TRUNCATE_LENGTH
557
+ ? resultContent.slice(0, TOOL_RESULT_TRUNCATE_LENGTH) + ' [truncated]'
558
+ : resultContent;
559
+ emitStream({
560
+ eventType: 'tool_result',
561
+ content: truncated,
562
+ });
563
+ }
564
+ }
565
+ }
566
+ continue;
567
+ }
568
+ // Final result — turn is complete but session stays alive
569
+ if (message.type === 'result') {
570
+ flushText();
571
+ const result = message;
572
+ console.log(`[stream] result session=${capturedSessionId} subtype=${result.subtype} cost=$${result.total_cost_usd?.toFixed(4) ?? '?'}`);
573
+ markStreamingDone();
574
+ this.emit('stream:end', {
575
+ sessionId: capturedSessionId ?? '', streamId,
576
+ success: result.subtype === 'success',
577
+ error: result.subtype !== 'success'
578
+ ? (result.errors?.join('; ') || `Session ended: ${result.subtype}`)
579
+ : undefined,
580
+ totalCostUsd: result.total_cost_usd,
581
+ tokenUsage: result.usage
582
+ ? { input: result.usage.input_tokens, output: result.usage.output_tokens }
583
+ : undefined,
584
+ });
585
+ return;
586
+ }
587
+ }
588
+ flushText();
589
+ console.log(`[stream] ended without result session=${capturedSessionId} (cancel or unexpected)`);
590
+ markStreamingDone();
591
+ this.emit('stream:end', { sessionId: capturedSessionId ?? '', streamId, success: true });
592
+ }
593
+ catch (error) {
594
+ flushText();
595
+ console.error(`[stream] error session=${capturedSessionId}:`, error);
596
+ markStreamingDone();
597
+ const msg = error instanceof Error ? error.message : 'Unknown error';
598
+ this.emit('stream:end', { sessionId: capturedSessionId ?? '', streamId, success: false, error: msg });
599
+ }
600
+ }
601
+ }
602
+ //# sourceMappingURL=claudeCodeService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeCodeService.js","sourceRoot":"","sources":["../../src/ai/claudeCodeService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * JSONL persistence for Claude session message history.
3
+ *
4
+ * Each session gets a file at:
5
+ * ~/.quicksave/state/sessions/<session-id>/messages.jsonl
6
+ *
7
+ * One JSON object per line, matching ClaudeHistoryMessage shape.
8
+ * Append-only writes; full-file reads on cold resume.
9
+ */
10
+ import type { ClaudeHistoryMessage } from '@sumicom/quicksave-shared';
11
+ /**
12
+ * Return the directory for a specific session's persistent data.
13
+ * Creates the directory if it doesn't exist.
14
+ */
15
+ export declare function getSessionDir(sessionId: string): string;
16
+ /**
17
+ * Return the path to a session's messages JSONL file.
18
+ */
19
+ export declare function getMessagesFilePath(sessionId: string): string;
20
+ /**
21
+ * Append a single message to the session's JSONL file.
22
+ * Errors are logged, not thrown.
23
+ */
24
+ export declare function appendMessageToJSONL(sessionId: string, message: ClaudeHistoryMessage): void;
25
+ /**
26
+ * Load all messages from a session's JSONL file.
27
+ * Returns empty array if file doesn't exist or is unreadable.
28
+ * Skips malformed lines with a warning.
29
+ */
30
+ export declare function loadMessagesFromJSONL(sessionId: string): ClaudeHistoryMessage[];
31
+ //# sourceMappingURL=sessionStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionStore.d.ts","sourceRoot":"","sources":["../../src/ai/sessionStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEtE;;;GAGG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,oBAAoB,GAC5B,IAAI,CAWN;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,GAChB,oBAAoB,EAAE,CA2BxB"}