@shardworks/claude-code-apparatus 0.1.148 → 0.1.149

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.
package/README.md ADDED
@@ -0,0 +1,148 @@
1
+ # `@shardworks/claude-code-apparatus`
2
+
3
+ Claude Code session provider apparatus for Nexus. Implements the `AnimatorSessionProvider` interface for the Claude Code CLI, enabling the Animator to launch and manage AI sessions. Also provides the **Session Babysitter** — a detached process that hosts sessions independently of the guild lifecycle.
4
+
5
+ Depends on `@shardworks/animator-apparatus` (types), `@shardworks/tools-apparatus` (tool definitions and routing), and `@shardworks/nexus-core`.
6
+
7
+ ---
8
+
9
+ ## Installation
10
+
11
+ ```json
12
+ {
13
+ "dependencies": {
14
+ "@shardworks/claude-code-apparatus": "workspace:*"
15
+ }
16
+ }
17
+ ```
18
+
19
+ ## API
20
+
21
+ ### Session Provider
22
+
23
+ The default export is a `Plugin` whose apparatus `provides` an `AnimatorSessionProvider`:
24
+
25
+ ```typescript
26
+ import createClaudeCodeProvider from '@shardworks/claude-code-apparatus';
27
+
28
+ // In guild.json:
29
+ // { "animator": { "sessionProvider": "claude-code" } }
30
+ ```
31
+
32
+ The provider implements `launch()` and `cancel()`:
33
+
34
+ - **`launch(config)`** — spawns `claude` in autonomous mode (`--print -`, `--output-format stream-json`). When `config.streaming` is true, yields `SessionChunk` objects in real-time. Returns `{ chunks, result, processInfo }`.
35
+ - **`cancel(cancelMetadata)`** — sends SIGTERM to the claude process using the PID from `cancelMetadata`.
36
+
37
+ ### MCP Server
38
+
39
+ The package exports functions for running MCP tool servers:
40
+
41
+ ```typescript
42
+ import { createMcpServer, startMcpHttpServer } from '@shardworks/claude-code-apparatus';
43
+
44
+ // Create an MCP server with resolved tool definitions
45
+ const mcpServer = await createMcpServer(toolDefinitions);
46
+
47
+ // Or start an HTTP server on an ephemeral port
48
+ const handle = await startMcpHttpServer(toolDefinitions);
49
+ console.log(handle.url); // "http://127.0.0.1:PORT/sse"
50
+ await handle.close(); // cleanup
51
+ ```
52
+
53
+ ### Stream Parsing
54
+
55
+ Exported utilities for parsing Claude's NDJSON output:
56
+
57
+ ```typescript
58
+ import {
59
+ processNdjsonBuffer,
60
+ parseStreamJsonMessage,
61
+ extractFinalAssistantText,
62
+ } from '@shardworks/claude-code-apparatus';
63
+ ```
64
+
65
+ - **`processNdjsonBuffer(buffer, handler)`** — splits NDJSON buffer on newlines, calls handler for each parsed JSON object, returns remaining incomplete buffer.
66
+ - **`parseStreamJsonMessage(msg, acc)`** — processes a single NDJSON message, accumulates transcript/metrics, returns `SessionChunk[]`.
67
+ - **`extractFinalAssistantText(transcript)`** — walks transcript backwards to find the last assistant message's text content.
68
+
69
+ ## Session Babysitter
70
+
71
+ The babysitter is a standalone Node.js script that runs as a detached process, hosting a claude session independently of the guild. It survives guild restarts.
72
+
73
+ ### Entry Point
74
+
75
+ ```bash
76
+ node dist/babysitter.js # reads config from stdin
77
+ ```
78
+
79
+ Or import the module for programmatic use:
80
+
81
+ ```typescript
82
+ import { runBabysitter } from '@shardworks/claude-code-apparatus/babysitter';
83
+ ```
84
+
85
+ ### Config (via stdin)
86
+
87
+ The spawning process writes JSON config to the babysitter's stdin:
88
+
89
+ ```typescript
90
+ interface BabysitterConfig {
91
+ sessionId: string; // Pre-generated session ID
92
+ guildToolUrl: string; // Guild's Tool HTTP API URL (e.g. "http://127.0.0.1:7471")
93
+ dbPath: string; // Path to guild's SQLite database
94
+ claudeArgs: string[]; // CLI args for claude (--model, --system-prompt-file, etc.)
95
+ cwd: string; // Working directory for the claude process
96
+ env: Record<string, string>; // Environment variables for the claude process
97
+ prompt: string; // Initial prompt piped to claude's stdin
98
+ tools: SerializedTool[]; // Tool definitions with JSON Schema params
99
+ startedAt: string; // ISO timestamp of session start
100
+ provider: string; // Provider name (e.g. "claude-code")
101
+ metadata?: Record<string, unknown>; // Optional session metadata
102
+ }
103
+
104
+ interface SerializedTool {
105
+ name: string;
106
+ description: string;
107
+ params: Record<string, unknown>; // JSON Schema
108
+ }
109
+ ```
110
+
111
+ ### Lifecycle
112
+
113
+ 1. **Read config** from stdin, parse JSON, validate required fields
114
+ 2. **Open SQLite** (WAL mode) for real-time transcript streaming
115
+ 3. **Start MCP/SSE proxy server** — registers tools that forward calls to the guild's Tool HTTP API with retry and exponential backoff
116
+ 4. **Prepare session files** — temp directory, mcp-config.json pointing to the proxy server
117
+ 5. **Spawn claude** — pipes prompt to stdin, captures NDJSON stdout
118
+ 6. **Report "running"** — calls `session-running` tool on guild via HTTP (DLQ fallback)
119
+ 7. **Stream transcript** — parses NDJSON, writes to `books_animator_transcripts` table in SQLite after each message batch
120
+ 8. **Report result** — calls `session-record` tool on guild via HTTP (DLQ fallback)
121
+ 9. **Cleanup** — close MCP server, close SQLite, remove temp directory
122
+
123
+ ### Error Handling
124
+
125
+ - **Tool call proxy errors**: retried with exponential backoff (1s initial, 8s max, 60s timeout). If retries exhaust, returns error to claude as MCP tool result — doesn't crash.
126
+ - **Lifecycle reporting errors**: if guild is unreachable, payload is written to `.nexus/dlq/{sessionId}[-running].json` for later drain.
127
+ - **Top-level errors**: attempts to report `status: 'failed'` to guild, falls back to DLQ, then exits non-zero.
128
+
129
+ ## Exports
130
+
131
+ | Entry point | Description |
132
+ |---|---|
133
+ | `.` (`src/index.ts`) | Session provider plugin, MCP server, stream parsing utilities |
134
+ | `./babysitter` (`src/babysitter.ts`) | Babysitter module — `runBabysitter()`, config parsing, proxy server, transcript DB |
135
+
136
+ ## Configuration
137
+
138
+ Configured in `guild.json` under the `animator` key:
139
+
140
+ ```json
141
+ {
142
+ "animator": {
143
+ "sessionProvider": "claude-code"
144
+ }
145
+ }
146
+ ```
147
+
148
+ No additional configuration fields. The model is passed per-session via the Animator.
@@ -0,0 +1,152 @@
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 { type StreamJsonResult } from './index.ts';
20
+ /** A serialized tool definition as received in the babysitter config. */
21
+ export interface SerializedTool {
22
+ /** Tool name (e.g. 'writ-list'). */
23
+ name: string;
24
+ /** Tool description. */
25
+ description: string;
26
+ /** JSON Schema for the tool's input parameters. */
27
+ params: Record<string, unknown>;
28
+ }
29
+ /** Config written to the babysitter's stdin by the spawning process. */
30
+ export interface BabysitterConfig {
31
+ sessionId: string;
32
+ guildToolUrl: string;
33
+ dbPath: string;
34
+ claudeArgs: string[];
35
+ cwd: string;
36
+ env: Record<string, string>;
37
+ prompt: string;
38
+ tools: SerializedTool[];
39
+ startedAt: string;
40
+ provider: string;
41
+ metadata?: Record<string, unknown>;
42
+ }
43
+ export interface McpProxyHandle {
44
+ /** URL for --mcp-config (e.g. "http://127.0.0.1:PORT/sse"). */
45
+ url: string;
46
+ /** Shut down the HTTP server and MCP transport. */
47
+ close(): Promise<void>;
48
+ }
49
+ /**
50
+ * Read the babysitter config from stdin.
51
+ *
52
+ * Reads stdin to completion, parses the JSON, and validates required fields.
53
+ * The spawning process writes config and closes the write end.
54
+ */
55
+ export declare function readConfigFromStdin(stream?: NodeJS.ReadableStream): Promise<BabysitterConfig>;
56
+ /**
57
+ * Call a guild HTTP API endpoint with exponential backoff retry.
58
+ *
59
+ * Retries on connection errors (ECONNREFUSED, ECONNRESET, ETIMEDOUT).
60
+ * Returns the parsed JSON response on success.
61
+ * Throws after RETRY_TIMEOUT_MS of retrying.
62
+ */
63
+ export declare function callGuildHttpApi(url: string, sessionId: string, body: unknown, timeoutMs?: number): Promise<unknown>;
64
+ /**
65
+ * Write a payload to the Dead Letter Queue.
66
+ *
67
+ * Creates the DLQ directory if it doesn't exist. Writes the payload as
68
+ * pretty-printed JSON. Used as a fallback when the guild HTTP API is
69
+ * unreachable for lifecycle calls.
70
+ */
71
+ export declare function writeToDlq(cwd: string, filename: string, payload: unknown): void;
72
+ /**
73
+ * Create an MCP/SSE HTTP server that proxies tool calls to the guild.
74
+ *
75
+ * For each tool in the config, registers an MCP tool whose handler
76
+ * forwards the call to the guild's Tool HTTP API via HTTP POST.
77
+ *
78
+ * Uses the low-level MCP Server class to register tools with raw
79
+ * JSON Schema (the serialized params from the config).
80
+ */
81
+ export declare function createProxyMcpHttpServer(tools: SerializedTool[], guildToolUrl: string, sessionId: string): Promise<McpProxyHandle>;
82
+ /** Minimal interface for the SQLite database used by the babysitter. */
83
+ export interface TranscriptDb {
84
+ /** Write a transcript entry (id, content JSON). */
85
+ writeTranscript(sessionId: string, content: string): void;
86
+ /** Close the database connection. */
87
+ close(): void;
88
+ }
89
+ /**
90
+ * Open the guild's SQLite database for transcript streaming.
91
+ *
92
+ * Creates the database file and table if they don't exist.
93
+ * Enables WAL mode for concurrent read access by other processes
94
+ * (Oculus, CLI queries, other agents).
95
+ *
96
+ * Uses dynamic import() to load better-sqlite3 at runtime. This avoids
97
+ * requiring the native module at import time (beneficial for type-checking
98
+ * and testing).
99
+ */
100
+ export declare function openTranscriptDb(dbPath: string): Promise<TranscriptDb>;
101
+ /**
102
+ * Initialize a TranscriptDb from a Database constructor.
103
+ *
104
+ * Shared logic between openTranscriptDb() and test injection.
105
+ * Exported for testing — allows injecting a mock Database constructor.
106
+ */
107
+ export declare function initTranscriptDb(DatabaseConstructor: new (path: string) => {
108
+ pragma(stmt: string): unknown;
109
+ prepare(sql: string): {
110
+ run(...params: unknown[]): void;
111
+ };
112
+ exec(sql: string): void;
113
+ close(): void;
114
+ }, dbPath: string): TranscriptDb;
115
+ /**
116
+ * Write the current transcript to SQLite.
117
+ */
118
+ export declare function writeTranscript(db: TranscriptDb, sessionId: string, messages: Record<string, unknown>[]): void;
119
+ /**
120
+ * Report "running" status to the guild via the session-running tool.
121
+ *
122
+ * If the guild is unreachable, writes the payload to the DLQ.
123
+ */
124
+ export declare function reportRunning(config: BabysitterConfig, claudePid: number, timeoutMs?: number): Promise<void>;
125
+ /**
126
+ * Report the final session result to the guild via the session-record tool.
127
+ *
128
+ * If the guild is unreachable, writes the payload to the DLQ.
129
+ */
130
+ export declare function reportResult(config: BabysitterConfig, result: StreamJsonResult, transcript: Record<string, unknown>[], timeoutMs?: number): Promise<void>;
131
+ /**
132
+ * Run the session babysitter.
133
+ *
134
+ * This is the main orchestration function. It:
135
+ * 1. Opens SQLite for transcript streaming
136
+ * 2. Starts the MCP proxy server
137
+ * 3. Prepares session files (tmpDir, system prompt, mcp-config)
138
+ * 4. Spawns claude
139
+ * 5. Reports "running" status
140
+ * 6. Streams transcript to SQLite
141
+ * 7. Reports result on exit
142
+ * 8. Cleans up
143
+ */
144
+ export declare function runBabysitter(config: BabysitterConfig, deps?: {
145
+ /** Injected TranscriptDb for testing (avoids loading better-sqlite3). */
146
+ db?: TranscriptDb;
147
+ /** Override spawn for testing. */
148
+ spawnFn?: typeof spawn;
149
+ /** Override retry timeout for testing (default: 60_000ms). */
150
+ retryTimeoutMs?: number;
151
+ }): Promise<void>;
152
+ //# sourceMappingURL=babysitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"babysitter.d.ts","sourceRoot":"","sources":["../src/babysitter.ts"],"names":[],"mappings":"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"}
@@ -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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shardworks/claude-code-apparatus",
3
- "version": "0.1.148",
3
+ "version": "0.1.149",
4
4
  "license": "ISC",
5
5
  "repository": {
6
6
  "type": "git",
@@ -13,16 +13,22 @@
13
13
  ".": {
14
14
  "types": "./dist/index.d.ts",
15
15
  "import": "./dist/index.js"
16
+ },
17
+ "./babysitter": {
18
+ "types": "./dist/babysitter.d.ts",
19
+ "import": "./dist/babysitter.js"
16
20
  }
17
21
  },
18
22
  "dependencies": {
19
23
  "@modelcontextprotocol/sdk": "1.27.1",
24
+ "better-sqlite3": "12.8.0",
20
25
  "zod": "4.3.6",
21
- "@shardworks/tools-apparatus": "0.1.148",
22
- "@shardworks/animator-apparatus": "0.1.148",
23
- "@shardworks/nexus-core": "0.1.148"
26
+ "@shardworks/animator-apparatus": "0.1.149",
27
+ "@shardworks/nexus-core": "0.1.149",
28
+ "@shardworks/tools-apparatus": "0.1.149"
24
29
  },
25
30
  "devDependencies": {
31
+ "@types/better-sqlite3": "7.6.13",
26
32
  "@types/node": "25.5.0"
27
33
  },
28
34
  "files": [