botinabox 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1268 @@
1
+ import { C as ChannelAdapter, H as HealthStatus, I as InboundMessage } from './channel-m9f7MFD7.js';
2
+ export { A as Attachment, a as ChannelCapabilities, b as ChannelConfig, c as ChannelMeta, d as ChatType, F as FormattingMode, O as OutboundPayload, S as SendResult } from './channel-m9f7MFD7.js';
3
+ import { T as TokenUsage, L as LLMProvider, M as ModelInfo, R as ResolvedModel, C as ChatMessage } from './provider-qqJYv9nv.js';
4
+ export { a as ChatParams, b as ChatResult, c as ContentBlock, d as ToolDefinition, e as ToolUse } from './provider-qqJYv9nv.js';
5
+ import * as better_sqlite3 from 'better-sqlite3';
6
+
7
+ /** Execution adapter types — Story 1.5 / 3.4 / 3.5 */
8
+ type RunStatus = "queued" | "running" | "succeeded" | "failed" | "cancelled";
9
+ interface RunContext {
10
+ runId: string;
11
+ agentId: string;
12
+ agentSlug: string;
13
+ taskId?: string;
14
+ taskTitle?: string;
15
+ taskDescription?: string;
16
+ model: string;
17
+ workdir: string;
18
+ sessionParams?: unknown;
19
+ abortSignal?: AbortSignal;
20
+ onLog?: (line: string) => void;
21
+ }
22
+ interface RunResult {
23
+ status: "succeeded" | "failed";
24
+ output?: string;
25
+ error?: string;
26
+ usage?: TokenUsage;
27
+ costCents?: number;
28
+ sessionParams?: unknown;
29
+ clearSession?: boolean;
30
+ durationMs: number;
31
+ }
32
+ interface ExecutionAdapter {
33
+ id: string;
34
+ execute(ctx: RunContext): Promise<RunResult>;
35
+ }
36
+
37
+ /** Agent types — Story 1.5 / 3.1 */
38
+ type AgentStatus = "idle" | "running" | "paused" | "terminated" | "error";
39
+ interface AgentDefinition {
40
+ slug: string;
41
+ name: string;
42
+ role?: string;
43
+ adapter: string;
44
+ model?: string;
45
+ workdir?: string;
46
+ instructionsFile?: string;
47
+ maxConcurrentRuns?: number;
48
+ budgetMonthlyCents?: number;
49
+ canCreateAgents?: boolean;
50
+ skipPermissions?: boolean;
51
+ config?: Record<string, unknown>;
52
+ }
53
+ interface AgentRecord extends AgentDefinition {
54
+ id: string;
55
+ status: AgentStatus;
56
+ spentMonthlyCents: number;
57
+ createdAt: string;
58
+ updatedAt: string;
59
+ deletedAt?: string;
60
+ }
61
+ interface AgentFilter {
62
+ status?: AgentStatus | AgentStatus[];
63
+ role?: string;
64
+ adapter?: string;
65
+ }
66
+ interface BudgetCheck {
67
+ allowed: boolean;
68
+ status: "ok" | "warning" | "hard_stop";
69
+ spentCents: number;
70
+ limitCents?: number;
71
+ message?: string;
72
+ }
73
+
74
+ /** Task types — Story 1.5 / 3.2 */
75
+ type TaskStatus = "backlog" | "todo" | "in_progress" | "in_review" | "done" | "blocked" | "cancelled";
76
+ interface RetryPolicy {
77
+ maxRetries: number;
78
+ backoffMs: number;
79
+ backoffMultiplier: number;
80
+ maxBackoffMs: number;
81
+ }
82
+ interface TaskDefinition {
83
+ title: string;
84
+ description?: string;
85
+ assigneeId?: string;
86
+ priority?: number;
87
+ parentId?: string;
88
+ dependsOn?: string[];
89
+ followupAgentId?: string;
90
+ followupTemplate?: string;
91
+ chainOriginId?: string;
92
+ chainDepth?: number;
93
+ retryPolicy?: RetryPolicy;
94
+ metadata?: Record<string, unknown>;
95
+ }
96
+ interface TaskRecord extends Required<Pick<TaskDefinition, "title" | "priority">> {
97
+ id: string;
98
+ description: string;
99
+ assigneeId?: string;
100
+ status: TaskStatus;
101
+ priority: number;
102
+ parentId?: string;
103
+ dependsOn: string[];
104
+ followupAgentId?: string;
105
+ followupTemplate?: string;
106
+ chainOriginId?: string;
107
+ chainDepth: number;
108
+ retryPolicy?: RetryPolicy;
109
+ retryCount: number;
110
+ maxRetries: number;
111
+ nextRetryAt?: string;
112
+ executionRunId?: string;
113
+ result?: string;
114
+ completedOutput?: string;
115
+ metadata?: Record<string, unknown>;
116
+ createdAt: string;
117
+ updatedAt: string;
118
+ completedAt?: string;
119
+ deletedAt?: string;
120
+ }
121
+
122
+ /** Bot configuration types — Story 1.2 / 1.5 */
123
+ interface DataConfig {
124
+ path: string;
125
+ walMode: boolean;
126
+ backupDir?: string;
127
+ }
128
+ interface ModelConfig {
129
+ aliases: Record<string, string>;
130
+ default: string;
131
+ routing: Record<string, string>;
132
+ fallbackChain: string[];
133
+ costLimit?: {
134
+ perRunCents?: number;
135
+ };
136
+ }
137
+ interface SecurityConfig {
138
+ fieldLengthLimits?: Record<string, number>;
139
+ allowedFilePrefixes?: string[];
140
+ }
141
+ interface RenderConfig {
142
+ outputDir: string;
143
+ watchIntervalMs: number;
144
+ }
145
+ interface UpdateConfig {
146
+ policy: "auto-all" | "auto-compatible" | "auto-patch" | "notify" | "manual";
147
+ checkIntervalMs: number;
148
+ maintenanceWindow?: {
149
+ utcHourStart: number;
150
+ utcHourEnd: number;
151
+ days?: Array<"mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun">;
152
+ };
153
+ }
154
+ interface BudgetConfig {
155
+ globalMonthlyCents?: number;
156
+ warnPercent: number;
157
+ }
158
+ interface EntityColumnDef {
159
+ type: "uuid" | "text" | "integer" | "boolean" | "datetime" | "real";
160
+ required?: boolean;
161
+ default?: string | number | boolean;
162
+ references?: string;
163
+ }
164
+ interface EntityConfig {
165
+ columns: Record<string, EntityColumnDef>;
166
+ relations?: Array<{
167
+ type: "hasMany" | "manyToMany" | "belongsTo";
168
+ table: string;
169
+ through?: string;
170
+ localKey?: string;
171
+ remoteKey?: string;
172
+ }>;
173
+ }
174
+ interface AgentConfig {
175
+ slug: string;
176
+ name: string;
177
+ role?: string;
178
+ adapter: string;
179
+ model?: string;
180
+ workdir?: string;
181
+ instructionsFile?: string;
182
+ maxConcurrentRuns?: number;
183
+ budgetMonthlyCents?: number;
184
+ canCreateAgents?: boolean;
185
+ skipPermissions?: boolean;
186
+ config?: Record<string, unknown>;
187
+ }
188
+ interface BotConfig {
189
+ data: DataConfig;
190
+ channels: Record<string, {
191
+ enabled: boolean;
192
+ accounts?: Record<string, unknown>;
193
+ } & Record<string, unknown>>;
194
+ agents: AgentConfig[];
195
+ providers: Record<string, {
196
+ enabled: boolean;
197
+ } & Record<string, unknown>>;
198
+ models: ModelConfig;
199
+ entities: Record<string, EntityConfig>;
200
+ security: SecurityConfig;
201
+ render: RenderConfig;
202
+ updates: UpdateConfig;
203
+ budget: BudgetConfig;
204
+ workflows?: Record<string, WorkflowConfigEntry>;
205
+ }
206
+ interface WorkflowConfigEntry {
207
+ name: string;
208
+ description?: string;
209
+ steps: WorkflowStepConfig[];
210
+ trigger?: {
211
+ type: "task_completed" | "event" | "schedule" | "manual";
212
+ filter?: Record<string, unknown>;
213
+ };
214
+ }
215
+ interface WorkflowStepConfig {
216
+ id: string;
217
+ name: string;
218
+ agentSlug?: string;
219
+ taskTemplate: {
220
+ title: string;
221
+ description: string;
222
+ };
223
+ dependsOn?: string[];
224
+ onComplete?: "next" | "parallel" | "end";
225
+ onFail?: "abort" | "skip" | "retry";
226
+ retryPolicy?: RetryPolicy;
227
+ }
228
+
229
+ /** Workflow types — Story 1.5 / 5.1 */
230
+ type WorkflowRunStatus = "running" | "completed" | "failed" | "cancelled";
231
+ interface WorkflowStep$1 {
232
+ id: string;
233
+ name: string;
234
+ agentSlug?: string;
235
+ agentResolver?: string;
236
+ taskTemplate: {
237
+ title: string;
238
+ description: string;
239
+ };
240
+ dependsOn?: string[];
241
+ onComplete?: "next" | "parallel" | "end";
242
+ onFail?: "abort" | "skip" | "retry";
243
+ retryPolicy?: RetryPolicy;
244
+ condition?: string;
245
+ }
246
+ interface WorkflowDefinition$1 {
247
+ slug: string;
248
+ name: string;
249
+ description?: string;
250
+ steps: WorkflowStep$1[];
251
+ trigger?: WorkflowTrigger;
252
+ }
253
+ interface WorkflowTrigger {
254
+ type: "task_completed" | "event" | "schedule" | "manual";
255
+ filter?: Record<string, unknown>;
256
+ }
257
+ interface WorkflowRunRecord {
258
+ id: string;
259
+ workflowId: string;
260
+ status: WorkflowRunStatus;
261
+ currentStep: number;
262
+ context: Record<string, unknown>;
263
+ originTaskId?: string;
264
+ startedAt: string;
265
+ finishedAt?: string;
266
+ error?: string;
267
+ }
268
+
269
+ /** Shared constants — event names, default values, status enums */
270
+ /** Hook/event name constants */
271
+ declare const EVENTS: {
272
+ readonly COST_RECORDED: "cost.recorded";
273
+ readonly AGENT_CREATED: "agent.created";
274
+ readonly AGENT_STATUS_CHANGED: "agent.status_changed";
275
+ readonly BUDGET_EXCEEDED: "budget.exceeded";
276
+ readonly TASK_CREATED: "task.created";
277
+ readonly TASK_COMPLETED: "task.completed";
278
+ readonly TASK_FAILED: "task.failed";
279
+ readonly TASK_CANCELLED: "task.cancelled";
280
+ readonly RUN_STARTED: "run.started";
281
+ readonly RUN_COMPLETED: "run.completed";
282
+ readonly RUN_FAILED: "run.failed";
283
+ readonly MESSAGE_INBOUND: "message.inbound";
284
+ readonly MESSAGE_ROUTED: "message.routed";
285
+ readonly MESSAGE_PROCESSED: "message.processed";
286
+ readonly MESSAGE_OUTBOUND: "message.outbound";
287
+ readonly MESSAGE_SENT: "message.sent";
288
+ readonly UPDATE_AVAILABLE: "update.available";
289
+ readonly UPDATE_STARTED: "update.started";
290
+ readonly UPDATE_COMPLETED: "update.completed";
291
+ readonly UPDATE_FAILED: "update.failed";
292
+ readonly WORKFLOW_STARTED: "workflow.started";
293
+ readonly WORKFLOW_STEP_COMPLETED: "workflow.step_completed";
294
+ readonly WORKFLOW_COMPLETED: "workflow.completed";
295
+ readonly WORKFLOW_FAILED: "workflow.failed";
296
+ };
297
+ /** Default config values */
298
+ declare const DEFAULTS: {
299
+ readonly TASK_POLL_INTERVAL_MS: 30000;
300
+ readonly NOTIFICATION_POLL_INTERVAL_MS: 5000;
301
+ readonly HEARTBEAT_INTERVAL_MS: 300000;
302
+ readonly ORPHAN_REAP_INTERVAL_MS: 300000;
303
+ readonly STALE_RUN_THRESHOLD_MS: 1800000;
304
+ readonly STALE_TASK_AGE_MS: 7200000;
305
+ readonly MAX_CHAIN_DEPTH: 5;
306
+ readonly MAX_NOTIFICATION_RETRIES: 3;
307
+ readonly UPDATE_CHECK_INTERVAL_MS: 86400000;
308
+ readonly RENDER_WATCH_INTERVAL_MS: 30000;
309
+ readonly DATA_PATH: "./data/bot.db";
310
+ readonly RENDER_OUTPUT_DIR: "./context";
311
+ readonly LOG_PATH_TEMPLATE: "./data/runs/{runId}.ndjson";
312
+ readonly BUDGET_WARN_PERCENT: 80;
313
+ };
314
+ /** Task status values */
315
+ declare const TASK_STATUSES: readonly ["backlog", "todo", "in_progress", "in_review", "done", "blocked", "cancelled"];
316
+ /** Agent status values */
317
+ declare const AGENT_STATUSES: readonly ["idle", "running", "paused", "terminated", "error"];
318
+ /** Run status values */
319
+ declare const RUN_STATUSES: readonly ["queued", "running", "succeeded", "failed", "cancelled"];
320
+
321
+ type HookHandler = (context: Record<string, unknown>) => Promise<void> | void;
322
+ type Unsubscribe = () => void;
323
+ interface HookOptions {
324
+ /** 0–100, default 50. Lower = runs first. */
325
+ priority?: number;
326
+ /** Auto-unsubscribe after first invocation. */
327
+ once?: boolean;
328
+ /** Only fire if context matches all filter key/value pairs. */
329
+ filter?: Record<string, unknown>;
330
+ }
331
+ interface HookRegistration {
332
+ event: string;
333
+ handler: HookHandler;
334
+ priority: number;
335
+ once: boolean;
336
+ filter?: Record<string, unknown>;
337
+ /** Internal auto-increment for stable sort within same priority */
338
+ id: number;
339
+ }
340
+
341
+ /**
342
+ * Priority-ordered event bus for decoupled inter-layer communication.
343
+ * Story 1.1 — handlers run in priority order, errors are isolated,
344
+ * and registrations are unsubscribable.
345
+ */
346
+ declare class HookBus {
347
+ private readonly registrations;
348
+ private nextId;
349
+ register(event: string, handler: HookHandler, opts?: HookOptions): Unsubscribe;
350
+ emit(event: string, context: Record<string, unknown>): Promise<void>;
351
+ /** Emit synchronously (use only when async is not needed) */
352
+ emitSync(event: string, context: Record<string, unknown>): void;
353
+ hasListeners(event: string): boolean;
354
+ listRegistered(): string[];
355
+ /** Remove all handlers for an event, or all handlers if no event given */
356
+ clear(event?: string): void;
357
+ }
358
+
359
+ interface ConfigLoadError {
360
+ field: string;
361
+ message: string;
362
+ }
363
+ interface ConfigLoadResult {
364
+ config: BotConfig;
365
+ errors: ConfigLoadError[];
366
+ }
367
+ /**
368
+ * Load and merge config from file, with env var interpolation and runtime overrides.
369
+ * Merge order: defaults < config file < runtime overrides
370
+ */
371
+ declare function loadConfig(opts?: {
372
+ configPath?: string;
373
+ overrides?: Partial<BotConfig>;
374
+ env?: Record<string, string | undefined>;
375
+ }): ConfigLoadResult;
376
+ /** Get the loaded config singleton. Call loadConfig() first. */
377
+ declare function getConfig(): BotConfig;
378
+ /** Initialize the config singleton. Returns errors if any. */
379
+ declare function initConfig(opts?: Parameters<typeof loadConfig>[0]): ConfigLoadError[];
380
+ /** Reset the singleton (for testing) */
381
+ declare function _resetConfig(): void;
382
+
383
+ /**
384
+ * Interpolate ${ENV_VAR} references in YAML string values.
385
+ * Recursively walks objects and arrays.
386
+ */
387
+ declare function interpolateEnv(value: unknown, env?: Record<string, string | undefined>): unknown;
388
+
389
+ interface SchemaError {
390
+ path: string;
391
+ message: string;
392
+ }
393
+ declare function validateConfig(config: unknown): SchemaError[];
394
+
395
+ declare const DEFAULT_CONFIG: BotConfig;
396
+
397
+ declare class ProviderRegistry {
398
+ private providers;
399
+ register(provider: LLMProvider): void;
400
+ unregister(id: string): void;
401
+ get(id: string): LLMProvider | undefined;
402
+ list(): LLMProvider[];
403
+ listModels(): ModelInfo[];
404
+ }
405
+
406
+ declare class ModelRouter {
407
+ private readonly registry;
408
+ private readonly config;
409
+ constructor(registry: ProviderRegistry, config: ModelConfig);
410
+ /**
411
+ * Resolve a model ID or alias to a ResolvedModel.
412
+ * 1. Look up alias in config.aliases (or use as-is)
413
+ * 2. Search all registered providers for a model with that id
414
+ */
415
+ resolve(modelIdOrAlias: string): ResolvedModel | undefined;
416
+ /**
417
+ * Try primary model, then each in config.fallbackChain.
418
+ * Throws if none found.
419
+ */
420
+ resolveWithFallback(modelIdOrAlias: string): ResolvedModel;
421
+ /**
422
+ * Use config.routing[purpose] ?? config.default, then resolveWithFallback.
423
+ */
424
+ resolveForPurpose(purpose: string): ResolvedModel;
425
+ /** Returns all models from all registered providers. */
426
+ listAvailable(): ModelInfo[];
427
+ }
428
+
429
+ type Importer$1 = (packageName: string) => Promise<unknown>;
430
+ /**
431
+ * Scans nodeModulesPath/@botinabox/{pkg}/package.json for each package in the scope.
432
+ * If pkg.botinabox?.type === 'provider', dynamically imports the package
433
+ * and returns the discovered LLMProvider instances.
434
+ *
435
+ * The optional importer parameter allows injection for testing.
436
+ */
437
+ declare function discoverProviders(nodeModulesPath: string, importer?: Importer$1): Promise<LLMProvider[]>;
438
+
439
+ /**
440
+ * ChannelRegistry — manages channel adapter lifecycle.
441
+ * Story 4.1
442
+ */
443
+
444
+ declare class ChannelRegistryError extends Error {
445
+ constructor(message: string);
446
+ }
447
+ declare class ChannelRegistry {
448
+ private readonly adapters;
449
+ private started;
450
+ /**
451
+ * Register a channel adapter.
452
+ * Throws if an adapter with the same id is already registered.
453
+ * If registry is already started, immediately connects the adapter.
454
+ */
455
+ register(adapter: ChannelAdapter, config?: unknown): void;
456
+ /**
457
+ * Unregister a channel adapter.
458
+ * Disconnects the adapter if it exists.
459
+ */
460
+ unregister(id: string): Promise<void>;
461
+ /**
462
+ * Reconfigure an adapter: disconnect, update config, reconnect.
463
+ */
464
+ reconfigure(id: string, config: unknown): Promise<void>;
465
+ /**
466
+ * Run health checks on all registered adapters.
467
+ */
468
+ healthCheck(): Promise<Record<string, HealthStatus>>;
469
+ /** Get an adapter by ID. */
470
+ get(id: string): ChannelAdapter | undefined;
471
+ /** List all registered adapters. */
472
+ list(): ChannelAdapter[];
473
+ /**
474
+ * Start: connect all registered adapters and mark registry as started.
475
+ */
476
+ start(): Promise<void>;
477
+ /**
478
+ * Stop: disconnect all registered adapters.
479
+ */
480
+ stop(): Promise<void>;
481
+ }
482
+
483
+ /**
484
+ * Auto-discovery for channel adapters.
485
+ * Scans @botinabox/* packages for botinabox.type === 'channel'.
486
+ * Story 4.1
487
+ */
488
+
489
+ type Importer = (packageName: string) => Promise<unknown>;
490
+ /**
491
+ * Scans nodeModulesPath/@botinabox/{pkg}/package.json for each package in the scope.
492
+ * If pkg.botinabox?.type === 'channel', dynamically imports the package
493
+ * and returns the discovered ChannelAdapter instances.
494
+ *
495
+ * The optional importer parameter allows injection for testing.
496
+ */
497
+ declare function discoverChannels(nodeModulesPath: string, importer?: Importer): Promise<ChannelAdapter[]>;
498
+
499
+ interface TableDefinition {
500
+ columns: Record<string, string>;
501
+ primaryKey?: string | string[];
502
+ tableConstraints?: string[];
503
+ relations?: Record<string, RelationDef>;
504
+ render?: string | ((rows: Row[]) => string);
505
+ outputFile?: string;
506
+ filter?: (rows: Row[]) => Row[];
507
+ }
508
+ interface RelationDef {
509
+ type: 'belongsTo' | 'hasMany';
510
+ table: string;
511
+ foreignKey: string;
512
+ references?: string;
513
+ }
514
+ interface EntityContextDef {
515
+ table: string;
516
+ directory: string;
517
+ slugColumn: string;
518
+ files: Record<string, EntityFileSpec>;
519
+ indexFile?: string;
520
+ protectedFiles?: string[];
521
+ }
522
+ interface EntityFileSpec {
523
+ source: EntitySource;
524
+ render: string | ((rows: Row[]) => string);
525
+ junctionColumns?: string[];
526
+ omitIfEmpty?: boolean;
527
+ }
528
+ type EntitySource = {
529
+ type: 'self';
530
+ } | {
531
+ type: 'hasMany';
532
+ table: string;
533
+ foreignKey: string;
534
+ filters?: Filter[];
535
+ softDelete?: boolean;
536
+ orderBy?: string;
537
+ limit?: number;
538
+ } | {
539
+ type: 'manyToMany';
540
+ junctionTable: string;
541
+ localKey: string;
542
+ remoteKey: string;
543
+ remoteTable: string;
544
+ filters?: Filter[];
545
+ orderBy?: string;
546
+ limit?: number;
547
+ } | {
548
+ type: 'belongsTo';
549
+ table: string;
550
+ foreignKey: string;
551
+ } | {
552
+ type: 'enriched';
553
+ include: Record<string, EntitySource>;
554
+ } | {
555
+ type: 'custom';
556
+ resolve: (row: Row, adapter: SqliteAdapter) => Row[];
557
+ };
558
+ interface Filter {
559
+ col: string;
560
+ op: 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'like' | 'in' | 'isNull' | 'isNotNull';
561
+ val?: unknown;
562
+ }
563
+ interface QueryOptions {
564
+ where?: Record<string, unknown>;
565
+ filters?: Filter[];
566
+ orderBy?: string | Array<{
567
+ col: string;
568
+ dir: 'asc' | 'desc';
569
+ }>;
570
+ orderDir?: 'asc' | 'desc';
571
+ limit?: number;
572
+ offset?: number;
573
+ }
574
+ type Row = Record<string, unknown>;
575
+ type PkLookup = string | Record<string, unknown>;
576
+ interface SqliteAdapter {
577
+ run(sql: string, params?: unknown[]): better_sqlite3.RunResult;
578
+ get<T = Row>(sql: string, params?: unknown[]): T | undefined;
579
+ all<T = Row>(sql: string, params?: unknown[]): T[];
580
+ tableInfo(table: string): TableInfoRow[];
581
+ invalidateTableCache(table: string): void;
582
+ }
583
+ interface TableInfoRow {
584
+ cid: number;
585
+ name: string;
586
+ type: string;
587
+ notnull: number;
588
+ dflt_value: unknown;
589
+ pk: number;
590
+ }
591
+ interface SeedItem {
592
+ table: string;
593
+ rows: Row[];
594
+ naturalKey?: string | string[];
595
+ junctions?: Array<{
596
+ table: string;
597
+ items: Array<Row>;
598
+ }>;
599
+ softDeleteMissing?: boolean;
600
+ }
601
+
602
+ declare class DataStoreError extends Error {
603
+ constructor(message: string);
604
+ }
605
+ /**
606
+ * Thin wrapper around Lattice that provides the botinabox DataStore API.
607
+ *
608
+ * Delegates all data operations to the latticesql package. Application-level
609
+ * events (task.created, run.completed, etc.) remain on the HookBus — they are
610
+ * emitted by orchestrator modules, not the data layer.
611
+ */
612
+ declare class DataStore {
613
+ private lattice;
614
+ private readonly hooks;
615
+ private readonly outputDir;
616
+ private _initialized;
617
+ private readonly deferredStatements;
618
+ constructor(opts: {
619
+ dbPath: string;
620
+ outputDir?: string;
621
+ wal?: boolean;
622
+ hooks?: HookBus;
623
+ });
624
+ /**
625
+ * Register a table definition. Must be called before init().
626
+ *
627
+ * tableConstraints may contain both inline constraints (FOREIGN KEY, UNIQUE)
628
+ * and standalone SQL statements (CREATE INDEX). Standalone statements are
629
+ * deferred and executed after init() creates the tables.
630
+ */
631
+ define(name: string, def: TableDefinition): void;
632
+ /**
633
+ * Register an entity context definition for per-entity file rendering.
634
+ */
635
+ defineEntityContext(name: string, def: EntityContextDef): void;
636
+ init(opts?: {
637
+ migrations?: Array<{
638
+ version: string;
639
+ sql: string;
640
+ }>;
641
+ }): Promise<void>;
642
+ private assertInitialized;
643
+ insert(table: string, row: Row): Promise<Row>;
644
+ upsert(table: string, row: Row): Promise<Row>;
645
+ update(table: string, pk: PkLookup, changes: Row): Promise<Row>;
646
+ delete(table: string, pk: PkLookup): Promise<void>;
647
+ /**
648
+ * Get a single row by primary key.
649
+ * Returns undefined if not found (Lattice returns null).
650
+ */
651
+ get(table: string, pk: PkLookup): Promise<Row | undefined>;
652
+ query(table: string, opts?: QueryOptions): Promise<Row[]>;
653
+ count(table: string, opts?: QueryOptions): Promise<number>;
654
+ link(junctionTable: string, row: Row): Promise<void>;
655
+ unlink(junctionTable: string, row: Row): Promise<void>;
656
+ migrate(migrations: Array<{
657
+ version: string;
658
+ sql: string;
659
+ }>): Promise<void>;
660
+ seed(items: SeedItem[]): Promise<void>;
661
+ render(): Promise<void>;
662
+ reconcile(): Promise<void>;
663
+ tableInfo(table: string): TableInfoRow[];
664
+ close(): void;
665
+ on(event: string, handler: (context: Record<string, unknown>) => void): void;
666
+ }
667
+
668
+ declare class AgentRegistry {
669
+ private db;
670
+ private hooks;
671
+ constructor(db: DataStore, hooks: HookBus);
672
+ register(agent: {
673
+ slug: string;
674
+ name: string;
675
+ adapter: string;
676
+ role?: string;
677
+ [key: string]: unknown;
678
+ }, opts?: {
679
+ actorAgentId?: string;
680
+ }): Promise<string>;
681
+ getById(id: string): Promise<Record<string, unknown> | undefined>;
682
+ getBySlug(slug: string): Promise<Record<string, unknown> | undefined>;
683
+ list(filter?: {
684
+ status?: string;
685
+ role?: string;
686
+ }): Promise<Record<string, unknown>[]>;
687
+ update(id: string, changes: Record<string, unknown>): Promise<void>;
688
+ setStatus(id: string, newStatus: string): Promise<void>;
689
+ terminate(id: string): Promise<void>;
690
+ seedFromConfig(agentConfigs: Array<{
691
+ slug: string;
692
+ name: string;
693
+ adapter: string;
694
+ [key: string]: unknown;
695
+ }>): Promise<void>;
696
+ }
697
+
698
+ declare const MAX_CHAIN_DEPTH = 5;
699
+ /**
700
+ * Throws if depth exceeds the maximum allowed chain depth.
701
+ */
702
+ declare function checkChainDepth(depth: number, max?: number): void;
703
+ /**
704
+ * Build chain origin metadata for a new child task.
705
+ * If parentTaskId is provided, sets chain_origin_id and increments depth.
706
+ * Otherwise returns depth=0 with no origin.
707
+ */
708
+ declare function buildChainOrigin(parentTaskId?: string, parentOriginId?: string, parentDepth?: number): {
709
+ chain_origin_id?: string;
710
+ chain_depth: number;
711
+ };
712
+
713
+ declare class TaskQueue {
714
+ private db;
715
+ private hooks;
716
+ private config?;
717
+ private pollTimer;
718
+ private readonly pollIntervalMs;
719
+ private readonly staleThresholdMs;
720
+ constructor(db: DataStore, hooks: HookBus, config?: {
721
+ pollIntervalMs?: number;
722
+ staleThresholdMs?: number;
723
+ } | undefined);
724
+ create(task: {
725
+ title: string;
726
+ description?: string;
727
+ assignee_id?: string;
728
+ priority?: number;
729
+ chain_depth?: number;
730
+ chain_origin_id?: string;
731
+ [key: string]: unknown;
732
+ }): Promise<string>;
733
+ update(id: string, changes: Record<string, unknown>): Promise<void>;
734
+ get(id: string): Promise<Record<string, unknown> | undefined>;
735
+ list(filter?: {
736
+ status?: string;
737
+ assignee_id?: string;
738
+ }): Promise<Record<string, unknown>[]>;
739
+ startPolling(): void;
740
+ stopPolling(): void;
741
+ private poll;
742
+ }
743
+
744
+ /**
745
+ * MessagePipeline — routes inbound messages to the task queue.
746
+ * Story 4.2
747
+ */
748
+
749
+ declare class MessagePipeline {
750
+ private readonly hooks;
751
+ private readonly agentRegistry;
752
+ private readonly taskQueue;
753
+ private readonly config;
754
+ private readonly agentBindings;
755
+ constructor(hooks: HookBus, agentRegistry: AgentRegistry, taskQueue: TaskQueue, config: BotConfig);
756
+ /**
757
+ * Process an inbound message end-to-end.
758
+ * 1. Emit 'message.inbound'
759
+ * 2. Resolve agent
760
+ * 3. Check policy (allowlist / mention gate)
761
+ * 4. Create task
762
+ * 5. Emit 'message.processed'
763
+ */
764
+ processInbound(msg: InboundMessage): Promise<void>;
765
+ /**
766
+ * Resolve the best agent for a given inbound message.
767
+ * Returns agentId (slug) or undefined if no match.
768
+ */
769
+ resolveAgent(msg: InboundMessage): string | undefined;
770
+ /**
771
+ * Evaluate messaging policy for the given agent.
772
+ * Returns false if the message is blocked.
773
+ */
774
+ evaluatePolicy(msg: InboundMessage, agentId: string): boolean;
775
+ }
776
+
777
+ /**
778
+ * Chat routing — maps channel/scope to agentId.
779
+ * Story 4.2
780
+ */
781
+
782
+ /**
783
+ * Build a map from channel identifier to agentId.
784
+ * Each agent may have a config.channel or config.channels binding.
785
+ */
786
+ declare function buildAgentBindings(agents: AgentConfig[]): Map<string, string>;
787
+
788
+ /**
789
+ * Chat policy helpers — allowlist and mention gate checks.
790
+ * Story 4.2
791
+ */
792
+
793
+ /**
794
+ * Returns true if the sender is in the allowlist.
795
+ * If allowFrom is empty, all senders are allowed.
796
+ */
797
+ declare function checkAllowlist(allowFrom: string[], senderId: string): boolean;
798
+ /**
799
+ * Returns true if the message passes the mention gate.
800
+ * In group/channel contexts, the bot must be mentioned (body contains @botId or similar).
801
+ * In direct contexts, always passes.
802
+ */
803
+ declare function checkMentionGate(msg: InboundMessage, botId: string): boolean;
804
+
805
+ /**
806
+ * SessionKey — structured key for chat sessions.
807
+ * Story 4.3
808
+ */
809
+ declare class SessionKey {
810
+ readonly agentId: string;
811
+ readonly channel: string;
812
+ readonly scope: string;
813
+ constructor(agentId: string, channel: string, scope: string);
814
+ toString(): string;
815
+ toJSON(): {
816
+ agentId: string;
817
+ channel: string;
818
+ scope: string;
819
+ };
820
+ static fromString(key: string): SessionKey;
821
+ /**
822
+ * Build a session key from structured parameters.
823
+ *
824
+ * @param agentId - The agent identifier
825
+ * @param channel - The channel identifier
826
+ * @param chatType - 'dm' or 'group'
827
+ * @param peerId - The peer/user ID
828
+ * @param dmScope - DM scoping strategy
829
+ * - 'main' → single session per agent+channel regardless of peer
830
+ * - 'per-peer' → one session per (agent, peer)
831
+ * - 'per-channel-peer' → one session per (agent, channel, peer)
832
+ */
833
+ static build(agentId: string, channel: string, chatType: "dm" | "group", peerId: string, dmScope: "main" | "per-peer" | "per-channel-peer"): SessionKey;
834
+ }
835
+
836
+ /**
837
+ * ChatSessionManager — wraps orchestrator SessionManager with SessionKey-based lookup.
838
+ * Story 4.3
839
+ */
840
+
841
+ declare class ChatSessionManager {
842
+ private readonly inner;
843
+ constructor(db: DataStore);
844
+ save(key: SessionKey, params: Record<string, unknown>): Promise<string>;
845
+ load(key: SessionKey): Promise<Record<string, unknown> | undefined>;
846
+ clear(key: SessionKey): Promise<void>;
847
+ shouldClear(session: Record<string, unknown>, opts: {
848
+ maxRuns?: number;
849
+ maxAgeHours?: number;
850
+ }): Promise<boolean>;
851
+ }
852
+
853
+ /**
854
+ * NotificationQueue — persistent outbound notification queue with retry.
855
+ * Story 4.4
856
+ */
857
+
858
+ interface NotificationQueueOpts {
859
+ maxRetries?: number;
860
+ pollIntervalMs?: number;
861
+ }
862
+ declare class NotificationQueue {
863
+ private readonly db;
864
+ private readonly hooks;
865
+ private readonly channelRegistry;
866
+ private readonly maxRetries;
867
+ private readonly pollIntervalMs;
868
+ private timer;
869
+ constructor(db: DataStore, hooks: HookBus, channelRegistry: ChannelRegistry, opts?: NotificationQueueOpts);
870
+ /**
871
+ * Enqueue a notification for delivery.
872
+ * Returns the notification ID.
873
+ */
874
+ enqueue(channel: string, recipient: string, payload: {
875
+ text: string;
876
+ threadId?: string;
877
+ [key: string]: unknown;
878
+ }): Promise<string>;
879
+ /** Start the background worker polling for pending notifications. */
880
+ startWorker(): void;
881
+ /** Stop the background worker. */
882
+ stopWorker(): void;
883
+ private processNext;
884
+ }
885
+
886
+ /**
887
+ * Text chunker — splits long text into chunks at natural boundaries.
888
+ * Story 4.4
889
+ */
890
+ /**
891
+ * Split text into chunks of at most maxLen characters.
892
+ * Splits at paragraph boundaries first, then sentence, then word, then hard-cuts.
893
+ */
894
+ declare function chunkText(text: string, maxLen: number): string[];
895
+
896
+ /**
897
+ * Text formatter — converts markdown to channel-specific formats.
898
+ * Story 4.4
899
+ */
900
+ /**
901
+ * Format text for the given mode:
902
+ * - 'mrkdwn': Slack's mrkdwn format (**bold** → *bold*, _italic_ preserved, `code` preserved)
903
+ * - 'html': basic markdown → HTML (strong, em, code, pre)
904
+ * - 'plain': strip markdown markers
905
+ */
906
+ declare function formatText(text: string, mode: "mrkdwn" | "html" | "plain"): string;
907
+
908
+ /**
909
+ * Define all 15 core tables on a DataStore instance.
910
+ * Call before db.init().
911
+ */
912
+ declare function defineCoreTables(db: DataStore): void;
913
+
914
+ /** Initial migration set for core tables */
915
+ declare const CORE_MIGRATIONS: Array<{
916
+ version: string;
917
+ sql: string;
918
+ }>;
919
+
920
+ interface SanitizerOptions {
921
+ fieldLengthLimits?: Record<string, number>;
922
+ truncateSuffix?: string;
923
+ }
924
+ interface AuditEvent {
925
+ table: string;
926
+ operation: 'insert' | 'update' | 'delete';
927
+ pk: unknown;
928
+ timestamp: number;
929
+ changedColumns?: string[];
930
+ }
931
+
932
+ /**
933
+ * Sanitizes a row object by:
934
+ * 1. Stripping null bytes from string values
935
+ * 2. Stripping control characters (preserving \n, \r, \t)
936
+ * 3. Truncating fields that exceed their byte length limit
937
+ *
938
+ * Non-string values pass through unchanged.
939
+ * Returns a new object — input is never mutated.
940
+ */
941
+ declare function sanitize(row: Record<string, unknown>, opts?: SanitizerOptions): Record<string, unknown>;
942
+
943
+ interface ColumnValidator {
944
+ validateWrite(table: string, row: Record<string, unknown>): Record<string, unknown>;
945
+ validateRead(table: string, columns: string[]): void;
946
+ invalidateCache(table: string): void;
947
+ }
948
+ /**
949
+ * Validates column names against the live SQLite schema.
950
+ *
951
+ * - validateWrite: strips unknown columns silently
952
+ * - validateRead: throws on unknown columns
953
+ */
954
+ declare class ColumnValidatorImpl implements ColumnValidator {
955
+ private readonly db;
956
+ constructor(db: DataStore);
957
+ private getValidColumns;
958
+ validateWrite(table: string, row: Record<string, unknown>): Record<string, unknown>;
959
+ validateRead(table: string, columns: string[]): void;
960
+ invalidateCache(_table: string): void;
961
+ }
962
+
963
+ interface AuditEmitterOptions {
964
+ auditTables?: string[];
965
+ }
966
+ /**
967
+ * Emits audit events via the HookBus for tracked tables.
968
+ *
969
+ * - auditTables defaults to [] (nothing audited)
970
+ * - '*' wildcard audits all tables
971
+ * - emit is fire-and-forget — errors are swallowed, no awaiting
972
+ */
973
+ declare class AuditEmitter {
974
+ private readonly hooks;
975
+ private readonly auditTables;
976
+ constructor(hooks: HookBus, opts?: AuditEmitterOptions);
977
+ shouldAudit(table: string): boolean;
978
+ emit(event: AuditEvent): void;
979
+ }
980
+
981
+ interface PackageUpdate {
982
+ name: string;
983
+ installedVersion: string;
984
+ latestVersion: string;
985
+ updateType: 'patch' | 'minor' | 'major';
986
+ }
987
+ interface UpdateManifest {
988
+ checkedAt: string;
989
+ packages: PackageUpdate[];
990
+ hasUpdates: boolean;
991
+ }
992
+
993
+ /**
994
+ * Simple semver utilities — no external deps.
995
+ */
996
+ declare function parseVersion(v: string): [number, number, number];
997
+ declare function compareVersions(a: string, b: string): -1 | 0 | 1;
998
+ declare function classifyUpdate(from: string, to: string): 'patch' | 'minor' | 'major' | 'none';
999
+
1000
+ declare class UpdateChecker {
1001
+ private nodeModulesPath;
1002
+ private opts?;
1003
+ private readonly fetchFn;
1004
+ constructor(nodeModulesPath: string, opts?: {
1005
+ fetch?: typeof globalThis.fetch;
1006
+ } | undefined);
1007
+ getInstalledPackages(): string[];
1008
+ check(packageNames?: string[]): Promise<UpdateManifest>;
1009
+ }
1010
+
1011
+ declare class BackupManager {
1012
+ private projectRoot;
1013
+ constructor(projectRoot: string);
1014
+ backup(): Promise<string>;
1015
+ restore(backupPath: string): Promise<void>;
1016
+ cleanup(backupPath: string): Promise<void>;
1017
+ }
1018
+
1019
+ type UpdatePolicy = 'auto-all' | 'auto-compatible' | 'auto-patch' | 'notify' | 'manual';
1020
+ declare class UpdateManager {
1021
+ private checker;
1022
+ private db;
1023
+ private hooks;
1024
+ private opts?;
1025
+ private backupManager;
1026
+ constructor(checker: UpdateChecker, db: DataStore, hooks: HookBus, opts?: {
1027
+ projectRoot?: string;
1028
+ policy?: UpdatePolicy;
1029
+ maintenanceWindow?: {
1030
+ utcHourStart: number;
1031
+ utcHourEnd: number;
1032
+ };
1033
+ } | undefined);
1034
+ checkAndNotify(): Promise<UpdateManifest>;
1035
+ applyUpdates(updates: PackageUpdate[]): Promise<void>;
1036
+ isInMaintenanceWindow(): boolean;
1037
+ filterByPolicy(updates: PackageUpdate[]): PackageUpdate[];
1038
+ }
1039
+
1040
+ interface PackageMigration {
1041
+ version: string;
1042
+ package: string;
1043
+ sql: string;
1044
+ }
1045
+ /**
1046
+ * Runs package migrations using the __lattice_migrations table for tracking.
1047
+ * Each migration is keyed by "{package}:{version}" to ensure idempotency.
1048
+ */
1049
+ declare function runPackageMigrations(db: DataStore, migrations: PackageMigration[]): Promise<void>;
1050
+
1051
+ declare class RunManager {
1052
+ private db;
1053
+ private hooks;
1054
+ private config?;
1055
+ private locks;
1056
+ private orphanTimer;
1057
+ private readonly staleThresholdMs;
1058
+ constructor(db: DataStore, hooks: HookBus, config?: {
1059
+ staleThresholdMs?: number;
1060
+ maxBackoffMs?: number;
1061
+ } | undefined);
1062
+ isLocked(agentId: string): boolean;
1063
+ startRun(agentId: string, taskId: string, adapter?: string): Promise<string>;
1064
+ finishRun(runId: string, result: {
1065
+ exitCode: number;
1066
+ output?: string;
1067
+ costCents?: number;
1068
+ usage?: unknown;
1069
+ }): Promise<void>;
1070
+ reapOrphans(): Promise<void>;
1071
+ startOrphanReaper(intervalMs?: number): void;
1072
+ stopOrphanReaper(): void;
1073
+ }
1074
+
1075
+ declare class BudgetController {
1076
+ private db;
1077
+ private hooks;
1078
+ constructor(db: DataStore, hooks: HookBus);
1079
+ checkBudget(agentId: string): Promise<{
1080
+ allowed: boolean;
1081
+ reason?: string;
1082
+ currentSpendCents: number;
1083
+ limitCents: number;
1084
+ }>;
1085
+ resetMonthlySpend(agentId: string): Promise<void>;
1086
+ globalCheck(): Promise<{
1087
+ allowed: boolean;
1088
+ totalSpentCents: number;
1089
+ limitCents: number;
1090
+ }>;
1091
+ }
1092
+
1093
+ interface WorkflowStep {
1094
+ id: string;
1095
+ name: string;
1096
+ agentSlug?: string;
1097
+ taskTemplate: {
1098
+ title: string;
1099
+ description: string;
1100
+ };
1101
+ dependsOn?: string[];
1102
+ onComplete?: 'next' | 'parallel' | 'end';
1103
+ onFail?: 'abort' | 'skip' | 'retry';
1104
+ }
1105
+ interface WorkflowDefinition {
1106
+ name: string;
1107
+ description?: string;
1108
+ steps: WorkflowStep[];
1109
+ trigger?: {
1110
+ type: 'task_completed' | 'event' | 'schedule' | 'manual';
1111
+ filter?: Record<string, unknown>;
1112
+ };
1113
+ }
1114
+ declare class WorkflowEngine {
1115
+ private db;
1116
+ private hooks;
1117
+ private taskQueue;
1118
+ constructor(db: DataStore, hooks: HookBus, taskQueue: TaskQueue);
1119
+ /**
1120
+ * Define/register a workflow.
1121
+ */
1122
+ define(slug: string, def: WorkflowDefinition): Promise<void>;
1123
+ /**
1124
+ * Start a workflow run.
1125
+ */
1126
+ start(workflowSlug: string, context: Record<string, unknown>): Promise<string>;
1127
+ /**
1128
+ * Called when a task with workflow_run_id completes.
1129
+ */
1130
+ onStepCompleted(taskId: string, output: string): Promise<void>;
1131
+ /**
1132
+ * Mark a workflow run as failed.
1133
+ */
1134
+ onStepFailed(taskId: string, error: string): Promise<void>;
1135
+ private _createStepTask;
1136
+ }
1137
+
1138
+ declare class WakeupQueue {
1139
+ private db;
1140
+ constructor(db: DataStore);
1141
+ enqueue(agentId: string, source: string, context?: Record<string, unknown>): Promise<string>;
1142
+ coalesce(agentId: string, context?: Record<string, unknown>): Promise<void>;
1143
+ getNext(agentId: string): Promise<Record<string, unknown> | undefined>;
1144
+ markFired(wakeupId: string, runId: string): Promise<void>;
1145
+ }
1146
+
1147
+ declare class SessionManager {
1148
+ private db;
1149
+ constructor(db: DataStore);
1150
+ save(agentId: string, channelId: string, peerId: string, params: Record<string, unknown>): Promise<string>;
1151
+ load(agentId: string, channelId: string, peerId: string): Promise<Record<string, unknown> | undefined>;
1152
+ clear(agentId: string, channelId: string, peerId: string): Promise<void>;
1153
+ shouldClear(session: Record<string, unknown>, opts: {
1154
+ maxRuns?: number;
1155
+ maxAgeHours?: number;
1156
+ }): Promise<boolean>;
1157
+ private _find;
1158
+ }
1159
+
1160
+ declare class NdjsonLogger {
1161
+ private logPath;
1162
+ constructor(logPath: string);
1163
+ log(stream: 'stdout' | 'stderr', chunk: string): void;
1164
+ close(): void;
1165
+ }
1166
+
1167
+ declare class HeartbeatScheduler {
1168
+ private wakeupQueue;
1169
+ private hooks;
1170
+ private timers;
1171
+ constructor(wakeupQueue: WakeupQueue, hooks: HookBus);
1172
+ start(agents: Array<{
1173
+ id: string;
1174
+ heartbeat_config: string;
1175
+ }>): void;
1176
+ stop(): void;
1177
+ }
1178
+
1179
+ /**
1180
+ * Creates a config revision record with before/after snapshots.
1181
+ * Note: uses config_revisions table with config_yaml storing JSON of {agentId, before, after}.
1182
+ */
1183
+ declare function createConfigRevision(db: DataStore, agentId: string, before: Record<string, unknown>, after: Record<string, unknown>): Promise<void>;
1184
+
1185
+ /**
1186
+ * Dependency resolution utilities for workflow steps and task deps.
1187
+ */
1188
+ interface StepRef {
1189
+ id: string;
1190
+ dependsOn?: string[];
1191
+ }
1192
+ /**
1193
+ * DFS cycle detection — returns true if cycle exists.
1194
+ */
1195
+ declare function detectCycle(steps: StepRef[]): boolean;
1196
+ /**
1197
+ * Returns step IDs in topological (execution) order.
1198
+ * Throws if a cycle is detected.
1199
+ */
1200
+ declare function topologicalSort(steps: StepRef[]): string[];
1201
+ /**
1202
+ * Returns true if all dependencies are satisfied (present in completedTaskIds).
1203
+ */
1204
+ declare function areDependenciesMet(taskDepsJson: string | undefined, completedTaskIds: Set<string>): boolean;
1205
+
1206
+ /**
1207
+ * Simple template interpolation for workflow step templates.
1208
+ * Supports {{key}} and {{steps.stepId.output}} patterns.
1209
+ */
1210
+ declare function interpolate(template: string, context: Record<string, unknown>): string;
1211
+
1212
+ declare class ApiExecutionAdapter {
1213
+ private modelRouter;
1214
+ readonly type = "api";
1215
+ constructor(modelRouter: ModelRouter);
1216
+ execute(ctx: {
1217
+ agent: {
1218
+ id: string;
1219
+ model?: string;
1220
+ adapter_config?: string;
1221
+ };
1222
+ task: {
1223
+ description?: string;
1224
+ context?: string;
1225
+ };
1226
+ sessionParams?: {
1227
+ history?: ChatMessage[];
1228
+ };
1229
+ contextFiles?: string[];
1230
+ abortSignal?: AbortSignal;
1231
+ onLog?: (stream: 'stdout' | 'stderr', chunk: string) => void;
1232
+ }): Promise<{
1233
+ output: string;
1234
+ exitCode: number;
1235
+ usage: TokenUsage & {
1236
+ provider: string;
1237
+ model: string;
1238
+ };
1239
+ sessionParams: {
1240
+ history: ChatMessage[];
1241
+ };
1242
+ }>;
1243
+ }
1244
+
1245
+ declare class CliExecutionAdapter {
1246
+ readonly type = "cli";
1247
+ execute(ctx: {
1248
+ agent: {
1249
+ id: string;
1250
+ cwd?: string;
1251
+ adapter_config?: string;
1252
+ skip_permissions?: boolean;
1253
+ };
1254
+ task: {
1255
+ title: string;
1256
+ description?: string;
1257
+ context?: string;
1258
+ };
1259
+ logPath?: string;
1260
+ onLog?: (stream: string, chunk: string) => void;
1261
+ abortSignal?: AbortSignal;
1262
+ }): Promise<{
1263
+ output: string;
1264
+ exitCode: number;
1265
+ }>;
1266
+ }
1267
+
1268
+ export { AGENT_STATUSES, type AgentConfig, type AgentDefinition, type AgentFilter, type AgentRecord, AgentRegistry, type AgentStatus, ApiExecutionAdapter, AuditEmitter, type AuditEvent, BackupManager, type BotConfig, type BudgetCheck, type BudgetConfig, BudgetController, CORE_MIGRATIONS, ChannelAdapter, ChannelRegistry, ChannelRegistryError, ChatMessage, ChatSessionManager, CliExecutionAdapter, type ColumnValidator, ColumnValidatorImpl, type ConfigLoadError, type ConfigLoadResult, DEFAULTS, DEFAULT_CONFIG, type DataConfig, DataStore, DataStoreError, EVENTS, type EntityColumnDef, type EntityConfig, type EntityContextDef, type EntityFileSpec, type EntitySource, type ExecutionAdapter, type Filter, HealthStatus, HeartbeatScheduler, HookBus, type HookHandler, type HookOptions, type HookRegistration, InboundMessage, LLMProvider, MAX_CHAIN_DEPTH, MessagePipeline, type ModelConfig, ModelInfo, ModelRouter, NdjsonLogger, NotificationQueue, type PackageMigration, type PackageUpdate, type PkLookup, ProviderRegistry, type QueryOptions, RUN_STATUSES, type RelationDef, type RenderConfig, ResolvedModel, type RetryPolicy, type Row, type RunContext, RunManager, type RunResult, type RunStatus, type SanitizerOptions, type SchemaError, type SecurityConfig, type SeedItem, SessionKey, SessionManager, type SqliteAdapter, type StepRef, TASK_STATUSES, type TableDefinition, type TableInfoRow, type TaskDefinition, TaskQueue, type TaskRecord, type TaskStatus, TokenUsage, type Unsubscribe, UpdateChecker, type UpdateConfig, UpdateManager, type UpdateManifest, WakeupQueue, type WorkflowConfigEntry, type WorkflowDefinition$1 as WorkflowDefinition, WorkflowEngine, type WorkflowRunRecord, type WorkflowRunStatus, type WorkflowStep$1 as WorkflowStep, type WorkflowStepConfig, type WorkflowTrigger, _resetConfig, areDependenciesMet, buildAgentBindings, buildChainOrigin, checkAllowlist, checkChainDepth, checkMentionGate, chunkText, classifyUpdate, compareVersions, createConfigRevision, defineCoreTables, detectCycle, discoverChannels, discoverProviders, formatText, getConfig, initConfig, interpolate, interpolateEnv, loadConfig, parseVersion, runPackageMigrations, sanitize, topologicalSort, validateConfig };