@sumicom/quicksave 0.5.2 → 0.6.1

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 (89) hide show
  1. package/dist/ai/asyncQueue.d.ts +17 -0
  2. package/dist/ai/asyncQueue.d.ts.map +1 -0
  3. package/dist/ai/asyncQueue.js +49 -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 +73 -0
  10. package/dist/ai/cardBuilder.d.ts.map +1 -0
  11. package/dist/ai/cardBuilder.js +595 -0
  12. package/dist/ai/cardBuilder.js.map +1 -0
  13. package/dist/ai/claudeCliProvider.d.ts +19 -0
  14. package/dist/ai/claudeCliProvider.d.ts.map +1 -0
  15. package/dist/ai/claudeCliProvider.js +466 -0
  16. package/dist/ai/claudeCliProvider.js.map +1 -0
  17. package/dist/ai/claudeSdkProvider.d.ts +18 -0
  18. package/dist/ai/claudeSdkProvider.d.ts.map +1 -0
  19. package/dist/ai/claudeSdkProvider.js +418 -0
  20. package/dist/ai/claudeSdkProvider.js.map +1 -0
  21. package/dist/ai/commitSummary.d.ts +4 -0
  22. package/dist/ai/commitSummary.d.ts.map +1 -1
  23. package/dist/ai/commitSummary.js +80 -40
  24. package/dist/ai/commitSummary.js.map +1 -1
  25. package/dist/ai/provider.d.ts +54 -0
  26. package/dist/ai/provider.d.ts.map +1 -0
  27. package/dist/ai/provider.js +2 -0
  28. package/dist/ai/provider.js.map +1 -0
  29. package/dist/ai/sandboxMcp.d.ts +12 -0
  30. package/dist/ai/sandboxMcp.d.ts.map +1 -0
  31. package/dist/ai/sandboxMcp.js +12 -0
  32. package/dist/ai/sandboxMcp.js.map +1 -0
  33. package/dist/ai/sandboxMcpStdio.d.ts +16 -0
  34. package/dist/ai/sandboxMcpStdio.d.ts.map +1 -0
  35. package/dist/ai/sandboxMcpStdio.js +127 -0
  36. package/dist/ai/sandboxMcpStdio.js.map +1 -0
  37. package/dist/ai/sessionManager.d.ts +100 -0
  38. package/dist/ai/sessionManager.d.ts.map +1 -0
  39. package/dist/ai/sessionManager.js +595 -0
  40. package/dist/ai/sessionManager.js.map +1 -0
  41. package/dist/ai/sessionRegistry.d.ts +28 -0
  42. package/dist/ai/sessionRegistry.d.ts.map +1 -0
  43. package/dist/ai/sessionRegistry.js +148 -0
  44. package/dist/ai/sessionRegistry.js.map +1 -0
  45. package/dist/connection/connection.d.ts +24 -6
  46. package/dist/connection/connection.d.ts.map +1 -1
  47. package/dist/connection/connection.js +85 -13
  48. package/dist/connection/connection.js.map +1 -1
  49. package/dist/connection/pubsub.d.ts +41 -0
  50. package/dist/connection/pubsub.d.ts.map +1 -0
  51. package/dist/connection/pubsub.js +101 -0
  52. package/dist/connection/pubsub.js.map +1 -0
  53. package/dist/connection/pubsub.test.d.ts +2 -0
  54. package/dist/connection/pubsub.test.d.ts.map +1 -0
  55. package/dist/connection/pubsub.test.js +96 -0
  56. package/dist/connection/pubsub.test.js.map +1 -0
  57. package/dist/git/operations.d.ts +6 -1
  58. package/dist/git/operations.d.ts.map +1 -1
  59. package/dist/git/operations.js +31 -2
  60. package/dist/git/operations.js.map +1 -1
  61. package/dist/handlers/messageHandler.d.ts +25 -5
  62. package/dist/handlers/messageHandler.d.ts.map +1 -1
  63. package/dist/handlers/messageHandler.js +266 -29
  64. package/dist/handlers/messageHandler.js.map +1 -1
  65. package/dist/handlers/messageHandler.test.js +1 -1
  66. package/dist/index.js +192 -41
  67. package/dist/index.js.map +1 -1
  68. package/dist/service/ensureDaemon.d.ts.map +1 -1
  69. package/dist/service/ensureDaemon.js +15 -2
  70. package/dist/service/ensureDaemon.js.map +1 -1
  71. package/dist/service/ipc.test.js +6 -6
  72. package/dist/service/ipcClient.js +1 -1
  73. package/dist/service/run.d.ts.map +1 -1
  74. package/dist/service/run.js +120 -11
  75. package/dist/service/run.js.map +1 -1
  76. package/dist/service/singleton.d.ts +4 -0
  77. package/dist/service/singleton.d.ts.map +1 -1
  78. package/dist/service/singleton.js +28 -2
  79. package/dist/service/singleton.js.map +1 -1
  80. package/dist/service/singleton.test.js +1 -1
  81. package/dist/service/types.d.ts +29 -0
  82. package/dist/service/types.d.ts.map +1 -1
  83. package/dist/service/types.js +11 -0
  84. package/dist/service/types.js.map +1 -1
  85. package/package.json +5 -3
  86. package/dist/ai/claudeCodeService.d.ts +0 -111
  87. package/dist/ai/claudeCodeService.d.ts.map +0 -1
  88. package/dist/ai/claudeCodeService.js +0 -764
  89. package/dist/ai/claudeCodeService.js.map +0 -1
