@shardworks/claude-code-apparatus 0.1.148 → 0.1.150

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.
@@ -0,0 +1,471 @@
1
+ /**
2
+ * Session Babysitter — detached process that hosts a claude session.
3
+ *
4
+ * A standalone Node.js script that:
5
+ * 1. Reads config from stdin (spawned by the claude-code provider)
6
+ * 2. Opens the guild's SQLite database for transcript streaming
7
+ * 3. Starts an MCP/SSE server that proxies tool calls to the guild
8
+ * 4. Spawns claude with prepared session files
9
+ * 5. Reports session lifecycle events via the guild's HTTP API
10
+ * 6. Streams transcript data to SQLite in real-time
11
+ * 7. Reports the final result and cleans up
12
+ *
13
+ * The babysitter is a detached process: it survives guild restarts.
14
+ * All guild communication is via HTTP (tool server) and SQLite (transcripts).
15
+ *
16
+ * See: docs/architecture/detached-sessions.md
17
+ */
18
+ import { spawn } from 'node:child_process';
19
+ import fs from 'node:fs';
20
+ import os from 'node:os';
21
+ import path from 'node:path';
22
+ import http from 'node:http';
23
+ import { fileURLToPath } from 'node:url';
24
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
25
+ import { ListToolsRequestSchema, CallToolRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
26
+ import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
27
+ import { toolNameToRoute } from '@shardworks/tools-apparatus';
28
+ import { processNdjsonBuffer, parseStreamJsonMessage, extractFinalAssistantText, } from "./index.js";
29
+ // ── Retry constants ─────────────────────────────────────────────────────
30
+ const RETRY_INITIAL_DELAY_MS = 1_000;
31
+ const RETRY_MAX_DELAY_MS = 8_000;
32
+ const RETRY_TIMEOUT_MS = 60_000;
33
+ const RETRYABLE_CODES = new Set(['ECONNREFUSED', 'ECONNRESET', 'ETIMEDOUT']);
34
+ // ── stdin config reader ─────────────────────────────────────────────────
35
+ /**
36
+ * Read the babysitter config from stdin.
37
+ *
38
+ * Reads stdin to completion, parses the JSON, and validates required fields.
39
+ * The spawning process writes config and closes the write end.
40
+ */
41
+ export async function readConfigFromStdin(stream = process.stdin) {
42
+ const chunks = [];
43
+ for await (const chunk of stream) {
44
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
45
+ }
46
+ const raw = Buffer.concat(chunks).toString('utf-8');
47
+ if (!raw.trim()) {
48
+ throw new Error('Empty config received on stdin');
49
+ }
50
+ let parsed;
51
+ try {
52
+ parsed = JSON.parse(raw);
53
+ }
54
+ catch {
55
+ throw new Error(`Invalid JSON config on stdin: ${raw.slice(0, 200)}`);
56
+ }
57
+ const config = parsed;
58
+ // Validate required fields
59
+ const required = [
60
+ 'sessionId', 'guildToolUrl', 'dbPath', 'claudeArgs',
61
+ 'cwd', 'env', 'prompt', 'tools', 'startedAt', 'provider',
62
+ ];
63
+ for (const field of required) {
64
+ if (config[field] === undefined || config[field] === null) {
65
+ throw new Error(`Missing required config field: ${field}`);
66
+ }
67
+ }
68
+ return config;
69
+ }
70
+ // ── HTTP retry helper ───────────────────────────────────────────────────
71
+ /**
72
+ * Call a guild HTTP API endpoint with exponential backoff retry.
73
+ *
74
+ * Retries on connection errors (ECONNREFUSED, ECONNRESET, ETIMEDOUT).
75
+ * Returns the parsed JSON response on success.
76
+ * Throws after RETRY_TIMEOUT_MS of retrying.
77
+ */
78
+ export async function callGuildHttpApi(url, sessionId, body, timeoutMs = RETRY_TIMEOUT_MS) {
79
+ const startTime = Date.now();
80
+ let delay = RETRY_INITIAL_DELAY_MS;
81
+ let lastError;
82
+ while (Date.now() - startTime < timeoutMs) {
83
+ try {
84
+ const response = await fetch(url, {
85
+ method: 'POST',
86
+ headers: {
87
+ 'Content-Type': 'application/json',
88
+ 'X-Session-Id': sessionId,
89
+ },
90
+ body: JSON.stringify(body),
91
+ });
92
+ if (!response.ok) {
93
+ const text = await response.text().catch(() => '');
94
+ throw new Error(`HTTP ${response.status}: ${text.slice(0, 500)}`);
95
+ }
96
+ return await response.json();
97
+ }
98
+ catch (err) {
99
+ lastError = err instanceof Error ? err : new Error(String(err));
100
+ // Check if the error is retryable (connection-level error)
101
+ const code = err.code;
102
+ const cause = err.cause;
103
+ const causeCode = cause?.code;
104
+ const isRetryable = (code && RETRYABLE_CODES.has(code)) ||
105
+ (causeCode && RETRYABLE_CODES.has(causeCode)) ||
106
+ (lastError.message.includes('fetch failed'));
107
+ if (!isRetryable) {
108
+ throw lastError;
109
+ }
110
+ // Wait before retrying
111
+ const remaining = timeoutMs - (Date.now() - startTime);
112
+ if (remaining <= 0)
113
+ break;
114
+ await new Promise((resolve) => setTimeout(resolve, Math.min(delay, remaining)));
115
+ delay = Math.min(delay * 2, RETRY_MAX_DELAY_MS);
116
+ }
117
+ }
118
+ throw new Error(`Guild HTTP API unreachable after ${timeoutMs}ms: ${lastError?.message ?? 'unknown error'}`);
119
+ }
120
+ // ── DLQ writer ──────────────────────────────────────────────────────────
121
+ /**
122
+ * Write a payload to the Dead Letter Queue.
123
+ *
124
+ * Creates the DLQ directory if it doesn't exist. Writes the payload as
125
+ * pretty-printed JSON. Used as a fallback when the guild HTTP API is
126
+ * unreachable for lifecycle calls.
127
+ */
128
+ export function writeToDlq(cwd, filename, payload) {
129
+ const dlqDir = path.join(cwd, '.nexus', 'dlq');
130
+ fs.mkdirSync(dlqDir, { recursive: true });
131
+ fs.writeFileSync(path.join(dlqDir, filename), JSON.stringify(payload, null, 2));
132
+ }
133
+ // ── MCP proxy server ────────────────────────────────────────────────────
134
+ /**
135
+ * Create an MCP/SSE HTTP server that proxies tool calls to the guild.
136
+ *
137
+ * For each tool in the config, registers an MCP tool whose handler
138
+ * forwards the call to the guild's Tool HTTP API via HTTP POST.
139
+ *
140
+ * Uses the low-level MCP Server class to register tools with raw
141
+ * JSON Schema (the serialized params from the config).
142
+ */
143
+ export async function createProxyMcpHttpServer(tools, guildToolUrl, sessionId) {
144
+ const server = new Server({ name: 'nexus-guild-proxy', version: '0.0.0' }, { capabilities: { tools: {} } });
145
+ // Register tools/list handler — advertises all tools with their JSON Schema.
146
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
147
+ tools: tools.map((t) => ({
148
+ name: t.name,
149
+ description: t.description,
150
+ inputSchema: {
151
+ type: 'object',
152
+ ...t.params,
153
+ },
154
+ })),
155
+ }));
156
+ // Register tools/call handler — proxies each call to the guild HTTP API.
157
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
158
+ const toolName = request.params.name;
159
+ const params = request.params.arguments ?? {};
160
+ const route = toolNameToRoute(toolName);
161
+ const url = `${guildToolUrl}${route}`;
162
+ try {
163
+ const result = await callGuildHttpApi(url, sessionId, params);
164
+ const text = typeof result === 'string' ? result : JSON.stringify(result, null, 2);
165
+ return {
166
+ content: [{ type: 'text', text }],
167
+ };
168
+ }
169
+ catch (err) {
170
+ const message = err instanceof Error ? err.message : String(err);
171
+ return {
172
+ content: [{ type: 'text', text: `Error: ${message}` }],
173
+ isError: true,
174
+ };
175
+ }
176
+ });
177
+ // Wrap in HTTP server with SSE transport (same pattern as mcp-server.ts).
178
+ let transport = null;
179
+ const httpServer = http.createServer(async (req, res) => {
180
+ try {
181
+ if (req.method === 'GET' && req.url === '/sse') {
182
+ transport = new SSEServerTransport('/message', res);
183
+ await server.connect(transport);
184
+ }
185
+ else if (req.method === 'POST' && req.url?.startsWith('/message')) {
186
+ if (!transport) {
187
+ res.writeHead(400).end('No active SSE connection');
188
+ return;
189
+ }
190
+ await transport.handlePostMessage(req, res);
191
+ }
192
+ else {
193
+ res.writeHead(404).end('Not found');
194
+ }
195
+ }
196
+ catch {
197
+ if (!res.headersSent) {
198
+ res.writeHead(500).end('Internal Server Error');
199
+ }
200
+ }
201
+ });
202
+ await new Promise((resolve) => {
203
+ httpServer.listen(0, '127.0.0.1', resolve);
204
+ });
205
+ const addr = httpServer.address();
206
+ if (!addr || typeof addr === 'string') {
207
+ throw new Error('Failed to get MCP proxy server address');
208
+ }
209
+ const url = `http://127.0.0.1:${addr.port}/sse`;
210
+ return {
211
+ url,
212
+ async close() {
213
+ if (transport) {
214
+ await transport.close();
215
+ }
216
+ await new Promise((resolve, reject) => {
217
+ httpServer.close((err) => (err ? reject(err) : resolve()));
218
+ });
219
+ },
220
+ };
221
+ }
222
+ /**
223
+ * Open the guild's SQLite database for transcript streaming.
224
+ *
225
+ * Creates the database file and table if they don't exist.
226
+ * Enables WAL mode for concurrent read access by other processes
227
+ * (Oculus, CLI queries, other agents).
228
+ *
229
+ * Uses dynamic import() to load better-sqlite3 at runtime. This avoids
230
+ * requiring the native module at import time (beneficial for type-checking
231
+ * and testing).
232
+ */
233
+ export async function openTranscriptDb(dbPath) {
234
+ const { default: Database } = await import('better-sqlite3');
235
+ return initTranscriptDb(Database, dbPath);
236
+ }
237
+ /**
238
+ * Initialize a TranscriptDb from a Database constructor.
239
+ *
240
+ * Shared logic between openTranscriptDb() and test injection.
241
+ * Exported for testing — allows injecting a mock Database constructor.
242
+ */
243
+ export function initTranscriptDb(DatabaseConstructor, dbPath) {
244
+ const raw = new DatabaseConstructor(dbPath);
245
+ raw.pragma('journal_mode = WAL');
246
+ raw.exec(`
247
+ CREATE TABLE IF NOT EXISTS books_animator_transcripts (
248
+ id TEXT PRIMARY KEY,
249
+ content TEXT NOT NULL
250
+ )
251
+ `);
252
+ const stmt = raw.prepare('INSERT OR REPLACE INTO books_animator_transcripts (id, content) VALUES (?, ?)');
253
+ return {
254
+ writeTranscript(sessionId, content) {
255
+ stmt.run(sessionId, content);
256
+ },
257
+ close() {
258
+ raw.close();
259
+ },
260
+ };
261
+ }
262
+ /**
263
+ * Write the current transcript to SQLite.
264
+ */
265
+ export function writeTranscript(db, sessionId, messages) {
266
+ const content = JSON.stringify({ id: sessionId, messages });
267
+ db.writeTranscript(sessionId, content);
268
+ }
269
+ // ── Session lifecycle reporting ─────────────────────────────────────────
270
+ /**
271
+ * Report "running" status to the guild via the session-running tool.
272
+ *
273
+ * If the guild is unreachable, writes the payload to the DLQ.
274
+ */
275
+ export async function reportRunning(config, claudePid, timeoutMs) {
276
+ const route = toolNameToRoute('session-running');
277
+ const url = `${config.guildToolUrl}${route}`;
278
+ const payload = {
279
+ sessionId: config.sessionId,
280
+ startedAt: config.startedAt,
281
+ provider: config.provider,
282
+ metadata: config.metadata,
283
+ cancelMetadata: { pid: claudePid },
284
+ };
285
+ try {
286
+ await callGuildHttpApi(url, config.sessionId, payload, timeoutMs);
287
+ }
288
+ catch {
289
+ writeToDlq(config.cwd, `${config.sessionId}-running.json`, payload);
290
+ }
291
+ }
292
+ /**
293
+ * Report the final session result to the guild via the session-record tool.
294
+ *
295
+ * If the guild is unreachable, writes the payload to the DLQ.
296
+ */
297
+ export async function reportResult(config, result, transcript, timeoutMs) {
298
+ const route = toolNameToRoute('session-record');
299
+ const url = `${config.guildToolUrl}${route}`;
300
+ const status = result.exitCode === 0 ? 'completed' : 'failed';
301
+ const output = extractFinalAssistantText(transcript);
302
+ const payload = {
303
+ sessionId: config.sessionId,
304
+ status,
305
+ exitCode: result.exitCode,
306
+ error: status === 'failed' ? `claude exited with code ${result.exitCode}` : undefined,
307
+ costUsd: result.costUsd,
308
+ tokenUsage: result.tokenUsage,
309
+ output,
310
+ providerSessionId: result.providerSessionId,
311
+ transcript,
312
+ };
313
+ try {
314
+ await callGuildHttpApi(url, config.sessionId, payload, timeoutMs);
315
+ }
316
+ catch {
317
+ writeToDlq(config.cwd, `${config.sessionId}.json`, payload);
318
+ }
319
+ }
320
+ // ── Main babysitter function ────────────────────────────────────────────
321
+ /**
322
+ * Run the session babysitter.
323
+ *
324
+ * This is the main orchestration function. It:
325
+ * 1. Opens SQLite for transcript streaming
326
+ * 2. Starts the MCP proxy server
327
+ * 3. Prepares session files (tmpDir, system prompt, mcp-config)
328
+ * 4. Spawns claude
329
+ * 5. Reports "running" status
330
+ * 6. Streams transcript to SQLite
331
+ * 7. Reports result on exit
332
+ * 8. Cleans up
333
+ */
334
+ export async function runBabysitter(config, deps) {
335
+ const spawnFn = deps?.spawnFn ?? spawn;
336
+ const retryTimeoutMs = deps?.retryTimeoutMs;
337
+ let db = null;
338
+ let mcpHandle = null;
339
+ let tmpDir = null;
340
+ let claudeProc = null;
341
+ try {
342
+ // 1. Open SQLite
343
+ db = deps?.db ?? await openTranscriptDb(config.dbPath);
344
+ // 2. Start MCP proxy server
345
+ mcpHandle = await createProxyMcpHttpServer(config.tools, config.guildToolUrl, config.sessionId);
346
+ // 3. Prepare session files
347
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'nsg-babysitter-'));
348
+ const args = [...config.claudeArgs];
349
+ // Write system prompt if present in args (already handled by claudeArgs)
350
+ // Write mcp-config pointing to the babysitter's MCP proxy server
351
+ const mcpConfig = {
352
+ mcpServers: {
353
+ 'nexus-guild': {
354
+ type: 'sse',
355
+ url: mcpHandle.url,
356
+ },
357
+ },
358
+ };
359
+ const mcpConfigPath = path.join(tmpDir, 'mcp-config.json');
360
+ fs.writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig));
361
+ args.push('--mcp-config', mcpConfigPath, '--strict-mcp-config');
362
+ // Add autonomous mode flags
363
+ args.push('--print', '-', '--output-format', 'stream-json', '--verbose');
364
+ // 4. Spawn claude
365
+ claudeProc = spawnFn('claude', args, {
366
+ cwd: config.cwd,
367
+ stdio: ['pipe', 'pipe', 'inherit'],
368
+ env: { ...process.env, ...config.env },
369
+ });
370
+ // Pipe prompt to claude's stdin, then close
371
+ if (config.prompt) {
372
+ claudeProc.stdin.write(config.prompt);
373
+ }
374
+ claudeProc.stdin.end();
375
+ // 5. Report "running" status (don't await — fire and forget with retry)
376
+ const runningPromise = reportRunning(config, claudeProc.pid, retryTimeoutMs).catch((err) => {
377
+ process.stderr.write(`[babysitter] Failed to report running: ${err}\n`);
378
+ });
379
+ // 6. Consume stdout, stream transcript
380
+ const acc = { transcript: [] };
381
+ let buffer = '';
382
+ claudeProc.stdout.on('data', (chunk) => {
383
+ buffer += chunk.toString();
384
+ const prevLength = acc.transcript.length;
385
+ buffer = processNdjsonBuffer(buffer, (msg) => {
386
+ parseStreamJsonMessage(msg, acc);
387
+ });
388
+ // Write transcript to SQLite if new messages were added
389
+ if (acc.transcript.length > prevLength && db) {
390
+ writeTranscript(db, config.sessionId, acc.transcript);
391
+ }
392
+ });
393
+ // 7. Wait for claude to exit
394
+ const exitCode = await new Promise((resolve, reject) => {
395
+ claudeProc.on('error', (err) => {
396
+ reject(new Error(`Failed to spawn claude: ${err.message}`));
397
+ });
398
+ claudeProc.on('close', (code) => {
399
+ resolve(code ?? 1);
400
+ });
401
+ });
402
+ // Ensure running report completed before recording result
403
+ await runningPromise;
404
+ // Build result
405
+ const result = {
406
+ exitCode,
407
+ transcript: acc.transcript,
408
+ costUsd: acc.costUsd,
409
+ tokenUsage: acc.tokenUsage,
410
+ providerSessionId: acc.providerSessionId,
411
+ };
412
+ // 8. Report result
413
+ await reportResult(config, result, acc.transcript, retryTimeoutMs);
414
+ }
415
+ catch (err) {
416
+ // Top-level error: attempt to report failure
417
+ const message = err instanceof Error ? err.message : String(err);
418
+ try {
419
+ const route = toolNameToRoute('session-record');
420
+ const url = `${config.guildToolUrl}${route}`;
421
+ await callGuildHttpApi(url, config.sessionId, {
422
+ sessionId: config.sessionId,
423
+ status: 'failed',
424
+ exitCode: 1,
425
+ error: message,
426
+ }, retryTimeoutMs);
427
+ }
428
+ catch {
429
+ writeToDlq(config.cwd, `${config.sessionId}.json`, {
430
+ sessionId: config.sessionId,
431
+ status: 'failed',
432
+ exitCode: 1,
433
+ error: message,
434
+ });
435
+ }
436
+ throw err;
437
+ }
438
+ finally {
439
+ // 9. Cleanup
440
+ await mcpHandle?.close().catch(() => { });
441
+ db?.close();
442
+ if (tmpDir) {
443
+ fs.rmSync(tmpDir, { recursive: true, force: true });
444
+ }
445
+ }
446
+ }
447
+ // ── Entry point ─────────────────────────────────────────────────────────
448
+ /**
449
+ * Script entry point — reads config from stdin and runs the babysitter.
450
+ *
451
+ * Only executes when this file is run directly (not when imported).
452
+ */
453
+ async function main() {
454
+ try {
455
+ const config = await readConfigFromStdin();
456
+ await runBabysitter(config);
457
+ process.exit(0);
458
+ }
459
+ catch (err) {
460
+ process.stderr.write(`[babysitter] Fatal error: ${err instanceof Error ? err.message : String(err)}\n`);
461
+ process.exit(1);
462
+ }
463
+ }
464
+ // Check if this module is the entry point
465
+ const isEntryPoint = process.argv[1] &&
466
+ (process.argv[1] === fileURLToPath(import.meta.url) ||
467
+ process.argv[1].endsWith('/babysitter.js'));
468
+ if (isEntryPoint) {
469
+ main();
470
+ }
471
+ //# sourceMappingURL=babysitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"babysitter.js","sourceRoot":"","sources":["../src/babysitter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Detached session launch — spawns a babysitter process instead of claude directly.
3
+ *
4
+ * The babysitter runs as a detached process that survives guild restarts.
5
+ * It hosts the MCP server, spawns claude, streams transcripts to SQLite,
6
+ * and reports lifecycle events to the guild via HTTP.
7
+ *
8
+ * See: docs/architecture/detached-sessions.md
9
+ */
10
+ import { spawn } from 'node:child_process';
11
+ import type { SessionProviderConfig, SessionProviderResult, SessionChunk, SessionDoc } from '@shardworks/animator-apparatus';
12
+ import type { ReadOnlyBook } from '@shardworks/stacks-apparatus';
13
+ import type { ResolvedTool } from '@shardworks/tools-apparatus';
14
+ import type { BabysitterConfig, SerializedTool } from './babysitter.ts';
15
+ /**
16
+ * Serialize a ResolvedTool's Zod params to a SerializedTool with JSON Schema.
17
+ *
18
+ * Uses Zod 4's built-in `z.toJSONSchema()` to convert the params schema.
19
+ * The resulting JSON Schema is what the babysitter's MCP proxy server
20
+ * advertises to claude via tools/list.
21
+ */
22
+ export declare function serializeTool(rt: ResolvedTool): SerializedTool;
23
+ /**
24
+ * Serialize an array of ResolvedTools to SerializedTools.
25
+ */
26
+ export declare function serializeTools(tools: ResolvedTool[]): SerializedTool[];
27
+ /** Resolve the guild's Tool HTTP API URL. */
28
+ export declare function resolveGuildToolUrl(): string;
29
+ /** Resolve the path to the guild's SQLite database. */
30
+ export declare function resolveDbPath(): string;
31
+ /** Resolve the babysitter script path (compiled output). */
32
+ export declare function resolveBabysitterPath(): string;
33
+ export interface DetachedLaunchOptions {
34
+ /** Override babysitter script path (for testing). */
35
+ babysitterPath?: string;
36
+ /** Override guild tool URL (for testing). */
37
+ guildToolUrl?: string;
38
+ /** Override database path (for testing). */
39
+ dbPath?: string;
40
+ /** Override poll interval in ms (for testing). */
41
+ pollIntervalMs?: number;
42
+ /** Override poll timeout in ms (for testing). */
43
+ pollTimeoutMs?: number;
44
+ /** Override sessions book (for testing). */
45
+ sessionsBook?: ReadOnlyBook<SessionDoc>;
46
+ /** Override spawn function (for testing). */
47
+ spawnFn?: typeof spawn;
48
+ /** Session metadata from the AnimateRequest. */
49
+ metadata?: Record<string, unknown>;
50
+ }
51
+ /**
52
+ * Build a BabysitterConfig from the provider's SessionProviderConfig.
53
+ *
54
+ * Serializes tools from Zod schemas to JSON Schema, resolves guild
55
+ * infrastructure paths, and constructs the base CLI args for claude.
56
+ */
57
+ export declare function buildBabysitterConfig(config: SessionProviderConfig, opts?: DetachedLaunchOptions): BabysitterConfig;
58
+ /**
59
+ * Poll the sessions book until the session reaches a terminal status.
60
+ *
61
+ * Returns the SessionDoc when status is no longer 'running'.
62
+ * Throws on timeout.
63
+ */
64
+ export declare function pollForTerminalStatus(sessionsBook: ReadOnlyBook<SessionDoc>, sessionId: string, pollIntervalMs?: number, pollTimeoutMs?: number): Promise<SessionDoc>;
65
+ /**
66
+ * Poll the sessions book until cancelMetadata.pid is available.
67
+ *
68
+ * The babysitter reports the claude PID via the session-running tool,
69
+ * which writes cancelMetadata to the SessionDoc. We poll for it.
70
+ */
71
+ export declare function pollForProcessInfo(sessionsBook: ReadOnlyBook<SessionDoc>, sessionId: string, pollIntervalMs?: number, pollTimeoutMs?: number): Promise<Record<string, unknown>>;
72
+ /**
73
+ * Launch a detached babysitter process.
74
+ *
75
+ * Returns the same { chunks, result, processInfo } shape as the attached
76
+ * provider, but:
77
+ * - chunks: completes immediately (empty) — transcripts stream to SQLite
78
+ * - result: polls sessions book for terminal status
79
+ * - processInfo: polls SessionDoc for cancelMetadata (contains claude PID)
80
+ */
81
+ export declare function launchDetached(config: SessionProviderConfig, opts?: DetachedLaunchOptions): {
82
+ chunks: AsyncIterable<SessionChunk>;
83
+ result: Promise<SessionProviderResult>;
84
+ processInfo?: Promise<Record<string, unknown>>;
85
+ };
86
+ //# sourceMappingURL=detached.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detached.d.ts","sourceRoot":"","sources":["../src/detached.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAQ3C,OAAO,KAAK,EACV,qBAAqB,EACrB,qBAAqB,EACrB,YAAY,EACZ,UAAU,EACX,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAa,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAaxE;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,cAAc,CAc9D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,cAAc,EAAE,CAEtE;AAID,6CAA6C;AAC7C,wBAAgB,mBAAmB,IAAI,MAAM,CAO5C;AAED,uDAAuD;AACvD,wBAAgB,aAAa,IAAI,MAAM,CAGtC;AAED,4DAA4D;AAC5D,wBAAgB,qBAAqB,IAAI,MAAM,CAM9C;AAID,MAAM,WAAW,qBAAqB;IACpC,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IACxC,6CAA6C;IAC7C,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;IACvB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,qBAAqB,EAC7B,IAAI,CAAC,EAAE,qBAAqB,GAC3B,gBAAgB,CAqClB;AAID;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,YAAY,CAAC,UAAU,CAAC,EACtC,SAAS,EAAE,MAAM,EACjB,cAAc,GAAE,MAAyB,EACzC,aAAa,GAAE,MAAwB,GACtC,OAAO,CAAC,UAAU,CAAC,CAmBrB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,YAAY,CAAC,UAAU,CAAC,EACtC,SAAS,EAAE,MAAM,EACjB,cAAc,GAAE,MAAyB,EACzC,aAAa,GAAE,MAAe,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAwBlC;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,qBAAqB,EAC7B,IAAI,CAAC,EAAE,qBAAqB,GAC3B;IACD,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;IACpC,MAAM,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAChD,CAmFA"}