@neotx/core 0.1.0-alpha.2 → 0.1.0-alpha.20

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
@@ -86,14 +86,21 @@ declare const mcpServerConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
86
86
  args: z.ZodOptional<z.ZodArray<z.ZodString>>;
87
87
  env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
88
88
  }, z.core.$strip>], "type">;
89
+ declare const gitStrategySchema: z.ZodDefault<z.ZodEnum<{
90
+ pr: "pr";
91
+ branch: "branch";
92
+ }>>;
93
+ type GitStrategy = z.infer<typeof gitStrategySchema>;
89
94
  declare const repoConfigSchema: z.ZodObject<{
90
95
  path: z.ZodString;
91
96
  name: z.ZodOptional<z.ZodString>;
92
97
  defaultBranch: z.ZodDefault<z.ZodString>;
93
98
  branchPrefix: z.ZodDefault<z.ZodString>;
94
99
  pushRemote: z.ZodDefault<z.ZodString>;
95
- autoCreatePr: z.ZodDefault<z.ZodBoolean>;
96
- prBaseBranch: z.ZodOptional<z.ZodString>;
100
+ gitStrategy: z.ZodDefault<z.ZodEnum<{
101
+ pr: "pr";
102
+ branch: "branch";
103
+ }>>;
97
104
  }, z.core.$strip>;
