@neotx/core 0.1.0-alpha.22 → 0.1.0-alpha.25

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.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { z, ZodType } from 'zod';
2
2
  import { HookEvent as HookEvent$1, HookCallbackMatcher } from '@anthropic-ai/claude-agent-sdk';
3
+ import { ChildProcess } from 'node:child_process';
3
4
 
4
5
  declare const agentModelSchema: z.ZodEnum<{
5
6
  opus: "opus";
@@ -38,6 +39,7 @@ declare const agentConfigSchema: z.ZodObject<{
38
39
  name: z.ZodString;
39
40
  extends: z.ZodOptional<z.ZodString>;
40
41
  description: z.ZodOptional<z.ZodString>;
42
+ version: z.ZodOptional<z.ZodString>;
41
43
  model: z.ZodOptional<z.ZodEnum<{
42
44
  opus: "opus";
43
45
  sonnet: "sonnet";
@@ -62,12 +64,31 @@ declare const agentConfigSchema: z.ZodObject<{
62
64
  writable: "writable";
63
65
  }>>;
64
66
  maxTurns: z.ZodOptional<z.ZodNumber>;
67
+ maxCost: z.ZodOptional<z.ZodNumber>;
65
68
  mcpServers: z.ZodOptional<z.ZodArray<z.ZodString>>;
69
+ agents: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
70
+ description: z.ZodString;
71
+ prompt: z.ZodString;
72
+ tools: z.ZodOptional<z.ZodArray<z.ZodEnum<{
73
+ Read: "Read";
74
+ Write: "Write";
75
+ Edit: "Edit";
76
+ Bash: "Bash";
77
+ Glob: "Glob";
78
+ Grep: "Grep";
79
+ Agent: "Agent";
80
+ WebSearch: "WebSearch";
81
+ WebFetch: "WebFetch";
82
+ NotebookEdit: "NotebookEdit";
83
+ }>>>;
84
+ model: z.ZodOptional<z.ZodEnum<{
85
+ opus: "opus";
86
+ sonnet: "sonnet";
87
+ haiku: "haiku";
88
+ }>>;
89
+ }, z.core.$strip>>>;
66
90
  }, z.core.$strip>;
67
91
  type AgentConfig = z.infer<typeof agentConfigSchema>;
68
- type AgentModel = z.infer<typeof agentModelSchema>;
69
- type AgentTool = z.infer<typeof agentToolSchema>;
70
- type AgentToolEntry = z.infer<typeof agentToolEntrySchema>;
71
92
 
72
93
  /**
73
94
  * Load a single agent definition from a YAML file.
@@ -368,18 +389,31 @@ declare function removeRepoFromGlobalConfig(pathOrName: string): Promise<boolean
368
389
  */
369
390
  declare function listReposFromGlobalConfig(): Promise<RepoConfig[]>;
370
391
 
392
+ interface SubagentDefinition {
393
+ description: string;
394
+ prompt: string;
395
+ tools?: string[] | undefined;
396
+ model?: string | undefined;
397
+ }
371
398
  interface AgentDefinition {
372
399
  description: string;
373
400
  prompt: string;
374
401
  tools: string[];
375
402
  model: string;
376
403
  mcpServers?: string[] | undefined;
404
+ agents?: Record<string, SubagentDefinition> | undefined;
377
405
  }
378
406
  interface ResolvedAgent {
379
407
  name: string;
380
408
  definition: AgentDefinition;
381
409
  sandbox: "writable" | "readonly";
382
410
  maxTurns?: number | undefined;
411
+ /**
412
+ * Maximum cost in USD for this agent session.
413
+ * Checked post-session; if session cost >= maxCost, budget_exceeded error is thrown.
414
+ */
415
+ maxCost?: number | undefined;
416
+ version?: string | undefined;
383
417
  source: "built-in" | "custom" | "extended";
384
418
  }
385
419
  interface PersistedRun {
@@ -391,14 +425,18 @@ interface PersistedRun {
391
425
  branch?: string | undefined;
392
426
  sessionPath?: string | undefined;
393
427
  pid?: number | undefined;
394
- status: "running" | "paused" | "completed" | "failed";
428
+ status: "running" | "paused" | "completed" | "failed" | "blocked";
429
+ /** Reason why this run is blocked (if status is "blocked") */
430
+ blockedReason?: string | undefined;
431
+ /** Timestamp when the run was blocked */
432
+ blockedAt?: string | undefined;
395
433
  steps: Record<string, StepResult>;
396
434
  createdAt: string;
397
435
  updatedAt: string;
398
436
  metadata?: Record<string, unknown> | undefined;
399
437
  }
400
438
  interface StepResult {
401
- status: "pending" | "running" | "success" | "failure" | "skipped";
439
+ status: "pending" | "running" | "success" | "failure" | "skipped" | "blocked";
402
440
  sessionId?: string | undefined;
403
441
  output?: unknown;
404
442
  rawOutput?: string | undefined;
@@ -410,6 +448,8 @@ interface StepResult {
410
448
  startedAt?: string | undefined;
411
449
  completedAt?: string | undefined;
412
450
  error?: string | undefined;
451
+ /** Reason why this step is blocked (if status is "blocked") */
452
+ blockedReason?: string | undefined;
413
453
  attempt: number;
414
454
  }
415
455
  type Priority = "critical" | "high" | "medium" | "low";
@@ -1012,6 +1052,13 @@ declare function getRunDispatchPath(repoSlug: string, runId: string): string;
1012
1052
  * Path to the log file for a detached run.
1013
1053
  */
1014
1054
  declare function getRunLogPath(repoSlug: string, runId: string): string;
1055
+ /**
1056
+ * Path to the worker startup confirmation file for a detached run.
1057
+ * This file is written immediately after worker process starts to confirm
1058
+ * it survived the spawn phase. The parent process checks for this file
1059
+ * to detect early worker crashes.
1060
+ */
1061
+ declare function getWorkerStartedPath(repoSlug: string, runId: string): string;
1015
1062
  /**
1016
1063
  * Directory for all supervisor instances: ~/.neo/supervisors/
1017
1064
  */
@@ -1029,6 +1076,15 @@ declare function getSupervisorInboxPath(name: string): string;
1029
1076
  declare function getSupervisorEventsPath(name: string): string;
1030
1077
  declare function getSupervisorLockPath(name: string): string;
1031
1078
  declare function getSupervisorDecisionsPath(name: string): string;
1079
+ /**
1080
+ * Path to the children registry file: ~/.neo/supervisors/<name>/children.json
1081
+ * Written by ChildRegistry, read by the TUI to display focused child supervisors.
1082
+ */
1083
+ declare function getSupervisorChildrenPath(name: string): string;
1084
+ /**
1085
+ * Directory for a specific focused supervisor: ~/.neo/supervisors/focused/<id>/
1086
+ */
1087
+ declare function getFocusedSupervisorDir(supervisorId: string): string;
1032
1088
 
1033
1089
  interface ParsedOutput {
1034
1090
  rawOutput: string;
@@ -1058,7 +1114,9 @@ interface SessionOptions {
1058
1114
  env?: Record<string, string>;
1059
1115
  initTimeoutMs: number;
1060
1116
  maxDurationMs: number;
1117
+ maxTurns?: number | undefined;
1061
1118
  resumeSessionId?: string | undefined;
1119
+ agents?: Record<string, unknown> | undefined;
1062
1120
  onEvent?: ((event: SessionEvent) => void) | undefined;
1063
1121
  }
1064
1122
  interface SessionResult {
@@ -1102,6 +1160,9 @@ interface RecoveryOptions extends SessionOptions {
1102
1160
  *
1103
1161
  * Non-retryable errors skip to immediate failure.
1104
1162
  * Backoff: backoffBaseMs * attempt between levels.
1163
+ *
1164
+ * On retry, the prompt is enriched with failure context from the previous
1165
+ * attempt, giving the agent information to try a different approach.
1105
1166
  */
1106
1167
  declare function runWithRecovery(options: RecoveryOptions): Promise<SessionResult>;
1107
1168
 
@@ -1208,6 +1269,16 @@ type DecisionInput = Omit<Decision, "id" | "createdAt" | "answeredAt" | "answer"
1208
1269
  * JSONL-backed store for decisions.
1209
1270
  * Append-only with in-place updates for answers and expiration.
1210
1271
  * Uses an in-memory mutex to serialize write operations.
1272
+ *
1273
+ * Compaction Strategy:
1274
+ * - Threshold-based compaction triggers on either:
1275
+ * 1. Tombstone ratio exceeds 30% of total valid entries (tombstones / (valid decisions + tombstones), excluding malformed lines)
1276
+ * 2. File size exceeds 10MB (prevents unbounded growth)
1277
+ * - Compaction rebuilds the file, filtering out tombstoned entries and preserving active decisions
1278
+ * - In-memory index maintains O(1) lookup without full file scans
1279
+ * - Compaction runs synchronously within the write lock to maintain consistency
1280
+ * - During compaction: all write operations are blocked until compaction completes, preventing race conditions
1281
+ * - Concurrent reads during compaction may return stale data from before compaction started
1211
1282
  */
1212
1283
  declare class DecisionStore {
1213
1284
  private readonly filePath;
@@ -1215,6 +1286,8 @@ declare class DecisionStore {
1215
1286
  private readonly dirCache;
1216
1287
  /** Promise-based mutex to serialize write operations */
1217
1288
  private writeLock;
1289
+ /** Maximum file size in bytes before validation fails (default: 10MB) */
1290
+ private readonly maxFileSizeBytes;
1218
1291
  constructor(filePath: string);
1219
1292
  /**
1220
1293
  * Acquire the write lock and execute a callback.
@@ -1223,6 +1296,7 @@ declare class DecisionStore {
1223
1296
  private withWriteLock;
1224
1297
  /**
1225
1298
  * Create a new decision and persist it.
1299
+ * Uses a mutex to serialize concurrent calls and prevent race conditions.
1226
1300
  * @returns The generated decision ID
1227
1301
  */
1228
1302
  create(input: DecisionInput): Promise<string>;
@@ -1245,6 +1319,11 @@ declare class DecisionStore {
1245
1319
  * Get a specific decision by ID.
1246
1320
  */
1247
1321
  get(id: string): Promise<Decision | null>;
1322
+ /**
1323
+ * Check if a decision has already been answered without throwing.
1324
+ * Returns true if answered, false otherwise (including non-existent decisions).
1325
+ */
1326
+ isAnswered(id: string): Promise<boolean>;
1248
1327
  /**
1249
1328
  * Auto-answer expired decisions with their defaultAnswer.
1250
1329
  * Decisions without defaultAnswer are marked as expired (expiredAt).
@@ -1314,10 +1393,10 @@ declare const activityEntrySchema: z.ZodObject<{
1314
1393
  message: "message";
1315
1394
  decision: "decision";
1316
1395
  tool_use: "tool_use";
1396
+ warning: "warning";
1397
+ action: "action";
1317
1398
  event: "event";
1318
1399
  heartbeat: "heartbeat";
1319
- action: "action";
1320
- warning: "warning";
1321
1400
  thinking: "thinking";
1322
1401
  plan: "plan";
1323
1402
  dispatch: "dispatch";
@@ -1379,8 +1458,8 @@ declare const activityQueryOptionsSchema: z.ZodObject<{
1379
1458
  error: "error";
1380
1459
  message: "message";
1381
1460
  decision: "decision";
1382
- event: "event";
1383
1461
  action: "action";
1462
+ event: "event";
1384
1463
  plan: "plan";
1385
1464
  dispatch: "dispatch";
1386
1465
  }>>;
@@ -1402,15 +1481,84 @@ type QueuedEvent = {
1402
1481
  kind: "internal";
1403
1482
  eventKind: InternalEventKind;
1404
1483
  timestamp: string;
1484
+ } | {
1485
+ kind: "child_supervisor";
1486
+ message: ChildToParentMessage;
1487
+ timestamp: string;
1405
1488
  };
1489
+ declare const childHandleSchema: z.ZodObject<{
1490
+ supervisorId: z.ZodString;
1491
+ objective: z.ZodString;
1492
+ depth: z.ZodNumber;
1493
+ startedAt: z.ZodString;
1494
+ lastProgressAt: z.ZodString;
1495
+ costUsd: z.ZodDefault<z.ZodNumber>;
1496
+ maxCostUsd: z.ZodOptional<z.ZodNumber>;
1497
+ sessionId: z.ZodOptional<z.ZodString>;
1498
+ status: z.ZodEnum<{
1499
+ running: "running";
1500
+ failed: "failed";
1501
+ blocked: "blocked";
1502
+ complete: "complete";
1503
+ stalled: "stalled";
1504
+ }>;
1505
+ }, z.core.$strip>;
1506
+ type ChildHandle = z.infer<typeof childHandleSchema>;
1507
+ declare const childToParentMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1508
+ type: z.ZodLiteral<"progress">;
1509
+ supervisorId: z.ZodString;
1510
+ summary: z.ZodString;
1511
+ costDelta: z.ZodNumber;
1512
+ }, z.core.$strip>, z.ZodObject<{
1513
+ type: z.ZodLiteral<"complete">;
1514
+ supervisorId: z.ZodString;
1515
+ summary: z.ZodString;
1516
+ evidence: z.ZodArray<z.ZodString>;
1517
+ }, z.core.$strip>, z.ZodObject<{
1518
+ type: z.ZodLiteral<"blocked">;
1519
+ supervisorId: z.ZodString;
1520
+ reason: z.ZodString;
1521
+ question: z.ZodString;
1522
+ urgency: z.ZodEnum<{
1523
+ high: "high";
1524
+ low: "low";
1525
+ }>;
1526
+ }, z.core.$strip>, z.ZodObject<{
1527
+ type: z.ZodLiteral<"failed">;
1528
+ supervisorId: z.ZodString;
1529
+ error: z.ZodString;
1530
+ }, z.core.$strip>, z.ZodObject<{
1531
+ type: z.ZodLiteral<"session">;
1532
+ supervisorId: z.ZodString;
1533
+ sessionId: z.ZodString;
1534
+ }, z.core.$strip>], "type">;
1535
+ type ChildToParentMessage = z.infer<typeof childToParentMessageSchema>;
1536
+ declare const parentToChildMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1537
+ type: z.ZodLiteral<"unblock">;
1538
+ answer: z.ZodString;
1539
+ }, z.core.$strip>, z.ZodObject<{
1540
+ type: z.ZodLiteral<"stop">;
1541
+ }, z.core.$strip>, z.ZodObject<{
1542
+ type: z.ZodLiteral<"inject">;
1543
+ context: z.ZodString;
1544
+ }, z.core.$strip>], "type">;
1545
+ type ParentToChildMessage = z.infer<typeof parentToChildMessageSchema>;
1406
1546
 
1407
1547
  declare class ActivityLog {
1408
1548
  readonly filePath: string;
1409
1549
  private readonly dir;
1550
+ /** Promise-based mutex to serialize write operations */
1551
+ private writeLock;
1410
1552
  constructor(dir: string);
1553
+ /**
1554
+ * Acquire the write lock and execute a callback.
1555
+ * Serializes write operations to prevent race conditions during rotation.
1556
+ */
1557
+ private withWriteLock;
1411
1558
  /**
1412
1559
  * Append a structured entry to the activity log.
1413
1560
  * Rotates the file if it exceeds MAX_SIZE_BYTES.
1561
+ * Uses a mutex to serialize concurrent calls and prevent race conditions.
1414
1562
  */
1415
1563
  append(entry: ActivityEntry): Promise<void>;
1416
1564
  /**
@@ -1424,11 +1572,171 @@ declare class ActivityLog {
1424
1572
  private checkRotation;
1425
1573
  }
1426
1574
 
1575
+ declare const supervisorCompleteSchema: z.ZodObject<{
1576
+ summary: z.ZodString;
1577
+ evidence: z.ZodArray<z.ZodString>;
1578
+ branch: z.ZodOptional<z.ZodString>;
1579
+ criteriaResults: z.ZodArray<z.ZodObject<{
1580
+ criterion: z.ZodString;
1581
+ met: z.ZodBoolean;
1582
+ evidence: z.ZodString;
1583
+ }, z.core.$strip>>;
1584
+ }, z.core.$strip>;
1585
+ declare const supervisorBlockedSchema: z.ZodObject<{
1586
+ reason: z.ZodString;
1587
+ question: z.ZodString;
1588
+ context: z.ZodString;
1589
+ urgency: z.ZodEnum<{
1590
+ high: "high";
1591
+ low: "low";
1592
+ }>;
1593
+ }, z.core.$strip>;
1594
+ type SupervisorCompleteInput = z.infer<typeof supervisorCompleteSchema>;
1595
+ type SupervisorBlockedInput = z.infer<typeof supervisorBlockedSchema>;
1596
+ interface ToolDefinition {
1597
+ name: string;
1598
+ description: string;
1599
+ inputSchema: Record<string, unknown>;
1600
+ }
1601
+
1602
+ /**
1603
+ * Opaque session handle — each adapter stores what it needs.
1604
+ * Persisted via SupervisorStore so it survives process restart.
1605
+ * Only "claude" is implemented now — others are reserved for future providers.
1606
+ */
1607
+ type SessionHandle = {
1608
+ provider: "claude";
1609
+ sessionId: string;
1610
+ };
1611
+ type SupervisorMessageKind = "text" | "tool_use" | "end";
1612
+ interface SupervisorMessage {
1613
+ kind: SupervisorMessageKind;
1614
+ toolName?: string;
1615
+ toolInput?: unknown;
1616
+ text?: string;
1617
+ }
1618
+ interface AIQueryOptions {
1619
+ prompt: string;
1620
+ tools: ToolDefinition[];
1621
+ sessionHandle?: SessionHandle;
1622
+ systemPrompt?: string;
1623
+ model?: string;
1624
+ }
1625
+ /**
1626
+ * Adapter interface for AI providers.
1627
+ * ClaudeAdapter is the default implementation.
1628
+ * Future: OpenAIAdapter, GeminiAdapter, OllamaAdapter.
1629
+ */
1630
+ interface AIAdapter {
1631
+ /**
1632
+ * Execute one turn of the supervisor conversation.
1633
+ * Returns an async iterable of structured messages.
1634
+ */
1635
+ query(options: AIQueryOptions): AsyncIterable<SupervisorMessage>;
1636
+ /** Returns the current session handle (undefined before first turn). */
1637
+ getSessionHandle(): SessionHandle | undefined;
1638
+ /** Restore a previously persisted session handle. */
1639
+ restoreSession(handle: SessionHandle): void;
1640
+ }
1641
+
1642
+ declare class ClaudeAdapter implements AIAdapter {
1643
+ private sessionHandle;
1644
+ getSessionHandle(): SessionHandle | undefined;
1645
+ restoreSession(handle: SessionHandle): void;
1646
+ query(options: AIQueryOptions): AsyncIterable<SupervisorMessage>;
1647
+ }
1648
+
1649
+ interface ChildSpawnCommand {
1650
+ objective: string;
1651
+ acceptanceCriteria: string[];
1652
+ maxCostUsd?: number;
1653
+ }
1654
+ /**
1655
+ * Parse a child:spawn command from inbox message.
1656
+ * Format: "child:spawn <JSON payload>"
1657
+ */
1658
+ declare function parseChildSpawnCommand(text: string): ChildSpawnCommand | null;
1659
+
1660
+ interface ChildRegistryOptions {
1661
+ onMessage: (message: ChildToParentMessage) => void;
1662
+ stallTimeoutMs?: number;
1663
+ /** If provided, children.json is written here after every mutation. */
1664
+ childrenFilePath?: string;
1665
+ }
1666
+ /**
1667
+ * Tracks all active focused supervisor child processes.
1668
+ * Handles IPC message routing, budget enforcement, and stall detection.
1669
+ */
1670
+ declare class ChildRegistry {
1671
+ private readonly handles;
1672
+ private readonly processes;
1673
+ private readonly stopCallbacks;
1674
+ private readonly stallTimers;
1675
+ private readonly onMessage;
1676
+ private readonly stallTimeoutMs;
1677
+ private readonly childrenFilePath;
1678
+ constructor(options: ChildRegistryOptions);
1679
+ /**
1680
+ * Register a child handle.
1681
+ */
1682
+ register(handle: ChildHandle, stopCallback?: () => void, childProcess?: ChildProcess): void;
1683
+ get(supervisorId: string): ChildHandle | undefined;
1684
+ list(): ChildHandle[];
1685
+ /**
1686
+ * Send a message to a child via IPC.
1687
+ */
1688
+ send(supervisorId: string, message: ParentToChildMessage): void;
1689
+ /**
1690
+ * Handle an incoming IPC message from a child.
1691
+ * Updates state, enforces budget, forwards to caller.
1692
+ */
1693
+ handleMessage(message: ChildToParentMessage): void;
1694
+ /**
1695
+ * Remove a child from the registry and clean up.
1696
+ */
1697
+ remove(supervisorId: string): void;
1698
+ /**
1699
+ * Send stop to all children (called on daemon shutdown).
1700
+ */
1701
+ stopAll(): void;
1702
+ private stopChild;
1703
+ private persistChildren;
1704
+ private resetStallTimer;
1705
+ private clearStallTimer;
1706
+ }
1707
+
1708
+ interface SpawnChildOptions {
1709
+ objective: string;
1710
+ acceptanceCriteria: string[];
1711
+ registry: ChildRegistry;
1712
+ workerPath: string;
1713
+ parentName: string;
1714
+ maxCostUsd?: number;
1715
+ depth?: number;
1716
+ }
1717
+ interface SpawnChildResult {
1718
+ supervisorId: string;
1719
+ childProcess: ChildProcess;
1720
+ }
1721
+ /**
1722
+ * Spawn a focused child supervisor as a forked process.
1723
+ * The child communicates via IPC and is tracked by the ChildRegistry.
1724
+ */
1725
+ declare function spawnChildSupervisor(options: SpawnChildOptions): Promise<SpawnChildResult>;
1726
+
1727
+ /**
1728
+ * Read child handles from children.json.
1729
+ * Returns empty array if file does not exist or is malformed.
1730
+ */
1731
+ declare function readChildrenFile(filePath: string): Promise<ChildHandle[]>;
1732
+
1427
1733
  interface SupervisorDaemonOptions {
1428
1734
  name: string;
1429
1735
  config: GlobalConfig;
1430
1736
  /** Path to bundled default SUPERVISOR.md (e.g. from @neotx/agents) */
1431
1737
  defaultInstructionsPath?: string | undefined;
1738
+ /** Path to child-supervisor-worker.js for spawning child processes */
1739
+ workerPath?: string | undefined;
1432
1740
  }
1433
1741
  /**
1434
1742
  * Orchestrates all supervisor components: webhook server, event queue,
@@ -1439,11 +1747,13 @@ declare class SupervisorDaemon {
1439
1747
  private readonly config;
1440
1748
  private readonly dir;
1441
1749
  private readonly defaultInstructionsPath;
1750
+ private readonly workerPath;
1442
1751
  private webhookServer;
1443
1752
  private eventQueue;
1444
1753
  private heartbeatLoop;
1445
1754
  private activityLog;
1446
1755
  private decisionStore;
1756
+ private childRegistry;
1447
1757
  private sessionId;
1448
1758
  constructor(options: SupervisorDaemonOptions);
1449
1759
  start(): Promise<void>;
@@ -1451,6 +1761,16 @@ declare class SupervisorDaemon {
1451
1761
  private getHealthInfo;
1452
1762
  private readState;
1453
1763
  private writeState;
1764
+ /**
1765
+ * Atomically acquire a lockfile using O_EXCL flag.
1766
+ * Handles stale locks by checking if the owning process is still alive.
1767
+ *
1768
+ * Note: A small race window exists between stale lock removal and retry.
1769
+ * Another process could grab the lock during this window, which is acceptable
1770
+ * because we detect and report it on the retry attempt. This is a best-effort
1771
+ * pattern — a true CAS (compare-and-swap) would require platform-specific APIs.
1772
+ */
1773
+ private acquireLock;
1454
1774
  private readLockPid;
1455
1775
  /**
1456
1776
  * Handle decision:answer webhook events.
@@ -1459,6 +1779,89 @@ declare class SupervisorDaemon {
1459
1779
  private handleDecisionAnswer;
1460
1780
  }
1461
1781
 
1782
+ declare const directiveTriggerSchema: z.ZodEnum<{
1783
+ idle: "idle";
1784
+ startup: "startup";
1785
+ shutdown: "shutdown";
1786
+ }>;
1787
+ type DirectiveTrigger = z.infer<typeof directiveTriggerSchema>;
1788
+ declare const directiveSchema: z.ZodObject<{
1789
+ id: z.ZodString;
1790
+ trigger: z.ZodEnum<{
1791
+ idle: "idle";
1792
+ startup: "startup";
1793
+ shutdown: "shutdown";
1794
+ }>;
1795
+ action: z.ZodString;
1796
+ description: z.ZodOptional<z.ZodString>;
1797
+ priority: z.ZodDefault<z.ZodNumber>;
1798
+ enabled: z.ZodDefault<z.ZodBoolean>;
1799
+ createdAt: z.ZodCoercedString<unknown>;
1800
+ expiresAt: z.ZodOptional<z.ZodCoercedString<unknown>>;
1801
+ lastTriggeredAt: z.ZodOptional<z.ZodCoercedString<unknown>>;
1802
+ }, z.core.$strip>;
1803
+ type Directive = z.infer<typeof directiveSchema>;
1804
+ interface DirectiveCreateInput {
1805
+ trigger: DirectiveTrigger;
1806
+ action: string;
1807
+ description?: string;
1808
+ priority?: number;
1809
+ expiresAt?: string;
1810
+ }
1811
+ /**
1812
+ * Parse a human-readable duration string into an ISO timestamp.
1813
+ *
1814
+ * Supported formats:
1815
+ * - "for X hours" / "for X minutes" / "for X days"
1816
+ * - "until midnight"
1817
+ * - "until HH:MM"
1818
+ * - "2h" / "30m" / "7d" (shorthand)
1819
+ * - "indefinitely" / "" → returns undefined (no expiry)
1820
+ *
1821
+ * @returns ISO timestamp string or undefined for indefinite
1822
+ */
1823
+ declare function parseDirectiveDuration(input: string): string | undefined;
1824
+ /**
1825
+ * JSONL-based store for persistent directives.
1826
+ * Each line is a complete directive record (append-only with periodic compaction).
1827
+ * Uses an in-memory mutex to serialize write operations.
1828
+ */
1829
+ declare class DirectiveStore {
1830
+ private readonly filePath;
1831
+ /** Promise-based mutex to serialize write operations */
1832
+ private writeLock;
1833
+ constructor(filePath: string);
1834
+ /**
1835
+ * Acquire the write lock and execute a callback.
1836
+ * Serializes all write operations to prevent race conditions.
1837
+ */
1838
+ private withWriteLock;
1839
+ /**
1840
+ * Create a new directive and persist it.
1841
+ * Uses a mutex to serialize concurrent calls and prevent race conditions.
1842
+ */
1843
+ create(input: DirectiveCreateInput): Promise<string>;
1844
+ get(id: string): Promise<Directive | undefined>;
1845
+ list(): Promise<Directive[]>;
1846
+ /**
1847
+ * Get active directives (enabled, not expired).
1848
+ * Optionally filter by trigger type.
1849
+ * Sorted by priority descending.
1850
+ */
1851
+ active(trigger?: DirectiveTrigger): Promise<Directive[]>;
1852
+ toggle(id: string, enabled: boolean): Promise<void>;
1853
+ markTriggered(id: string): Promise<void>;
1854
+ delete(id: string): Promise<void>;
1855
+ /**
1856
+ * Remove directives that expired more than 24 hours ago.
1857
+ * Returns IDs of removed directives.
1858
+ */
1859
+ expireOld(): Promise<string[]>;
1860
+ private readAll;
1861
+ private writeAll;
1862
+ private append;
1863
+ }
1864
+
1462
1865
  interface EventQueueOptions {
1463
1866
  maxEventsPerSec: number;
1464
1867
  }
@@ -1488,6 +1891,7 @@ interface DrainAndGroupResult {
1488
1891
  */
1489
1892
  declare class EventQueue {
1490
1893
  private readonly queue;
1894
+ /** Set of event IDs for deduplication. Map preserves insertion order, so first entry is oldest. */
1491
1895
  private readonly seenIds;
1492
1896
  private readonly maxSeenIds;
1493
1897
  private readonly maxEventsPerSec;
@@ -1497,11 +1901,23 @@ declare class EventQueue {
1497
1901
  private fileOffsets;
1498
1902
  /** Resolve function to wake up the heartbeat loop when an event arrives */
1499
1903
  private wakeUp;
1904
+ /** Write locks keyed by file path to serialize read-modify-write operations */
1905
+ private readonly writeLocks;
1500
1906
  constructor(options: EventQueueOptions);
1907
+ /**
1908
+ * Acquire the write lock for a file path and execute a callback.
1909
+ * Serializes write operations per-file to prevent race conditions during read-modify-write.
1910
+ */
1911
+ private withWriteLock;
1501
1912
  /**
1502
1913
  * Push an event into the queue. Applies dedup and rate limiting.
1503
1914
  */
1504
1915
  push(event: QueuedEvent): boolean;
1916
+ /**
1917
+ * Evicts the oldest entry from seenIds.
1918
+ * Map preserves insertion order, so the first key is the oldest — O(1) eviction.
1919
+ */
1920
+ private evictOldestSeenId;
1505
1921
  /**
1506
1922
  * Drain all queued events and return them. Clears the queue.
1507
1923
  */
@@ -1533,6 +1949,10 @@ declare class EventQueue {
1533
1949
  interrupt(): void;
1534
1950
  private getEventId;
1535
1951
  private watchJsonlFile;
1952
+ /**
1953
+ * Properly close and remove a watcher from the active list.
1954
+ */
1955
+ private cleanupWatcher;
1536
1956
  private readNewLines;
1537
1957
  private replayFile;
1538
1958
  /**
@@ -1542,6 +1962,69 @@ declare class EventQueue {
1542
1962
  private markInFile;
1543
1963
  }
1544
1964
 
1965
+ interface FocusedSupervisorState {
1966
+ supervisorId: string;
1967
+ status: "running" | "blocked" | "complete" | "failed";
1968
+ startedAt: string;
1969
+ costUsd: number;
1970
+ objective?: string;
1971
+ lastProgressAt?: string;
1972
+ }
1973
+ /**
1974
+ * Pluggable persistence interface for focused supervisor state.
1975
+ * Default implementation: JsonlSupervisorStore (zero-infra, CLI use case).
1976
+ * Future: SqliteSupervisorStore, PostgresSupervisorStore.
1977
+ */
1978
+ interface SupervisorStore {
1979
+ getSessionId(supervisorId: string): Promise<string | undefined>;
1980
+ saveSessionId(supervisorId: string, sessionId: string): Promise<void>;
1981
+ appendActivity(supervisorId: string, entry: ActivityEntry): Promise<void>;
1982
+ getRecentActivity(supervisorId: string, limit?: number): Promise<ActivityEntry[]>;
1983
+ getState(supervisorId: string): Promise<FocusedSupervisorState | null>;
1984
+ saveState(supervisorId: string, state: FocusedSupervisorState): Promise<void>;
1985
+ recordCost(supervisorId: string, costUsd: number): Promise<void>;
1986
+ getTotalCost(supervisorId: string): Promise<number>;
1987
+ }
1988
+
1989
+ interface FocusedLoopOptions {
1990
+ supervisorId: string;
1991
+ objective: string;
1992
+ acceptanceCriteria: string[];
1993
+ adapter: AIAdapter;
1994
+ store: SupervisorStore;
1995
+ onComplete: (result: SupervisorCompleteInput) => void | Promise<void>;
1996
+ onBlocked: (blocked: SupervisorBlockedInput) => void | Promise<void>;
1997
+ onProgress: (summary: string, costDelta: number) => void | Promise<void>;
1998
+ tickIntervalMs?: number;
1999
+ systemPrompt?: string;
2000
+ }
2001
+ /**
2002
+ * Runs a persistent SDK conversation focused on a single objective.
2003
+ * Loops via runOnce() until supervisor_complete or supervisor_blocked is called,
2004
+ * or until stop() is called.
2005
+ */
2006
+ declare class FocusedLoop {
2007
+ private readonly options;
2008
+ private stopping;
2009
+ private injectedContext;
2010
+ constructor(options: FocusedLoopOptions);
2011
+ /** Inject context from parent supervisor (via IPC inject message). */
2012
+ injectContext(context: string): void;
2013
+ /** Signal the loop to stop after the current turn. */
2014
+ stop(): void;
2015
+ /**
2016
+ * Execute one turn of the focused loop.
2017
+ * Returns true if the loop should continue, false if it should stop.
2018
+ */
2019
+ runOnce(): Promise<boolean>;
2020
+ /**
2021
+ * Run the full loop until complete, blocked, or stopped.
2022
+ */
2023
+ run(): Promise<void>;
2024
+ /** Returns true if the tool call is terminal (complete or blocked). */
2025
+ private handleToolUse;
2026
+ }
2027
+
1545
2028
  declare const supervisorWebhookEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1546
2029
  type: z.ZodLiteral<"supervisor_started">;
1547
2030
  supervisorId: z.ZodString;
@@ -1556,6 +2039,13 @@ declare const supervisorWebhookEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject
1556
2039
  todayUsd: z.ZodNumber;
1557
2040
  limitUsd: z.ZodNumber;
1558
2041
  }, z.core.$strip>;
2042
+ }, z.core.$strip>, z.ZodObject<{
2043
+ type: z.ZodLiteral<"heartbeat_failure">;
2044
+ supervisorId: z.ZodString;
2045
+ heartbeatId: z.ZodString;
2046
+ timestamp: z.ZodString;
2047
+ error: z.ZodString;
2048
+ consecutiveFailures: z.ZodNumber;
1559
2049
  }, z.core.$strip>, z.ZodObject<{
1560
2050
  type: z.ZodLiteral<"run_dispatched">;
1561
2051
  supervisorId: z.ZodString;
@@ -1576,6 +2066,14 @@ declare const supervisorWebhookEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject
1576
2066
  output: z.ZodOptional<z.ZodString>;
1577
2067
  costUsd: z.ZodNumber;
1578
2068
  durationMs: z.ZodNumber;
2069
+ }, z.core.$strip>, z.ZodObject<{
2070
+ type: z.ZodLiteral<"ghost_run_recovered">;
2071
+ supervisorId: z.ZodString;
2072
+ runId: z.ZodString;
2073
+ agent: z.ZodString;
2074
+ repo: z.ZodString;
2075
+ timestamp: z.ZodString;
2076
+ reason: z.ZodLiteral<"supervisor crashed">;
1579
2077
  }, z.core.$strip>, z.ZodObject<{
1580
2078
  type: z.ZodLiteral<"supervisor_stopped">;
1581
2079
  supervisorId: z.ZodString;
@@ -1609,6 +2107,14 @@ interface HeartbeatLoopOptions {
1609
2107
  repoPath?: string | undefined;
1610
2108
  /** Debounce time in ms for config file changes (default: 500) */
1611
2109
  configWatcherDebounceMs?: number | undefined;
2110
+ /** Optional child registry for focused supervisor IPC integration */
2111
+ childRegistry?: ChildRegistry | undefined;
2112
+ /** Path to child-supervisor-worker.js for spawning child processes */
2113
+ workerPath?: string | undefined;
2114
+ /** Name of this supervisor instance (for child spawn registration) */
2115
+ supervisorName?: string | undefined;
2116
+ /** Path to directives storage */
2117
+ directivesPath?: string | undefined;
1612
2118
  }
1613
2119
  /**
1614
2120
  * The core autonomous loop. At each iteration:
@@ -1638,16 +2144,55 @@ declare class HeartbeatLoop {
1638
2144
  private readonly memoryDbPath;
1639
2145
  private readonly onWebhookEvent;
1640
2146
  private decisionStore;
2147
+ /** Cache of decision IDs already answered in this session to prevent re-answer spam */
2148
+ private readonly answeredDecisionIds;
1641
2149
  /** ConfigWatcher for hot-reload support */
1642
2150
  private configWatcher;
1643
2151
  private configStore;
1644
2152
  private readonly repoPath;
1645
2153
  private readonly configWatcherDebounceMs;
2154
+ private readonly childRegistry;
2155
+ private readonly workerPath;
2156
+ private readonly supervisorName;
2157
+ private directiveStore;
2158
+ private readonly directivesPath;
2159
+ private errorBoundary;
1646
2160
  constructor(options: HeartbeatLoopOptions);
1647
2161
  /** Path to the inbox/events directory for markProcessed() calls */
1648
2162
  get eventsPath(): string;
2163
+ /** Track store initialization failures for health reporting */
2164
+ private storeInitErrors;
1649
2165
  private getMemoryStore;
2166
+ private taskStore;
2167
+ private getTaskStore;
1650
2168
  private getDecisionStore;
2169
+ private getDirectiveStore;
2170
+ /**
2171
+ * Returns the health status of all stores.
2172
+ * Useful for diagnostics and monitoring degraded mode.
2173
+ */
2174
+ getStoreHealth(): {
2175
+ memory: {
2176
+ available: boolean;
2177
+ error: string | undefined;
2178
+ };
2179
+ task: {
2180
+ available: boolean;
2181
+ error: string | undefined;
2182
+ };
2183
+ directive: {
2184
+ available: boolean;
2185
+ error: string | undefined;
2186
+ };
2187
+ decision: {
2188
+ available: boolean;
2189
+ };
2190
+ };
2191
+ /**
2192
+ * Get or create the HeartbeatErrorBoundary instance.
2193
+ * Lazily initialized to ensure sessionId is available.
2194
+ */
2195
+ private getErrorBoundary;
1651
2196
  start(): Promise<void>;
1652
2197
  stop(): void;
1653
2198
  /**
@@ -1671,11 +2216,11 @@ declare class HeartbeatLoop {
1671
2216
  */
1672
2217
  private processDecisions;
1673
2218
  /**
1674
- * Gather event context: drain queue, fetch active runs, memories, and recent actions.
2219
+ * Gather event context: drain queue, fetch active runs, memories, tasks, recent actions, and active directives.
1675
2220
  */
1676
2221
  private gatherEventContext;
1677
2222
  /**
1678
- * Handle post-SDK processing: mark events as processed, consolidate log buffer.
2223
+ * Handle post-SDK processing: mark events as processed, consolidate log buffer, clean up old directives.
1679
2224
  */
1680
2225
  private handlePostSdkProcessing;
1681
2226
  /**
@@ -1737,8 +2282,23 @@ declare class HeartbeatLoop {
1737
2282
  /**
1738
2283
  * Process decision:answer events from inbox messages.
1739
2284
  * Expected format: "decision:answer <decisionId> <answer>"
2285
+ *
2286
+ * Uses an in-memory deduplication cache to prevent re-answering decisions
2287
+ * that have already been processed, avoiding the "already answered" error spam.
1740
2288
  */
1741
2289
  private processDecisionAnswers;
2290
+ /**
2291
+ * Process child:* commands from inbox messages.
2292
+ * Routes inject/unblock/stop to the ChildRegistry via IPC.
2293
+ * These messages are consumed here and not forwarded to the AI prompt.
2294
+ */
2295
+ private processChildCommands;
2296
+ /**
2297
+ * Process child:spawn commands from inbox messages.
2298
+ * These come from `neo supervise --parent=X` CLI invocations.
2299
+ */
2300
+ private processChildSpawnCommands;
2301
+ private applyDecisionAnswer;
1742
2302
  /**
1743
2303
  * Read persisted run data to extract actual status, cost, and duration.
1744
2304
  * Returns null if the run file cannot be found or parsed.
@@ -1759,10 +2319,22 @@ declare class HeartbeatLoop {
1759
2319
  private emitRunDispatched;
1760
2320
  /** Emit RunCompletedEvent when processing run_complete events */
1761
2321
  private emitRunCompleted;
2322
+ /** Emit GhostRunRecoveredEvent when a ghost run is detected and marked failed */
2323
+ private emitGhostRunRecovered;
2324
+ /**
2325
+ * Scan for ghost runs from crashed supervisors on startup.
2326
+ * Marks them as failed and emits events for logging/debugging.
2327
+ */
2328
+ private recoverGhostRuns;
1762
2329
  }
1763
2330
 
2331
+ /**
2332
+ * Read all entries from log-buffer.jsonl.
2333
+ */
2334
+ declare function readLogBuffer(dir: string): Promise<LogBufferEntry[]>;
1764
2335
  /**
1765
2336
  * Append a single entry to the log buffer file.
2337
+ * Uses a mutex to serialize concurrent calls and prevent race conditions.
1766
2338
  */
1767
2339
  declare function appendLogBuffer(dir: string, entry: LogBufferEntry): Promise<void>;
1768
2340
 
@@ -1770,29 +2342,24 @@ interface Embedder {
1770
2342
  embed(texts: string[]): Promise<number[][]>;
1771
2343
  readonly dimensions: number;
1772
2344
  }
1773
- declare class LocalEmbedder implements Embedder {
1774
- readonly dimensions = 384;
1775
- embed(texts: string[]): Promise<number[][]>;
1776
- }
1777
2345
 
1778
2346
  declare const memoryTypeSchema: z.ZodEnum<{
1779
- fact: "fact";
1780
- procedure: "procedure";
1781
- episode: "episode";
2347
+ knowledge: "knowledge";
2348
+ warning: "warning";
1782
2349
  focus: "focus";
1783
- feedback: "feedback";
1784
- task: "task";
1785
2350
  }>;
1786
2351
  type MemoryType = z.infer<typeof memoryTypeSchema>;
2352
+ declare const knowledgeSubtypeSchema: z.ZodEnum<{
2353
+ fact: "fact";
2354
+ procedure: "procedure";
2355
+ }>;
2356
+ type KnowledgeSubtype = z.infer<typeof knowledgeSubtypeSchema>;
1787
2357
  declare const memoryEntrySchema: z.ZodObject<{
1788
2358
  id: z.ZodString;
1789
2359
  type: z.ZodEnum<{
1790
- fact: "fact";
1791
- procedure: "procedure";
1792
- episode: "episode";
2360
+ knowledge: "knowledge";
2361
+ warning: "warning";
1793
2362
  focus: "focus";
1794
- feedback: "feedback";
1795
- task: "task";
1796
2363
  }>;
1797
2364
  scope: z.ZodString;
1798
2365
  content: z.ZodString;
@@ -1806,17 +2373,14 @@ declare const memoryEntrySchema: z.ZodObject<{
1806
2373
  runId: z.ZodOptional<z.ZodString>;
1807
2374
  category: z.ZodOptional<z.ZodString>;
1808
2375
  severity: z.ZodOptional<z.ZodString>;
1809
- supersedes: z.ZodOptional<z.ZodString>;
2376
+ subtype: z.ZodOptional<z.ZodString>;
1810
2377
  }, z.core.$strip>;
1811
2378
  type MemoryEntry = z.infer<typeof memoryEntrySchema>;
1812
2379
  declare const memoryWriteInputSchema: z.ZodObject<{
1813
2380
  type: z.ZodEnum<{
1814
- fact: "fact";
1815
- procedure: "procedure";
1816
- episode: "episode";
2381
+ knowledge: "knowledge";
2382
+ warning: "warning";
1817
2383
  focus: "focus";
1818
- feedback: "feedback";
1819
- task: "task";
1820
2384
  }>;
1821
2385
  scope: z.ZodDefault<z.ZodString>;
1822
2386
  content: z.ZodString;
@@ -1827,7 +2391,7 @@ declare const memoryWriteInputSchema: z.ZodObject<{
1827
2391
  runId: z.ZodOptional<z.ZodString>;
1828
2392
  category: z.ZodOptional<z.ZodString>;
1829
2393
  severity: z.ZodOptional<z.ZodString>;
1830
- supersedes: z.ZodOptional<z.ZodString>;
2394
+ subtype: z.ZodOptional<z.ZodString>;
1831
2395
  }, z.core.$strip>;
1832
2396
  type MemoryWriteInput = z.input<typeof memoryWriteInputSchema>;
1833
2397
  interface MemoryQuery {
@@ -1843,18 +2407,31 @@ interface MemoryStats {
1843
2407
  byType: Record<string, number>;
1844
2408
  byScope: Record<string, number>;
1845
2409
  }
2410
+ interface SearchResult extends MemoryEntry {
2411
+ /** Relevance score from 0 to 1, where 1 is most relevant */
2412
+ score: number;
2413
+ }
1846
2414
 
1847
2415
  declare class MemoryStore {
1848
2416
  private db;
1849
- private embedder;
1850
- private hasVec;
1851
- constructor(dbPath: string, embedder?: Embedder | null);
2417
+ constructor(dbPath: string);
1852
2418
  private initSchema;
1853
2419
  /**
1854
- * Migrate existing tables whose CHECK constraint predates the 'task' type.
1855
- * SQLite doesn't allow ALTER CHECK, so we recreate the table if needed.
2420
+ * Migrate from old schema to new schema BEFORE applying new constraints.
2421
+ *
2422
+ * This MUST run before CREATE TABLE IF NOT EXISTS with new CHECK constraints.
2423
+ * Otherwise, existing databases with old constraints will fail UPDATE operations
2424
+ * because the old CHECK constraint rejects new type values ('knowledge', 'warning').
2425
+ *
2426
+ * Migration steps:
2427
+ * - fact, procedure → knowledge (with subtype)
2428
+ * - feedback → warning
2429
+ * - episode → delete
2430
+ * - task → deleted (migrated by TaskStore)
2431
+ * - Add subtype column if missing
2432
+ * - Recreate table with new CHECK constraint
1856
2433
  */
1857
- private migrateCheckConstraint;
2434
+ private migrateSchemaIfNeeded;
1858
2435
  write(input: MemoryWriteInput): Promise<string>;
1859
2436
  update(id: string, content: string): void;
1860
2437
  updateFields(id: string, fields: {
@@ -1864,11 +2441,87 @@ declare class MemoryStore {
1864
2441
  }): void;
1865
2442
  forget(id: string): void;
1866
2443
  query(opts?: MemoryQuery): MemoryEntry[];
1867
- search(text: string, opts?: MemoryQuery): Promise<MemoryEntry[]>;
2444
+ search(text: string, opts?: MemoryQuery): Promise<SearchResult[]>;
1868
2445
  markAccessed(ids: string[]): void;
1869
2446
  decay(maxAgeDays?: number, minAccessCount?: number): number;
1870
2447
  expireEphemeral(): number;
1871
2448
  stats(): MemoryStats;
2449
+ /**
2450
+ * Get the top N most-accessed memories.
2451
+ */
2452
+ topAccessed(limit?: number): MemoryEntry[];
2453
+ close(): void;
2454
+ }
2455
+
2456
+ declare const taskStatusSchema: z.ZodEnum<{
2457
+ blocked: "blocked";
2458
+ pending: "pending";
2459
+ in_progress: "in_progress";
2460
+ done: "done";
2461
+ abandoned: "abandoned";
2462
+ }>;
2463
+ type TaskStatus = z.infer<typeof taskStatusSchema>;
2464
+ declare const taskPrioritySchema: z.ZodEnum<{
2465
+ critical: "critical";
2466
+ high: "high";
2467
+ medium: "medium";
2468
+ low: "low";
2469
+ }>;
2470
+ type TaskPriority = z.infer<typeof taskPrioritySchema>;
2471
+ declare const taskEntrySchema: z.ZodObject<{
2472
+ id: z.ZodString;
2473
+ title: z.ZodString;
2474
+ scope: z.ZodString;
2475
+ status: z.ZodEnum<{
2476
+ blocked: "blocked";
2477
+ pending: "pending";
2478
+ in_progress: "in_progress";
2479
+ done: "done";
2480
+ abandoned: "abandoned";
2481
+ }>;
2482
+ priority: z.ZodOptional<z.ZodEnum<{
2483
+ critical: "critical";
2484
+ high: "high";
2485
+ medium: "medium";
2486
+ low: "low";
2487
+ }>>;
2488
+ initiative: z.ZodOptional<z.ZodString>;
2489
+ dependsOn: z.ZodOptional<z.ZodString>;
2490
+ context: z.ZodOptional<z.ZodString>;
2491
+ runId: z.ZodOptional<z.ZodString>;
2492
+ createdAt: z.ZodString;
2493
+ updatedAt: z.ZodString;
2494
+ }, z.core.$strip>;
2495
+ type TaskEntry = z.infer<typeof taskEntrySchema>;
2496
+ interface TaskCreateInput {
2497
+ title: string;
2498
+ scope: string;
2499
+ status: TaskStatus;
2500
+ priority?: TaskPriority;
2501
+ initiative?: string;
2502
+ dependsOn?: string;
2503
+ context?: string;
2504
+ runId?: string;
2505
+ }
2506
+ interface TaskQuery {
2507
+ initiative?: string;
2508
+ status?: TaskStatus[];
2509
+ scope?: string;
2510
+ }
2511
+ declare class TaskStore {
2512
+ private db;
2513
+ constructor(dbPath: string);
2514
+ private initSchema;
2515
+ /**
2516
+ * Migrate existing task-type memory entries to the tasks table.
2517
+ * One-time migration on first open.
2518
+ */
2519
+ private migrateFromMemories;
2520
+ createTask(input: TaskCreateInput): string;
2521
+ getTask(id: string): TaskEntry | undefined;
2522
+ updateStatus(id: string, status: TaskStatus, runId?: string): void;
2523
+ getTasks(query?: TaskQuery): TaskEntry[];
2524
+ deleteTask(id: string): void;
1872
2525
  close(): void;
1873
2526
  }
1874
2527
 
@@ -1911,6 +2564,47 @@ declare class StatusReader {
1911
2564
  private isRunning;
1912
2565
  }
1913
2566
 
2567
+ declare const spawnChildSupervisorInputSchema: z.ZodObject<{
2568
+ objective: z.ZodString;
2569
+ acceptanceCriteria: z.ZodArray<z.ZodString>;
2570
+ maxCostUsd: z.ZodOptional<z.ZodNumber>;
2571
+ }, z.core.$strip>;
2572
+ type SpawnChildSupervisorInput = z.infer<typeof spawnChildSupervisorInputSchema>;
2573
+ declare const SPAWN_CHILD_SUPERVISOR_TOOL: ToolDefinition;
2574
+
2575
+ /**
2576
+ * JSONL-backed SupervisorStore implementation.
2577
+ * Zero dependencies beyond Node.js built-ins.
2578
+ * Default implementation for CLI usage (zero-infra).
2579
+ *
2580
+ * Layout per supervisor:
2581
+ * <baseDir>/<supervisorId>/session.json — SDK session ID
2582
+ * <baseDir>/<supervisorId>/activity.jsonl — activity log
2583
+ * <baseDir>/<supervisorId>/state.json — current state
2584
+ * <baseDir>/<supervisorId>/cost.json — accumulated cost
2585
+ */
2586
+ declare class JsonlSupervisorStore implements SupervisorStore {
2587
+ private readonly baseDir;
2588
+ /** Promise-based mutex to serialize write operations */
2589
+ private writeLock;
2590
+ constructor(baseDir: string);
2591
+ /**
2592
+ * Acquire the write lock and execute a callback.
2593
+ * Serializes all write operations to prevent race conditions.
2594
+ */
2595
+ private withWriteLock;
2596
+ private supervisorDir;
2597
+ private ensureDir;
2598
+ getSessionId(supervisorId: string): Promise<string | undefined>;
2599
+ saveSessionId(supervisorId: string, sessionId: string): Promise<void>;
2600
+ appendActivity(supervisorId: string, entry: ActivityEntry): Promise<void>;
2601
+ getRecentActivity(supervisorId: string, limit?: number): Promise<ActivityEntry[]>;
2602
+ getState(supervisorId: string): Promise<FocusedSupervisorState | null>;
2603
+ saveState(supervisorId: string, state: FocusedSupervisorState): Promise<void>;
2604
+ recordCost(supervisorId: string, costUsd: number): Promise<void>;
2605
+ getTotalCost(supervisorId: string): Promise<number>;
2606
+ }
2607
+
1914
2608
  interface WebhookServerOptions {
1915
2609
  port: number;
1916
2610
  secret?: string | undefined;
@@ -1934,6 +2628,8 @@ declare class WebhookServer {
1934
2628
  private readonly eventsPath;
1935
2629
  private readonly onEvent;
1936
2630
  private readonly getHealth;
2631
+ /** Promise-based mutex to serialize write operations */
2632
+ private writeLock;
1937
2633
  constructor(options: WebhookServerOptions);
1938
2634
  start(): Promise<void>;
1939
2635
  stop(): Promise<void>;
@@ -1941,6 +2637,11 @@ declare class WebhookServer {
1941
2637
  private handleWebhook;
1942
2638
  private readBody;
1943
2639
  private sendJson;
2640
+ /**
2641
+ * Acquire the write lock and execute a callback.
2642
+ * Serializes all write operations to prevent race conditions.
2643
+ */
2644
+ private withWriteLock;
1944
2645
  }
1945
2646
 
1946
2647
  declare const webhookEntrySchema: z.ZodObject<{
@@ -1988,4 +2689,4 @@ declare function testWebhooks(): Promise<WebhookTestResult[]>;
1988
2689
 
1989
2690
  declare const VERSION = "0.1.0";
1990
2691
 
1991
- export { type ActiveSession, type ActivityEntry, ActivityLog, type ActivityQueryOptions, type AgentConfig, type AgentDefinition, type AgentMessageEvent, type AgentModel, AgentRegistry, type AgentTool, type AgentToolEntry, type AgentToolUseEvent, type AuditLogMiddleware, type BudgetAlertEvent, ConfigStore, type CostEntry, CostJournal, type CostUpdateEvent, type Decision, type DecisionInput, type DecisionOption, DecisionStore, type DispatchInput, type Embedder, EventJournal, EventQueue, type GateWaitingEvent, type GitStrategy, type GlobalConfig, HeartbeatLoop, type HeartbeatLoopOptions, type HookEvent, type InboxMessage, LocalEmbedder, type LoopDetectionMiddleware, type McpServerConfig, type MemoryEntry, type MemoryQuery, type MemoryStats, MemoryStore, type MemoryType, type MemoryWriteInput, type Middleware, type MiddlewareChain, type MiddlewareContext, type MiddlewareContextMap, type MiddlewareEvent, type MiddlewareHandler, type MiddlewareResult, type NeoConfig, type NeoEvent, NeoEventEmitter, Orchestrator, type OrchestratorOptions, type OrchestratorShutdownEvent, type OrchestratorStatus, type ParsedOutput, type PersistedRun, type Priority, type QueueDequeueEvent, type QueueEnqueueEvent, type QueuedEvent, type RecoveryOptions, type RepoConfig, type RepoConfigInput, type ResolvedAgent, type RunContext, type SDKHooks, type SandboxConfig, Semaphore, type SemaphoreCallbacks, type SemaphoreConfig, type SessionCloneInfo, type SessionCompleteEvent, SessionError, type SessionEvent, type SessionExecutionConfig, type SessionExecutionDeps, type SessionExecutionInput, type SessionExecutionResult, SessionExecutor, type SessionFailEvent, type SessionOptions, type SessionResult, type SessionStartEvent, StatusReader, type StepCompleteEvent, type StepResult, type StepStartEvent, SupervisorDaemon, type SupervisorDaemonOptions, type SupervisorDaemonState, type SupervisorDaemonState as SupervisorState, type SupervisorStatus, type TaskResult, VERSION, WebhookDispatcher, type WebhookEntry, type WebhookEntryInput, type WebhookIncomingEvent, WebhookServer, type WebhookTestPayload, type WebhookTestResult, activityEntrySchema, addRepoToGlobalConfig, addWebhook, agentConfigSchema, agentModelSchema, agentSandboxSchema, agentToolEntrySchema, agentToolSchema, appendLogBuffer, auditLog, budgetGuard, buildFullPrompt, buildGitStrategyInstructions, buildMiddlewareChain, buildReportingInstructions, buildSDKHooks, buildSandboxConfig, createBranch, createSessionClone, decisionOptionSchema, decisionSchema, deleteBranch, fetchRemote, getBranchName, getCurrentBranch, getDataDir, getJournalsDir, getRepoRunsDir, getRunDispatchPath, getRunLogPath, getRunsDir, getSupervisorActivityPath, getSupervisorDecisionsPath, getSupervisorDir, getSupervisorEventsPath, getSupervisorInboxPath, getSupervisorLockPath, getSupervisorStatePath, getSupervisorsDir, globalConfigSchema, inboxMessageSchema, isProcessAlive, listReposFromGlobalConfig, listSessionClones, listWebhooks, loadAgentFile, loadConfig, loadGlobalConfig, loadRepoInstructions, loopDetection, matchesFilter, mcpServerConfigSchema, neoConfigSchema, parseOutput, pushBranch, pushSessionBranch, removeRepoFromGlobalConfig, removeSessionClone, removeWebhook, repoConfigSchema, repoOverrideConfigSchema, resolveAgent, runSession, runWithRecovery, supervisorDaemonStateSchema, supervisorDaemonStateSchema as supervisorStateSchema, supervisorStatusSchema, testWebhooks, toRepoSlug, webhookEntrySchema, webhookIncomingEventSchema };
2692
+ export { type AIAdapter, type AIQueryOptions, type ActiveSession, type ActivityEntry, ActivityLog, type ActivityQueryOptions, type AgentDefinition, type AgentMessageEvent, AgentRegistry, type AgentToolUseEvent, type AuditLogMiddleware, type BudgetAlertEvent, type ChildHandle, type ChildSpawnCommand, ClaudeAdapter, ConfigStore, type CostEntry, CostJournal, type CostUpdateEvent, type Decision, type DecisionInput, type DecisionOption, DecisionStore, type Directive, type DirectiveCreateInput, DirectiveStore, type DirectiveTrigger, type DispatchInput, type Embedder, EventJournal, EventQueue, FocusedLoop, type FocusedLoopOptions, type GateWaitingEvent, type GlobalConfig, HeartbeatLoop, type HeartbeatLoopOptions, type HookEvent, type InboxMessage, JsonlSupervisorStore, type KnowledgeSubtype, type LogBufferEntry, type LoopDetectionMiddleware, type McpServerConfig, type MemoryEntry, type MemoryQuery, type MemoryStats, MemoryStore, type MemoryType, type MemoryWriteInput, type Middleware, type MiddlewareChain, type MiddlewareContext, type MiddlewareContextMap, type MiddlewareEvent, type MiddlewareHandler, type MiddlewareResult, type NeoConfig, type NeoEvent, NeoEventEmitter, Orchestrator, type OrchestratorOptions, type OrchestratorShutdownEvent, type OrchestratorStatus, type ParentToChildMessage, type ParsedOutput, type PersistedRun, type Priority, type QueueDequeueEvent, type QueueEnqueueEvent, type QueuedEvent, type RecoveryOptions, type RepoConfig, type RepoConfigInput, type ResolvedAgent, type RunContext, type SDKHooks, SPAWN_CHILD_SUPERVISOR_TOOL, type SandboxConfig, Semaphore, type SemaphoreCallbacks, type SemaphoreConfig, type SessionCloneInfo, type SessionCompleteEvent, SessionError, type SessionEvent, type SessionExecutionConfig, type SessionExecutionDeps, type SessionExecutionInput, type SessionExecutionResult, SessionExecutor, type SessionFailEvent, type SessionHandle, type SessionOptions, type SessionResult, type SessionStartEvent, type SpawnChildOptions, type SpawnChildResult, type SpawnChildSupervisorInput, StatusReader, type StepCompleteEvent, type StepResult, type StepStartEvent, type SubagentDefinition, SupervisorDaemon, type SupervisorDaemonOptions, type SupervisorDaemonState, type SupervisorMessage, type SupervisorStatus, type TaskCreateInput, type TaskEntry, type TaskPriority, type TaskQuery, type TaskResult, type TaskStatus, TaskStore, VERSION, WebhookDispatcher, type WebhookEntry, type WebhookEntryInput, type WebhookIncomingEvent, WebhookServer, type WebhookTestPayload, type WebhookTestResult, activityEntrySchema, addRepoToGlobalConfig, addWebhook, agentConfigSchema, agentModelSchema, agentSandboxSchema, agentToolEntrySchema, agentToolSchema, appendLogBuffer, auditLog, budgetGuard, buildFullPrompt, buildGitStrategyInstructions, buildMiddlewareChain, buildReportingInstructions, buildSDKHooks, buildSandboxConfig, createBranch, createSessionClone, decisionOptionSchema, decisionSchema, deleteBranch, fetchRemote, getBranchName, getCurrentBranch, getDataDir, getFocusedSupervisorDir, getJournalsDir, getRepoRunsDir, getRunDispatchPath, getRunLogPath, getRunsDir, getSupervisorActivityPath, getSupervisorChildrenPath, getSupervisorDecisionsPath, getSupervisorDir, getSupervisorEventsPath, getSupervisorInboxPath, getSupervisorLockPath, getSupervisorStatePath, getSupervisorsDir, getWorkerStartedPath, globalConfigSchema, inboxMessageSchema, isProcessAlive, knowledgeSubtypeSchema, listReposFromGlobalConfig, listSessionClones, listWebhooks, loadAgentFile, loadConfig, loadGlobalConfig, loadRepoInstructions, loopDetection, matchesFilter, mcpServerConfigSchema, neoConfigSchema, parseChildSpawnCommand, parseDirectiveDuration, parseOutput, pushBranch, pushSessionBranch, readChildrenFile, readLogBuffer, removeRepoFromGlobalConfig, removeSessionClone, removeWebhook, repoConfigSchema, repoOverrideConfigSchema, resolveAgent, runSession, runWithRecovery, spawnChildSupervisor, spawnChildSupervisorInputSchema, supervisorDaemonStateSchema, supervisorStatusSchema, taskEntrySchema, taskPrioritySchema, taskStatusSchema, testWebhooks, toRepoSlug, webhookEntrySchema, webhookIncomingEventSchema };