aisnitch 0.2.19 → 0.2.21

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/dist/index.d.cts CHANGED
@@ -68,6 +68,8 @@ declare const ConfigSchema: z.ZodObject<{
68
68
  kiro: "kiro";
69
69
  "augment-code": "augment-code";
70
70
  mistral: "mistral";
71
+ zed: "zed";
72
+ pi: "pi";
71
73
  unknown: "unknown";
72
74
  }> & z.core.$partial, z.ZodObject<{
73
75
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -106,7 +108,7 @@ type AISnitchConfig = infer<typeof ConfigSchema>;
106
108
  * @description Runtime Zod schemas and constants for the AISnitch CloudEvents-based event contract.
107
109
  * @functions
108
110
  * → createUuidV7
109
- * @exports AISNITCH_EVENT_TYPES, TOOL_NAMES, ERROR_TYPES, CESP_CATEGORIES, ToolInputSchema, EventDataSchema, AISnitchEventTypeSchema, ToolNameSchema, ErrorTypeSchema, CESPCategorySchema, AISnitchEventSchema, createUuidV7
111
+ * @exports AISNITCH_EVENT_TYPES, TOOL_NAMES, ERROR_TYPES, CESP_CATEGORIES, ToolInputSchema, ToolCallNameSchema, ThinkingContentSchema, FinalMessageSchema, ToolResultSchema, MessageContentSchema, EventDataSchema, AISnitchEventTypeSchema, ToolNameSchema, ErrorTypeSchema, CESPCategorySchema, AISnitchEventSchema, createUuidV7
110
112
  * @see ./types.ts
111
113
  * @see ./cesp.ts
112
114
  * @see ./factory.ts
@@ -119,7 +121,7 @@ declare const AISNITCH_EVENT_TYPES: readonly ["session.start", "session.end", "t
119
121
  /**
120
122
  * Supported AI tool identifiers recognized by AISnitch.
121
123
  */
122
- declare const TOOL_NAMES: readonly ["claude-code", "opencode", "gemini-cli", "codex", "goose", "copilot-cli", "cursor", "aider", "amp", "cline", "continue", "windsurf", "qwen-code", "openclaw", "openhands", "kilo", "devin", "kiro", "augment-code", "mistral", "unknown"];
124
+ declare const TOOL_NAMES: readonly ["claude-code", "opencode", "gemini-cli", "codex", "goose", "copilot-cli", "cursor", "aider", "amp", "cline", "continue", "windsurf", "qwen-code", "openclaw", "openhands", "kilo", "devin", "kiro", "augment-code", "mistral", "zed", "pi", "unknown"];
123
125
  /**
124
126
  * Normalized error categories attached to `agent.error` events.
125
127
  */
@@ -139,6 +141,34 @@ declare const ToolInputSchema: z.ZodObject<{
139
141
  filePath: z.ZodOptional<z.ZodString>;
140
142
  command: z.ZodOptional<z.ZodString>;
141
143
  }, z.core.$strict>;
144
+ /**
145
+ * 📖 Thinking content extracted from AI model reasoning chains.
146
+ * This field captures the internal "thinking" or reasoning output that
147
+ * models like Claude produce before generating their final response.
148
+ */
149
+ declare const ThinkingContentSchema: z.ZodString;
150
+ /**
151
+ * 📖 Tool call name — the specific tool being invoked.
152
+ * Examples: "Edit", "Bash", "Grep", "Read", "Write", "WebSearch"
153
+ * Different from `toolInput` which contains the tool's parameters.
154
+ */
155
+ declare const ToolCallNameSchema: z.ZodString;
156
+ /**
157
+ * 📖 Final message shown at the end of an AI run.
158
+ * This is typically a summary, completion message, or result text
159
+ * displayed to the user after the agent finishes its work.
160
+ */
161
+ declare const FinalMessageSchema: z.ZodString;
162
+ /**
163
+ * 📖 Tool execution result — short result from a tool call.
164
+ * Can include success messages, error messages, or short outputs.
165
+ */
166
+ declare const ToolResultSchema: z.ZodString;
167
+ /**
168
+ * 📖 Raw message content from AI responses.
169
+ * Captures the actual text generated by the model before tool calls.
170
+ */
171
+ declare const MessageContentSchema: z.ZodString;
142
172
  /**
143
173
  * Runtime schema for the supported tool names.
144
174
  */
@@ -163,6 +193,8 @@ declare const ToolNameSchema: z.ZodEnum<{
163
193
  kiro: "kiro";
164
194
  "augment-code": "augment-code";
165
195
  mistral: "mistral";
196
+ zed: "zed";
197
+ pi: "pi";
166
198
  unknown: "unknown";
167
199
  }>;
168
200
  /**
@@ -248,6 +280,11 @@ declare const EventDataSchema: z.ZodObject<{
248
280
  instanceId: z.ZodOptional<z.ZodString>;
249
281
  instanceIndex: z.ZodOptional<z.ZodNumber>;
250
282
  instanceTotal: z.ZodOptional<z.ZodNumber>;
283
+ thinkingContent: z.ZodOptional<z.ZodString>;
284
+ toolCallName: z.ZodOptional<z.ZodString>;
285
+ finalMessage: z.ZodOptional<z.ZodString>;
286
+ toolResult: z.ZodOptional<z.ZodString>;
287
+ messageContent: z.ZodOptional<z.ZodString>;
251
288
  }, z.core.$strict>;
252
289
  /**
253
290
  * Runtime schema for the full normalized AISnitch event envelope.
@@ -292,6 +329,8 @@ declare const AISnitchEventSchema: z.ZodObject<{
292
329
  kiro: "kiro";
293
330
  "augment-code": "augment-code";
294
331
  mistral: "mistral";
332
+ zed: "zed";
333
+ pi: "pi";
295
334
  unknown: "unknown";
296
335
  }>;
297
336
  'aisnitch.sessionid': z.ZodString;
@@ -336,6 +375,11 @@ declare const AISnitchEventSchema: z.ZodObject<{
336
375
  instanceId: z.ZodOptional<z.ZodString>;
337
376
  instanceIndex: z.ZodOptional<z.ZodNumber>;
338
377
  instanceTotal: z.ZodOptional<z.ZodNumber>;
378
+ thinkingContent: z.ZodOptional<z.ZodString>;
379
+ toolCallName: z.ZodOptional<z.ZodString>;
380
+ finalMessage: z.ZodOptional<z.ZodString>;
381
+ toolResult: z.ZodOptional<z.ZodString>;
382
+ messageContent: z.ZodOptional<z.ZodString>;
339
383
  }, z.core.$strict>;
340
384
  }, z.core.$strict>;
341
385
 
@@ -440,6 +484,11 @@ declare const NormalizedAdapterHookPayloadSchema: z.ZodObject<{
440
484
  instanceId: z.ZodOptional<z.ZodOptional<z.ZodString>>;
441
485
  instanceIndex: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
442
486
  instanceTotal: z.ZodOptional<z.ZodOptional<z.ZodNumber>>;
487
+ thinkingContent: z.ZodOptional<z.ZodOptional<z.ZodString>>;
488
+ toolCallName: z.ZodOptional<z.ZodOptional<z.ZodString>>;
489
+ finalMessage: z.ZodOptional<z.ZodOptional<z.ZodString>>;
490
+ toolResult: z.ZodOptional<z.ZodOptional<z.ZodString>>;
491
+ messageContent: z.ZodOptional<z.ZodOptional<z.ZodString>>;
443
492
  }, z.core.$strict>>;
444
493
  pid: z.ZodOptional<z.ZodNumber>;
445
494
  transcriptPath: z.ZodOptional<z.ZodString>;
@@ -1036,6 +1085,91 @@ declare class OpenCodeAdapter extends BaseAdapter {
1036
1085
  private pollOpenCodeProcesses;
1037
1086
  }
1038
1087
 
1088
+ /**
1089
+ * @file src/adapters/pi.ts
1090
+ * @description Pi AI Agent adapter using Pi's local API and log monitoring.
1091
+ * @functions
1092
+ * → detectPiInstance
1093
+ * @exports PiAdapter
1094
+ * @see ./base.ts
1095
+ * @see ../core/events/types.ts
1096
+ */
1097
+
1098
+ /**
1099
+ * 📖 Pi is a coding agent by MiniMax. This adapter detects Pi activity through:
1100
+ * 1. Process detection (pgrep for pi processes)
1101
+ * 2. MiniMax API / local socket detection
1102
+ * 3. Log file monitoring
1103
+ */
1104
+ declare class PiAdapter extends BaseAdapter {
1105
+ readonly displayName = "Pi (MiniMax)";
1106
+ readonly name: "pi";
1107
+ readonly strategies: readonly InterceptionStrategy[];
1108
+ private readonly apiPort;
1109
+ private readonly logPath;
1110
+ private poller;
1111
+ private activePiSessions;
1112
+ private lastCheckedTime;
1113
+ constructor(options: AdapterRuntimeOptions);
1114
+ start(): Promise<void>;
1115
+ stop(): Promise<void>;
1116
+ handleHook(payload: unknown): Promise<void>;
1117
+ private startPolling;
1118
+ private pollPiActivity;
1119
+ private detectPiInstance;
1120
+ private checkMiniMaxApi;
1121
+ private processPiApiResponse;
1122
+ private emitSessionStart;
1123
+ private emitThinking;
1124
+ private emitToolCall;
1125
+ private emitOutput;
1126
+ private emitError;
1127
+ private emitIdle;
1128
+ private mapEventType;
1129
+ private buildEventData;
1130
+ }
1131
+
1132
+ /**
1133
+ * @file src/adapters/zed.ts
1134
+ * @description Zed AI Agent adapter using log file monitoring and IPC detection.
1135
+ * @functions
1136
+ * → extractZedEventFromLog
1137
+ * @exports ZedAdapter
1138
+ * @see ./base.ts
1139
+ * @see ../core/events/types.ts
1140
+ */
1141
+
1142
+ /**
1143
+ * 📖 Zed Agent (zed.dev) exposes a local HTTP API on port 9876 for its agent.
1144
+ * This adapter polls that endpoint and watches Zed's log file for activity.
1145
+ */
1146
+ declare class ZedAdapter extends BaseAdapter {
1147
+ readonly displayName = "Zed AI";
1148
+ readonly name: "zed";
1149
+ readonly strategies: readonly InterceptionStrategy[];
1150
+ private readonly logPaths;
1151
+ private readonly apiPort;
1152
+ private readonly pollIntervalMs;
1153
+ private poller;
1154
+ private lastEventTime;
1155
+ private activeZedSessions;
1156
+ constructor(options: AdapterRuntimeOptions);
1157
+ start(): Promise<void>;
1158
+ stop(): Promise<void>;
1159
+ handleHook(payload: unknown): Promise<void>;
1160
+ private startPolling;
1161
+ private pollZedStatus;
1162
+ private checkLogFiles;
1163
+ private parseLogContent;
1164
+ private extractZedEventFromLog;
1165
+ private emitSessionStart;
1166
+ private emitThinking;
1167
+ private emitToolCall;
1168
+ private emitIdle;
1169
+ private mapEventType;
1170
+ private buildEventData;
1171
+ }
1172
+
1039
1173
  /**
1040
1174
  * @file src/adapters/registry.ts
1041
1175
  * @description Adapter registry that owns built-in adapter instances and orchestrates their lifecycle.
@@ -1164,12 +1298,402 @@ declare function analyzeTerminalOutputChunk(input: {
1164
1298
  * @see ./codex.ts
1165
1299
  * @see ./openclaw.ts
1166
1300
  * @see ./opencode.ts
1301
+ * @see ./pi.ts
1302
+ * @see ./zed.ts
1167
1303
  */
1168
1304
 
1169
1305
  /**
1170
1306
  * Instantiates the built-in adapters that ship with AISnitch.
1171
1307
  */
1172
- declare function createDefaultAdapters(options: AdapterRuntimeOptions): readonly [AiderAdapter, ClaudeCodeAdapter, CopilotCLIAdapter, CursorAdapter, DevinAdapter, GeminiCLIAdapter, GooseAdapter, KiloAdapter, CodexAdapter, OpenClawAdapter, OpenCodeAdapter];
1308
+ declare function createDefaultAdapters(options: AdapterRuntimeOptions): readonly [AiderAdapter, ClaudeCodeAdapter, CopilotCLIAdapter, CursorAdapter, DevinAdapter, GeminiCLIAdapter, GooseAdapter, KiloAdapter, CodexAdapter, OpenClawAdapter, OpenCodeAdapter, PiAdapter, ZedAdapter];
1309
+
1310
+ /**
1311
+ * @file src/core/errors.ts
1312
+ * @description Centralized error hierarchy for AISnitch with typed error codes and context.
1313
+ *
1314
+ * This module provides a consistent error taxonomy across the entire application:
1315
+ * - `AISnitchError` — base class for all AISnitch-specific errors
1316
+ * - `AdapterError` — adapter lifecycle, parsing, or emission failures
1317
+ * - `PipelineError` — pipeline orchestration, component startup, or shutdown failures
1318
+ * - `ValidationError` — Zod parsing failures and schema violations
1319
+ * - `NetworkError` — HTTP, WebSocket, or Unix Domain Socket failures
1320
+ * - `TimeoutError` — async operations that exceed their deadline
1321
+ *
1322
+ * Each error carries a machine-readable `code` field for programmatic handling
1323
+ * and an optional `context` bag for debugging. Errors serialize cleanly to JSON
1324
+ * so they can be logged via pino without losing structure.
1325
+ *
1326
+ * @functions
1327
+ * → none
1328
+ * @exports AISnitchError, AdapterError, PipelineError, ValidationError, NetworkError, TimeoutError, isAISnitchError, isRetryableError
1329
+ * @see ./result.ts
1330
+ * @see ./retry.ts
1331
+ * @see ./timeout.ts
1332
+ */
1333
+ /**
1334
+ * Base class for all AISnitch-specific errors.
1335
+ *
1336
+ * @example
1337
+ * ```typescript
1338
+ * throw new AISnitchError(
1339
+ * 'Event validation failed',
1340
+ * 'EVENT_VALIDATION_ERROR',
1341
+ * { eventId: event.id, issues: parseResult.error.issues }
1342
+ * );
1343
+ * ```
1344
+ */
1345
+ declare class AISnitchError extends Error {
1346
+ /**
1347
+ * Machine-readable error code for programmatic handling.
1348
+ * Format: `SUBCATEGORY_SPECIFIC_DETAIL` (uppercase with underscores).
1349
+ */
1350
+ readonly code: string;
1351
+ /**
1352
+ * Arbitrary context bag forwarded to the logger for structured debugging.
1353
+ */
1354
+ readonly context?: Readonly<Record<string, unknown>>;
1355
+ constructor(message: string, code: string, context?: Readonly<Record<string, unknown>>);
1356
+ /**
1357
+ * Full error chain for logging: `[name] code — message`.
1358
+ */
1359
+ toString(): string;
1360
+ /**
1361
+ * JSON serialization friendly to pino serializers.
1362
+ */
1363
+ toJSON(): object;
1364
+ }
1365
+ /**
1366
+ * Errors originating from adapter lifecycle, payload parsing, or event emission.
1367
+ *
1368
+ * @example
1369
+ * ```typescript
1370
+ * throw new AdapterError(
1371
+ * 'Claude Code transcript read failed',
1372
+ * 'ADAPTER_CLAUDE_CODE_FILE_ERROR',
1373
+ * { filePath: transcriptPath, cause: error }
1374
+ * );
1375
+ * ```
1376
+ */
1377
+ declare class AdapterError extends AISnitchError {
1378
+ constructor(message: string, code: string, context?: Readonly<Record<string, unknown>>);
1379
+ /**
1380
+ * Factory for adapter-specific errors with auto-generated codes.
1381
+ */
1382
+ static withAutoCode(message: string, tool: string, context?: Readonly<Record<string, unknown>>): AdapterError;
1383
+ }
1384
+ /**
1385
+ * Errors originating from pipeline orchestration, component startup, or shutdown.
1386
+ *
1387
+ * @example
1388
+ * ```typescript
1389
+ * throw new PipelineError(
1390
+ * 'Failed to start WebSocket server',
1391
+ * 'PIPELINE_WS_START_FAILED',
1392
+ * { port: configuredPort, cause: error }
1393
+ * );
1394
+ * ```
1395
+ */
1396
+ declare class PipelineError extends AISnitchError {
1397
+ constructor(message: string, code: string, context?: Readonly<Record<string, unknown>>);
1398
+ }
1399
+ /**
1400
+ * Errors from Zod schema parsing failures and data validation violations.
1401
+ *
1402
+ * @example
1403
+ * ```typescript
1404
+ * const result = EventDataSchema.safeParse(rawPayload);
1405
+ * if (!result.success) {
1406
+ * throw new ValidationError(
1407
+ * 'Invalid event data payload',
1408
+ * 'VALIDATION_EVENT_DATA_INVALID',
1409
+ * { issues: result.error.issues }
1410
+ * );
1411
+ * }
1412
+ * ```
1413
+ */
1414
+ declare class ValidationError extends AISnitchError {
1415
+ constructor(message: string, code: string, context?: Readonly<Record<string, unknown>>);
1416
+ }
1417
+ /**
1418
+ * Errors from network operations: HTTP requests, WebSocket connections, UDS.
1419
+ *
1420
+ * @example
1421
+ * ```typescript
1422
+ * throw new NetworkError(
1423
+ * 'Health endpoint unreachable',
1424
+ * 'NETWORK_HTTP_CONNECT_FAILED',
1425
+ * { host: '127.0.0.1', port: 4821, cause: error }
1426
+ * );
1427
+ * ```
1428
+ */
1429
+ declare class NetworkError extends AISnitchError {
1430
+ constructor(message: string, code: string, context?: Readonly<Record<string, unknown>>);
1431
+ }
1432
+ /**
1433
+ * Errors from async operations that exceed their configured deadline.
1434
+ *
1435
+ * @example
1436
+ * ```typescript
1437
+ * throw new TimeoutError(
1438
+ * 'Adapter stop timed out after 5 seconds',
1439
+ * 'TIMEOUT_SHUTDOWN',
1440
+ * { component: 'ClaudeCodeAdapter', timeoutMs: 5_000 }
1441
+ * );
1442
+ * ```
1443
+ */
1444
+ declare class TimeoutError extends AISnitchError {
1445
+ constructor(message: string, code: string, context?: Readonly<Record<string, unknown>>);
1446
+ }
1447
+ /**
1448
+ * Type guard to narrow any `unknown` error to an AISnitch error.
1449
+ *
1450
+ * @example
1451
+ * ```typescript
1452
+ * } catch (error: unknown) {
1453
+ * if (isAISnitchError(error)) {
1454
+ * console.error(`AISnitch error ${error.code}: ${error.message}`);
1455
+ * } else {
1456
+ * console.error('Unexpected error', error);
1457
+ * }
1458
+ * }
1459
+ * ```
1460
+ */
1461
+ declare function isAISnitchError(error: unknown): error is AISnitchError;
1462
+ /**
1463
+ * Determines whether an error is safe to retry (transient vs. permanent).
1464
+ *
1465
+ * Returns `true` for network timeouts, connection reset, and rate-limit errors.
1466
+ * Returns `false` for validation errors, authentication failures, and programming bugs.
1467
+ *
1468
+ * @example
1469
+ * ```typescript
1470
+ * try {
1471
+ * return await operation();
1472
+ * } catch (error: unknown) {
1473
+ * if (isRetryableError(error)) {
1474
+ * throw error; // let retry logic handle it
1475
+ * }
1476
+ * throw error; // propagate as-is (non-retryable)
1477
+ * }
1478
+ * ```
1479
+ */
1480
+ declare function isRetryableError(error: unknown): boolean;
1481
+
1482
+ /**
1483
+ * @file src/core/circuit-breaker.ts
1484
+ * @description Circuit breaker pattern implementation for resilient adapter operation.
1485
+ *
1486
+ * The circuit breaker prevents cascading failures when an adapter repeatedly fails:
1487
+ *
1488
+ * ```
1489
+ * CLOSED (normal) ──[N failures]──→ OPEN (failing fast)
1490
+ * ↑ │
1491
+ * │ [half-open after timeout]
1492
+ * │ ↓
1493
+ * └──────[success]──── HALF-OPEN (testing recovery)
1494
+ * ```
1495
+ *
1496
+ * When an adapter fails `threshold` times within `windowMs`, the breaker opens:
1497
+ * - Subsequent calls fail immediately with `CircuitOpenError` (no network round-trips)
1498
+ * - After `halfOpenAfterMs`, one test call is allowed to check recovery
1499
+ * - If it succeeds → close the circuit (back to normal operation)
1500
+ * - If it fails → reopen and wait again
1501
+ *
1502
+ * ## When to use this
1503
+ *
1504
+ * - Adapter `emit()` calls that can fail repeatedly (file system errors, hook timeouts)
1505
+ * - Network operations with unreliable backends
1506
+ * - Any operation where persistent failure is worse than temporary unavailability
1507
+ *
1508
+ * ## When NOT to use this
1509
+ *
1510
+ * - One-off errors that are unlikely to repeat
1511
+ * - Validation failures (these indicate a programming bug, not a transient fault)
1512
+ * - Operations that are already idempotent with built-in retry (prefer `withRetry`)
1513
+ *
1514
+ * @functions
1515
+ * → none
1516
+ * @exports CircuitState, CircuitOpenError, CircuitBreaker
1517
+ * @see ./errors.ts
1518
+ * @see ./retry.ts
1519
+ * @see ./timeout.ts
1520
+ */
1521
+
1522
+ /**
1523
+ * Observable state of a circuit breaker.
1524
+ */
1525
+ interface CircuitState {
1526
+ /**
1527
+ * Number of consecutive failures since last success.
1528
+ */
1529
+ readonly failures: number;
1530
+ /**
1531
+ * Timestamp of the last failure (ms since epoch), or null if never failed.
1532
+ */
1533
+ readonly lastFailureAt: number | null;
1534
+ /**
1535
+ * Current state of the circuit.
1536
+ * - `closed`: Normal operation, requests pass through
1537
+ * - `open`: Failing fast, requests are rejected immediately
1538
+ * - `half-open`: Testing recovery, one request is allowed through
1539
+ */
1540
+ readonly state: 'closed' | 'open' | 'half-open';
1541
+ }
1542
+ /**
1543
+ * Error thrown when a circuit is open and the operation is rejected.
1544
+ */
1545
+ declare class CircuitOpenError extends AISnitchError {
1546
+ readonly circuitId: string;
1547
+ readonly state: CircuitState;
1548
+ constructor(circuitId: string, state: CircuitState);
1549
+ toString(): string;
1550
+ }
1551
+ /**
1552
+ * Configuration for a circuit breaker instance.
1553
+ */
1554
+ interface CircuitBreakerOptions {
1555
+ /**
1556
+ * Number of consecutive failures before opening the circuit.
1557
+ * @default 5
1558
+ */
1559
+ readonly failureThreshold?: number;
1560
+ /**
1561
+ * Time window in milliseconds to count failures within.
1562
+ * @default 60_000 (1 minute)
1563
+ */
1564
+ readonly windowMs?: number;
1565
+ /**
1566
+ * Time to wait before transitioning from OPEN to HALF-OPEN.
1567
+ * @default 30_000 (30 seconds)
1568
+ */
1569
+ readonly halfOpenAfterMs?: number;
1570
+ /**
1571
+ * Human-readable identifier for this circuit (shown in logs).
1572
+ * @default 'unnamed'
1573
+ */
1574
+ readonly id?: string;
1575
+ /**
1576
+ * Optional predicate to decide which errors count toward the threshold.
1577
+ * Return `true` to count as a failure, `false` to ignore (success-like failure).
1578
+ * @default isRetryableError
1579
+ */
1580
+ readonly shouldCountAsFailure?: (error: unknown) => boolean;
1581
+ /**
1582
+ * Set to `true` to reset the failure counter after any success in CLOSED state.
1583
+ * Set to `false` to only reset after `failureThreshold` successes.
1584
+ * @default true
1585
+ */
1586
+ readonly resetOnSuccess?: boolean;
1587
+ }
1588
+ /**
1589
+ * Circuit breaker state machine.
1590
+ *
1591
+ * ## State transitions
1592
+ *
1593
+ * ```
1594
+ * CLOSED ──[failure + threshold reached]──→ OPEN
1595
+ * ▲ │
1596
+ * │ [halfOpenAfterMs elapsed]
1597
+ * │ ↓
1598
+ * │ HALF-OPEN
1599
+ * │ │
1600
+ * │ [test call succeeds]
1601
+ * │ ↓
1602
+ * └────────────[reset]───────────────────┘
1603
+ * ```
1604
+ *
1605
+ * ## Usage
1606
+ *
1607
+ * ```typescript
1608
+ * const breaker = new CircuitBreaker({
1609
+ * id: 'claude-code.emit',
1610
+ * failureThreshold: 3,
1611
+ * windowMs: 60_000,
1612
+ * });
1613
+ *
1614
+ * async function safeEmit(event: AISnitchEvent) {
1615
+ * return breaker.execute(() => adapter.emit(event));
1616
+ * }
1617
+ * ```
1618
+ */
1619
+ declare class CircuitBreaker {
1620
+ private failures;
1621
+ private lastFailureAt;
1622
+ private state;
1623
+ private halfOpenTestStartedAt;
1624
+ private readonly options;
1625
+ constructor(options?: CircuitBreakerOptions);
1626
+ /**
1627
+ * Executes an async operation through the circuit breaker.
1628
+ *
1629
+ * - If the circuit is CLOSED → runs `fn` and updates state based on result
1630
+ * - If the circuit is HALF-OPEN → runs `fn` once to test recovery
1631
+ * - If the circuit is OPEN → throws `CircuitOpenError` immediately (no call)
1632
+ *
1633
+ * @param fn - The async operation to protect
1634
+ * @returns The result of `fn` if successful
1635
+ * @throws CircuitOpenError if the circuit is OPEN
1636
+ * @throws The error from `fn` if it throws (and `shouldCountAsFailure` returns true)
1637
+ */
1638
+ execute<T>(fn: () => Promise<T>): Promise<T>;
1639
+ /**
1640
+ * Returns the current observable circuit state.
1641
+ */
1642
+ getState(): CircuitState;
1643
+ /**
1644
+ * Forces the circuit to CLOSED (resets failure count and state).
1645
+ * Useful for manual recovery after a known-fix or after a maintenance window.
1646
+ */
1647
+ reset(): void;
1648
+ /**
1649
+ * Pre-warms the circuit by performing one test call in HALF-OPEN state.
1650
+ * If the circuit is already HALF-OPEN, this does nothing.
1651
+ * If the circuit is CLOSED, this does nothing.
1652
+ */
1653
+ preWarm(fn: () => Promise<void>): Promise<void>;
1654
+ private executeClosed;
1655
+ private executeHalfOpen;
1656
+ private onSuccess;
1657
+ private onFailure;
1658
+ private transitionToOpen;
1659
+ private transitionToHalfOpen;
1660
+ private transitionToClosed;
1661
+ private shouldTransitionToHalfOpen;
1662
+ }
1663
+ /**
1664
+ * Shared circuit breaker instances for common AISnitch operations.
1665
+ * These are module-level singletons to avoid creating new breakers on every call.
1666
+ *
1667
+ * Usage:
1668
+ * ```typescript
1669
+ * import { SHARED_BREAKERS } from './circuit-breaker.js';
1670
+ *
1671
+ * // Wrap an adapter emit call
1672
+ * await SHARED_BREAKERS.adapterEmit.execute(() => adapter.emit(event));
1673
+ * ```
1674
+ */
1675
+ declare const SHARED_BREAKERS: Readonly<{
1676
+ /**
1677
+ * Breaker for adapter event emission.
1678
+ * Threshold: 5 failures in 60s → open for 30s → half-open test.
1679
+ */
1680
+ adapterEmit: CircuitBreaker;
1681
+ /**
1682
+ * Breaker for file system operations (transcript reading, config loading).
1683
+ * More tolerant: 10 failures in 60s → open for 30s.
1684
+ */
1685
+ fileSystem: CircuitBreaker;
1686
+ /**
1687
+ * Breaker for HTTP/HTTPS requests.
1688
+ * Stricter: 3 failures in 30s → open for 15s.
1689
+ */
1690
+ httpRequest: CircuitBreaker;
1691
+ /**
1692
+ * Breaker for process detection operations.
1693
+ * Most tolerant: 20 failures in 60s → open for 10s.
1694
+ */
1695
+ processDetection: CircuitBreaker;
1696
+ }>;
1173
1697
 
1174
1698
  /**
1175
1699
  * @file src/core/config/defaults.ts
@@ -1762,12 +2286,815 @@ declare class Pipeline {
1762
2286
  * Returns the in-process event bus for direct wiring in tests or future TUI code.
1763
2287
  */
1764
2288
  getEventBus(): EventBus;
2289
+ /**
2290
+ * Returns the adapter registry for graceful shutdown coordination.
2291
+ */
2292
+ getAdapterRegistry(): AdapterRegistry | undefined;
2293
+ /**
2294
+ * Returns the HTTP receiver for graceful shutdown coordination.
2295
+ */
2296
+ getHttpReceiver(): HTTPReceiver;
2297
+ /**
2298
+ * Returns the UDS server for graceful shutdown coordination.
2299
+ */
2300
+ getUdsServer(): UDSServer;
2301
+ /**
2302
+ * Returns the WebSocket server for graceful shutdown coordination.
2303
+ */
2304
+ getWsServer(): WSServer;
1765
2305
  private getHealthSnapshot;
1766
2306
  private handleHook;
1767
2307
  private handleHookInner;
1768
2308
  private isPlainRecord;
1769
2309
  }
1770
2310
 
2311
+ /**
2312
+ * @file src/core/graceful-shutdown.ts
2313
+ * @description Graceful shutdown coordination to prevent orphaned resources and partial state.
2314
+ *
2315
+ * Graceful shutdown is critical for a long-running daemon like AISnitch:
2316
+ * - **No orphaned servers**: HTTP/WebSocket/UDS servers must be closed cleanly
2317
+ * - **No resource leaks**: file watchers, pollers, timers must be stopped
2318
+ * - **Clean PID files**: stale PID files confuse subsequent launches
2319
+ * - **Clean state files**: daemon-state.json must be removed on exit
2320
+ *
2321
+ * This module provides:
2322
+ * - `withShutdownTimeout()` — wrap a shutdown function with a deadline
2323
+ * - `shutdownInOrder()` — stop components in reverse dependency order
2324
+ * - `GracefulShutdownManager` — coordinates all shutdown signals (SIGTERM, SIGINT, SIGHUP)
2325
+ *
2326
+ * ## Shutdown order for AISnitch pipeline
2327
+ *
2328
+ * ```
2329
+ * 1. adapters.stopAll() — stop watching files, kill pollers, close watchers
2330
+ * 2. httpReceiver.stop() — close HTTP server
2331
+ * 3. udsServer.stop() — close Unix Domain Socket
2332
+ * 4. wsServer.stop() — close WebSocket server (consumers get disconnected)
2333
+ * 5. eventBus.unsubscribeAll() — remove all listeners
2334
+ * 6. cleanup PID/state files — prevent stale state on next launch
2335
+ * ```
2336
+ *
2337
+ * @functions
2338
+ * → withShutdownTimeout
2339
+ * → shutdownInOrder
2340
+ * @exports GracefulShutdownManager, ShutdownComponents, withShutdownTimeout, shutdownInOrder
2341
+ * @see ./errors.ts (TimeoutError)
2342
+ * @see ./timeout.ts (DEFAULT_TIMEOUTS)
2343
+ * @see ../cli/runtime.ts (shutdown orchestration)
2344
+ */
2345
+ /**
2346
+ * All AISnitch components that participate in graceful shutdown.
2347
+ * Stopped in reverse dependency order (last-started = first-stopped).
2348
+ */
2349
+ interface ShutdownComponents {
2350
+ readonly adapterRegistry?: {
2351
+ stopAll: () => Promise<void>;
2352
+ };
2353
+ readonly httpReceiver?: {
2354
+ stop: () => Promise<void>;
2355
+ };
2356
+ readonly udsServer?: {
2357
+ stop: () => Promise<void>;
2358
+ };
2359
+ readonly wsServer?: {
2360
+ stop: () => Promise<void>;
2361
+ };
2362
+ readonly eventBus?: {
2363
+ unsubscribeAll: () => void;
2364
+ };
2365
+ readonly cleanupFns?: ReadonlyArray<() => Promise<void> | void>;
2366
+ }
2367
+ /**
2368
+ * Wraps an async shutdown operation with a deadline.
2369
+ *
2370
+ * If the shutdown completes within `timeoutMs`, returns normally.
2371
+ * If the timeout fires first, logs a warning and continues (forces through).
2372
+ *
2373
+ * This ensures that a misbehaving component can never indefinitely block
2374
+ * daemon shutdown and leave the system in a half-dead state.
2375
+ *
2376
+ * @example
2377
+ * ```typescript
2378
+ * await withShutdownTimeout(
2379
+ * () => adapter.stop(),
2380
+ * DEFAULT_TIMEOUTS.adapterShutdown,
2381
+ * 'ClaudeCodeAdapter'
2382
+ * );
2383
+ * ```
2384
+ *
2385
+ * @param fn - Async shutdown function to execute
2386
+ * @param timeoutMs - Maximum time to wait in milliseconds
2387
+ * @param component - Human-readable name for logging
2388
+ */
2389
+ declare function withShutdownTimeout(fn: () => Promise<void>, timeoutMs: number, component: string): Promise<void>;
2390
+ /**
2391
+ * Stops AISnitch components in safe reverse-dependency order with individual timeouts.
2392
+ *
2393
+ * ## Why reverse order?
2394
+ *
2395
+ * The pipeline starts: adapters → HTTP → UDS → WS → eventBus
2396
+ * If we stop WS before HTTP, new connections keep arriving at HTTP.
2397
+ * If we stop eventBus before WS, consumers get events from the bus but can't send them.
2398
+ * Therefore, stop in reverse: eventBus → WS → UDS → HTTP → adapters.
2399
+ *
2400
+ * @example
2401
+ * ```typescript
2402
+ * await shutdownInOrder(
2403
+ * {
2404
+ * eventBus: pipeline.getEventBus(),
2405
+ * wsServer: pipeline.getWSServer(),
2406
+ * httpReceiver: pipeline.getHTTPReceiver(),
2407
+ * udsServer: pipeline.getUDSServer(),
2408
+ * adapterRegistry: pipeline.getAdapterRegistry(),
2409
+ * cleanupFns: [
2410
+ * () => removePid(pathOptions),
2411
+ * () => removeDaemonState(pathOptions),
2412
+ * ],
2413
+ * },
2414
+ * {
2415
+ * eventBus: 1_000,
2416
+ * wsServer: 3_000,
2417
+ * httpReceiver: 2_000,
2418
+ * udsServer: 2_000,
2419
+ * adapterRegistry: 5_000,
2420
+ * },
2421
+ * 'AISnitch pipeline'
2422
+ * );
2423
+ * ```
2424
+ *
2425
+ * @param components - Components to shut down
2426
+ * @param timeouts - Per-component timeout in milliseconds
2427
+ * @param label - Human-readable label for logging
2428
+ */
2429
+ declare function shutdownInOrder(components: ShutdownComponents, timeouts: Partial<Record<keyof ShutdownComponents, number>>, label: string): Promise<void>;
2430
+ /**
2431
+ * Coordinates all shutdown signals (SIGTERM, SIGINT, SIGHUP) for a process.
2432
+ *
2433
+ * ## Why a manager class?
2434
+ *
2435
+ * - Multiple signals can arrive in quick succession (e.g., SIGTERM then SIGINT)
2436
+ * - Handlers must be idempotent (second call does nothing)
2437
+ * - The manager tracks whether shutdown is already in progress
2438
+ * - It ensures the main process exits with the correct exit code
2439
+ *
2440
+ * @example
2441
+ * ```typescript
2442
+ * const manager = new GracefulShutdownManager({
2443
+ * onShutdown: async (signal) => {
2444
+ * await shutdownInOrder(pipeline, timeouts, 'pipeline');
2445
+ * await cleanupFiles(pathOptions);
2446
+ * },
2447
+ * signal: 'SIGTERM',
2448
+ * });
2449
+ *
2450
+ * process.on('SIGTERM', manager.handler);
2451
+ * process.on('SIGINT', manager.handler);
2452
+ *
2453
+ * // Call handler manually to trigger shutdown from anywhere
2454
+ * await manager.shutdown('manual-trigger');
2455
+ * ```
2456
+ */
2457
+ declare class GracefulShutdownManager {
2458
+ private readonly options;
2459
+ private shuttingDown;
2460
+ private readonly pendingHandlers;
2461
+ /**
2462
+ * Creates a new shutdown manager.
2463
+ *
2464
+ * @param options - Configuration options
2465
+ * @param options.onShutdown - Async function called when shutdown is triggered
2466
+ * @param options.exitCode - Exit code to use (default: 0 for graceful, 1 for errors)
2467
+ * @param options.exitDelayMs - Delay before `process.exit()` (default: 100ms for flush)
2468
+ */
2469
+ constructor(options: {
2470
+ readonly onShutdown: (signal: string) => Promise<void>;
2471
+ readonly exitCode?: number;
2472
+ readonly exitDelayMs?: number;
2473
+ });
2474
+ /**
2475
+ * Synchronous handler function suitable for `process.on()`.
2476
+ *
2477
+ * Multiple calls are safe — only the first call executes `onShutdown`.
2478
+ * Subsequent calls queue to the internal pending set and run after the
2479
+ * first shutdown completes.
2480
+ */
2481
+ get handler(): (signal: string) => void;
2482
+ /**
2483
+ * Manually triggers shutdown from async code (e.g., TUI quit button).
2484
+ *
2485
+ * @param signal - Signal name (for logging)
2486
+ */
2487
+ shutdown(signal?: string): void;
2488
+ /**
2489
+ * Returns whether shutdown is currently in progress.
2490
+ */
2491
+ isShuttingDown(): boolean;
2492
+ private runShutdown;
2493
+ }
2494
+ /**
2495
+ * Wraps a shutdown promise with an overall deadline.
2496
+ * If the overall shutdown exceeds the deadline, forces the process to exit.
2497
+ *
2498
+ * This is the last resort: no shutdown operation should ever take this long,
2499
+ * but a runaway deadlock could theoretically block forever without it.
2500
+ *
2501
+ * @example
2502
+ * ```typescript
2503
+ * const shutdownComplete = shutdownInOrder(components, timeouts, 'pipeline');
2504
+ * await withOverallShutdownTimeout(shutdownComplete, DEFAULT_TIMEOUTS.daemonShutdown, 'AISnitch');
2505
+ * ```
2506
+ */
2507
+ declare function withOverallShutdownTimeout(shutdownPromise: Promise<void>, timeoutMs: number, label: string): Promise<void>;
2508
+
2509
+ /**
2510
+ * @file src/core/result.ts
2511
+ * @description Simple Result type for explicit error handling without relying on try/catch.
2512
+ *
2513
+ * This is a lightweight alternative to fp-ts Either for cases where you want to force
2514
+ * callers to handle the error case explicitly but don't need the full fp-ts ecosystem.
2515
+ *
2516
+ * The `Result<T, E>` type has two states:
2517
+ * - `{ success: true, value: T }` — operation succeeded with a value
2518
+ * - `{ success: false, error: E }` — operation failed with an error
2519
+ *
2520
+ * Usage pattern:
2521
+ * ```typescript
2522
+ * function parseConfig(raw: unknown): Result<AISnitchConfig, ValidationError> {
2523
+ * const result = ConfigSchema.safeParse(raw);
2524
+ * if (!result.success) {
2525
+ * return err(new ValidationError(
2526
+ * 'Invalid config', 'VALIDATION_CONFIG_INVALID',
2527
+ * { issues: result.error.issues }
2528
+ * ));
2529
+ * }
2530
+ * return ok(result.data);
2531
+ * }
2532
+ *
2533
+ * // Caller must handle both cases
2534
+ * const result = parseConfig(raw);
2535
+ * if (isErr(result)) {
2536
+ * logger.error({ error: result.error }, 'Config parsing failed');
2537
+ * return;
2538
+ * }
2539
+ * // result.value is guaranteed to exist here
2540
+ * useConfig(result.value);
2541
+ * ```
2542
+ *
2543
+ * @functions
2544
+ * → ok
2545
+ * → err
2546
+ * → isOk
2547
+ * → isErr
2548
+ * → mapOk
2549
+ * → mapErr
2550
+ * → flatMap
2551
+ * → fromPromise
2552
+ * @exports Result, ok, err, isOk, isErr, mapOk, mapErr, flatMap, fromPromise
2553
+ * @see ./errors.ts
2554
+ * @see ./retry.ts
2555
+ */
2556
+ /**
2557
+ * Discriminated union representing either a successful value or a failure error.
2558
+ *
2559
+ * @typeParam T - The success value type
2560
+ * @typeParam E - The error type (defaults to `Error`)
2561
+ */
2562
+ type Result<T, E = Error> = {
2563
+ readonly success: true;
2564
+ readonly value: T;
2565
+ } | {
2566
+ readonly success: false;
2567
+ readonly error: E;
2568
+ };
2569
+ /**
2570
+ * Narrowing type guard for the success case.
2571
+ *
2572
+ * @example
2573
+ * ```typescript
2574
+ * const result = maybeDoSomething();
2575
+ * if (isOk(result)) {
2576
+ * console.log(result.value); // TypeScript knows result.value exists
2577
+ * }
2578
+ * ```
2579
+ */
2580
+ declare function isOk<T, E>(result: Result<T, E>): result is {
2581
+ success: true;
2582
+ value: T;
2583
+ };
2584
+ /**
2585
+ * Narrowing type guard for the error case.
2586
+ *
2587
+ * @example
2588
+ * ```typescript
2589
+ * const result = maybeDoSomething();
2590
+ * if (isErr(result)) {
2591
+ * console.error(result.error); // TypeScript knows result.error exists
2592
+ * }
2593
+ * ```
2594
+ */
2595
+ declare function isErr<T, E>(result: Result<T, E>): result is {
2596
+ success: false;
2597
+ error: E;
2598
+ };
2599
+ /**
2600
+ * Constructs a successful result with a value.
2601
+ *
2602
+ * @example
2603
+ * ```typescript
2604
+ * const result = ok({ userId: 42, name: 'Alice' });
2605
+ * // { success: true, value: { userId: 42, name: 'Alice' } }
2606
+ * ```
2607
+ */
2608
+ declare function ok<T>(value: T): Result<T, never>;
2609
+ /**
2610
+ * Constructs a failed result with an error.
2611
+ *
2612
+ * @example
2613
+ * ```typescript
2614
+ * const result = err(new Error('Not found'));
2615
+ * // { success: false, error: Error('Not found') }
2616
+ * ```
2617
+ */
2618
+ declare function err<E extends Error = Error>(error: E): Result<never, E>;
2619
+ /**
2620
+ * Maps the success value through a transformation function.
2621
+ * Errors pass through unchanged.
2622
+ *
2623
+ * @example
2624
+ * ```typescript
2625
+ * const result: Result<User, Error> = ok({ id: 1, name: 'Alice' });
2626
+ * const mapped = mapOk(result, (user) => user.name.toUpperCase());
2627
+ * // { success: true, value: 'ALICE' }
2628
+ * ```
2629
+ */
2630
+ declare function mapOk<T, E, U>(result: Result<T, E>, fn: (value: T) => U): Result<U, E>;
2631
+ /**
2632
+ * Maps the error value through a transformation function.
2633
+ * Success values pass through unchanged.
2634
+ *
2635
+ * @example
2636
+ * ```typescript
2637
+ * const result: Result<User, Error> = err(new Error('original'));
2638
+ * const mapped = mapErr(result, (error) => new CustomError(error.message));
2639
+ * // { success: false, error: CustomError('original') }
2640
+ * ```
2641
+ */
2642
+ declare function mapErr<T, E, F extends Error>(result: Result<T, E>, fn: (error: E) => F): Result<T, F>;
2643
+ /**
2644
+ * Chains Result operations: if the first Result succeeds, apply `fn` to its value.
2645
+ * If it fails, propagate the error without calling `fn`.
2646
+ *
2647
+ * @example
2648
+ * ```typescript
2649
+ * const result = await flatMap(
2650
+ * await parseConfig(raw),
2651
+ * (config) => validateAdapters(config.adapters)
2652
+ * );
2653
+ * // Either returns parseConfig's error, or the error from validateAdapters
2654
+ * ```
2655
+ */
2656
+ declare function flatMap<T, E, U, F extends Error>(result: Result<T, E>, fn: (value: T) => Result<U, F> | Promise<Result<U, F>>): Promise<Result<U, E | F>>;
2657
+ /**
2658
+ * Converts a Promise to a Result, catching errors automatically.
2659
+ * Rejections become `{ success: false, error: E }`.
2660
+ *
2661
+ * @example
2662
+ * ```typescript
2663
+ * const result = await fromPromise(
2664
+ * fetch('http://127.0.0.1:4821/health'),
2665
+ * (error) => new NetworkError(
2666
+ * 'Health check failed',
2667
+ * 'NETWORK_HTTP_CONNECT_FAILED',
2668
+ * { cause: error }
2669
+ * )
2670
+ * );
2671
+ * if (isErr(result)) {
2672
+ * logger.warn({ error: result.error }, 'Daemon health check failed');
2673
+ * return null;
2674
+ * }
2675
+ * const health = await result.value.json();
2676
+ * ```
2677
+ */
2678
+ declare function fromPromise<T, E extends Error>(promise: Promise<T>, mapError: (reason: unknown) => E): Promise<Result<T, E>>;
2679
+ /**
2680
+ * Synchronous version of `fromPromise` for non-async functions.
2681
+ *
2682
+ * @example
2683
+ * ```typescript
2684
+ * const result = fromSync(() => JSON.parse(rawJson), (e) =>
2685
+ * new ValidationError('Invalid JSON', 'VALIDATION_JSON_PARSE', { cause: e })
2686
+ * );
2687
+ * ```
2688
+ */
2689
+ declare function fromSync<T, E extends Error>(fn: () => T, mapError: (reason: unknown) => E): Result<T, E>;
2690
+
2691
+ /**
2692
+ * @file src/core/retry.ts
2693
+ * @description Exponential backoff retry utilities for transient operations.
2694
+ *
2695
+ * Retry logic is essential for resilience against:
2696
+ * - Network flakiness (connection refused, timeouts, DNS failures)
2697
+ * - Transient file-system contention (file locked, directory not ready)
2698
+ * - External API rate limits (backoff on 429 Too Many Requests)
2699
+ *
2700
+ * This module provides:
2701
+ * - `withRetry()` — async function with exponential backoff
2702
+ * - `RetryOptions` — configurable retry parameters
2703
+ * - `DefaultRetryOptions` — sensible defaults for AISnitch workloads
2704
+ *
2705
+ * Usage:
2706
+ * ```typescript
2707
+ * const result = await withRetry(
2708
+ * () => fetchHealth(daemonPort),
2709
+ * {
2710
+ * attempts: 3,
2711
+ * delayMs: 500,
2712
+ * backoff: 2,
2713
+ * context: 'daemon-health-check',
2714
+ * }
2715
+ * );
2716
+ * ```
2717
+ *
2718
+ * @functions
2719
+ * → withRetry
2720
+ * → sleep
2721
+ * → DefaultRetryOptions
2722
+ * @exports RetryOptions, DefaultRetryOptions, withRetry, sleep
2723
+ * @see ./errors.ts
2724
+ * @see ./result.ts
2725
+ */
2726
+ /**
2727
+ * Configuration for retry behaviour.
2728
+ */
2729
+ interface RetryOptions {
2730
+ /**
2731
+ * Maximum number of attempts before giving up.
2732
+ * @default 3
2733
+ */
2734
+ readonly attempts: number;
2735
+ /**
2736
+ * Initial delay in milliseconds between retries.
2737
+ * @default 500
2738
+ */
2739
+ readonly delayMs: number;
2740
+ /**
2741
+ * Multiplicative factor for delay after each attempt.
2742
+ * @default 2
2743
+ */
2744
+ readonly backoff: number;
2745
+ /**
2746
+ * Maximum total time in milliseconds across all retries.
2747
+ * @default 30_000
2748
+ */
2749
+ readonly maxTotalDelayMs: number;
2750
+ /**
2751
+ * Human-readable label used in log messages for traceability.
2752
+ */
2753
+ readonly context: string;
2754
+ /**
2755
+ * Optional predicate to filter which errors trigger a retry.
2756
+ * By default, `isRetryableError()` is used.
2757
+ * Return `true` to retry, `false` to give up immediately.
2758
+ */
2759
+ readonly shouldRetry?: (error: unknown) => boolean;
2760
+ /**
2761
+ * Set to `true` to jitter the delay slightly (±25%) to avoid thundering herd.
2762
+ * @default true
2763
+ */
2764
+ readonly jitter?: boolean;
2765
+ }
2766
+ /**
2767
+ * Sensible defaults tuned for AISnitch workloads:
2768
+ * - Quick first retry (500ms) for responsiveness
2769
+ * - Exponential backoff to back off gracefully
2770
+ * - 3 attempts to avoid long stalls
2771
+ * - Jitter enabled to spread load
2772
+ */
2773
+ declare const DefaultRetryOptions: Readonly<RetryOptions>;
2774
+ /**
2775
+ * Blocks the current async execution for the given number of milliseconds.
2776
+ *
2777
+ * @example
2778
+ * ```typescript
2779
+ * await sleep(1000); // wait 1 second
2780
+ * ```
2781
+ */
2782
+ declare function sleep(ms: number): Promise<void>;
2783
+ /**
2784
+ * Wraps an async operation with exponential-backoff retry logic.
2785
+ *
2786
+ * ## How it works
2787
+ *
2788
+ * 1. Executes `fn` immediately (no initial delay)
2789
+ * 2. If it succeeds → returns the result
2790
+ * 3. If it throws and `shouldRetry(error)` returns `true` and attempts remain:
2791
+ * - Logs a warning at attempt level (warn) and at failure level (error)
2792
+ * - Waits `delayMs * backoff^attempt` milliseconds (with optional jitter)
2793
+ * - Repeats from step 1
2794
+ * 4. If it throws and `shouldRetry(error)` returns `false` → throws immediately
2795
+ * 5. If all attempts are exhausted → throws the last error
2796
+ *
2797
+ * ## When NOT to use this
2798
+ *
2799
+ * - **Permanent failures** (e.g., validation errors, missing required files)
2800
+ * → Use `isRetryableError()` to filter these out automatically
2801
+ * - **Operations that are not idempotent** → only retry if `fn` is safe to re-execute
2802
+ * - **User-facing latency-sensitive paths** → use a shorter `delayMs` and fewer `attempts`
2803
+ *
2804
+ * @example
2805
+ * ```typescript
2806
+ * // Retry a flaky health check up to 3 times
2807
+ * const health = await withRetry(
2808
+ * () => fetch('http://127.0.0.1:4821/health').then(r => r.json()),
2809
+ * {
2810
+ * ...DefaultRetryOptions,
2811
+ * context: 'daemon-health-check',
2812
+ * }
2813
+ * );
2814
+ * ```
2815
+ */
2816
+ declare function withRetry<T>(fn: () => Promise<T>, options: Partial<RetryOptions> & {
2817
+ context: string;
2818
+ }): Promise<T>;
2819
+ /**
2820
+ * Convenience wrapper for fire-and-forget retries (no return value needed).
2821
+ * Logs failures but never throws — useful for non-critical background tasks.
2822
+ *
2823
+ * @example
2824
+ * ```typescript
2825
+ * // Best-effort metric reporting — don't fail the main flow
2826
+ * fireAndForgetRetry(
2827
+ * () => sendMetrics(metrics),
2828
+ * { context: 'metrics-report', attempts: 2 }
2829
+ * );
2830
+ * ```
2831
+ */
2832
+ declare function fireAndForgetRetry<T>(fn: () => Promise<T>, options: Partial<RetryOptions> & {
2833
+ context: string;
2834
+ }): void;
2835
+ /**
2836
+ * Builds a retry-enabled version of any async function.
2837
+ * The returned function will automatically retry on retryable errors.
2838
+ *
2839
+ * @example
2840
+ * ```typescript
2841
+ * const safeReadFile = withRetryOn(
2842
+ * (path: string) => readFile(path, 'utf8'),
2843
+ * { attempts: 3, delayMs: 200, context: 'file-read' }
2844
+ * );
2845
+ *
2846
+ * const content = await safeReadFile('/path/to/file.txt');
2847
+ * ```
2848
+ */
2849
+ declare function withRetryOn<T extends (...args: never[]) => Promise<unknown>>(fn: T, options: Partial<RetryOptions> & {
2850
+ context: string;
2851
+ }): T;
2852
+
2853
+ /**
2854
+ * @file src/core/safety.ts
2855
+ * @description Type-safe extraction helpers for working with untyped record data.
2856
+ *
2857
+ * AISnitch often deals with loosely-typed payloads:
2858
+ * - Hook payloads from third-party tools (Claude Code, OpenCode, etc.)
2859
+ * - JSONL transcript observations parsed from raw JSON
2860
+ * - Config files loaded from disk
2861
+ * - Event data fields that may be undefined
2862
+ *
2863
+ * This module provides:
2864
+ * - `getString()` / `getNumber()` / `getBoolean()` — safe extractors with type narrowing
2865
+ * - `getStringOrDefault()` / `getNumberOrDefault()` — with fallback defaults
2866
+ * - `getArray()` / `getObject()` — structural validation
2867
+ * - `getSafeInteger()` — integer with bounds checking
2868
+ * - `getPositiveNumber()` — positive values only
2869
+ * - `isValidPort()` — network port validation (1-65535)
2870
+ * - `isValidPathLength()` — POSIX path limit check (4096 chars)
2871
+ * - `isValidStringLength()` — max string length check
2872
+ *
2873
+ * ## Why not just use optional chaining?
2874
+ *
2875
+ * Optional chaining (`?.`) protects against null/undefined access chains, but it:
2876
+ * - Does NOT validate the type of the value (e.g., `obj.key` could be `string | number | null`)
2877
+ * - Does NOT enforce constraints (e.g., port range, string max length)
2878
+ * - Does NOT normalize values (e.g., trimming strings, clamping numbers)
2879
+ *
2880
+ * These helpers do all of the above in one call.
2881
+ *
2882
+ * @functions
2883
+ * → getString
2884
+ * → getNumber
2885
+ * → getBoolean
2886
+ * → getSafeInteger
2887
+ * → getPositiveNumber
2888
+ * → isValidPort
2889
+ * → isValidPathLength
2890
+ * → isValidStringLength
2891
+ * → getArray
2892
+ * → getObject
2893
+ * @exports getString, getNumber, getBoolean, getSafeInteger, getPositiveNumber, isValidPort, isValidPathLength, isValidStringLength, getArray, getObject
2894
+ * @see ./errors.ts
2895
+ * @see ./result.ts
2896
+ */
2897
+ /**
2898
+ * Maximum valid TCP/UDP port number.
2899
+ * Ports below 1024 require root privileges on Unix.
2900
+ */
2901
+ declare const MAX_PORT = 65535;
2902
+ /**
2903
+ * Minimum valid TCP/UDP port number.
2904
+ */
2905
+ declare const MIN_PORT = 1;
2906
+ /**
2907
+ * Maximum path length per POSIX (NAME_MAX).
2908
+ * Most filesystems support 255 bytes per path component, but the total path
2909
+ * can grow much longer. 4096 is a safe upper bound for in-memory validation.
2910
+ */
2911
+ declare const MAX_PATH_LENGTH = 4096;
2912
+ /**
2913
+ * Maximum string length for most AISnitch fields (file paths, model names, etc.).
2914
+ * Beyond this, truncation or rejection is safer than silent truncation.
2915
+ */
2916
+ declare const MAX_GENERIC_STRING_LENGTH = 10000;
2917
+ /**
2918
+ * Maximum length for short labels (tool names, session IDs, event types).
2919
+ * These should always be kept short for display.
2920
+ */
2921
+ declare const MAX_LABEL_LENGTH = 255;
2922
+ /**
2923
+ * Extracts a non-empty trimmed string from a record field.
2924
+ *
2925
+ * @example
2926
+ * ```typescript
2927
+ * const model = getString(payload, 'model');
2928
+ * // → 'claude-sonnet-4-20250514' | undefined
2929
+ * ```
2930
+ */
2931
+ declare function getString(record: Record<string, unknown>, key: string): string | undefined;
2932
+ /**
2933
+ * Extracts a string and enforces a maximum length.
2934
+ * If the string exceeds `maxLength`, it is truncated to that length.
2935
+ *
2936
+ * @example
2937
+ * ```typescript
2938
+ * const truncated = getStringWithMaxLength(payload, 'errorMessage', 10_000);
2939
+ * ```
2940
+ */
2941
+ declare function getStringWithMaxLength(record: Record<string, unknown>, key: string, maxLength: number): string | undefined;
2942
+ /**
2943
+ * Extracts a finite number from a record field.
2944
+ *
2945
+ * Filters out `NaN`, `Infinity`, `-Infinity`.
2946
+ *
2947
+ * @example
2948
+ * ```typescript
2949
+ * const pid = getNumber(payload, 'pid');
2950
+ * // → 12345 | undefined
2951
+ * ```
2952
+ */
2953
+ declare function getNumber(record: Record<string, unknown>, key: string): number | undefined;
2954
+ /**
2955
+ * Extracts a finite integer within a range.
2956
+ *
2957
+ * @example
2958
+ * ```typescript
2959
+ * const seqnum = getSafeInteger(payload, 'seqnum', { min: 1 });
2960
+ * // → 42 | undefined
2961
+ * ```
2962
+ */
2963
+ declare function getSafeInteger(record: Record<string, unknown>, key: string, options?: {
2964
+ min?: number;
2965
+ max?: number;
2966
+ }): number | undefined;
2967
+ /**
2968
+ * Extracts a positive number ( > 0).
2969
+ *
2970
+ * @example
2971
+ * ```typescript
2972
+ * const tokens = getPositiveNumber(payload, 'tokensUsed');
2973
+ * // → 1500 | undefined (rejects 0, negative)
2974
+ * ```
2975
+ */
2976
+ declare function getPositiveNumber(record: Record<string, unknown>, key: string): number | undefined;
2977
+ /**
2978
+ * Extracts a boolean from a record field.
2979
+ *
2980
+ * Handles the common "stringified boolean" pattern where config files
2981
+ * or query parameters store booleans as strings ('true', 'false').
2982
+ *
2983
+ * @example
2984
+ * ```typescript
2985
+ * const enabled = getBoolean(record, 'enabled');
2986
+ * // → true | false | undefined
2987
+ * ```
2988
+ */
2989
+ declare function getBoolean(record: Record<string, unknown>, key: string): boolean | undefined;
2990
+ /**
2991
+ * Extracts an array from a record field.
2992
+ *
2993
+ * @example
2994
+ * ```typescript
2995
+ * const parts = getArray(payload, 'content');
2996
+ * // → unknown[] | undefined
2997
+ * ```
2998
+ */
2999
+ declare function getArray<T = unknown>(record: Record<string, unknown>, key: string): T[] | undefined;
3000
+ /**
3001
+ * Extracts a plain object from a record field.
3002
+ *
3003
+ * Returns `undefined` for arrays, class instances, `null`, primitives.
3004
+ *
3005
+ * @example
3006
+ * ```typescript
3007
+ * const toolInput = getObject(payload, 'tool_input');
3008
+ * // → Record<string, unknown> | undefined
3009
+ * ```
3010
+ */
3011
+ declare function getObject(record: Record<string, unknown>, key: string): Record<string, unknown> | undefined;
3012
+ /**
3013
+ * Validates whether a port number is within the valid TCP/UDP range (1-65535).
3014
+ *
3015
+ * @example
3016
+ * ```typescript
3017
+ * const port = getSafeInteger(payload, 'port', { min: 1, max: 65535 });
3018
+ * if (isValidPort(port)) {
3019
+ * server.listen(port);
3020
+ * }
3021
+ * ```
3022
+ */
3023
+ declare function isValidPort(port: number | undefined): port is number;
3024
+ /**
3025
+ * Validates whether a path string is within the POSIX NAME_MAX limit.
3026
+ *
3027
+ * Uses the conservative 4096-character limit (actual NAME_MAX varies by FS).
3028
+ * This check is useful for in-memory validation before file system operations.
3029
+ *
3030
+ * @example
3031
+ * ```typescript
3032
+ * const filePath = getString(payload, 'filePath');
3033
+ * if (filePath && isValidPathLength(filePath)) {
3034
+ * readFile(filePath);
3035
+ * }
3036
+ * ```
3037
+ */
3038
+ declare function isValidPathLength(path: string | undefined): path is string;
3039
+ /**
3040
+ * Validates whether a string does not exceed a maximum length.
3041
+ *
3042
+ * @example
3043
+ * ```typescript
3044
+ * const message = getString(payload, 'errorMessage');
3045
+ * if (message && isValidStringLength(message, 10_000)) {
3046
+ * log(message);
3047
+ * }
3048
+ * ```
3049
+ */
3050
+ declare function isValidStringLength(value: string | undefined, maxLength: number): value is string;
3051
+ /**
3052
+ * Checks whether a value is a plain object (not null, not array, not class instance).
3053
+ *
3054
+ * Uses `Object.prototype.toString` to detect class instances:
3055
+ * - Plain objects return `'[object Object]'`
3056
+ * - Class instances return `'[object ClassName]'`
3057
+ *
3058
+ * @example
3059
+ * ```typescript
3060
+ * if (isRecord(payload)) {
3061
+ * const value = payload[key]; // TypeScript narrows to Record<string, unknown>
3062
+ * }
3063
+ * ```
3064
+ */
3065
+ declare function isRecord(value: unknown): value is Record<string, unknown>;
3066
+ /**
3067
+ * Type guard to narrow any `unknown` to a non-null value.
3068
+ *
3069
+ * @example
3070
+ * ```typescript
3071
+ * const cleaned = value != null ? value : defaultValue;
3072
+ * // or using the guard:
3073
+ * if (isNotNull(value)) { ... }
3074
+ * ```
3075
+ */
3076
+ declare function isNotNull<T>(value: T): value is T & NonNullable<unknown>;
3077
+ /**
3078
+ * Extracts a port number with full validation (in range, integer, finite).
3079
+ *
3080
+ * @example
3081
+ * ```typescript
3082
+ * const port = getPort(record, 'httpPort');
3083
+ * // → 4821 | undefined
3084
+ * ```
3085
+ */
3086
+ declare function getPort(record: Record<string, unknown>, key: string): number | undefined;
3087
+ /**
3088
+ * Extracts a sequence number (positive integer >= 1).
3089
+ *
3090
+ * @example
3091
+ * ```typescript
3092
+ * const seqnum = getSeqnum(record, 'seqnum');
3093
+ * // → 42 | undefined
3094
+ * ```
3095
+ */
3096
+ declare function getSeqnum(record: Record<string, unknown>, key: string): number | undefined;
3097
+
1771
3098
  /**
1772
3099
  * @file src/core/session-identity.ts
1773
3100
  * @description Shared helpers for deriving stable session ids and readable session labels from partial runtime metadata.
@@ -1821,6 +3148,166 @@ declare function formatSessionShortId(tool: ToolName, sessionId: string | undefi
1821
3148
  */
1822
3149
  declare function formatSessionLabelFromEvent(event: AISnitchEvent): string;
1823
3150
 
3151
+ /**
3152
+ * @file src/core/timeout.ts
3153
+ * @description Async operation timeout wrappers to prevent indefinite blocking.
3154
+ *
3155
+ * AISnitch processes many async operations (file reads, HTTP requests, process
3156
+ * detection, file watchers, adapter startup/shutdown). Without explicit timeouts,
3157
+ * any of these can block the entire daemon indefinitely if the underlying resource
3158
+ * becomes unresponsive (e.g., NFS mount stuck, disk I/O stalled, external API hanging).
3159
+ *
3160
+ * This module provides:
3161
+ * - `withTimeout()` — race a promise against a deadline
3162
+ * - `TimeoutError` — typed error thrown on timeout
3163
+ * - `DEFAULT_TIMEOUTS` — sane defaults per operation type
3164
+ *
3165
+ * Usage:
3166
+ * ```typescript
3167
+ * // Fail-fast: don't wait more than 3s for a file read
3168
+ * const content = await withTimeout(
3169
+ * readFile('/path/to/transcript.jsonl', 'utf8'),
3170
+ * 3_000,
3171
+ * 'claude-transcript-read'
3172
+ * );
3173
+ * ```
3174
+ *
3175
+ * @functions
3176
+ * → withTimeout
3177
+ * → DEFAULT_TIMEOUTS
3178
+ * @exports DEFAULT_TIMEOUTS, withTimeout
3179
+ * @see ./errors.ts (TimeoutError)
3180
+ * @see ./graceful-shutdown.ts
3181
+ */
3182
+
3183
+ /**
3184
+ * Named timeout windows for common AISnitch operations.
3185
+ *
3186
+ * These defaults are conservative but reasonable for local development:
3187
+ * - File operations: fast on local SSDs, need headroom for larger logs
3188
+ * - HTTP requests: generous (30s) because AI tool hooks can be slow
3189
+ * - Process detection: frequent polling, keep each poll short
3190
+ * - Adapter lifecycle: moderate (10s) for graceful shutdowns
3191
+ *
3192
+ * Override per-call via the `withTimeout()` `timeoutMs` parameter.
3193
+ */
3194
+ declare const DEFAULT_TIMEOUTS: Readonly<{
3195
+ /**
3196
+ * File read/write operations (JSONL transcripts, config files).
3197
+ * Default: 5 seconds
3198
+ */
3199
+ readonly fileOperation: 5000;
3200
+ /**
3201
+ * HTTP requests to health endpoint or external APIs.
3202
+ * Default: 30 seconds
3203
+ */
3204
+ readonly httpRequest: 30000;
3205
+ /**
3206
+ * Process detection commands (`pgrep`, `ps aux`).
3207
+ * Default: 3 seconds
3208
+ */
3209
+ readonly processDetection: 3000;
3210
+ /**
3211
+ * Adapter startup (file watchers, hook bridges, pollers).
3212
+ * Default: 10 seconds
3213
+ */
3214
+ readonly adapterStartup: 10000;
3215
+ /**
3216
+ * Adapter shutdown (graceful cleanup, watcher close).
3217
+ * Default: 5 seconds — after this, resources are force-closed
3218
+ */
3219
+ readonly adapterShutdown: 5000;
3220
+ /**
3221
+ * Daemon graceful shutdown (stop all components in order).
3222
+ * Default: 30 seconds
3223
+ */
3224
+ readonly daemonShutdown: 30000;
3225
+ /**
3226
+ * WebSocket connection establishment.
3227
+ * Default: 10 seconds
3228
+ */
3229
+ readonly wsConnection: 10000;
3230
+ /**
3231
+ * Overall pipeline start (all components).
3232
+ * Default: 15 seconds
3233
+ */
3234
+ readonly pipelineStartup: 15000;
3235
+ }>;
3236
+ /**
3237
+ * Type representing the keys of `DEFAULT_TIMEOUTS`.
3238
+ */
3239
+ type TimeoutName = keyof typeof DEFAULT_TIMEOUTS;
3240
+ /**
3241
+ * Races a promise against a deadline.
3242
+ *
3243
+ * If the promise resolves first, returns the resolved value.
3244
+ * If the timeout fires first, throws a `TimeoutError`.
3245
+ *
3246
+ * The timeout is implemented via `Promise.race()` so it does not
3247
+ * forcefully abort the underlying promise — the promise continues
3248
+ * running in the background. For truly cancellable operations,
3249
+ * consider `AbortController` in addition to this utility.
3250
+ *
3251
+ * @example
3252
+ * ```typescript
3253
+ * try {
3254
+ * const result = await withTimeout(
3255
+ * fetch('http://example.com/slow-endpoint'),
3256
+ * 5_000,
3257
+ * 'external-api-call'
3258
+ * );
3259
+ * return await result.json();
3260
+ * } catch (error) {
3261
+ * if (error instanceof TimeoutError) {
3262
+ * logger.warn({ context: error.context }, 'Operation timed out');
3263
+ * return null;
3264
+ * }
3265
+ * throw error;
3266
+ * }
3267
+ * ```
3268
+ *
3269
+ * @param promise - The async operation to race
3270
+ * @param timeoutMs - Maximum time to wait in milliseconds
3271
+ * @param context - Human-readable label for logging and error context
3272
+ * @returns The resolved value if `promise` wins the race
3273
+ * @throws TimeoutError if the timeout fires first
3274
+ */
3275
+ declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, context: string): Promise<T>;
3276
+ /**
3277
+ * Wraps a promise with a timeout and logs a warning if it times out.
3278
+ * Unlike `withTimeout()`, this never throws — it falls through to the
3279
+ * original promise's result (or error) if the timeout fires first.
3280
+ *
3281
+ * Best-effort: useful for non-critical background operations where a
3282
+ * timeout should log a warning but not crash the flow.
3283
+ *
3284
+ * @example
3285
+ * ```typescript
3286
+ * // Log a warning but don't fail if process detection hangs
3287
+ * await timeoutWarning(
3288
+ * listProcesses(processListCommand),
3289
+ * DEFAULT_TIMEOUTS.processDetection,
3290
+ * 'claude-process-detection'
3291
+ * );
3292
+ * ```
3293
+ */
3294
+ declare function timeoutWarning<T>(promise: Promise<T>, timeoutMs: number, context: string): Promise<T>;
3295
+ /**
3296
+ * Gets the timeout value for a named operation.
3297
+ *
3298
+ * @example
3299
+ * ```typescript
3300
+ * const timeoutMs = getTimeout('adapterShutdown');
3301
+ * // → 5_000
3302
+ * ```
3303
+ */
3304
+ declare function getTimeout(name: TimeoutName): number;
3305
+ /**
3306
+ * Checks whether an error is a TimeoutError.
3307
+ * Shorthand for `error instanceof TimeoutError` with explicit return type.
3308
+ */
3309
+ declare function isTimeoutError(error: unknown): error is TimeoutError;
3310
+
1824
3311
  /**
1825
3312
  * @file src/package-info.ts
1826
3313
  * @description Shared package metadata constants consumed by the public index, CLI, and TUI without creating import cycles.
@@ -2596,4 +4083,4 @@ declare function renderAttachedTui(options: AttachedTuiOptions): Promise<void>;
2596
4083
  */