@@ -0,0 +1,595 @@
1
+ import { EventEmitter } from 'events';
2
+ import { resolve, join } from 'path';
3
+ import { readFile, writeFile, mkdir } from 'fs/promises';
4
+ import { DEFAULT_MODEL, matchAllowPattern } from '@sumicom/quicksave-shared';
5
+ import { StreamCardBuilder, buildCardsFromHistory } from './cardBuilder.js';
6
+ import { SANDBOX_BASH_TOOL, SET_TITLE_TOOL } from './sandboxMcp.js';
7
+ import { getSessionRegistry } from './sessionRegistry.js';
8
+ /**
9
+ * Events emitted:
10
+ * 'card-event' (event: CardEvent)
11
+ * 'card-stream-end' (result: CardStreamEnd)
12
+ * 'user-input-request' (request: ClaudeUserInputRequestPayload)
13
+ * 'user-input-resolved' ({ requestId, sessionId })
14
+ * 'session-updated' ({ sessionId, isActive, isStreaming, hasPendingInput, permissionMode })
15
+ * 'preferences-updated' (prefs: ClaudePreferences)
16
+ * 'session-config-updated' ({ sessionId, config: Record<string, ConfigValue> })
17
+ */
18
+ /** Tools auto-approved at each permission level (no user prompt). */
19
+ const AUTO_APPROVE = {
20
+ bypassPermissions: new Set([
21
+ 'Edit', 'Write', 'NotebookEdit', 'TodoWrite', 'Agent', 'EnterWorktree', 'ExitWorktree',
22
+ 'WebFetch', 'WebSearch', 'Bash',
23
+ 'Skill', 'ToolSearch', 'Config',
24
+ 'CronCreate', 'CronDelete', 'CronList', 'RemoteTrigger',
25
+ 'EnterPlanMode', 'ExitPlanMode',
26
+ 'TaskOutput', 'TaskStop',
27
+ ]),
28
+ acceptEdits: new Set(['Edit', 'Write', 'NotebookEdit', 'TodoWrite', 'Agent', 'EnterWorktree', 'ExitWorktree', 'EnterPlanMode']),
29
+ default: new Set(['TodoWrite', 'EnterWorktree', 'ExitWorktree', 'Agent', 'EnterPlanMode']),
30
+ plan: new Set(['EnterPlanMode']),
31
+ };
32
+ const DEFAULT_SYSTEM_PROMPT = [
33
+ 'For non-destructive shell commands (ls, cat, find, git log, git status, git diff, etc.), prefer SandboxBash over Bash. SandboxBash runs in a sandboxed environment. Use Bash only for commands that modify state.',
34
+ 'Call SetTitle to set a descriptive session title when you start a new task or switch context. Keep titles short (e.g. "Fixing auth middleware", "Adding unit tests for UserService"). Update it when the focus changes.',
35
+ ].join('\n\n');
36
+ function buildSystemPrompt(extra) {
37
+ return extra ? `${DEFAULT_SYSTEM_PROMPT}\n\n${extra}` : DEFAULT_SYSTEM_PROMPT;
38
+ }
39
+ export class SessionManager extends EventEmitter {
40
+ sessions = new Map();
41
+ sessionPermissions = new Map();
42
+ sessionSandboxed = new Map();
43
+ sessionConfigs = new Map();
44
+ pendingInputRequests = new Map();
45
+ requestCounter = 0;
46
+ runtimeAllowPatterns = [];
47
+ preferences = { model: DEFAULT_MODEL };
48
+ provider;
49
+ /** SDK-based provider (alternative to CLI). Selected by QUICKSAVE_PROVIDER=sdk env var. */
50
+ sdkProvider;
51
+ /** Guards against concurrent cold resumes. Queues prompts arriving while a spawn is in flight. */
52
+ coldResumeInFlight = new Map();
53
+ constructor(provider, sdkProvider) {
54
+ super();
55
+ this.provider = provider;
56
+ this.sdkProvider = sdkProvider;
57
+ }
58
+ /** Select provider based on QUICKSAVE_PROVIDER env var. Default: CLI. */
59
+ getActiveProvider() {
60
+ if (process.env.QUICKSAVE_PROVIDER === 'sdk' && this.sdkProvider) {
61
+ return this.sdkProvider;
62
+ }
63
+ return this.provider;
64
+ }
65
+ // ── Preferences ──
66
+ async initPreferences() {
67
+ // Model is tracked from the last session's init event via onModelDetected callback.
68
+ }
69
+ getPreferences() {
70
+ return { ...this.preferences };
71
+ }
72
+ setPreferences(prefs) {
73
+ const next = { ...this.preferences };
74
+ let changed = false;
75
+ if (prefs.model !== undefined && prefs.model !== this.preferences.model) {
76
+ next.model = prefs.model;
77
+ changed = true;
78
+ }
79
+ if (prefs.reasoningEffort !== undefined && prefs.reasoningEffort !== this.preferences.reasoningEffort) {
80
+ next.reasoningEffort = prefs.reasoningEffort;
81
+ changed = true;
82
+ }
83
+ if (changed) {
84
+ this.preferences = next;
85
+ this.emit('preferences-updated', this.preferences);
86
+ }
87
+ return { ...this.preferences };
88
+ }
89
+ // ── Session Config ──
90
+ getSessionConfig(sessionId) {
91
+ return { ...this.sessionConfigs.get(sessionId) };
92
+ }
93
+ setSessionConfig(sessionId, key, value) {
94
+ const prev = this.sessionConfigs.get(sessionId) ?? {};
95
+ const next = { ...prev, [key]: value };
96
+ this.sessionConfigs.set(sessionId, next);
97
+ if (key === 'model' && typeof value === 'string') {
98
+ this.setPreferences({ model: value });
99
+ }
100
+ else if (key === 'reasoningEffort' && (typeof value === 'string' || value === null)) {
101
+ this.setPreferences({ reasoningEffort: value });
102
+ }
103
+ else if (key === 'permissionMode' && typeof value === 'string') {
104
+ this.setPermissionLevel(sessionId, value);
105
+ }
106
+ else if (key === 'sandboxed' && typeof value === 'boolean') {
107
+ this.sessionSandboxed.set(sessionId, value);
108
+ const ps = this.sessions.get(sessionId);
109
+ if (ps)
110
+ ps.sandboxed = value;
111
+ }
112
+ this.emit('session-config-updated', { sessionId, config: next });
113
+ return next;
114
+ }
115
+ // ── Session Lifecycle ──
116
+ async startSession(opts) {
117
+ const validModes = ['default', 'acceptEdits', 'bypassPermissions', 'plan'];
118
+ const level = validModes.includes(opts.permissionMode)
119
+ ? opts.permissionMode : 'acceptEdits';
120
+ const sandboxed = !!opts.sandboxed;
121
+ const systemPrompt = buildSystemPrompt(opts.systemPrompt);
122
+ // Create cardBuilder with 'pending' sessionId — will be updated after provider returns real one
123
+ const cardBuilder = new StreamCardBuilder('pending', opts.streamId, opts.cwd);
124
+ const callbacks = this.makeCallbacks('pending');
125
+ const { sessionId, session: providerSession } = await this.getActiveProvider().startSession({
126
+ prompt: opts.prompt,
127
+ cwd: opts.cwd,
128
+ streamId: opts.streamId,
129
+ model: opts.model,
130
+ permissionLevel: level,
131
+ sandboxed,
132
+ systemPrompt,
133
+ }, cardBuilder, callbacks);
134
+ // Update cardBuilder with real sessionId — new session has no prior JSONL
135
+ cardBuilder.updateSessionId(sessionId);
136
+ cardBuilder.jsonlCutoff = 0;
137
+ // Update callbacks to use real sessionId (re-bind the closures)
138
+ // The callbacks are already handed to the provider; for the permission handler
139
+ // we capture `sessionId` from the request parameter, so this is safe.
140
+ // Register session
141
+ this.sessionPermissions.set(sessionId, level);
142
+ if (sandboxed)
143
+ this.sessionSandboxed.set(sessionId, true);
144
+ const prevConfig = this.sessionConfigs.get(sessionId) ?? {};
145
+ this.sessionConfigs.set(sessionId, {
146
+ ...prevConfig,
147
+ model: opts.model ?? DEFAULT_MODEL,
148
+ permissionMode: level,
149
+ sandboxed,
150
+ });
151
+ const managed = {
152
+ sessionId,
153
+ providerSession,
154
+ cwd: opts.cwd,
155
+ streaming: true,
156
+ permissionLevel: level,
157
+ sandboxed,
158
+ cardBuilder,
159
+ };
160
+ this.sessions.set(sessionId, managed);
161
+ this.emitSessionUpdate(sessionId);
162
+ return sessionId;
163
+ }
164
+ async resumeSession(opts) {
165
+ const existing = this.sessions.get(opts.sessionId);
166
+ // Hot resume: session is streaming and provider session is alive
167
+ if (existing?.streaming && existing.providerSession?.alive) {
168
+ console.log(`[session-manager] hot resume session=${opts.sessionId.slice(0, 8)} streaming=true`);
169
+ // Add user prompt to cardBuilder for getCards on reconnect
170
+ if (existing.cardBuilder) {
171
+ existing.cardBuilder.userMessage(opts.prompt);
172
+ }
173
+ // Queue the streamId so consumeStream picks it up after the current turn's result
174
+ const ps = existing.providerSession;
175
+ if (ps.pendingStreamIds) {
176
+ ps.pendingStreamIds.push(opts.streamId);
177
+ }
178
+ existing.providerSession.sendUserMessage(opts.prompt);
179
+ return opts.sessionId;
180
+ }
181
+ // Cold resume already in flight — queue the prompt instead of spawning again
182
+ const inFlight = this.coldResumeInFlight.get(opts.sessionId);
183
+ if (inFlight) {
184
+ console.log(`[session-manager] cold resume in flight, queuing prompt for session=${opts.sessionId.slice(0, 8)}`);
185
+ inFlight.queuedPrompts.push(opts.prompt);
186
+ return opts.sessionId;
187
+ }
188
+ // Cold resume: mark as in-flight, then delegate to provider
189
+ console.log(`[session-manager] cold resume session=${opts.sessionId.slice(0, 8)}`);
190
+ const flight = { queuedPrompts: [] };
191
+ this.coldResumeInFlight.set(opts.sessionId, flight);
192
+ try {
193
+ const level = this.sessionPermissions.get(opts.sessionId) ?? 'acceptEdits';
194
+ const sandboxed = this.sessionSandboxed.get(opts.sessionId) ?? false;
195
+ const cardBuilder = existing?.cardBuilder ?? new StreamCardBuilder(opts.sessionId, opts.streamId, opts.cwd);
196
+ await cardBuilder.snapshotCutoff();
197
+ const callbacks = this.makeCallbacks(opts.sessionId);
198
+ const { sessionId, session: providerSession } = await this.getActiveProvider().resumeSession({
199
+ sessionId: opts.sessionId,
200
+ prompt: opts.prompt,
201
+ cwd: opts.cwd,
202
+ streamId: opts.streamId,
203
+ permissionLevel: level,
204
+ sandboxed,
205
+ systemPrompt: buildSystemPrompt(),
206
+ }, cardBuilder, callbacks);
207
+ // Update or create session entry
208
+ if (existing) {
209
+ existing.providerSession = providerSession;
210
+ existing.streaming = true;
211
+ }
212
+ else {
213
+ const managed = {
214
+ sessionId,
215
+ providerSession,
216
+ cwd: opts.cwd,
217
+ streaming: true,
218
+ permissionLevel: level,
219
+ sandboxed,
220
+ cardBuilder,
221
+ };
222
+ this.sessions.set(sessionId, managed);
223
+ }
224
+ this.emitSessionUpdate(sessionId);
225
+ // Drain queued prompts that arrived while spawning
226
+ for (const queued of flight.queuedPrompts) {
227
+ console.log(`[session-manager] draining queued prompt for session=${sessionId.slice(0, 8)}`);
228
+ providerSession.sendUserMessage(queued);
229
+ }
230
+ return sessionId;
231
+ }
232
+ finally {
233
+ this.coldResumeInFlight.delete(opts.sessionId);
234
+ }
235
+ }
236
+ async cancelSession(sessionId) {
237
+ const ps = this.sessions.get(sessionId);
238
+ if (!ps?.providerSession)
239
+ return false;
240
+ console.log(`[session-manager] cancel session=${sessionId.slice(0, 8)}`);
241
+ ps.providerSession.interrupt();
242
+ return true;
243
+ }
244
+ closeSession(sessionId) {
245
+ const ps = this.sessions.get(sessionId);
246
+ if (!ps)
247
+ return false;
248
+ if (ps.providerSession) {
249
+ ps.providerSession.kill();
250
+ ps.providerSession = null;
251
+ }
252
+ this.sessions.delete(sessionId);
253
+ this.emitSessionUpdate(sessionId);
254
+ return true;
255
+ }
256
+ // ── Permission ──
257
+ setPermissionLevel(sessionId, level) {
258
+ const ps = this.sessions.get(sessionId);
259
+ if (ps)
260
+ ps.permissionLevel = level;
261
+ this.sessionPermissions.set(sessionId, level);
262
+ this.emit('session-updated', {
263
+ sessionId,
264
+ isActive: !!ps,
265
+ isStreaming: ps?.streaming ?? false,
266
+ hasPendingInput: ps ? Array.from(this.pendingInputRequests.values()).some(p => p.request.sessionId === sessionId) : false,
267
+ permissionMode: level,
268
+ });
269
+ return true;
270
+ }
271
+ getPermissionLevel(sessionId) {
272
+ return this.sessions.get(sessionId)?.permissionLevel ?? 'acceptEdits';
273
+ }
274
+ resolveUserInput(response) {
275
+ const pending = this.pendingInputRequests.get(response.requestId);
276
+ if (!pending)
277
+ return false;
278
+ this.pendingInputRequests.delete(response.requestId);
279
+ pending.resolve(response);
280
+ // Clear pending input on the card
281
+ const ps = this.sessions.get(pending.request.sessionId);
282
+ if (ps?.cardBuilder) {
283
+ const cardEvt = ps.cardBuilder.clearPendingInput(response.requestId);
284
+ if (cardEvt)
285
+ this.emit('card-event', cardEvt);
286
+ }
287
+ // Persist allow pattern to settings.local.json if provided
288
+ if (response.allowPattern && ps?.cwd) {
289
+ this.persistAllowPattern(ps.cwd, response.allowPattern).catch((err) => {
290
+ console.error('[persistAllowPattern] failed:', err);
291
+ });
292
+ }
293
+ this.emit('user-input-resolved', { requestId: response.requestId, sessionId: pending.request.sessionId });
294
+ this.emitSessionUpdate(pending.request.sessionId);
295
+ return true;
296
+ }
297
+ // ── Query ──
298
+ getActiveSessions() {
299
+ const pendingSessionIds = new Set(Array.from(this.pendingInputRequests.values()).map(p => p.request.sessionId));
300
+ return Array.from(this.sessions.entries()).map(([id, ps]) => ({
301
+ sessionId: id,
302
+ cwd: ps.cwd,
303
+ isStreaming: ps.streaming,
304
+ hasPendingInput: pendingSessionIds.has(id),
305
+ permissionMode: ps.permissionLevel,
306
+ sandboxed: ps.sandboxed || undefined,
307
+ }));
308
+ }
309
+ isStreaming(sessionId) {
310
+ return this.sessions.get(sessionId)?.streaming ?? false;
311
+ }
312
+ isOpen(sessionId) {
313
+ return this.sessions.has(sessionId);
314
+ }
315
+ getSessionCwd(sessionId) {
316
+ return this.sessions.get(sessionId)?.cwd;
317
+ }
318
+ getActiveSessionCount() {
319
+ return this.sessions.size;
320
+ }
321
+ getCardBuilder(sessionId) {
322
+ return this.sessions.get(sessionId)?.cardBuilder ?? null;
323
+ }
324
+ async listAvailableSessions(cwd) {
325
+ const registry = getSessionRegistry();
326
+ const registryEntries = registry.getEntriesForProject(cwd);
327
+ const pendingSessionIds = new Set(Array.from(this.pendingInputRequests.values()).map(p => p.request.sessionId));
328
+ return registryEntries.map(entry => ({
329
+ sessionId: entry.sessionId,
330
+ summary: entry.title ?? entry.firstPrompt ?? entry.sessionId.slice(0, 8),
331
+ lastModified: entry.lastAccessedAt,
332
+ createdAt: entry.createdAt,
333
+ cwd: entry.cwd,
334
+ gitBranch: entry.gitBranch,
335
+ messageCount: entry.messageCount,
336
+ isActive: this.sessions.has(entry.sessionId),
337
+ isStreaming: this.sessions.get(entry.sessionId)?.streaming ?? false,
338
+ hasPendingInput: pendingSessionIds.has(entry.sessionId),
339
+ permissionMode: this.sessions.get(entry.sessionId)?.permissionLevel
340
+ ?? this.sessionPermissions.get(entry.sessionId),
341
+ }));
342
+ }
343
+ async getCards(sessionId, cwd, offset = 0, limit = 50) {
344
+ const ps = this.sessions.get(sessionId);
345
+ const cutoff = ps?.cardBuilder?.jsonlCutoff ?? undefined;
346
+ // Read JSONL history up to the cutoff (excludes the active turn's messages).
347
+ const result = await buildCardsFromHistory(sessionId, cwd, offset, limit, cutoff);
348
+ // Append in-memory cards for the active turn — no overlap, no dedup needed.
349
+ if (ps?.cardBuilder) {
350
+ const streamingCards = ps.cardBuilder.getCards();
351
+ if (streamingCards.length > 0) {
352
+ result.cards.push(...streamingCards);
353
+ result.total += streamingCards.length;
354
+ }
355
+ }
356
+ // Overlay pending inputs from pendingInputRequests onto matching cards.
357
+ const pendingByToolUseId = new Map();
358
+ for (const [, pending] of this.pendingInputRequests) {
359
+ if (pending.request.sessionId === sessionId && pending.request.toolUseId) {
360
+ pendingByToolUseId.set(pending.request.toolUseId, {
361
+ sessionId: pending.request.sessionId,
362
+ requestId: pending.request.requestId,
363
+ inputType: pending.request.inputType,
364
+ title: pending.request.title,
365
+ message: pending.request.message,
366
+ options: pending.request.options,
367
+ });
368
+ }
369
+ }
370
+ if (pendingByToolUseId.size > 0) {
371
+ for (const card of result.cards) {
372
+ if (card.type === 'tool_call' && card.toolUseId) {
373
+ const pending = pendingByToolUseId.get(card.toolUseId);
374
+ if (pending && !card.pendingInput) {
375
+ card.pendingInput = pending;
376
+ }
377
+ }
378
+ }
379
+ }
380
+ // Attach session title from config or registry
381
+ const configTitle = this.sessionConfigs.get(sessionId)?.title;
382
+ if (configTitle) {
383
+ result.title = configTitle;
384
+ }
385
+ else {
386
+ const registry = getSessionRegistry();
387
+ const entry = registry.getEntry(cwd, sessionId);
388
+ if (entry?.title)
389
+ result.title = entry.title;
390
+ }
391
+ return result;
392
+ }
393
+ getPendingInputRequests() {
394
+ return Array.from(this.pendingInputRequests.values()).map(p => p.request);
395
+ }
396
+ getDebugState() {
397
+ const pendingInputs = Array.from(this.pendingInputRequests.values()).map(p => ({
398
+ requestId: p.request.requestId,
399
+ sessionId: p.request.sessionId,
400
+ toolName: p.request.toolName,
401
+ agentId: p.request.agentId,
402
+ inputType: p.request.inputType,
403
+ }));
404
+ return { pendingInputs, activeSessions: this.getActiveSessions() };
405
+ }
406
+ cleanup() {
407
+ for (const [requestId, pending] of this.pendingInputRequests) {
408
+ pending.resolve({ sessionId: '', requestId, action: 'allow' });
409
+ }
410
+ this.pendingInputRequests.clear();
411
+ for (const [, ps] of this.sessions) {
412
+ if (ps.providerSession) {
413
+ try {
414
+ ps.providerSession.kill();
415
+ }
416
+ catch { }
417
+ ps.providerSession = null;
418
+ }
419
+ }
420
+ this.sessions.clear();
421
+ }
422
+ // ── Private: Callbacks Factory ──
423
+ makeCallbacks(_initialSessionId) {
424
+ return {
425
+ emitCardEvent: (event) => {
426
+ this.emit('card-event', event);
427
+ },
428
+ emitStreamEnd: (result) => {
429
+ this.emit('card-stream-end', result);
430
+ // Update session streaming state
431
+ const ps = this.sessions.get(result.sessionId);
432
+ if (ps) {
433
+ ps.streaming = false;
434
+ this.emitSessionUpdate(result.sessionId);
435
+ }
436
+ },
437
+ handlePermissionRequest: async (sessionId, req) => {
438
+ return this.handlePermissionRequest(sessionId, req);
439
+ },
440
+ onModelDetected: (model) => {
441
+ this.preferences.model = model;
442
+ },
443
+ };
444
+ }
445
+ // ── Private: Permission Handling ──
446
+ async handlePermissionRequest(sessionId, req) {
447
+ const { toolName, toolInput, toolUseId } = req;
448
+ // Check auto-approve rules first
449
+ if (this.shouldAutoApprove(sessionId, toolName, toolInput)) {
450
+ return { action: 'allow' };
451
+ }
452
+ // Check runtime allow patterns
453
+ if (this.runtimeAllowPatterns.some(p => matchAllowPattern(p, toolName, toolInput))) {
454
+ return { action: 'allow' };
455
+ }
456
+ // Forward to PWA for user decision
457
+ const requestId = `perm-${++this.requestCounter}`;
458
+ const isQuestion = toolName === 'AskUserQuestion';
459
+ const questions = isQuestion ? toolInput.questions : undefined;
460
+ const request = {
461
+ sessionId,
462
+ requestId,
463
+ inputType: isQuestion ? 'question' : 'permission',
464
+ title: isQuestion
465
+ ? questions?.[0]?.question ?? 'Question from Claude'
466
+ : `Allow ${toolName}?`,
467
+ message: isQuestion ? undefined : JSON.stringify(toolInput).slice(0, 500),
468
+ toolName,
469
+ toolInput,
470
+ toolUseId,
471
+ ...(isQuestion && questions ? {
472
+ options: questions.flatMap((q) => (q.options ?? []).map((opt) => ({
473
+ key: opt.label,
474
+ label: opt.label,
475
+ description: opt.description,
476
+ }))),
477
+ } : {}),
478
+ };
479
+ // Create card with pending input
480
+ const ps = this.sessions.get(sessionId);
481
+ const cb = ps?.cardBuilder;
482
+ if (cb) {
483
+ const pendingAttachment = {
484
+ sessionId,
485
+ requestId,
486
+ inputType: request.inputType,
487
+ title: request.title,
488
+ message: request.message,
489
+ options: request.options,
490
+ };
491
+ const cardEvt = cb.toolCallFromPermission(toolName, toolInput, toolUseId, pendingAttachment);
492
+ this.emit('card-event', cardEvt);
493
+ }
494
+ this.emit('user-input-request', request);
495
+ // Wait for user response
496
+ const response = await this.waitForUserInput(requestId, request);
497
+ if (response.action === 'deny') {
498
+ return { action: 'deny', response: response.response || 'User denied permission' };
499
+ }
500
+ // For AskUserQuestion, inject answer
501
+ if (isQuestion && response.response) {
502
+ const answers = {};
503
+ if (questions?.[0]?.question) {
504
+ answers[questions[0].question] = response.response;
505
+ }
506
+ return { action: 'allow', updatedInput: { ...toolInput, answers } };
507
+ }
508
+ return { action: 'allow' };
509
+ }
510
+ shouldAutoApprove(sessionId, toolName, input) {
511
+ // SetTitle — always approve
512
+ if (toolName === SET_TITLE_TOOL) {
513
+ if (input.title)
514
+ this.updateSessionTitle(sessionId, input.title);
515
+ return true;
516
+ }
517
+ // SandboxBash: auto-approve when sandboxed, otherwise check as Bash
518
+ if (toolName === SANDBOX_BASH_TOOL) {
519
+ if (this.sessions.get(sessionId)?.sandboxed)
520
+ return true;
521
+ toolName = 'Bash'; // fall through to permission check as Bash
522
+ }
523
+ // Check permission level auto-approve set
524
+ const level = this.sessions.get(sessionId)?.permissionLevel
525
+ ?? this.sessionPermissions.get(sessionId) ?? 'acceptEdits';
526
+ if (!AUTO_APPROVE[level].has(toolName))
527
+ return false;
528
+ // For file-writing tools, restrict to project cwd
529
+ const FILE_WRITE_TOOLS = new Set(['Write', 'Edit', 'NotebookEdit']);
530
+ if (FILE_WRITE_TOOLS.has(toolName)) {
531
+ const cwd = this.sessions.get(sessionId)?.cwd;
532
+ const filePath = (input.file_path ?? input.path);
533
+ if (filePath && cwd) {
534
+ const resolvedFile = resolve(filePath);
535
+ const resolvedCwd = resolve(cwd);
536
+ return resolvedFile === resolvedCwd || resolvedFile.startsWith(resolvedCwd + '/');
537
+ }
538
+ }
539
+ return true;
540
+ }
541
+ /** Update session title (triggered by SetTitle MCP tool). */
542
+ updateSessionTitle(sessionId, title) {
543
+ const config = this.sessionConfigs.get(sessionId) ?? {};
544
+ this.sessionConfigs.set(sessionId, { ...config, title });
545
+ this.emit('session-config-updated', { sessionId, config: this.sessionConfigs.get(sessionId) });
546
+ // Update session registry so it persists across restarts
547
+ const ps = this.sessions.get(sessionId);
548
+ if (ps?.cwd) {
549
+ const registry = getSessionRegistry();
550
+ const entry = registry.getEntry(ps.cwd, sessionId);
551
+ if (entry) {
552
+ registry.upsertEntry({ ...entry, title, lastAccessedAt: Date.now() });
553
+ }
554
+ }
555
+ }
556
+ emitSessionUpdate(sessionId) {
557
+ const ps = this.sessions.get(sessionId);
558
+ const hasPendingInput = Array.from(this.pendingInputRequests.values())
559
+ .some(p => p.request.sessionId === sessionId);
560
+ this.emit('session-updated', {
561
+ sessionId,
562
+ isActive: !!ps,
563
+ isStreaming: ps?.streaming ?? false,
564
+ hasPendingInput,
565
+ permissionMode: ps?.permissionLevel ?? this.sessionPermissions.get(sessionId),
566
+ sandboxed: ps?.sandboxed ?? this.sessionSandboxed.get(sessionId) ?? false,
567
+ });
568
+ }
569
+ async persistAllowPattern(cwd, pattern) {
570
+ if (!this.runtimeAllowPatterns.includes(pattern)) {
571
+ this.runtimeAllowPatterns.push(pattern);
572
+ }
573
+ const settingsPath = join(cwd, '.claude', 'settings.local.json');
574
+ let settings = {};
575
+ try {
576
+ settings = JSON.parse(await readFile(settingsPath, 'utf-8'));
577
+ }
578
+ catch { /* file doesn't exist yet */ }
579
+ const permissions = settings.permissions ?? {};
580
+ const allow = Array.isArray(permissions.allow) ? [...permissions.allow] : [];
581
+ if (!allow.includes(pattern)) {
582
+ allow.push(pattern);
583
+ settings.permissions = { ...permissions, allow };
584
+ await mkdir(join(cwd, '.claude'), { recursive: true });
585
+ await writeFile(settingsPath, JSON.stringify(settings, null, 2) + '\n');
586
+ console.log(`[persistAllowPattern] saved ${pattern} to ${settingsPath}`);
587
+ }
588
+ }
589
+ waitForUserInput(requestId, request) {
590
+ return new Promise((resolve) => {
591
+ this.pendingInputRequests.set(requestId, { resolve, request });
592
+ });
593
+ }
594
+ }
595
+ //# sourceMappingURL=sessionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionManager.js","sourceRoot":"","sources":["../../src/ai/sessionManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Session registry — tracks which sessions have been opened via quicksave.
3
+ *
4
+ * Storage layout:
5
+ * ~/.quicksave/state/session-registry/{encoded-project-path}/{sessionId}.json
6
+ *
7
+ * Path encoding: `/` → `-` (same convention as Claude Code's ~/.claude/projects/).
8
+ *
9
+ * In-memory: two-level Map<cwd, Map<sessionId, entry>>.
10
+ * Loaded once at daemon startup; writes update memory + single file synchronously.
11
+ */
12
+ import type { SessionRegistryEntry } from '@sumicom/quicksave-shared';
13
+ export declare class SessionRegistry {
14
+ private registry;
15
+ /**
16
+ * Scan session-registry directory and load all entries into memory.
17
+ */
18
+ loadAll(): void;
19
+ getEntry(cwd: string, sessionId: string): SessionRegistryEntry | undefined;
20
+ getEntriesForProject(cwd?: string): SessionRegistryEntry[];
21
+ upsertEntry(entry: SessionRegistryEntry): void;
22
+ updateEntry(cwd: string, sessionId: string, updates: Partial<SessionRegistryEntry>): SessionRegistryEntry | null;
23
+ deleteEntry(cwd: string, sessionId: string): boolean;
24
+ private setInMemory;
25
+ private writeToDisk;
26
+ }
27
+ export declare function getSessionRegistry(): SessionRegistry;
28
+ //# sourceMappingURL=sessionRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionRegistry.d.ts","sourceRoot":"","sources":["../../src/ai/sessionRegistry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAaH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAMtE,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAwD;IAExE;;OAEG;IACH,OAAO,IAAI,IAAI;IA8Cf,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAI1E,oBAAoB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,oBAAoB,EAAE;IAgB1D,WAAW,CAAC,KAAK,EAAE,oBAAoB,GAAG,IAAI;IAK9C,WAAW,CACT,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,CAAC,oBAAoB,CAAC,GACrC,oBAAoB,GAAG,IAAI;IAQ9B,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAoBpD,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,WAAW;CAepB;AAID,wBAAgB,kBAAkB,IAAI,eAAe,CAMpD"}