@telora/daemon-core 0.2.5

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.
Files changed (81) hide show
  1. package/dist/activity-tracker.d.ts +69 -0
  2. package/dist/activity-tracker.d.ts.map +1 -0
  3. package/dist/activity-tracker.js +155 -0
  4. package/dist/activity-tracker.js.map +1 -0
  5. package/dist/api-client.d.ts +94 -0
  6. package/dist/api-client.d.ts.map +1 -0
  7. package/dist/api-client.js +145 -0
  8. package/dist/api-client.js.map +1 -0
  9. package/dist/config.d.ts +117 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +348 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/engine.d.ts +120 -0
  14. package/dist/engine.d.ts.map +1 -0
  15. package/dist/engine.js +18 -0
  16. package/dist/engine.js.map +1 -0
  17. package/dist/escalation-types.d.ts +31 -0
  18. package/dist/escalation-types.d.ts.map +1 -0
  19. package/dist/escalation-types.js +24 -0
  20. package/dist/escalation-types.js.map +1 -0
  21. package/dist/event-logger.d.ts +13 -0
  22. package/dist/event-logger.d.ts.map +1 -0
  23. package/dist/event-logger.js +82 -0
  24. package/dist/event-logger.js.map +1 -0
  25. package/dist/git.d.ts +39 -0
  26. package/dist/git.d.ts.map +1 -0
  27. package/dist/git.js +72 -0
  28. package/dist/git.js.map +1 -0
  29. package/dist/index.d.ts +20 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +36 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/lifecycle.d.ts +104 -0
  34. package/dist/lifecycle.d.ts.map +1 -0
  35. package/dist/lifecycle.js +192 -0
  36. package/dist/lifecycle.js.map +1 -0
  37. package/dist/log-manager.d.ts +83 -0
  38. package/dist/log-manager.d.ts.map +1 -0
  39. package/dist/log-manager.js +217 -0
  40. package/dist/log-manager.js.map +1 -0
  41. package/dist/otel-env.d.ts +29 -0
  42. package/dist/otel-env.d.ts.map +1 -0
  43. package/dist/otel-env.js +44 -0
  44. package/dist/otel-env.js.map +1 -0
  45. package/dist/resilience.d.ts +127 -0
  46. package/dist/resilience.d.ts.map +1 -0
  47. package/dist/resilience.js +300 -0
  48. package/dist/resilience.js.map +1 -0
  49. package/dist/resource-governor.d.ts +83 -0
  50. package/dist/resource-governor.d.ts.map +1 -0
  51. package/dist/resource-governor.js +184 -0
  52. package/dist/resource-governor.js.map +1 -0
  53. package/dist/spawn.d.ts +72 -0
  54. package/dist/spawn.d.ts.map +1 -0
  55. package/dist/spawn.js +82 -0
  56. package/dist/spawn.js.map +1 -0
  57. package/dist/stream-json.d.ts +885 -0
  58. package/dist/stream-json.d.ts.map +1 -0
  59. package/dist/stream-json.js +298 -0
  60. package/dist/stream-json.js.map +1 -0
  61. package/dist/token-usage.d.ts +67 -0
  62. package/dist/token-usage.d.ts.map +1 -0
  63. package/dist/token-usage.js +150 -0
  64. package/dist/token-usage.js.map +1 -0
  65. package/dist/transforms.d.ts +64 -0
  66. package/dist/transforms.d.ts.map +1 -0
  67. package/dist/transforms.js +78 -0
  68. package/dist/transforms.js.map +1 -0
  69. package/dist/unified-config.d.ts +62 -0
  70. package/dist/unified-config.d.ts.map +1 -0
  71. package/dist/unified-config.js +155 -0
  72. package/dist/unified-config.js.map +1 -0
  73. package/dist/workflow-types.d.ts +202 -0
  74. package/dist/workflow-types.d.ts.map +1 -0
  75. package/dist/workflow-types.js +15 -0
  76. package/dist/workflow-types.js.map +1 -0
  77. package/dist/worktree.d.ts +92 -0
  78. package/dist/worktree.d.ts.map +1 -0
  79. package/dist/worktree.js +221 -0
  80. package/dist/worktree.js.map +1 -0
  81. package/package.json +57 -0