2597
4084
  declare function renderManagedTui(options: ManagedTuiOptions): Promise<void>;
2598
4085
 
2599
- export { AISNITCH_DESCRIPTION, AISNITCH_EVENT_TYPES, AISNITCH_PACKAGE_NAME, AISNITCH_VERSION, type AISnitchConfig, type AISnitchEvent, AISnitchEventSchema, type AISnitchEventType, AISnitchEventTypeSchema, type AISnitchLoggerLevel, type AISnitchScaffoldInfo, AUTO_UPDATE_MANAGERS, type AdapterConfig, AdapterConfigSchema, type AdapterPublishContext, AdapterRegistry, type AdapterRuntimeOptions, type AdapterStatus, AiderAdapter, type AiderAdapterOptions, type AiderHistoryObservation, type AiderHistoryParseResult, App, type AppProps, type AttachedTuiOptions, type AutoUpdateConfig, AutoUpdateConfigSchema, BaseAdapter, type CESPCategory, CESPCategorySchema, CESP_CATEGORIES, CESP_MAP, ClaudeCodeAdapter, type ClaudeCodeAdapterOptions, CodexAdapter, type CodexAdapterOptions, type ConfigPathOptions, ConfigSchema, ContextDetector, CopilotCLIAdapter, type CopilotCLIAdapterOptions, type CreateEventInput, CursorAdapter, type CursorAdapterOptions, DEFAULT_CONFIG, DEFAULT_TUI_FILTERS, DEFAULT_VISIBLE_EVENT_COUNT, DevinAdapter, type DevinAdapterOptions, ERROR_TYPES, EVENT_COLORS, EVENT_ICONS, EVENT_STREAM_LIMIT, type EnrichedContextFields, type ErrorType, ErrorTypeSchema, EventBus, type EventBusStats, type EventData, EventDataSchema, type EventHandler, EventLine, type EventLineProps, EventStream, type EventStreamProps, type EventStreamSource, FilterBar, type FilterBarProps, type FocusedPanel, type ForegroundTuiOptions, GeminiCLIAdapter, type GeminiCLIAdapterOptions, type GenericPTYObservation, GenericPTYSession, type GenericPTYSessionOptions, type GlobalActivityStatus, GlobalBadge, type GlobalBadgeProps, GooseAdapter, type GooseAdapterOptions, HTTPReceiver, type HTTPReceiverStartOptions, type HTTPReceiverStats, Header, type HeaderProps, type HealthSnapshot, HelpOverlay, type HookHandler, type InterceptionStrategy, KiloAdapter, type KiloAdapterOptions, LOG_LEVELS, ManagedDaemonApp, type ManagedDaemonAppProps, type ManagedTuiOptions, type ManagedTuiSnapshot, type MonitorCloseHandler, type MonitorOutput, type NormalizedAdapterHookPayload, OpenClawAdapter, type OpenClawAdapterOptions, OpenCodeAdapter, type OpenCodeAdapterOptions, Panel, type PanelProps, PanelStack, type PanelStackProps, Pipeline, type PipelineStartOptions, type PipelineStatus, type PortResolutionOptions, type ProcessContext, type ProcessInfo, RingBuffer, SESSION_STALE_AFTER_MS, type SelectorOption, type SessionFilterTarget, type SessionIdentityInput, SessionPanel, type SessionPanelProps, type SessionState, StatusBar, type StatusBarProps, TOOL_COLORS, TOOL_NAMES, TUI_THEME, TUI_VIEW_MODES, type ToolInput, ToolInputSchema, type ToolName, ToolNameSchema, type TuiDaemonSnapshot, type TuiFilters, type TuiInitialFilters, type TuiInteractionMode, type TuiStatusSnapshot, type TuiThemeColor, type TuiViewMode, UDSServer, type UDSServerStartOptions, type UDSServerStats, type UseEventStreamOptions, type UseEventStreamState, type UseKeyBindsOptions, type UseKeyBindsState, WSServer, type WSServerStartOptions, type WSServerStats, type WelcomeMessage, analyzeTerminalOutputChunk, appendEventToStream, applyEventFilters, applySessionFilters, attachEventBusMonitor, attachWebSocketMonitor, countActiveFilters, createDefaultAdapters, createEvent, createUuidV7, deriveGlobalActivityStatus, deriveSessions, ensureConfigDir, formatEventDetail, formatEventLine, formatEventTime, formatSessionLabel, formatSessionLabelFromEvent, formatSessionShortId, formatWelcomeLine, getAISnitchHomePath, getCESPCategory, getConfigPath, getPackageScaffoldInfo, getPendingFrozenEventCount, getSocketPath, getVisibleEventWindow, isGenericSessionId, loadConfig, logger, parseAiderHistoryMarkdown, renderAttachedTui, renderForegroundTui, renderManagedTui, resolveAvailablePort, resolveSessionId, saveConfig, setLoggerLevel, useEventStream, useKeyBinds, useSessions };
4086
+ export { AISNITCH_DESCRIPTION, AISNITCH_EVENT_TYPES, AISNITCH_PACKAGE_NAME, AISNITCH_VERSION, type AISnitchConfig, AISnitchError, type AISnitchEvent, AISnitchEventSchema, type AISnitchEventType, AISnitchEventTypeSchema, type AISnitchLoggerLevel, type AISnitchScaffoldInfo, AUTO_UPDATE_MANAGERS, type AdapterConfig, AdapterConfigSchema, AdapterError, type AdapterPublishContext, AdapterRegistry, type AdapterRuntimeOptions, type AdapterStatus, AiderAdapter, type AiderAdapterOptions, type AiderHistoryObservation, type AiderHistoryParseResult, App, type AppProps, type AttachedTuiOptions, type AutoUpdateConfig, AutoUpdateConfigSchema, BaseAdapter, type CESPCategory, CESPCategorySchema, CESP_CATEGORIES, CESP_MAP, CircuitBreaker, type CircuitBreakerOptions, CircuitOpenError, type CircuitState, ClaudeCodeAdapter, type ClaudeCodeAdapterOptions, CodexAdapter, type CodexAdapterOptions, type ConfigPathOptions, ConfigSchema, ContextDetector, CopilotCLIAdapter, type CopilotCLIAdapterOptions, type CreateEventInput, CursorAdapter, type CursorAdapterOptions, DEFAULT_CONFIG, DEFAULT_TIMEOUTS, DEFAULT_TUI_FILTERS, DEFAULT_VISIBLE_EVENT_COUNT, DefaultRetryOptions, DevinAdapter, type DevinAdapterOptions, ERROR_TYPES, EVENT_COLORS, EVENT_ICONS, EVENT_STREAM_LIMIT, type EnrichedContextFields, type ErrorType, ErrorTypeSchema, EventBus, type EventBusStats, type EventData, EventDataSchema, type EventHandler, EventLine, type EventLineProps, EventStream, type EventStreamProps, type EventStreamSource, FilterBar, type FilterBarProps, FinalMessageSchema, type FocusedPanel, type ForegroundTuiOptions, GeminiCLIAdapter, type GeminiCLIAdapterOptions, type GenericPTYObservation, GenericPTYSession, type GenericPTYSessionOptions, type GlobalActivityStatus, GlobalBadge, type GlobalBadgeProps, GooseAdapter, type GooseAdapterOptions, GracefulShutdownManager, HTTPReceiver, type HTTPReceiverStartOptions, type HTTPReceiverStats, Header, type HeaderProps, type HealthSnapshot, HelpOverlay, type HookHandler, type InterceptionStrategy, KiloAdapter, type KiloAdapterOptions, LOG_LEVELS, MAX_GENERIC_STRING_LENGTH, MAX_LABEL_LENGTH, MAX_PATH_LENGTH, MAX_PORT, MIN_PORT, ManagedDaemonApp, type ManagedDaemonAppProps, type ManagedTuiOptions, type ManagedTuiSnapshot, MessageContentSchema, type MonitorCloseHandler, type MonitorOutput, NetworkError, type NormalizedAdapterHookPayload, OpenClawAdapter, type OpenClawAdapterOptions, OpenCodeAdapter, type OpenCodeAdapterOptions, Panel, type PanelProps, PanelStack, type PanelStackProps, PiAdapter, Pipeline, PipelineError, type PipelineStartOptions, type PipelineStatus, type PortResolutionOptions, type ProcessContext, type ProcessInfo, type Result, type RetryOptions, RingBuffer, SESSION_STALE_AFTER_MS, SHARED_BREAKERS, type SelectorOption, type SessionFilterTarget, type SessionIdentityInput, SessionPanel, type SessionPanelProps, type SessionState, type ShutdownComponents, StatusBar, type StatusBarProps, TOOL_COLORS, TOOL_NAMES, TUI_THEME, TUI_VIEW_MODES, ThinkingContentSchema, TimeoutError, type TimeoutName, ToolCallNameSchema, type ToolInput, ToolInputSchema, type ToolName, ToolNameSchema, ToolResultSchema, type TuiDaemonSnapshot, type TuiFilters, type TuiInitialFilters, type TuiInteractionMode, type TuiStatusSnapshot, type TuiThemeColor, type TuiViewMode, UDSServer, type UDSServerStartOptions, type UDSServerStats, type UseEventStreamOptions, type UseEventStreamState, type UseKeyBindsOptions, type UseKeyBindsState, ValidationError, WSServer, type WSServerStartOptions, type WSServerStats, type WelcomeMessage, ZedAdapter, analyzeTerminalOutputChunk, appendEventToStream, applyEventFilters, applySessionFilters, attachEventBusMonitor, attachWebSocketMonitor, countActiveFilters, createDefaultAdapters, createEvent, createUuidV7, deriveGlobalActivityStatus, deriveSessions, ensureConfigDir, err, fireAndForgetRetry, flatMap, formatEventDetail, formatEventLine, formatEventTime, formatSessionLabel, formatSessionLabelFromEvent, formatSessionShortId, formatWelcomeLine, fromPromise, fromSync, getAISnitchHomePath, getArray, getBoolean, getCESPCategory, getConfigPath, getNumber, getObject, getPackageScaffoldInfo, getPendingFrozenEventCount, getPort, getPositiveNumber, getSafeInteger, getSeqnum, getSocketPath, getString, getStringWithMaxLength, getTimeout, getVisibleEventWindow, isAISnitchError, isErr, isGenericSessionId, isNotNull, isOk, isRecord, isRetryableError, isTimeoutError, isValidPathLength, isValidPort, isValidStringLength, loadConfig, logger, mapErr, mapOk, ok, parseAiderHistoryMarkdown, renderAttachedTui, renderForegroundTui, renderManagedTui, resolveAvailablePort, resolveSessionId, saveConfig, setLoggerLevel, shutdownInOrder, sleep, timeoutWarning, useEventStream, useKeyBinds, useSessions, withOverallShutdownTimeout, withRetry, withRetryOn, withShutdownTimeout, withTimeout };