98
105
  declare const globalConfigSchema: z.ZodObject<{
99
106
  repos: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -102,8 +109,10 @@ declare const globalConfigSchema: z.ZodObject<{
102
109
  defaultBranch: z.ZodDefault<z.ZodString>;
103
110
  branchPrefix: z.ZodDefault<z.ZodString>;
104
111
  pushRemote: z.ZodDefault<z.ZodString>;
105
- autoCreatePr: z.ZodDefault<z.ZodBoolean>;
106
- prBaseBranch: z.ZodOptional<z.ZodString>;
112
+ gitStrategy: z.ZodDefault<z.ZodEnum<{
113
+ pr: "pr";
114
+ branch: "branch";
115
+ }>>;
107
116
  }, z.core.$strip>>>;
108
117
  concurrency: z.ZodDefault<z.ZodObject<{
109
118
  maxSessions: z.ZodDefault<z.ZodNumber>;
@@ -121,6 +130,7 @@ declare const globalConfigSchema: z.ZodObject<{
121
130
  sessions: z.ZodDefault<z.ZodObject<{
122
131
  initTimeoutMs: z.ZodDefault<z.ZodNumber>;
123
132
  maxDurationMs: z.ZodDefault<z.ZodNumber>;
133
+ dir: z.ZodDefault<z.ZodString>;
124
134
  }, z.core.$strip>>;
125
135
  webhooks: z.ZodDefault<z.ZodArray<z.ZodObject<{
126
136
  url: z.ZodString;
@@ -131,13 +141,20 @@ declare const globalConfigSchema: z.ZodObject<{
131
141
  supervisor: z.ZodDefault<z.ZodObject<{
132
142
  port: z.ZodDefault<z.ZodNumber>;
133
143
  secret: z.ZodOptional<z.ZodString>;
134
- idleIntervalMs: z.ZodDefault<z.ZodNumber>;
135
- idleSkipMax: z.ZodDefault<z.ZodNumber>;
136
144
  heartbeatTimeoutMs: z.ZodDefault<z.ZodNumber>;
137
145
  maxConsecutiveFailures: z.ZodDefault<z.ZodNumber>;
138
146
  maxEventsPerSec: z.ZodDefault<z.ZodNumber>;
139
147
  dailyCapUsd: z.ZodDefault<z.ZodNumber>;
148
+ consolidationIntervalMs: z.ZodDefault<z.ZodNumber>;
149
+ compactionIntervalMs: z.ZodDefault<z.ZodNumber>;
150
+ eventTimeoutMs: z.ZodDefault<z.ZodNumber>;
140
151
  instructions: z.ZodOptional<z.ZodString>;
152
+ idleSkipMax: z.ZodDefault<z.ZodNumber>;
153
+ activeWorkSkipMax: z.ZodDefault<z.ZodNumber>;
154
+ autoDecide: z.ZodDefault<z.ZodBoolean>;
155
+ }, z.core.$strip>>;
156
+ memory: z.ZodDefault<z.ZodObject<{
157
+ embeddings: z.ZodDefault<z.ZodBoolean>;
141
158
  }, z.core.$strip>>;
142
159
  mcpServers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
143
160
  type: z.ZodLiteral<"http">;
@@ -166,8 +183,10 @@ declare const neoConfigSchema: z.ZodObject<{
166
183
  defaultBranch: z.ZodDefault<z.ZodString>;
167
184
  branchPrefix: z.ZodDefault<z.ZodString>;
168
185
  pushRemote: z.ZodDefault<z.ZodString>;
169
- autoCreatePr: z.ZodDefault<z.ZodBoolean>;
170
- prBaseBranch: z.ZodOptional<z.ZodString>;
186
+ gitStrategy: z.ZodDefault<z.ZodEnum<{
187
+ pr: "pr";
188
+ branch: "branch";
189
+ }>>;
171
190
  }, z.core.$strip>>>;
172
191
  concurrency: z.ZodDefault<z.ZodObject<{
173
192
  maxSessions: z.ZodDefault<z.ZodNumber>;
@@ -185,6 +204,7 @@ declare const neoConfigSchema: z.ZodObject<{
185
204
  sessions: z.ZodDefault<z.ZodObject<{
186
205
  initTimeoutMs: z.ZodDefault<z.ZodNumber>;
187
206
  maxDurationMs: z.ZodDefault<z.ZodNumber>;
207
+ dir: z.ZodDefault<z.ZodString>;
188
208
  }, z.core.$strip>>;
189
209
  webhooks: z.ZodDefault<z.ZodArray<z.ZodObject<{
190
210
  url: z.ZodString;
@@ -195,13 +215,20 @@ declare const neoConfigSchema: z.ZodObject<{
195
215
  supervisor: z.ZodDefault<z.ZodObject<{
196
216
  port: z.ZodDefault<z.ZodNumber>;
197
217
  secret: z.ZodOptional<z.ZodString>;
198
- idleIntervalMs: z.ZodDefault<z.ZodNumber>;
199
- idleSkipMax: z.ZodDefault<z.ZodNumber>;
200
218
  heartbeatTimeoutMs: z.ZodDefault<z.ZodNumber>;
201
219
  maxConsecutiveFailures: z.ZodDefault<z.ZodNumber>;
202
220
  maxEventsPerSec: z.ZodDefault<z.ZodNumber>;
203
221
  dailyCapUsd: z.ZodDefault<z.ZodNumber>;
222
+ consolidationIntervalMs: z.ZodDefault<z.ZodNumber>;
223
+ compactionIntervalMs: z.ZodDefault<z.ZodNumber>;
224
+ eventTimeoutMs: z.ZodDefault<z.ZodNumber>;
204
225
  instructions: z.ZodOptional<z.ZodString>;
226
+ idleSkipMax: z.ZodDefault<z.ZodNumber>;
227
+ activeWorkSkipMax: z.ZodDefault<z.ZodNumber>;
228
+ autoDecide: z.ZodDefault<z.ZodBoolean>;
229
+ }, z.core.$strip>>;
230
+ memory: z.ZodDefault<z.ZodObject<{
231
+ embeddings: z.ZodDefault<z.ZodBoolean>;
205
232
  }, z.core.$strip>>;
206
233
  mcpServers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodDiscriminatedUnion<[z.ZodObject<{
207
234
  type: z.ZodLiteral<"http">;
@@ -223,11 +250,94 @@ declare const neoConfigSchema: z.ZodObject<{
223
250
  ttlMs: z.ZodDefault<z.ZodNumber>;
224
251
  }, z.core.$strip>>;
225
252
  }, z.core.$strip>;
253
+ declare const repoOverrideConfigSchema: z.ZodObject<{
254
+ concurrency: z.ZodOptional<z.ZodOptional<z.ZodObject<{
255
+ maxSessions: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
256
+ maxPerRepo: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
257
+ queueMax: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
258
+ }, z.core.$strip>>>;
259
+ budget: z.ZodOptional<z.ZodOptional<z.ZodObject<{
260
+ dailyCapUsd: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
261
+ alertThresholdPct: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
262
+ }, z.core.$strip>>>;
263
+ recovery: z.ZodOptional<z.ZodOptional<z.ZodObject<{
264
+ maxRetries: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
265
+ backoffBaseMs: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
266
+ }, z.core.$strip>>>;
267
+ sessions: z.ZodOptional<z.ZodOptional<z.ZodObject<{
268
+ initTimeoutMs: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
269
+ maxDurationMs: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
270
+ dir: z.ZodOptional<z.ZodDefault<z.ZodString>>;
271
+ }, z.core.$strip>>>;
272
+ }, z.core.$strip>;
226
273
  type NeoConfig = z.infer<typeof neoConfigSchema>;
227
274
  type GlobalConfig = NeoConfig;
228
275
  type RepoConfig = z.infer<typeof repoConfigSchema>;
229
276
  type RepoConfigInput = z.input<typeof repoConfigSchema>;
230
277
  type McpServerConfig = z.infer<typeof mcpServerConfigSchema>;
278
+
279
+ /**
280
+ * Configuration store that loads and merges config files.
281
+ *
282
+ * Config precedence (highest to lowest):
283
+ * 1. Repo config: <repoPath>/.neo/config.yml
284
+ * 2. Global config: ~/.neo/config.yml
285
+ * 3. Default values (hardcoded)
286
+ *
287
+ * @example
288
+ * const store = new ConfigStore('/path/to/repo');
289
+ * await store.load();
290
+ * const dailyCap = store.get<number>('budget.dailyCapUsd');
291
+ */
292
+ declare class ConfigStore {
293
+ private repoPath;
294
+ private config;
295
+ constructor(repoPath?: string);
296
+ /**
297
+ * Loads and merges config files from all locations.
298
+ * Must be called before get() or getAll().
299
+ */
300
+ load(): Promise<void>;
301
+ /**
302
+ * Gets a config value using dot notation.
303
+ *
304
+ * @param key - Dot-separated path (e.g., "budget.dailyCapUsd")
305
+ * @returns The value at the path
306
+ * @throws Error if load() has not been called
307
+ *
308
+ * @example
309
+ * store.get<number>('budget.dailyCapUsd') // 500
310
+ * store.get<string>('sessions.dir') // '/tmp/neo-sessions'
311
+ */
312
+ get<T>(key: string): T;
313
+ /**
314
+ * Returns the full merged configuration.
315
+ *
316
+ * @throws Error if load() has not been called
317
+ */
318
+ getAll(): NeoConfig;
319
+ /**
320
+ * Returns the repository path, if one was provided.
321
+ * Used by ConfigWatcher to determine which files to watch.
322
+ */
323
+ getRepoPath(): string | undefined;
324
+ /**
325
+ * Loads global config from ~/.neo/config.yml
326
+ */
327
+ private loadGlobalConfig;
328
+ /**
329
+ * Loads repo-level overrides from <repoPath>/.neo/config.yml
330
+ */
331
+ private loadRepoConfig;
332
+ /**
333
+ * Loads and parses a YAML config file.
334
+ *
335
+ * @param filePath - Absolute path to the config file
336
+ * @returns Parsed YAML content or null if file doesn't exist
337
+ */
338
+ private loadFile;
339
+ }
340
+
231
341
  /**
232
342
  * Load NeoConfig from a single file (legacy compatibility).
233
343
  */
@@ -255,6 +365,7 @@ interface AgentDefinition {
255
365
  prompt: string;
256
366
  tools: string[];
257
367
  model: string;
368
+ mcpServers?: string[] | undefined;
258
369
  }
259
370
  interface ResolvedAgent {
260
371
  name: string;
@@ -263,39 +374,14 @@ interface ResolvedAgent {
263
374
  maxTurns?: number | undefined;
264
375
  source: "built-in" | "custom" | "extended";
265
376
  }
266
- interface WorkflowDefinition {
267
- name: string;
268
- description?: string | undefined;
269
- steps: Record<string, WorkflowStepDef | WorkflowGateDef>;
270
- }
271
- interface WorkflowStepDef {
272
- type?: "step" | undefined;
273
- agent: string;
274
- dependsOn?: string[] | undefined;
275
- prompt?: string | undefined;
276
- sandbox?: "writable" | "readonly" | undefined;
277
- maxTurns?: number | undefined;
278
- mcpServers?: string[] | undefined;
279
- recovery?: {
280
- maxRetries?: number | undefined;
281
- nonRetryable?: string[] | undefined;
282
- } | undefined;
283
- }
284
- interface WorkflowGateDef {
285
- type: "gate";
286
- dependsOn?: string[] | undefined;
287
- description: string;
288
- timeout?: string | undefined;
289
- autoApprove?: boolean | undefined;
290
- }
291
377
  interface PersistedRun {
292
378
  version: 1;
293
379
  runId: string;
294
- workflow: string;
380
+ agent: string;
295
381
  repo: string;
296
382
  prompt: string;
297
383
  branch?: string | undefined;
298
- worktreePath?: string | undefined;
384
+ sessionPath?: string | undefined;
299
385
  pid?: number | undefined;
300
386
  status: "running" | "paused" | "completed" | "failed";
301
387
  steps: Record<string, StepResult>;
@@ -308,6 +394,8 @@ interface StepResult {
308
394
  sessionId?: string | undefined;
309
395
  output?: unknown;
310
396
  rawOutput?: string | undefined;
397
+ prUrl?: string | undefined;
398
+ prNumber?: number | undefined;
311
399
  costUsd: number;
312
400
  durationMs: number;
313
401
  agent: string;
@@ -318,14 +406,16 @@ interface StepResult {
318
406
  }
319
407
  type Priority = "critical" | "high" | "medium" | "low";
320
408
  interface DispatchInput {
321
- workflow: string;
409
+ agent: string;
322
410
  repo: string;
323
411
  prompt: string;
324
412
  runId?: string | undefined;
413
+ branch?: string | undefined;
325
414
  step?: string | undefined;
326
415
  from?: string | undefined;
327
416
  retry?: string | undefined;
328
417
  priority?: Priority | undefined;
418
+ gitStrategy?: "pr" | "branch" | undefined;
329
419
  overrides?: {
330
420
  agents?: Record<string, string> | undefined;
331
421
  maxTurns?: number | undefined;
@@ -335,7 +425,7 @@ interface DispatchInput {
335
425
  }
336
426
  interface TaskResult {
337
427
  runId: string;
338
- workflow: string;
428
+ agent: string;
339
429
  repo: string;
340
430
  status: "success" | "failure" | "timeout" | "cancelled";
341
431
  steps: Record<string, StepResult>;
@@ -351,13 +441,12 @@ interface TaskResult {
351
441
  interface ActiveSession {
352
442
  sessionId: string;
353
443
  runId: string;
354
- workflow: string;
355
444
  step: string;
356
445
  agent: string;
357
446
  repo: string;
358
447
  status: "running" | "queued" | "waiting_gate";
359
448
  startedAt: string;
360
- worktreePath?: string | undefined;
449
+ sessionPath?: string | undefined;
361
450
  }
362
451
  interface OrchestratorStatus {
363
452
  paused: boolean;
@@ -368,9 +457,9 @@ interface OrchestratorStatus {
368
457
  budgetRemainingPct: number;
369
458
  uptime: number;
370
459
  }
371
- interface WorkflowContext {
460
+ interface RunContext {
372
461
  runId: string;
373
- workflow: string;
462
+ agent: string;
374
463
  repo: string;
375
464
  prompt: string;
376
465
  steps: Record<string, StepResult>;
@@ -380,7 +469,6 @@ interface SessionStartEvent {
380
469
  type: "session:start";
381
470
  sessionId: string;
382
471
  runId: string;
383
- workflow: string;
384
472
  step: string;
385
473
  agent: string;
386
474
  repo: string;
@@ -425,16 +513,16 @@ interface AgentMessageEvent {
425
513
  text: string;
426
514
  timestamp: string;
427
515
  }
428
- interface WorkflowStepStartEvent {
429
- type: "workflow:step_start";
516
+ interface StepStartEvent {
517
+ type: "step:start";
430
518
  runId: string;
431
519
  step: string;
432
520
  agent: string;
433
521
  metadata?: Record<string, unknown> | undefined;
434
522
  timestamp: string;
435
523
  }
436
- interface WorkflowStepCompleteEvent {
437
- type: "workflow:step_complete";
524
+ interface StepCompleteEvent {
525
+ type: "step:complete";
438
526
  runId: string;
439
527
  step: string;
440
528
  status: "success" | "failure" | "skipped";
@@ -448,7 +536,7 @@ interface GateWaitingEvent {
448
536
  runId: string;
449
537
  gate: string;
450
538
  description: string;
451
- context: WorkflowContext;
539
+ context: RunContext;
452
540
  approve: () => void;
453
541
  reject: (reason: string) => void;
454
542
  metadata?: Record<string, unknown> | undefined;
@@ -487,7 +575,7 @@ interface OrchestratorShutdownEvent {
487
575
  type: "orchestrator:shutdown";
488
576
  timestamp: string;
489
577
  }
490
- type NeoEvent = SessionStartEvent | SessionCompleteEvent | SessionFailEvent | AgentToolUseEvent | AgentMessageEvent | WorkflowStepStartEvent | WorkflowStepCompleteEvent | GateWaitingEvent | CostUpdateEvent | BudgetAlertEvent | QueueEnqueueEvent | QueueDequeueEvent | OrchestratorShutdownEvent;
578
+ type NeoEvent = SessionStartEvent | SessionCompleteEvent | SessionFailEvent | AgentToolUseEvent | AgentMessageEvent | StepStartEvent | StepCompleteEvent | GateWaitingEvent | CostUpdateEvent | BudgetAlertEvent | QueueEnqueueEvent | QueueDequeueEvent | OrchestratorShutdownEvent;
491
579
  type HookEvent = "PreToolUse" | "PostToolUse" | "Notification";
492
580
  interface Middleware {
493
581
  name: string;
@@ -512,7 +600,6 @@ interface MiddlewareContextMap {
512
600
  }
513
601
  interface MiddlewareContext {
514
602
  runId: string;
515
- workflow: string;
516
603
  step: string;
517
604
  agent: string;
518
605
  repo: string;
@@ -531,7 +618,6 @@ type MiddlewareResult = {
531
618
  interface CostEntry {
532
619
  timestamp: string;
533
620
  runId: string;
534
- workflow: string;
535
621
  step: string;
536
622
  sessionId: string;
537
623
  agent: string;
@@ -611,15 +697,13 @@ declare class Semaphore {
611
697
  */
612
698
  declare class CostJournal {
613
699
  private readonly dir;
614
- private dirCreated;
700
+ private readonly dirCache;
615
701
  private dayCache;
616
702
  constructor(options: {
617
703
  dir: string;
618
704
  });
619
705
  append(entry: CostEntry): Promise<void>;
620
706
  getDayTotal(date?: Date): Promise<number>;
621
- private fileForDate;
622
- private ensureDir;
623
707
  }
624
708
 
625
709
  /**
@@ -646,28 +730,31 @@ declare class NeoEventEmitter {
646
730
  */
647
731
  declare class EventJournal {
648
732
  private readonly dir;
649
- private dirCreated;
733
+ private readonly dirCache;
650
734
  constructor(options: {
651
735
  dir: string;
652
736
  });
653
737
  append(event: NeoEvent): Promise<void>;
654
- private fileForDate;
655
- private ensureDir;
656
738
  }
657
739
 
658
740
  type WebhookConfig = NeoConfig["webhooks"][number];
659
741
  /**
660
- * Fire-and-forget webhook dispatcher for NeoEvents.
742
+ * Webhook dispatcher for NeoEvents.
661
743
  *
662
744
  * - Matches events against per-webhook filters (exact or wildcard like "session:*")
663
745
  * - Excludes gate:waiting events (contain non-serializable callbacks)
664
746
  * - Signs payloads with HMAC-SHA256 when a secret is configured
665
- * - Never throws errors are silently swallowed (consistent with EventJournal)
747
+ * - Terminal events (session:complete, session:fail, budget:alert) are retried
748
+ * with exponential backoff on failure
749
+ * - Non-terminal events remain fire-and-forget
666
750
  */
667
751
  declare class WebhookDispatcher {
668
752
  private readonly webhooks;
753
+ private readonly pending;
669
754
  constructor(webhooks: WebhookConfig[]);
670
755
  dispatch(event: NeoEvent): void;
756
+ /** Wait for all pending terminal webhook deliveries to complete. */
757
+ flush(): Promise<void>;
671
758
  }
672
759
  /**
673
760
  * Check if an event type matches a filter list.
@@ -676,27 +763,48 @@ declare class WebhookDispatcher {
676
763
  */
677
764
  declare function matchesFilter(eventType: string, filters?: string[]): boolean;
678
765
 
766
+ interface SessionCloneInfo {
767
+ path: string;
768
+ branch: string;
769
+ repoPath: string;
770
+ }
771
+ /**
772
+ * Create an isolated git clone for an agent session.
773
+ * Uses `git clone --local` to hardlink objects (fast, no network).
774
+ * Then checks out the target branch (existing or new).
775
+ */
776
+ declare function createSessionClone(options: {
777
+ repoPath: string;
778
+ branch: string;
779
+ baseBranch: string;
780
+ sessionDir: string;
781
+ }): Promise<SessionCloneInfo>;
782
+ /**
783
+ * Remove a session clone directory.
784
+ * Idempotent — does not throw if the directory is already gone.
785
+ */
786
+ declare function removeSessionClone(sessionPath: string): Promise<void>;
787
+ /**
788
+ * List all session clones under a base directory.
789
+ */
790
+ declare function listSessionClones(sessionsBaseDir: string): Promise<SessionCloneInfo[]>;
791
+
679
792
  declare function createBranch(repoPath: string, branch: string, baseBranch: string): Promise<void>;
680
793
  declare function pushBranch(repoPath: string, branch: string, remote: string): Promise<void>;
681
794
  declare function fetchRemote(repoPath: string, remote: string): Promise<void>;
682
795
  declare function deleteBranch(repoPath: string, branch: string): Promise<void>;
683
796
  declare function getCurrentBranch(repoPath: string): Promise<string>;
684
797
  /**
685
- * Generate a deterministic branch name for a run.
686
- * Uses the repo's branchPrefix (default "feat") and the runId.
798
+ * Resolve the branch name for a run.
799
+ * If an explicit branch is provided, use it as-is.
800
+ * Otherwise, generate a deterministic name from the repo's branchPrefix and runId.
687
801
  */
688
- declare function getBranchName(config: RepoConfig, runId: string): string;
689
-
802
+ declare function getBranchName(config: RepoConfig, runId: string, branch?: string): string;
690
803
  /**
691
- * Per-repository in-memory mutex to serialise git operations.
692
- * Concurrent git commands on the same repo corrupt the index this prevents that.
804
+ * Push a branch from a session clone to a remote. Silently succeeds if
805
+ * the branch has no new commits to push.
693
806
  */
694
- /**
695
- * Execute `fn` while holding an exclusive lock for `repoPath`.
696
- * Concurrent calls for the same repo are queued and executed serially.
697
- * Operations on different repos run in parallel.
698
- */
699
- declare function withGitLock<T>(repoPath: string, fn: () => Promise<T>): Promise<T>;
807
+ declare function pushSessionBranch(sessionPath: string, branch: string, remote: string): Promise<void>;
700
808
 
701
809
  /**
702
810
  * SDK-compatible sandbox configuration.
@@ -715,40 +823,10 @@ interface SandboxConfig {
715
823
  /**
716
824
  * Build an SDK-compatible sandbox configuration for an agent.
717
825
  *
718
- * - Writable agents: all their tools are allowed, write paths include the worktree
826
+ * - Writable agents: all their tools are allowed, write paths include the session clone
719
827
  * - Readonly agents: write tools are filtered out, no writable paths
720
828
  */
721
- declare function buildSandboxConfig(agent: ResolvedAgent, worktreePath?: string): SandboxConfig;
722
-
723
- interface WorktreeInfo {
724
- path: string;
725
- branch: string;
726
- repoPath: string;
727
- }
728
- /**
729
- * Create a new git worktree with an associated branch.
730
- * Creates the branch from baseBranch, then adds the worktree at worktreeDir.
731
- */
732
- declare function createWorktree(options: {
733
- repoPath: string;
734
- branch: string;
735
- baseBranch: string;
736
- worktreeDir: string;
737
- }): Promise<WorktreeInfo>;
738
- /**
739
- * Remove a worktree. Does NOT delete the branch (branch stays for the PR).
740
- * Idempotent — does not throw if the worktree is already gone.
741
- */
742
- declare function removeWorktree(worktreePath: string): Promise<void>;
743
- /**
744
- * List all worktrees for a repository.
745
- */
746
- declare function listWorktrees(repoPath: string): Promise<WorktreeInfo[]>;
747
- /**
748
- * Clean up worktrees under worktreeBaseDir that no longer have a matching run.
749
- * Removes any subdirectory that is a git worktree.
750
- */
751
- declare function cleanupOrphanedWorktrees(worktreeBaseDir: string): Promise<void>;
829
+ declare function buildSandboxConfig(agent: ResolvedAgent, sessionPath?: string): SandboxConfig;
752
830
 
753
831
  /**
754
832
  * Audit log middleware.
@@ -815,32 +893,30 @@ declare function loopDetection(options: {
815
893
  interface OrchestratorOptions {
816
894
  middleware?: Middleware[] | undefined;
817
895
  journalDir?: string | undefined;
818
- builtInWorkflowDir?: string | undefined;
819
- customWorkflowDir?: string | undefined;
896
+ /** Skip orphan recovery on start — workers should set this to true to avoid false orphan detection on concurrent launches. */
897
+ skipOrphanRecovery?: boolean | undefined;
820
898
  }
821
899
  declare class Orchestrator extends NeoEventEmitter {
822
900
  private readonly config;
823
901
  private readonly semaphore;
824
902
  private readonly userMiddleware;
825
- private readonly workflows;
826
903
  private readonly registeredAgents;
827
904
  private readonly _activeSessions;
828
905
  private readonly idempotencyCache;
829
906
  private readonly abortControllers;
830
907
  private readonly repoIndex;
831
- private readonly createdRunDirs;
908
+ private readonly runStore;
832
909
  private readonly journalDir;
833
- private readonly builtInWorkflowDir;
834
- private readonly customWorkflowDir;
835
910
  private costJournal;
836
911
  private eventJournal;
837
912
  private webhookDispatcher;
913
+ private memoryStore;
838
914
  private _paused;
839
915
  private _costToday;
840
916
  private _startedAt;
841
917
  private _drainResolve;
918
+ private readonly skipOrphanRecovery;
842
919
  constructor(config: NeoConfig, options?: OrchestratorOptions);
843
- registerWorkflow(definition: WorkflowDefinition): void;
844
920
  registerAgent(agent: ResolvedAgent): void;
845
921
  dispatch(input: DispatchInput): Promise<TaskResult>;
846
922
  pause(): void;
@@ -870,23 +946,25 @@ declare class Orchestrator extends NeoEventEmitter {
870
946
  private buildDispatchContext;
871
947
  private executeStep;
872
948
  /**
873
- * Push the branch, then remove the worktree.
949
+ * Push the branch (writable only), then remove the session clone.
874
950
  * Runs in `finally` so it executes on both success and failure.
875
951
  */
876
- private finalizeWorktree;
952
+ private finalizeSession;
877
953
  private runAgentSession;
878
954
  private finalizeDispatch;
955
+ private getMemoryStore;
956
+ private loadMemoryContext;
879
957
  private emitCostEvents;
880
958
  private emitSessionComplete;
881
959
  private emitSessionFail;
882
960
  private validateInput;
883
961
  private evictExpiredIdempotencyEntries;
884
962
  private computeIdempotencyKey;
885
- private getFirstStep;
886
- private resolveStepAgent;
887
963
  private resolveRepo;
888
- private buildMiddlewareContext;
889
964
  private computeBudgetRemainingPct;
965
+ private resolveMcpServers;
966
+ /** Discover running supervisor daemons and return webhook configs for their endpoints. */
967
+ private discoverSupervisorWebhooks;
890
968
  private persistRun;
891
969
  private recoverOrphanedRuns;
892
970
  }
@@ -930,19 +1008,22 @@ declare function getSupervisorDir(name: string): string;
930
1008
  * Path to a supervisor state file: ~/.neo/supervisors/<name>/state.json
931
1009
  */
932
1010
  declare function getSupervisorStatePath(name: string): string;
933
- declare function getSupervisorMemoryPath(name: string): string;
934
1011
  declare function getSupervisorActivityPath(name: string): string;
935
1012
  declare function getSupervisorInboxPath(name: string): string;
936
1013
  declare function getSupervisorEventsPath(name: string): string;
937
1014
  declare function getSupervisorLockPath(name: string): string;
1015
+ declare function getSupervisorDecisionsPath(name: string): string;
938
1016
 
939
1017
  interface ParsedOutput {
940
1018
  rawOutput: string;
941
1019
  output?: unknown;
942
1020
  parseError?: string;
1021
+ prUrl?: string;
1022
+ prNumber?: number;
943
1023
  }
944
1024
  /**
945
1025
  * Parse agent output, optionally validating against a Zod schema.
1026
+ * Also extracts structured markers like PR_URL from the output.
946
1027
  *
947
1028
  * - If no schema: returns rawOutput only
948
1029
  * - If schema provided: extracts JSON from output, validates with schema
@@ -954,10 +1035,11 @@ interface SessionOptions {
954
1035
  agent: ResolvedAgent;
955
1036
  prompt: string;
956
1037
  repoPath?: string;
957
- worktreePath?: string;
1038
+ sessionPath?: string;
958
1039
  sandboxConfig: SandboxConfig;
959
1040
  hooks?: Record<string, unknown>;
960
- mcpServers?: McpServerConfig[];
1041
+ mcpServers?: Record<string, McpServerConfig>;
1042
+ env?: Record<string, string>;
961
1043
  initTimeoutMs: number;
962
1044
  maxDurationMs: number;
963
1045
  resumeSessionId?: string | undefined;
@@ -1007,23 +1089,174 @@ interface RecoveryOptions extends SessionOptions {
1007
1089
  */
1008
1090
  declare function runWithRecovery(options: RecoveryOptions): Promise<SessionResult>;
1009
1091
 
1092
+ declare function loadRepoInstructions(repoPath: string): Promise<string | undefined>;
1093
+ declare function buildGitStrategyInstructions(strategy: GitStrategy, agent: ResolvedAgent, branch: string, baseBranch: string, remote: string, metadata?: Record<string, unknown>): string | null;
1094
+ declare function buildReportingInstructions(_runId: string): string;
1095
+ declare function buildFullPrompt(agentPrompt: string | undefined, repoInstructions: string | undefined, gitInstructions: string | null, taskPrompt: string, memoryContext?: string | undefined, cwdInstructions?: string | undefined, reportingInstructions?: string | undefined): string;
1096
+
1097
+ interface SessionExecutionInput {
1098
+ runId: string;
1099
+ sessionId: string;
1100
+ agent: ResolvedAgent;
1101
+ repoConfig: RepoConfig;
1102
+ repoPath: string;
1103
+ prompt: string;
1104
+ branch?: string | undefined;
1105
+ gitStrategy: GitStrategy;
1106
+ sessionPath?: string | undefined;
1107
+ metadata?: Record<string, unknown> | undefined;
1108
+ startedAt: string;
1109
+ }
1110
+ interface SessionExecutionConfig {
1111
+ initTimeoutMs: number;
1112
+ maxDurationMs: number;
1113
+ maxRetries: number;
1114
+ backoffBaseMs: number;
1115
+ }
1116
+ interface SessionExecutionDeps {
1117
+ middleware: Middleware[];
1118
+ mcpServers?: Record<string, McpServerConfig> | undefined;
1119
+ memoryContext?: string | undefined;
1120
+ onAttempt?: (attempt: number, strategy: string) => void;
1121
+ }
1122
+ interface SessionExecutionResult extends StepResult {
1123
+ parsed: ParsedOutput;
1124
+ }
1125
+ /**
1126
+ * Encapsulates session execution logic: prompt building, SDK calls, and response processing.
1127
+ * Extracted from Orchestrator for better testability and separation of concerns.
1128
+ */
1129
+ declare class SessionExecutor {
1130
+ private readonly config;
1131
+ private readonly getContextValue;
1132
+ constructor(config: SessionExecutionConfig, getContextValue: (key: string) => unknown);
1133
+ /**
1134
+ * Execute an agent session with the given input and dependencies.
1135
+ * Handles prompt building, SDK invocation via recovery wrapper, and output parsing.
1136
+ */
1137
+ execute(input: SessionExecutionInput, deps: SessionExecutionDeps): Promise<SessionExecutionResult>;
1138
+ }
1139
+
1140
+ /**
1141
+ * Checks whether a process with the given PID is currently running.
1142
+ *
1143
+ * Uses the POSIX signal 0 trick: `process.kill(pid, 0)` doesn't actually
1144
+ * send a signal but checks whether the process exists and the current
1145
+ * process has permission to signal it. If the process doesn't exist,
1146
+ * an ESRCH error is thrown.
1147
+ *
1148
+ * @param pid - The process ID to check. Must be a positive integer.
1149
+ * @returns `true` if the process is alive and accessible, `false` otherwise.
1150
+ *
1151
+ * @example
1152
+ * ```ts
1153
+ * import { isProcessAlive } from "@/shared/process";
1154
+ *
1155
+ * // Check if current process is alive (always true)
1156
+ * isProcessAlive(process.pid); // => true
1157
+ *
1158
+ * // Check if a non-existent process is alive
1159
+ * isProcessAlive(999999); // => false
1160
+ * ```
1161
+ */
1162
+ declare function isProcessAlive(pid: number): boolean;
1163
+
1164
+ declare const decisionOptionSchema: z.ZodObject<{
1165
+ key: z.ZodString;
1166
+ label: z.ZodString;
1167
+ description: z.ZodOptional<z.ZodString>;
1168
+ }, z.core.$strip>;
1169
+ declare const decisionSchema: z.ZodObject<{
1170
+ id: z.ZodString;
1171
+ question: z.ZodString;
1172
+ context: z.ZodOptional<z.ZodString>;
1173
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
1174
+ key: z.ZodString;
1175
+ label: z.ZodString;
1176
+ description: z.ZodOptional<z.ZodString>;
1177
+ }, z.core.$strip>>>;
1178
+ type: z.ZodDefault<z.ZodString>;
1179
+ source: z.ZodString;
1180
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
1181
+ createdAt: z.ZodString;
1182
+ expiresAt: z.ZodOptional<z.ZodString>;
1183
+ defaultAnswer: z.ZodOptional<z.ZodString>;
1184
+ answeredAt: z.ZodOptional<z.ZodString>;
1185
+ answer: z.ZodOptional<z.ZodString>;
1186
+ expiredAt: z.ZodOptional<z.ZodString>;
1187
+ }, z.core.$strip>;
1188
+ type DecisionOption = z.infer<typeof decisionOptionSchema>;
1189
+ type Decision = z.infer<typeof decisionSchema>;
1190
+ type DecisionInput = Omit<Decision, "id" | "createdAt" | "answeredAt" | "answer" | "expiredAt">;
1191
+ /**
1192
+ * JSONL-backed store for decisions.
1193
+ * Append-only with in-place updates for answers and expiration.
1194
+ */
1195
+ declare class DecisionStore {
1196
+ private readonly filePath;
1197
+ private readonly dir;
1198
+ private readonly dirCache;
1199
+ constructor(filePath: string);
1200
+ /**
1201
+ * Create a new decision and persist it.
1202
+ * @returns The generated decision ID
1203
+ */
1204
+ create(input: DecisionInput): Promise<string>;
1205
+ /**
1206
+ * Answer a decision by ID.
1207
+ * Reads all entries, updates the matching one, and rewrites the file.
1208
+ */
1209
+ answer(id: string, answer: string): Promise<void>;
1210
+ /**
1211
+ * Get all pending decisions (unanswered, not expired, not timed out).
1212
+ */
1213
+ pending(): Promise<Decision[]>;
1214
+ /**
1215
+ * Get answered decisions, optionally filtered by timestamp.
1216
+ * @param since - ISO timestamp to filter decisions answered after this time
1217
+ */
1218
+ answered(since?: string): Promise<Decision[]>;
1219
+ /**
1220
+ * Get a specific decision by ID.
1221
+ */
1222
+ get(id: string): Promise<Decision | null>;
1223
+ /**
1224
+ * Auto-answer expired decisions with their defaultAnswer.
1225
+ * Decisions without defaultAnswer are marked as expired (expiredAt).
1226
+ * @returns The decisions that were auto-answered or marked expired
1227
+ */
1228
+ expire(): Promise<Decision[]>;
1229
+ private readAll;
1230
+ private writeAll;
1231
+ }
1232
+
1010
1233
  declare const supervisorDaemonStateSchema: z.ZodObject<{
1011
1234
  pid: z.ZodNumber;
1012
1235
  sessionId: z.ZodString;
1236
+ startedAt: z.ZodString;
1013
1237
  port: z.ZodNumber;
1014
1238
  cwd: z.ZodString;
1015
- startedAt: z.ZodString;
1016
1239
  lastHeartbeat: z.ZodOptional<z.ZodString>;
1017
1240
  heartbeatCount: z.ZodDefault<z.ZodNumber>;
1018
1241
  totalCostUsd: z.ZodDefault<z.ZodNumber>;
1019
1242
  todayCostUsd: z.ZodDefault<z.ZodNumber>;
1020
1243
  costResetDate: z.ZodOptional<z.ZodString>;
1021
1244
  idleSkipCount: z.ZodDefault<z.ZodNumber>;
1245
+ activeWorkSkipCount: z.ZodDefault<z.ZodNumber>;
1022
1246
  status: z.ZodDefault<z.ZodEnum<{
1023
1247
  running: "running";
1024
1248
  draining: "draining";
1025
1249
  stopped: "stopped";
1026
1250
  }>>;
1251
+ lastConsolidationHeartbeat: z.ZodDefault<z.ZodNumber>;
1252
+ lastCompactionHeartbeat: z.ZodDefault<z.ZodNumber>;
1253
+ lastConsolidationTimestamp: z.ZodOptional<z.ZodString>;
1254
+ wakeReason: z.ZodOptional<z.ZodEnum<{
1255
+ events: "events";
1256
+ timer: "timer";
1257
+ active_runs: "active_runs";
1258
+ forced: "forced";
1259
+ }>>;
1027
1260
  }, z.core.$strip>;
1028
1261
  type SupervisorDaemonState = z.infer<typeof supervisorDaemonStateSchema>;
1029
1262
  declare const webhookIncomingEventSchema: z.ZodObject<{
@@ -1038,6 +1271,7 @@ type WebhookIncomingEvent = z.infer<typeof webhookIncomingEventSchema>;
1038
1271
  declare const inboxMessageSchema: z.ZodObject<{
1039
1272
  id: z.ZodString;
1040
1273
  from: z.ZodEnum<{
1274
+ agent: "agent";
1041
1275
  tui: "tui";
1042
1276
  api: "api";
1043
1277
  external: "external";
@@ -1053,19 +1287,81 @@ declare const activityEntrySchema: z.ZodObject<{
1053
1287
  error: "error";
1054
1288
  message: "message";
1055
1289
  decision: "decision";
1290
+ tool_use: "tool_use";
1056
1291
  event: "event";
1057
1292
  heartbeat: "heartbeat";
1058
1293
  action: "action";
1294
+ warning: "warning";
1059
1295
  thinking: "thinking";
1060
1296
  plan: "plan";
1061
1297
  dispatch: "dispatch";
1062
- tool_use: "tool_use";
1063
1298
  }>;
1064
1299
  summary: z.ZodString;
1065
1300
  detail: z.ZodOptional<z.ZodUnknown>;
1066
1301
  timestamp: z.ZodString;
1067
1302
  }, z.core.$strip>;
1068
1303
  type ActivityEntry = z.infer<typeof activityEntrySchema>;
1304
+ declare const logBufferEntrySchema: z.ZodObject<{
1305
+ id: z.ZodString;
1306
+ type: z.ZodEnum<{
1307
+ decision: "decision";
1308
+ action: "action";
1309
+ progress: "progress";
1310
+ blocker: "blocker";
1311
+ milestone: "milestone";
1312
+ discovery: "discovery";
1313
+ }>;
1314
+ message: z.ZodString;
1315
+ agent: z.ZodOptional<z.ZodString>;
1316
+ runId: z.ZodOptional<z.ZodString>;
1317
+ repo: z.ZodOptional<z.ZodString>;
1318
+ target: z.ZodEnum<{
1319
+ memory: "memory";
1320
+ knowledge: "knowledge";
1321
+ digest: "digest";
1322
+ }>;
1323
+ timestamp: z.ZodString;
1324
+ consolidatedAt: z.ZodOptional<z.ZodString>;
1325
+ }, z.core.$strip>;
1326
+ type LogBufferEntry = z.infer<typeof logBufferEntrySchema>;
1327
+ declare const internalEventKindSchema: z.ZodEnum<{
1328
+ consolidation_timer: "consolidation_timer";
1329
+ active_run_check: "active_run_check";
1330
+ }>;
1331
+ type InternalEventKind = z.infer<typeof internalEventKindSchema>;
1332
+ declare const supervisorStatusSchema: z.ZodObject<{
1333
+ pid: z.ZodNumber;
1334
+ sessionId: z.ZodString;
1335
+ startedAt: z.ZodString;
1336
+ heartbeatCount: z.ZodNumber;
1337
+ totalCostUsd: z.ZodNumber;
1338
+ todayCostUsd: z.ZodNumber;
1339
+ status: z.ZodEnum<{
1340
+ running: "running";
1341
+ idle: "idle";
1342
+ stopping: "stopping";
1343
+ }>;
1344
+ lastHeartbeat: z.ZodString;
1345
+ activeRunCount: z.ZodNumber;
1346
+ recentActivitySummary: z.ZodArray<z.ZodString>;
1347
+ }, z.core.$strip>;
1348
+ type SupervisorStatus = z.infer<typeof supervisorStatusSchema>;
1349
+ declare const activityQueryOptionsSchema: z.ZodObject<{
1350
+ limit: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
1351
+ offset: z.ZodOptional<z.ZodDefault<z.ZodNumber>>;
1352
+ type: z.ZodOptional<z.ZodEnum<{
1353
+ error: "error";
1354
+ message: "message";
1355
+ decision: "decision";
1356
+ event: "event";
1357
+ action: "action";
1358
+ plan: "plan";
1359
+ dispatch: "dispatch";
1360
+ }>>;
1361
+ since: z.ZodOptional<z.ZodString>;
1362
+ until: z.ZodOptional<z.ZodString>;
1363
+ }, z.core.$strip>;
1364
+ type ActivityQueryOptions = z.infer<typeof activityQueryOptionsSchema>;
1069
1365
  type QueuedEvent = {
1070
1366
  kind: "webhook";
1071
1367
  data: WebhookIncomingEvent;
@@ -1076,6 +1372,10 @@ type QueuedEvent = {
1076
1372
  kind: "run_complete";
1077
1373
  runId: string;
1078
1374
  timestamp: string;
1375
+ } | {
1376
+ kind: "internal";
1377
+ eventKind: InternalEventKind;
1378
+ timestamp: string;
1079
1379
  };
1080
1380
 
1081
1381
  declare class ActivityLog {
@@ -1101,6 +1401,8 @@ declare class ActivityLog {
1101
1401
  interface SupervisorDaemonOptions {
1102
1402
  name: string;
1103
1403
  config: GlobalConfig;
1404
+ /** Path to bundled default SUPERVISOR.md (e.g. from @neotx/agents) */
1405
+ defaultInstructionsPath?: string | undefined;
1104
1406
  }
1105
1407
  /**
1106
1408
  * Orchestrates all supervisor components: webhook server, event queue,
@@ -1110,10 +1412,12 @@ declare class SupervisorDaemon {
1110
1412
  private readonly name;
1111
1413
  private readonly config;
1112
1414
  private readonly dir;
1415
+ private readonly defaultInstructionsPath;
1113
1416
  private webhookServer;
1114
1417
  private eventQueue;
1115
1418
  private heartbeatLoop;
1116
1419
  private activityLog;
1420
+ private decisionStore;
1117
1421
  private sessionId;
1118
1422
  constructor(options: SupervisorDaemonOptions);
1119
1423
  start(): Promise<void>;
@@ -1122,7 +1426,11 @@ declare class SupervisorDaemon {
1122
1426
  private readState;
1123
1427
  private writeState;
1124
1428
  private readLockPid;
1125
- private isProcessAlive;
1429
+ /**
1430
+ * Handle decision:answer webhook events.
1431
+ * Extracts decisionId and answer from the payload and records the answer.
1432
+ */
1433
+ private handleDecisionAnswer;
1126
1434
  }
1127
1435
 
1128
1436
  interface EventQueueOptions {
@@ -1138,6 +1446,10 @@ interface GroupedEvents {
1138
1446
  webhooks: QueuedEvent[];
1139
1447
  runCompletions: QueuedEvent[];
1140
1448
  }
1449
+ interface DrainAndGroupResult {
1450
+ grouped: GroupedEvents;
1451
+ rawEvents: QueuedEvent[];
1452
+ }
1141
1453
  /**
1142
1454
  * In-memory event queue with deduplication, rate limiting, and file watching.
1143
1455
  *
@@ -1171,14 +1483,15 @@ declare class EventQueue {
1171
1483
  /**
1172
1484
  * Drain and group events: deduplicates messages by content,
1173
1485
  * keeps webhooks and run completions separate.
1486
+ * Returns both grouped events AND original raw events for later marking as processed.
1174
1487
  */
1175
- drainAndGroup(): GroupedEvents;
1488
+ drainAndGroup(): DrainAndGroupResult;
1176
1489
  size(): number;
1177
1490
  /**
1178
1491
  * Start watching inbox.jsonl and events.jsonl for new entries.
1179
1492
  * New lines are parsed and pushed into the queue.
1180
1493
  */
1181
- startWatching(inboxPath: string, eventsPath: string): void;
1494
+ startWatching(inboxPath: string, eventsPath: string): Promise<void>;
1182
1495
  stopWatching(): void;
1183
1496
  /**
1184
1497
  * Replay unprocessed events from disk on startup.
@@ -1203,6 +1516,55 @@ declare class EventQueue {
1203
1516
  private markInFile;
1204
1517
  }
1205
1518
 
1519
+ declare const supervisorWebhookEventSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1520
+ type: z.ZodLiteral<"supervisor_started">;
1521
+ supervisorId: z.ZodString;
1522
+ startedAt: z.ZodString;
1523
+ }, z.core.$strip>, z.ZodObject<{
1524
+ type: z.ZodLiteral<"heartbeat">;
1525
+ supervisorId: z.ZodString;
1526
+ heartbeatNumber: z.ZodNumber;
1527
+ timestamp: z.ZodString;
1528
+ runsActive: z.ZodNumber;
1529
+ budget: z.ZodObject<{
1530
+ todayUsd: z.ZodNumber;
1531
+ limitUsd: z.ZodNumber;
1532
+ }, z.core.$strip>;
1533
+ }, z.core.$strip>, z.ZodObject<{
1534
+ type: z.ZodLiteral<"run_dispatched">;
1535
+ supervisorId: z.ZodString;
1536
+ runId: z.ZodString;
1537
+ agent: z.ZodString;
1538
+ repo: z.ZodString;
1539
+ branch: z.ZodString;
1540
+ prompt: z.ZodString;
1541
+ }, z.core.$strip>, z.ZodObject<{
1542
+ type: z.ZodLiteral<"run_completed">;
1543
+ supervisorId: z.ZodString;
1544
+ runId: z.ZodString;
1545
+ status: z.ZodEnum<{
1546
+ completed: "completed";
1547
+ failed: "failed";
1548
+ cancelled: "cancelled";
1549
+ }>;
1550
+ output: z.ZodOptional<z.ZodString>;
1551
+ costUsd: z.ZodNumber;
1552
+ durationMs: z.ZodNumber;
1553
+ }, z.core.$strip>, z.ZodObject<{
1554
+ type: z.ZodLiteral<"supervisor_stopped">;
1555
+ supervisorId: z.ZodString;
1556
+ stoppedAt: z.ZodString;
1557
+ reason: z.ZodEnum<{
1558
+ error: "error";
1559
+ budget_exceeded: "budget_exceeded";
1560
+ shutdown: "shutdown";
1561
+ manual: "manual";
1562
+ }>;
1563
+ }, z.core.$strip>], "type">;
1564
+ type SupervisorWebhookEvent = z.infer<typeof supervisorWebhookEventSchema>;
1565
+
1566
+ /** Callback for emitting webhook events */
1567
+ type WebhookEventEmitter = (event: SupervisorWebhookEvent) => void | Promise<void>;
1206
1568
  interface HeartbeatLoopOptions {
1207
1569
  config: GlobalConfig;
1208
1570
  supervisorDir: string;
@@ -1210,38 +1572,114 @@ interface HeartbeatLoopOptions {
1210
1572
  sessionId: string;
1211
1573
  eventQueue: EventQueue;
1212
1574
  activityLog: ActivityLog;
1575
+ /** Path to the inbox/events directory for markProcessed() calls */
1576
+ eventsPath: string;
1577
+ /** Path to bundled default SUPERVISOR.md (e.g. from @neotx/agents) */
1578
+ defaultInstructionsPath?: string | undefined;
1579
+ memoryDbPath?: string | undefined;
1580
+ /** Optional callback to emit webhook events at lifecycle points */
1581
+ onWebhookEvent?: WebhookEventEmitter | undefined;
1582
+ /** Repository path for config watching (enables hot-reload) */
1583
+ repoPath?: string | undefined;
1584
+ /** Debounce time in ms for config file changes (default: 500) */
1585
+ configWatcherDebounceMs?: number | undefined;
1213
1586
  }
1214
1587
  /**
1215
1588
  * The core autonomous loop. At each iteration:
1216
1589
  * 1. Drain events from the queue
1217
- * 2. Build a prompt with context + memory + events
1218
- * 3. Call sdk.query() for Claude to reason and act
1219
- * 4. Extract and save updated memory
1220
- * 5. Log activity
1221
- * 6. Wait for the next event or idle timeout
1590
+ * 2. Read log buffer entries
1591
+ * 3. Determine standard vs consolidation mode
1592
+ * 4. Build the appropriate prompt
1593
+ * 5. Call sdk.query() for Claude to reason and act
1594
+ * 6. Mark entries consolidated and compact log buffer (consolidation only)
1595
+ * 7. Log activity
1596
+ * 8. Wait for the next event or idle timeout
1222
1597
  */
1223
1598
  declare class HeartbeatLoop {
1224
1599
  private stopping;
1225
1600
  private consecutiveFailures;
1226
1601
  private activeAbort;
1227
- private readonly config;
1602
+ private config;
1228
1603
  private readonly supervisorDir;
1229
1604
  private readonly statePath;
1230
1605
  private sessionId;
1231
1606
  private readonly eventQueue;
1232
1607
  private readonly activityLog;
1608
+ private readonly _eventsPath;
1233
1609
  private customInstructions;
1610
+ private readonly defaultInstructionsPath;
1611
+ private memoryStore;
1612
+ private readonly memoryDbPath;
1613
+ private readonly onWebhookEvent;
1614
+ private decisionStore;
1615
+ /** ConfigWatcher for hot-reload support */
1616
+ private configWatcher;
1617
+ private configStore;
1618
+ private readonly repoPath;
1619
+ private readonly configWatcherDebounceMs;
1234
1620
  constructor(options: HeartbeatLoopOptions);
1621
+ /** Path to the inbox/events directory for markProcessed() calls */
1622
+ get eventsPath(): string;
1623
+ private getMemoryStore;
1624
+ private getDecisionStore;
1235
1625
  start(): Promise<void>;
1236
1626
  stop(): void;
1627
+ /**
1628
+ * Initialize and start the ConfigWatcher for hot-reload support.
1629
+ * Subscribes to config file changes and logs reload events.
1630
+ */
1631
+ private initConfigWatcher;
1632
+ /**
1633
+ * Handle config file changes. Propagates reloaded config to the running
1634
+ * loop and triggers an immediate heartbeat.
1635
+ */
1636
+ private handleConfigChange;
1237
1637
  private runHeartbeat;
1638
+ /**
1639
+ * Check if supervisor daily budget is exceeded.
1640
+ */
1641
+ private checkBudgetExceeded;
1642
+ /**
1643
+ * Handle skip logic for idle and active-work scenarios.
1644
+ * Uses IdleDetector to make skip decisions based on context.
1645
+ */
1646
+ private handleSkipLogic;
1647
+ /**
1648
+ * Determine heartbeat mode: compaction > consolidation > standard.
1649
+ */
1650
+ private determineHeartbeatMode;
1651
+ /**
1652
+ * Build the state update object after heartbeat completion.
1653
+ */
1654
+ private buildStateUpdate;
1655
+ /**
1656
+ * Build the prompt for the current heartbeat mode.
1657
+ */
1658
+ private buildHeartbeatModePrompt;
1659
+ /**
1660
+ * Call the Claude SDK and stream results.
1661
+ *
1662
+ * Uses Promise.race to enable non-blocking abort detection. The standard
1663
+ * `for await (const message of stream)` pattern only checks the abort signal
1664
+ * AFTER each yield — if the SDK hangs (no messages), the abort never executes.
1665
+ * This implementation races each iterator.next() against an abort promise,
1666
+ * allowing immediate response to shutdown/timeout signals.
1667
+ */
1668
+ private callSdk;
1238
1669
  private readState;
1239
1670
  private updateState;
1671
+ /**
1672
+ * Read persisted run files and return summaries of active (running/paused) runs.
1673
+ * Validates that "running" runs are actually alive by checking their PID.
1674
+ * Stale runs (dead PID past grace period) are filtered out to prevent ghost runs.
1675
+ */
1676
+ private getActiveRuns;
1240
1677
  /**
1241
1678
  * Load custom instructions from SUPERVISOR.md.
1242
1679
  * Resolution order:
1243
1680
  * 1. Explicit path via `supervisor.instructions` in config
1244
- * 2. Default: ~/.neo/SUPERVISOR.md
1681
+ * 2. User default: ~/.neo/SUPERVISOR.md
1682
+ * 3. Bundled default from @neotx/agents (if path provided)
1245
1683
  */
1246
1684
  private loadInstructions;
1247
1685
  /** Route a single SDK stream message to the appropriate log handler. */
@@ -1253,53 +1691,164 @@ declare class HeartbeatLoop {
1253
1691
  /** Detect agent dispatches from bash tool results. */
1254
1692
  private logToolResult;
1255
1693
  private sleep;
1694
+ /**
1695
+ * Process decision:answer events from inbox messages.
1696
+ * Expected format: "decision:answer <decisionId> <answer>"
1697
+ */
1698
+ private processDecisionAnswers;
1699
+ /**
1700
+ * Read persisted run data to extract actual status, cost, and duration.
1701
+ * Returns null if the run file cannot be found or parsed.
1702
+ */
1703
+ private readPersistedRun;
1704
+ /**
1705
+ * Emit a webhook event if a callback is configured.
1706
+ * Validates the event against its schema before emission.
1707
+ */
1708
+ private emitWebhookEvent;
1709
+ /** Emit SupervisorStartedEvent */
1710
+ private emitSupervisorStarted;
1711
+ /** Emit SupervisorStoppedEvent */
1712
+ private emitSupervisorStopped;
1713
+ /** Emit HeartbeatEvent */
1714
+ private emitHeartbeatCompleted;
1715
+ /** Emit RunDispatchedEvent from tool result detection */
1716
+ private emitRunDispatched;
1717
+ /** Emit RunCompletedEvent when processing run_complete events */
1718
+ private emitRunCompleted;
1256
1719
  }
1257
1720
 
1258
1721
  /**
1259
- * Load the supervisor memory from disk.
1260
- * Migrates from legacy memory.md if needed.
1722
+ * Append a single entry to the log buffer file.
1261
1723
  */
1262
- declare function loadMemory(dir: string): Promise<string>;
1263
- /**
1264
- * Save the supervisor memory to disk (full overwrite).
1265
- * Automatically compacts if needed.
1266
- */
1267
- declare function saveMemory(dir: string, content: string): Promise<void>;
1268
- /**
1269
- * Extract memory content from Claude's response using <memory>...</memory> tags.
1270
- */
1271
- declare function extractMemoryFromResponse(response: string): string | null;
1272
- /**
1273
- * Check if memory content exceeds the recommended size limit.
1274
- */
1275
- declare function checkMemorySize(content: string): {
1276
- ok: boolean;
1277
- sizeKB: number;
1278
- };
1724
+ declare function appendLogBuffer(dir: string, entry: LogBufferEntry): Promise<void>;
1279
1725
 
1280
- interface HeartbeatPromptOptions {
1281
- repos: RepoConfig[];
1282
- memory: string;
1283
- knowledge: string;
1284
- memorySizeKB: number;
1285
- grouped: GroupedEvents;
1286
- budgetStatus: {
1287
- todayUsd: number;
1288
- capUsd: number;
1289
- remainingPct: number;
1290
- };
1291
- activeRuns: string[];
1292
- heartbeatCount: number;
1293
- mcpServerNames: string[];
1294
- customInstructions?: string | undefined;
1726
+ interface Embedder {
1727
+ embed(texts: string[]): Promise<number[][]>;
1728
+ readonly dimensions: number;
1295
1729
  }
1730
+ declare class LocalEmbedder implements Embedder {
1731
+ readonly dimensions = 384;
1732
+ embed(texts: string[]): Promise<number[][]>;
1733
+ }
1734
+
1735
+ declare const memoryTypeSchema: z.ZodEnum<{
1736
+ fact: "fact";
1737
+ procedure: "procedure";
1738
+ episode: "episode";
1739
+ focus: "focus";
1740
+ feedback: "feedback";
1741
+ task: "task";
1742
+ }>;
1743
+ type MemoryType = z.infer<typeof memoryTypeSchema>;
1744
+ declare const memoryEntrySchema: z.ZodObject<{
1745
+ id: z.ZodString;
1746
+ type: z.ZodEnum<{
1747
+ fact: "fact";
1748
+ procedure: "procedure";
1749
+ episode: "episode";
1750
+ focus: "focus";
1751
+ feedback: "feedback";
1752
+ task: "task";
1753
+ }>;
1754
+ scope: z.ZodString;
1755
+ content: z.ZodString;
1756
+ source: z.ZodString;
1757
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
1758
+ createdAt: z.ZodString;
1759
+ lastAccessedAt: z.ZodString;
1760
+ accessCount: z.ZodDefault<z.ZodNumber>;
1761
+ expiresAt: z.ZodOptional<z.ZodString>;
1762
+ outcome: z.ZodOptional<z.ZodString>;
1763
+ runId: z.ZodOptional<z.ZodString>;
1764
+ category: z.ZodOptional<z.ZodString>;
1765
+ severity: z.ZodOptional<z.ZodString>;
1766
+ supersedes: z.ZodOptional<z.ZodString>;
1767
+ }, z.core.$strip>;
1768
+ type MemoryEntry = z.infer<typeof memoryEntrySchema>;
1769
+ declare const memoryWriteInputSchema: z.ZodObject<{
1770
+ type: z.ZodEnum<{
1771
+ fact: "fact";
1772
+ procedure: "procedure";
1773
+ episode: "episode";
1774
+ focus: "focus";
1775
+ feedback: "feedback";
1776
+ task: "task";
1777
+ }>;
1778
+ scope: z.ZodDefault<z.ZodString>;
1779
+ content: z.ZodString;
1780
+ source: z.ZodDefault<z.ZodString>;
1781
+ tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
1782
+ expiresAt: z.ZodOptional<z.ZodString>;
1783
+ outcome: z.ZodOptional<z.ZodString>;
1784
+ runId: z.ZodOptional<z.ZodString>;
1785
+ category: z.ZodOptional<z.ZodString>;
1786
+ severity: z.ZodOptional<z.ZodString>;
1787
+ supersedes: z.ZodOptional<z.ZodString>;
1788
+ }, z.core.$strip>;
1789
+ type MemoryWriteInput = z.input<typeof memoryWriteInputSchema>;
1790
+ interface MemoryQuery {
1791
+ scope?: string;
1792
+ types?: MemoryType[];
1793
+ since?: string;
1794
+ limit?: number;
1795
+ sortBy?: "relevance" | "createdAt" | "accessCount";
1796
+ tags?: string[];
1797
+ }
1798
+ interface MemoryStats {
1799
+ total: number;
1800
+ byType: Record<string, number>;
1801
+ byScope: Record<string, number>;
1802
+ }
1803
+
1804
+ declare class MemoryStore {
1805
+ private db;
1806
+ private embedder;
1807
+ private hasVec;
1808
+ constructor(dbPath: string, embedder?: Embedder | null);
1809
+ private initSchema;
1810
+ /**
1811
+ * Migrate existing tables whose CHECK constraint predates the 'task' type.
1812
+ * SQLite doesn't allow ALTER CHECK, so we recreate the table if needed.
1813
+ */
1814
+ private migrateCheckConstraint;
1815
+ write(input: MemoryWriteInput): Promise<string>;
1816
+ update(id: string, content: string): void;
1817
+ updateFields(id: string, fields: {
1818
+ content?: string;
1819
+ outcome?: string;
1820
+ runId?: string;
1821
+ }): void;
1822
+ forget(id: string): void;
1823
+ query(opts?: MemoryQuery): MemoryEntry[];
1824
+ search(text: string, opts?: MemoryQuery): Promise<MemoryEntry[]>;
1825
+ markAccessed(ids: string[]): void;
1826
+ decay(maxAgeDays?: number, minAccessCount?: number): number;
1827
+ expireEphemeral(): number;
1828
+ stats(): MemoryStats;
1829
+ close(): void;
1830
+ }
1831
+
1296
1832
  /**
1297
- * Build the prompt sent to Claude at each heartbeat.
1298
- *
1299
- * Includes: role definition, current memory, pending events,
1300
- * budget status, active runs, and available integrations.
1833
+ * Reads supervisor status from the daemon state file.
1834
+ * Returns null if the supervisor is not running or state file doesn't exist.
1301
1835
  */
1302
- declare function buildHeartbeatPrompt(opts: HeartbeatPromptOptions): string;
1836
+ declare class StatusReader {
1837
+ readonly dataDir: string;
1838
+ private readonly statePath;
1839
+ private readonly activityPath;
1840
+ constructor(dataDir: string);
1841
+ /**
1842
+ * Read and parse supervisor status from disk.
1843
+ * Returns null if the state file doesn't exist (supervisor not running).
1844
+ */
1845
+ getStatus(): Promise<SupervisorStatus | null>;
1846
+ /**
1847
+ * Query activity entries with optional filtering.
1848
+ * Returns empty array if the activity file doesn't exist or is empty.
1849
+ */
1850
+ queryActivity(options?: ActivityQueryOptions): ActivityEntry[];
1851
+ }
1303
1852
 
1304
1853
  interface WebhookServerOptions {
1305
1854
  port: number;
@@ -1333,49 +1882,49 @@ declare class WebhookServer {
1333
1882
  private sendJson;
1334
1883
  }
1335
1884
 
1336
- declare const workflowStepDefSchema: z.ZodObject<{
1337
- type: z.ZodDefault<z.ZodOptional<z.ZodLiteral<"step">>>;
1338
- agent: z.ZodString;
1339
- dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
1340
- prompt: z.ZodOptional<z.ZodString>;
1341
- sandbox: z.ZodOptional<z.ZodEnum<{
1342
- readonly: "readonly";
1343
- writable: "writable";
1344
- }>>;
1345
- maxTurns: z.ZodOptional<z.ZodNumber>;
1346
- mcpServers: z.ZodOptional<z.ZodArray<z.ZodString>>;
1347
- recovery: z.ZodOptional<z.ZodObject<{
1348
- maxRetries: z.ZodOptional<z.ZodNumber>;
1349
- nonRetryable: z.ZodOptional<z.ZodArray<z.ZodString>>;
1350
- }, z.core.$strip>>;
1351
- condition: z.ZodOptional<z.ZodString>;
1352
- }, z.core.$strip>;
1353
- declare const workflowGateDefSchema: z.ZodObject<{
1354
- type: z.ZodLiteral<"gate">;
1355
- dependsOn: z.ZodOptional<z.ZodArray<z.ZodString>>;
1356
- description: z.ZodString;
1357
- timeout: z.ZodOptional<z.ZodString>;
1358
- autoApprove: z.ZodOptional<z.ZodBoolean>;
1885
+ declare const webhookEntrySchema: z.ZodObject<{
1886
+ url: z.ZodString;
1887
+ events: z.ZodOptional<z.ZodArray<z.ZodString>>;
1888
+ secret: z.ZodOptional<z.ZodString>;
1889
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
1890
+ createdAt: z.ZodDefault<z.ZodString>;
1359
1891
  }, z.core.$strip>;
1360
- declare function loadWorkflow(filePath: string): Promise<WorkflowDefinition>;
1361
-
1892
+ type WebhookEntry = z.infer<typeof webhookEntrySchema>;
1893
+ type WebhookEntryInput = z.input<typeof webhookEntrySchema>;
1362
1894
  /**
1363
- * Registry for workflow definitions.
1364
- * Loads built-in workflows from a directory and optional custom workflows.
1365
- * Custom workflows with the same name override built-in ones.
1895
+ * Add a webhook endpoint to ~/.neo/webhooks.json.
1896
+ * Deduplicates by URL.
1366
1897
  */
1367
- declare class WorkflowRegistry {
1368
- private readonly builtInDir;
1369
- private readonly customDir;
1370
- private readonly workflows;
1371
- constructor(builtInDir: string, customDir?: string);
1372
- load(): Promise<void>;
1373
- get(name: string): WorkflowDefinition | undefined;
1374
- list(): WorkflowDefinition[];
1375
- has(name: string): boolean;
1376
- private loadFromDir;
1898
+ declare function addWebhook(input: WebhookEntryInput): Promise<WebhookEntry>;
1899
+ /**
1900
+ * Remove a webhook endpoint by URL.
1901
+ * Returns true if removed, false if not found.
1902
+ */
1903
+ declare function removeWebhook(url: string): Promise<boolean>;
1904
+ /**
1905
+ * List all configured webhooks.
1906
+ */
1907
+ declare function listWebhooks(): Promise<WebhookEntry[]>;
1908
+ interface WebhookTestPayload {
1909
+ type: "test";
1910
+ timestamp: string;
1911
+ runId: string;
1912
+ status: "test";
1913
+ summary: string;
1377
1914
  }
1915
+ interface WebhookTestResult {
1916
+ url: string;
1917
+ success: boolean;
1918
+ statusCode?: number;
1919
+ error?: string;
1920
+ durationMs: number;
1921
+ }
1922
+ /**
1923
+ * Send a test payload to all configured webhooks.
1924
+ * Returns results for each endpoint.
1925
+ */
1926
+ declare function testWebhooks(): Promise<WebhookTestResult[]>;
1378
1927
 
1379
1928
  declare const VERSION = "0.1.0";
1380
1929
 
1381
- export { type ActiveSession, type ActivityEntry, ActivityLog, type AgentConfig, type AgentDefinition, type AgentMessageEvent, type AgentModel, AgentRegistry, type AgentTool, type AgentToolEntry, type AgentToolUseEvent, type AuditLogMiddleware, type BudgetAlertEvent, type CostEntry, CostJournal, type CostUpdateEvent, type DispatchInput, EventJournal, EventQueue, type GateWaitingEvent, type GlobalConfig, HeartbeatLoop, type HeartbeatLoopOptions, type HeartbeatPromptOptions, type HookEvent, type InboxMessage, type LoopDetectionMiddleware, type McpServerConfig, 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 SDKHooks, type SandboxConfig, Semaphore, type SemaphoreCallbacks, type SemaphoreConfig, type SessionCompleteEvent, SessionError, type SessionEvent, type SessionFailEvent, type SessionOptions, type SessionResult, type SessionStartEvent, type StepResult, SupervisorDaemon, type SupervisorDaemonOptions, type SupervisorDaemonState, type SupervisorDaemonState as SupervisorState, type TaskResult, VERSION, WebhookDispatcher, type WebhookIncomingEvent, WebhookServer, type WorkflowContext, type WorkflowDefinition, type WorkflowGateDef, WorkflowRegistry, type WorkflowStepCompleteEvent, type WorkflowStepDef, type WorkflowStepStartEvent, type WorktreeInfo, activityEntrySchema, addRepoToGlobalConfig, agentConfigSchema, agentModelSchema, agentSandboxSchema, agentToolEntrySchema, agentToolSchema, auditLog, budgetGuard, buildHeartbeatPrompt, buildMiddlewareChain, buildSDKHooks, buildSandboxConfig, checkMemorySize, cleanupOrphanedWorktrees, createBranch, createWorktree, deleteBranch, extractMemoryFromResponse, fetchRemote, getBranchName, getCurrentBranch, getDataDir, getJournalsDir, getRepoRunsDir, getRunDispatchPath, getRunLogPath, getRunsDir, getSupervisorActivityPath, getSupervisorDir, getSupervisorEventsPath, getSupervisorInboxPath, getSupervisorLockPath, getSupervisorMemoryPath, getSupervisorStatePath, getSupervisorsDir, globalConfigSchema, inboxMessageSchema, listReposFromGlobalConfig, listWorktrees, loadAgentFile, loadConfig, loadGlobalConfig, loadMemory, loadWorkflow, loopDetection, matchesFilter, mcpServerConfigSchema, neoConfigSchema, parseOutput, pushBranch, removeRepoFromGlobalConfig, removeWorktree, repoConfigSchema, resolveAgent, runSession, runWithRecovery, saveMemory, supervisorDaemonStateSchema, supervisorDaemonStateSchema as supervisorStateSchema, toRepoSlug, webhookIncomingEventSchema, withGitLock, workflowGateDefSchema, workflowStepDefSchema };
1930
+ 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 };