package/dist/config.js ADDED
@@ -0,0 +1,348 @@
1
+ /**
2
+ * Shared configuration infrastructure for Telora daemon and factory engines.
3
+ *
4
+ * Provides:
5
+ * - BaseConfig interface with fields common to both DaemonConfig and FactoryConfig
6
+ * - Generic config file loader (JSON from disk)
7
+ * - Base config resolver (env vars over file config)
8
+ * - Base config validator (collects errors without throwing)
9
+ *
10
+ * Each engine imports these and layers its own fields on top.
11
+ */
12
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
13
+ import { resolve, dirname, basename } from 'node:path';
14
+ import { homedir } from 'node:os';
15
+ // ---------------------------------------------------------------------------
16
+ // Constants
17
+ // ---------------------------------------------------------------------------
18
+ /** Regex for UUID v1-v8 (loose check). */
19
+ export const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
20
+ /**
21
+ * Derive a short human-readable label for a product entry.
22
+ * Uses the basename of the product's repoPath (e.g., "/home/user/repos/telora" → "telora").
23
+ * Falls back to an 8-char ID slice if repoPath is empty.
24
+ */
25
+ export function productLabel(product) {
26
+ if (product.repoPath) {
27
+ const name = basename(product.repoPath);
28
+ if (name && name !== '.')
29
+ return name;
30
+ }
31
+ return product.id.slice(0, 8);
32
+ }
33
+ // ---------------------------------------------------------------------------
34
+ // Config file loader
35
+ // ---------------------------------------------------------------------------
36
+ /**
37
+ * Load a JSON config file from disk.
38
+ *
39
+ * Search order (when no explicit configPath):
40
+ * 1. ~/.telora/{defaultFilename} (global config, multi-product)
41
+ * 2. .telora/{defaultFilename} in cwd (repo-local, legacy)
42
+ *
43
+ * @param configPath Explicit path to a config file, or undefined to use defaults.
44
+ * @param defaultFilename Filename to look for inside `.telora/` (e.g. `daemon.json`).
45
+ * @returns Parsed JSON object, or an empty object if no config file is found.
46
+ * @throws If an explicit configPath is provided but the file does not exist,
47
+ * or if the file cannot be parsed as JSON.
48
+ */
49
+ export function loadConfigFile(configPath, defaultFilename) {
50
+ if (configPath) {
51
+ // Explicit path -- must exist
52
+ if (!existsSync(configPath)) {
53
+ throw new Error(`Config file not found: ${configPath}`);
54
+ }
55
+ return parseConfigFile(configPath);
56
+ }
57
+ // Try global config first: ~/.telora/{defaultFilename}
58
+ const globalPath = resolve(homedir(), '.telora', defaultFilename);
59
+ if (existsSync(globalPath)) {
60
+ return parseConfigFile(globalPath);
61
+ }
62
+ // Fall back to repo-local: .telora/{defaultFilename} in cwd
63
+ const localPath = resolve(process.cwd(), '.telora', defaultFilename);
64
+ if (existsSync(localPath)) {
65
+ const localConfig = parseConfigFile(localPath);
66
+ // Auto-migrate: repo-local config exists but no global config.
67
+ // Convert legacy single-product format to multi-product and write to global location.
68
+ const migrated = migrateToGlobalConfig(localConfig, process.cwd(), globalPath);
69
+ if (migrated) {
70
+ return parseConfigFile(globalPath);
71
+ }
72
+ return localConfig;
73
+ }
74
+ // No config file found -- return empty (env vars or init wizard will provide values)
75
+ return {};
76
+ }
77
+ /** Parse and validate a JSON config file. */
78
+ function parseConfigFile(path) {
79
+ try {
80
+ const content = readFileSync(path, 'utf-8');
81
+ const config = JSON.parse(content);
82
+ if (typeof config !== 'object' || config === null || Array.isArray(config)) {
83
+ throw new Error('Config file must contain a JSON object');
84
+ }
85
+ console.log(`Loaded config from ${path}`);
86
+ return config;
87
+ }
88
+ catch (err) {
89
+ throw new Error(`Failed to parse config file ${path}: ${err.message}`);
90
+ }
91
+ }
92
+ /**
93
+ * Migrate a repo-local legacy config to the global ~/.telora/ location.
94
+ *
95
+ * Converts legacy single-product format (productId + repoPath at top level)
96
+ * to the multi-product format (products array). If the config already has a
97
+ * products array, it is written as-is to the global location.
98
+ *
99
+ * @returns true if migration succeeded, false if skipped (e.g. already multi-product format in place)
100
+ */
101
+ function migrateToGlobalConfig(localConfig, repoPath, globalPath) {
102
+ try {
103
+ const migrated = { ...localConfig };
104
+ // Convert legacy single-product fields to products array
105
+ if (!Array.isArray(migrated.products)) {
106
+ const productId = typeof migrated.productId === 'string' ? migrated.productId : '';
107
+ const configRepoPath = typeof migrated.repoPath === 'string'
108
+ ? migrated.repoPath
109
+ : repoPath;
110
+ if (productId) {
111
+ migrated.products = [{ id: productId, repoPath: configRepoPath }];
112
+ // Remove legacy fields from the migrated config
113
+ delete migrated.productId;
114
+ delete migrated.repoPath;
115
+ }
116
+ }
117
+ // Ensure the global directory exists
118
+ const globalDir = dirname(globalPath);
119
+ if (!existsSync(globalDir)) {
120
+ mkdirSync(globalDir, { recursive: true });
121
+ }
122
+ writeFileSync(globalPath, JSON.stringify(migrated, null, 2) + '\n');
123
+ console.log(`Migrated config from repo-local to ${globalPath}. ` +
124
+ `The repo-local .telora/daemon.json can be removed.`);
125
+ return true;
126
+ }
127
+ catch (err) {
128
+ console.warn(`Failed to migrate config to global location: ${err.message}. ` +
129
+ `Using repo-local config.`);
130
+ return false;
131
+ }
132
+ }
133
+ // ---------------------------------------------------------------------------
134
+ // Env-var mapping for base fields
135
+ // ---------------------------------------------------------------------------
136
+ /**
137
+ * Mapping from BaseConfig field name to the environment variable that provides it.
138
+ * Used by resolveBaseConfig to prioritise env vars over file config.
139
+ * Note: `products` is excluded -- it's resolved separately via resolveProducts().
140
+ */
141
+ const BASE_ENV_MAP = {
142
+ teloraUrl: 'TELORA_URL',
143
+ trackerId: 'TELORA_TRACKER_ID',
144
+ organizationId: 'TELORA_ORGANIZATION_ID',
145
+ productId: 'TELORA_PRODUCT_ID',
146
+ repoPath: 'TELORA_REPO_PATH',
147
+ claudeCodePath: 'CLAUDE_CODE_PATH',
148
+ logDir: 'TELORA_LOG_DIR',
149
+ sessionTimeoutMs: 'SESSION_TIMEOUT_MS',
150
+ mcpConfigPath: 'MCP_CONFIG_PATH',
151
+ };
152
+ // ---------------------------------------------------------------------------
153
+ // Base config resolver
154
+ // ---------------------------------------------------------------------------
155
+ /**
156
+ * Resolve BaseConfig fields from a combination of file config and environment
157
+ * variables. Environment variables take priority over file config values.
158
+ *
159
+ * Returns a Partial<BaseConfig> so each engine can merge it with its own
160
+ * engine-specific fields. Fields that are not set in either source are omitted.
161
+ *
162
+ * Multi-product resolution:
163
+ * 1. If `products` array exists in config file, use it directly
164
+ * 2. If TELORA_PRODUCT_ID + TELORA_REPO_PATH env vars are set, they produce
165
+ * a single-entry products array (useful for CI/testing)
166
+ * 3. If only legacy `productId` + `repoPath` in config, normalize to products array
167
+ * 4. `productId` and `repoPath` on the result always reflect the first product
168
+ *
169
+ * @param fileConfig Parsed JSON from the config file (keys are camelCase field names).
170
+ * @param envOverrides Environment variables -- typically pass `process.env`.
171
+ */
172
+ export function resolveBaseConfig(fileConfig, envOverrides) {
173
+ const result = {};
174
+ for (const [field, envKey] of Object.entries(BASE_ENV_MAP)) {
175
+ const envVal = envOverrides[envKey];
176
+ const fileVal = fileConfig[field];
177
+ if (field === 'sessionTimeoutMs') {
178
+ // Numeric field -- parse from env string if present
179
+ if (envVal !== undefined && envVal !== '') {
180
+ result[field] = parseInt(envVal, 10);
181
+ }
182
+ else if (typeof fileVal === 'number') {
183
+ result[field] = fileVal;
184
+ }
185
+ }
186
+ else if (field === 'mcpConfigPath') {
187
+ // Nullable string -- env takes priority, then file, leave out if neither set
188
+ if (envVal !== undefined && envVal !== '') {
189
+ result[field] = envVal;
190
+ }
191
+ else if (typeof fileVal === 'string') {
192
+ result[field] = fileVal;
193
+ }
194
+ else {
195
+ result[field] = null;
196
+ }
197
+ }
198
+ else {
199
+ // Regular string fields
200
+ if (envVal !== undefined && envVal !== '') {
201
+ result[field] = envVal;
202
+ }
203
+ else if (typeof fileVal === 'string' && fileVal !== '') {
204
+ result[field] = fileVal;
205
+ }
206
+ }
207
+ }
208
+ // ── Multi-product resolution ──────────────────────────────────────
209
+ const products = resolveProducts(fileConfig, envOverrides, result);
210
+ if (products.length > 0) {
211
+ result.products = products;
212
+ // Keep productId/repoPath in sync with the first product for backward compat
213
+ result.productId = products[0].id;
214
+ result.repoPath = products[0].repoPath;
215
+ }
216
+ // Warn when legacy fields coexist with products array in config file
217
+ if (Array.isArray(fileConfig.products) && fileConfig.products.length > 0) {
218
+ if (typeof fileConfig.productId === 'string' || typeof fileConfig.repoPath === 'string') {
219
+ console.warn('WARNING: Config file has both "products" array and legacy "productId"/"repoPath" fields. ' +
220
+ 'The "products" array takes precedence. Remove the legacy fields to silence this warning.');
221
+ }
222
+ }
223
+ return result;
224
+ }
225
+ /**
226
+ * Resolve the products array from config file and env vars.
227
+ *
228
+ * Priority:
229
+ * 1. TELORA_PRODUCT_ID + TELORA_REPO_PATH env vars → single-entry array
230
+ * 2. `products` array in config file → use directly
231
+ * 3. Legacy `productId` + `repoPath` in config file → normalize to single-entry
232
+ */
233
+ function resolveProducts(fileConfig, envOverrides, resolvedBase) {
234
+ // Env-var override: single product from env (CI/testing use case)
235
+ const envProductId = envOverrides.TELORA_PRODUCT_ID;
236
+ const envRepoPath = envOverrides.TELORA_REPO_PATH;
237
+ if (envProductId && envProductId !== '') {
238
+ return [{
239
+ id: envProductId,
240
+ repoPath: envRepoPath && envRepoPath !== '' ? envRepoPath : process.cwd(),
241
+ }];
242
+ }
243
+ // Multi-product array in config file
244
+ const fileProducts = fileConfig.products;
245
+ if (Array.isArray(fileProducts) && fileProducts.length > 0) {
246
+ const entries = [];
247
+ for (const item of fileProducts) {
248
+ if (typeof item === 'object' && item !== null && !Array.isArray(item)) {
249
+ const obj = item;
250
+ const id = typeof obj.id === 'string' ? obj.id : '';
251
+ const repoPath = typeof obj.repoPath === 'string' ? obj.repoPath : '';
252
+ if (id) {
253
+ entries.push({ id, repoPath: repoPath || process.cwd() });
254
+ }
255
+ }
256
+ }
257
+ if (entries.length > 0)
258
+ return entries;
259
+ }
260
+ // Legacy single-product: normalize from resolved productId/repoPath
261
+ const productId = resolvedBase.productId;
262
+ const repoPath = resolvedBase.repoPath;
263
+ if (productId) {
264
+ return [{ id: productId, repoPath: repoPath || process.cwd() }];
265
+ }
266
+ return [];
267
+ }
268
+ // ---------------------------------------------------------------------------
269
+ // Base config validator
270
+ // ---------------------------------------------------------------------------
271
+ /**
272
+ * Validate the shared BaseConfig fields.
273
+ *
274
+ * Returns an array of human-readable error messages (never throws).
275
+ * Engines should call this, then append their own engine-specific validation
276
+ * errors before deciding whether to throw.
277
+ *
278
+ * @param config Partial base config to validate. Missing required fields
279
+ * are reported as errors.
280
+ */
281
+ export function validateBaseConfig(config) {
282
+ const errors = [];
283
+ // ---- Required string fields must be present and non-empty ----
284
+ if (!config.teloraUrl || !config.teloraUrl.trim()) {
285
+ errors.push('teloraUrl is required (set TELORA_URL or teloraUrl in config file)');
286
+ }
287
+ if (!config.trackerId || !config.trackerId.trim()) {
288
+ errors.push('trackerId is required (set TELORA_TRACKER_ID or trackerId in config file)');
289
+ }
290
+ if (!config.organizationId || !config.organizationId.trim()) {
291
+ errors.push('organizationId is required (set TELORA_ORGANIZATION_ID or organizationId in config file)');
292
+ }
293
+ // ---- Products array validation ----
294
+ if (config.products && config.products.length > 0) {
295
+ // Validate via products array (preferred)
296
+ const seenIds = new Set();
297
+ for (let i = 0; i < config.products.length; i++) {
298
+ const product = config.products[i];
299
+ if (!product.id || !product.id.trim()) {
300
+ errors.push(`products[${i}].id is required`);
301
+ }
302
+ else {
303
+ if (!UUID_REGEX.test(product.id)) {
304
+ errors.push(`products[${i}].id is not a valid UUID: "${product.id}"`);
305
+ }
306
+ if (seenIds.has(product.id)) {
307
+ errors.push(`Duplicate product ID: "${product.id}"`);
308
+ }
309
+ seenIds.add(product.id);
310
+ }
311
+ if (!product.repoPath || !product.repoPath.trim()) {
312
+ errors.push(`products[${i}].repoPath is required`);
313
+ }
314
+ }
315
+ }
316
+ else {
317
+ // Fallback to legacy single-product validation
318
+ if (!config.productId || !config.productId.trim()) {
319
+ errors.push('At least one product is required (set products array, or TELORA_PRODUCT_ID)');
320
+ }
321
+ if (!config.repoPath || !config.repoPath.trim()) {
322
+ errors.push('repoPath is required (set TELORA_REPO_PATH or repoPath in config file)');
323
+ }
324
+ }
325
+ // ---- URL format ----
326
+ if (config.teloraUrl && config.teloraUrl.trim()) {
327
+ try {
328
+ new URL(config.teloraUrl);
329
+ }
330
+ catch {
331
+ errors.push(`teloraUrl is not a valid URL: "${config.teloraUrl}"`);
332
+ }
333
+ }
334
+ // ---- UUID format for org ID ----
335
+ if (config.organizationId && config.organizationId.trim()) {
336
+ if (!UUID_REGEX.test(config.organizationId)) {
337
+ errors.push(`organizationId is not a valid UUID: "${config.organizationId}"`);
338
+ }
339
+ }
340
+ // Legacy productId UUID validation (when not using products array)
341
+ if (config.productId && config.productId.trim() && (!config.products || config.products.length === 0)) {
342
+ if (!UUID_REGEX.test(config.productId)) {
343
+ errors.push(`productId is not a valid UUID: "${config.productId}"`);
344
+ }
345
+ }
346
+ return errors;
347
+ }
348
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * ExecutionEngine interface -- the formal contract between the unified daemon
3
+ * process shell and individual execution engines (strategy, factory, etc.).
4
+ *
5
+ * The process shell manages lifecycle primitives (PID lock, signal handlers,
6
+ * config loading) and delegates engine-specific behavior through this interface.
7
+ * This allows adding future engines without modifying the shell.
8
+ *
9
+ * Lifecycle sequence (called by the process shell):
10
+ * 1. engine.init(config) -- store config, validate, connect
11
+ * 2. engine.recoverFromCrash() -- reconcile orphaned state (uses stored config)
12
+ * 3. engine.start() -- begin polling / listening loops
13
+ * ... running ...
14
+ * 4. engine.stop() -- stop accepting new work
15
+ * 5. engine.shutdown() -- graceful cleanup (kill processes, WIP commit, drain)
16
+ */
17
+ import type { BaseConfig } from './config.js';
18
+ import type { ResourceGovernor } from './resource-governor.js';
19
+ /** Health status of an execution engine. */
20
+ export interface EngineHealth {
21
+ /** Overall health status. */
22
+ status: 'healthy' | 'degraded' | 'unhealthy';
23
+ /** Number of active work items (strategy teams, factory instances, etc.). */
24
+ activeWorkItems: number;
25
+ /** Engine-specific details for status reporting. */
26
+ details: Record<string, unknown>;
27
+ }
28
+ /** Resource usage snapshot for an execution engine. */
29
+ export interface ResourceUsage {
30
+ /** Number of active Claude Code processes managed by this engine. */
31
+ activeClaudeProcesses: number;
32
+ /** Number of active git worktrees managed by this engine. */
33
+ activeWorktrees: number;
34
+ }
35
+ /**
36
+ * Contract that every execution engine must implement.
37
+ *
38
+ * The process shell treats engines as opaque boxes -- it only interacts
39
+ * through this interface. Engine internals (polling loops, state machines,
40
+ * spawn logic) are encapsulated within each engine's implementation.
41
+ */
42
+ export interface ExecutionEngine {
43
+ /** Human-readable engine identifier (e.g. 'strategy', 'factory'). */
44
+ readonly name: string;
45
+ /**
46
+ * Initialize the engine with its configuration.
47
+ *
48
+ * Responsibilities:
49
+ * - Store and validate engine-specific config
50
+ * - Initialize API clients, database connections, git state
51
+ * - Prepare internal state structures
52
+ *
53
+ * Called once before any other method. The config is a BaseConfig merged
54
+ * with engine-specific fields (e.g. DaemonConfig, FactoryConfig).
55
+ */
56
+ init(config: BaseConfig & Record<string, unknown>): Promise<void>;
57
+ /**
58
+ * Recover from a previous crash.
59
+ *
60
+ * Responsibilities:
61
+ * - Reconcile orphaned worktrees, stale sessions, stuck work items
62
+ * - Rebuild in-memory state from database and disk
63
+ * - Resolve git state inconsistencies
64
+ *
65
+ * Called after init(), before start(). Uses the config stored during init().
66
+ */
67
+ recoverFromCrash(): Promise<void>;
68
+ /**
69
+ * Start the engine's polling / listening loops.
70
+ *
71
+ * After this call the engine is actively processing work. The shell
72
+ * should not call start() more than once without an intervening stop().
73
+ */
74
+ start(): Promise<void>;
75
+ /**
76
+ * Stop accepting new work.
77
+ *
78
+ * In-progress work items continue, but no new work is picked up.
79
+ * This is the first phase of a graceful shutdown sequence.
80
+ */
81
+ stop(): void;
82
+ /**
83
+ * Graceful shutdown with full cleanup.
84
+ *
85
+ * Responsibilities:
86
+ * - Kill or wait for active child processes
87
+ * - WIP commit uncommitted changes in worktrees
88
+ * - Drain pending async updates
89
+ * - Release engine-specific resources
90
+ *
91
+ * Called after stop(). The engine should be inert after this returns.
92
+ */
93
+ shutdown(): Promise<void>;
94
+ /**
95
+ * Return a snapshot of the engine's health.
96
+ *
97
+ * Used by the process shell for status reporting (SIGUSR1, CLI status)
98
+ * and heartbeat payloads.
99
+ */
100
+ healthCheck(): EngineHealth;
101
+ /**
102
+ * Return a snapshot of the engine's resource usage.
103
+ *
104
+ * Used by the resource governor for concurrency decisions and by
105
+ * the status command for utilization reporting.
106
+ */
107
+ getResourceUsage(): ResourceUsage;
108
+ /**
109
+ * Inject a resource governor for cross-engine concurrency control.
110
+ *
111
+ * Called by the process shell after engine construction but before start().
112
+ * Engines that support concurrency limits should store the governor and
113
+ * use it to acquire/release slots when spawning work items.
114
+ *
115
+ * Optional: engines that do not need governor-based concurrency control
116
+ * may omit this method.
117
+ */
118
+ setGovernor?(gov: ResourceGovernor): void;
119
+ }
120
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAM/D,4CAA4C;AAC5C,MAAM,WAAW,YAAY;IAC3B,6BAA6B;IAC7B,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7C,6EAA6E;IAC7E,eAAe,EAAE,MAAM,CAAC;IACxB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAMD,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,qBAAqB,EAAE,MAAM,CAAC;IAC9B,6DAA6D;IAC7D,eAAe,EAAE,MAAM,CAAC;CACzB;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;OAUG;IACH,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElE;;;;;;;;;OASG;IACH,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC;;;;;OAKG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;;;OAKG;IACH,IAAI,IAAI,IAAI,CAAC;IAEb;;;;;;;;;;OAUG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B;;;;;OAKG;IACH,WAAW,IAAI,YAAY,CAAC;IAE5B;;;;;OAKG;IACH,gBAAgB,IAAI,aAAa,CAAC;IAElC;;;;;;;;;OASG;IACH,WAAW,CAAC,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC3C"}
package/dist/engine.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * ExecutionEngine interface -- the formal contract between the unified daemon
3
+ * process shell and individual execution engines (strategy, factory, etc.).
4
+ *
5
+ * The process shell manages lifecycle primitives (PID lock, signal handlers,
6
+ * config loading) and delegates engine-specific behavior through this interface.
7
+ * This allows adding future engines without modifying the shell.
8
+ *
9
+ * Lifecycle sequence (called by the process shell):
10
+ * 1. engine.init(config) -- store config, validate, connect
11
+ * 2. engine.recoverFromCrash() -- reconcile orphaned state (uses stored config)
12
+ * 3. engine.start() -- begin polling / listening loops
13
+ * ... running ...
14
+ * 4. engine.stop() -- stop accepting new work
15
+ * 5. engine.shutdown() -- graceful cleanup (kill processes, WIP commit, drain)
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Shared escalation reason types for daemon and factory engines.
3
+ *
4
+ * The `reason_type` column in agent_escalations uses these values to
5
+ * classify what kind of help the agent needs from a human.
6
+ *
7
+ * Both engines should import from here to stay in sync with the DB enum.
8
+ */
9
+ /**
10
+ * Union of valid escalation reason types.
11
+ *
12
+ * These correspond to the values accepted by the agent_escalations table
13
+ * and the Telora API escalation endpoints.
14
+ */
15
+ export type EscalationReasonType = 'decision_needed' | 'error_encountered' | 'out_of_scope' | 'blocked_by_external' | 'needs_clarification' | 'security_concern';
16
+ /**
17
+ * Const object of all valid escalation reason types.
18
+ *
19
+ * Usage:
20
+ * import { ESCALATION_REASONS } from '@telora/daemon-core';
21
+ * createEscalation({ reasonType: ESCALATION_REASONS.ERROR_ENCOUNTERED, ... });
22
+ */
23
+ export declare const ESCALATION_REASONS: {
24
+ DECISION_NEEDED: "decision_needed";
25
+ ERROR_ENCOUNTERED: "error_encountered";
26
+ OUT_OF_SCOPE: "out_of_scope";
27
+ BLOCKED_BY_EXTERNAL: "blocked_by_external";
28
+ NEEDS_CLARIFICATION: "needs_clarification";
29
+ SECURITY_CONCERN: "security_concern";
30
+ };
31
+ //# sourceMappingURL=escalation-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escalation-types.d.ts","sourceRoot":"","sources":["../src/escalation-types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAC5B,iBAAiB,GACjB,mBAAmB,GACnB,cAAc,GACd,qBAAqB,GACrB,qBAAqB,GACrB,kBAAkB,CAAC;AAEvB;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB;;;;;;;CAOiB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Shared escalation reason types for daemon and factory engines.
3
+ *
4
+ * The `reason_type` column in agent_escalations uses these values to
5
+ * classify what kind of help the agent needs from a human.
6
+ *
7
+ * Both engines should import from here to stay in sync with the DB enum.
8
+ */
9
+ /**
10
+ * Const object of all valid escalation reason types.
11
+ *
12
+ * Usage:
13
+ * import { ESCALATION_REASONS } from '@telora/daemon-core';
14
+ * createEscalation({ reasonType: ESCALATION_REASONS.ERROR_ENCOUNTERED, ... });
15
+ */
16
+ export const ESCALATION_REASONS = {
17
+ DECISION_NEEDED: 'decision_needed',
18
+ ERROR_ENCOUNTERED: 'error_encountered',
19
+ OUT_OF_SCOPE: 'out_of_scope',
20
+ BLOCKED_BY_EXTERNAL: 'blocked_by_external',
21
+ NEEDS_CLARIFICATION: 'needs_clarification',
22
+ SECURITY_CONCERN: 'security_concern',
23
+ };
24
+ //# sourceMappingURL=escalation-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escalation-types.js","sourceRoot":"","sources":["../src/escalation-types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAoBH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,eAAe,EAAE,iBAA0B;IAC3C,iBAAiB,EAAE,mBAA4B;IAC/C,YAAY,EAAE,cAAuB;IACrC,mBAAmB,EAAE,qBAA8B;IACnD,mBAAmB,EAAE,qBAA8B;IACnD,gBAAgB,EAAE,kBAA2B;CACC,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Event logger - formats stream-json events for human-readable log output.
3
+ *
4
+ * Converts structured NDJSON events from Claude Code's stream-json output
5
+ * into concise log lines for the agent's stdout log file.
6
+ */
7
+ import type { OutputEvent } from './stream-json.js';
8
+ /**
9
+ * Format a stream-json event as a human-readable log line.
10
+ * Returns null for events that don't need logging.
11
+ */
12
+ export declare function formatEventForLog(event: OutputEvent): string | null;
13
+ //# sourceMappingURL=event-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-logger.d.ts","sourceRoot":"","sources":["../src/event-logger.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,WAAW,EAUZ,MAAM,kBAAkB,CAAC;AAE1B;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CA2EnE"}