@stoneforge/smithy 1.1.0 → 1.4.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.
Files changed (179) hide show
  1. package/README.md +109 -18
  2. package/dist/cli/commands/agent.js +10 -10
  3. package/dist/cli/commands/agent.js.map +1 -1
  4. package/dist/cli/commands/pool.d.ts.map +1 -1
  5. package/dist/cli/commands/pool.js +33 -16
  6. package/dist/cli/commands/pool.js.map +1 -1
  7. package/dist/cli/commands/serve.d.ts +4 -16
  8. package/dist/cli/commands/serve.d.ts.map +1 -1
  9. package/dist/cli/commands/serve.js +0 -1
  10. package/dist/cli/commands/serve.js.map +1 -1
  11. package/dist/index.d.ts +2 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +2 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/prompts/director.md +2 -2
  16. package/dist/prompts/index.d.ts.map +1 -1
  17. package/dist/prompts/index.js +6 -3
  18. package/dist/prompts/index.js.map +1 -1
  19. package/dist/prompts/persistent-worker.md +1 -1
  20. package/dist/prompts/steward-base.md +4 -4
  21. package/dist/prompts/steward-recovery.md +113 -0
  22. package/dist/prompts/worker.md +12 -1
  23. package/dist/providers/claude/headless.d.ts +2 -0
  24. package/dist/providers/claude/headless.d.ts.map +1 -1
  25. package/dist/providers/claude/headless.js +8 -0
  26. package/dist/providers/claude/headless.js.map +1 -1
  27. package/dist/providers/claude/index.js +1 -1
  28. package/dist/providers/claude/index.js.map +1 -1
  29. package/dist/runtime/session-manager.d.ts +22 -2
  30. package/dist/runtime/session-manager.d.ts.map +1 -1
  31. package/dist/runtime/session-manager.js +74 -16
  32. package/dist/runtime/session-manager.js.map +1 -1
  33. package/dist/runtime/spawner.d.ts.map +1 -1
  34. package/dist/runtime/spawner.js +10 -0
  35. package/dist/runtime/spawner.js.map +1 -1
  36. package/dist/server/config.d.ts.map +1 -1
  37. package/dist/server/config.js +3 -1
  38. package/dist/server/config.js.map +1 -1
  39. package/dist/server/daemon-state.d.ts.map +1 -1
  40. package/dist/server/daemon-state.js +5 -3
  41. package/dist/server/daemon-state.js.map +1 -1
  42. package/dist/server/events-websocket.d.ts.map +1 -1
  43. package/dist/server/events-websocket.js +7 -5
  44. package/dist/server/events-websocket.js.map +1 -1
  45. package/dist/server/formatters.d.ts +16 -2
  46. package/dist/server/formatters.d.ts.map +1 -1
  47. package/dist/server/formatters.js +23 -2
  48. package/dist/server/formatters.js.map +1 -1
  49. package/dist/server/index.d.ts.map +1 -1
  50. package/dist/server/index.js +16 -12
  51. package/dist/server/index.js.map +1 -1
  52. package/dist/server/lsp-websocket.d.ts.map +1 -1
  53. package/dist/server/lsp-websocket.js +10 -8
  54. package/dist/server/lsp-websocket.js.map +1 -1
  55. package/dist/server/routes/agents.d.ts.map +1 -1
  56. package/dist/server/routes/agents.js +81 -15
  57. package/dist/server/routes/agents.js.map +1 -1
  58. package/dist/server/routes/daemon.d.ts.map +1 -1
  59. package/dist/server/routes/daemon.js +6 -4
  60. package/dist/server/routes/daemon.js.map +1 -1
  61. package/dist/server/routes/events.d.ts.map +1 -1
  62. package/dist/server/routes/events.js +4 -2
  63. package/dist/server/routes/events.js.map +1 -1
  64. package/dist/server/routes/extensions.d.ts.map +1 -1
  65. package/dist/server/routes/extensions.js +9 -7
  66. package/dist/server/routes/extensions.js.map +1 -1
  67. package/dist/server/routes/index.d.ts +1 -0
  68. package/dist/server/routes/index.d.ts.map +1 -1
  69. package/dist/server/routes/index.js +1 -0
  70. package/dist/server/routes/index.js.map +1 -1
  71. package/dist/server/routes/plugins.d.ts.map +1 -1
  72. package/dist/server/routes/plugins.js +6 -4
  73. package/dist/server/routes/plugins.js.map +1 -1
  74. package/dist/server/routes/pools.d.ts.map +1 -1
  75. package/dist/server/routes/pools.js +26 -7
  76. package/dist/server/routes/pools.js.map +1 -1
  77. package/dist/server/routes/scheduler.d.ts.map +1 -1
  78. package/dist/server/routes/scheduler.js +9 -7
  79. package/dist/server/routes/scheduler.js.map +1 -1
  80. package/dist/server/routes/sessions.d.ts.map +1 -1
  81. package/dist/server/routes/sessions.js +17 -15
  82. package/dist/server/routes/sessions.js.map +1 -1
  83. package/dist/server/routes/settings.d.ts +10 -0
  84. package/dist/server/routes/settings.d.ts.map +1 -0
  85. package/dist/server/routes/settings.js +65 -0
  86. package/dist/server/routes/settings.js.map +1 -0
  87. package/dist/server/routes/tasks.d.ts.map +1 -1
  88. package/dist/server/routes/tasks.js +54 -31
  89. package/dist/server/routes/tasks.js.map +1 -1
  90. package/dist/server/routes/upload.d.ts.map +1 -1
  91. package/dist/server/routes/upload.js +3 -1
  92. package/dist/server/routes/upload.js.map +1 -1
  93. package/dist/server/routes/workflows.d.ts.map +1 -1
  94. package/dist/server/routes/workflows.js +17 -15
  95. package/dist/server/routes/workflows.js.map +1 -1
  96. package/dist/server/routes/workspace-files.d.ts.map +1 -1
  97. package/dist/server/routes/workspace-files.js +11 -9
  98. package/dist/server/routes/workspace-files.js.map +1 -1
  99. package/dist/server/routes/worktrees.d.ts.map +1 -1
  100. package/dist/server/routes/worktrees.js +6 -4
  101. package/dist/server/routes/worktrees.js.map +1 -1
  102. package/dist/server/server.d.ts.map +1 -1
  103. package/dist/server/server.js +10 -8
  104. package/dist/server/server.js.map +1 -1
  105. package/dist/server/services/lsp-manager.d.ts.map +1 -1
  106. package/dist/server/services/lsp-manager.js +15 -13
  107. package/dist/server/services/lsp-manager.js.map +1 -1
  108. package/dist/server/services.d.ts +2 -2
  109. package/dist/server/services.d.ts.map +1 -1
  110. package/dist/server/services.js +41 -13
  111. package/dist/server/services.js.map +1 -1
  112. package/dist/server/static.d.ts.map +1 -1
  113. package/dist/server/static.js +3 -1
  114. package/dist/server/static.js.map +1 -1
  115. package/dist/server/websocket.d.ts.map +1 -1
  116. package/dist/server/websocket.js +6 -4
  117. package/dist/server/websocket.js.map +1 -1
  118. package/dist/services/agent-pool-service.d.ts.map +1 -1
  119. package/dist/services/agent-pool-service.js +7 -8
  120. package/dist/services/agent-pool-service.js.map +1 -1
  121. package/dist/services/agent-registry.d.ts +8 -1
  122. package/dist/services/agent-registry.d.ts.map +1 -1
  123. package/dist/services/agent-registry.js +27 -4
  124. package/dist/services/agent-registry.js.map +1 -1
  125. package/dist/services/dispatch-daemon.d.ts +64 -2
  126. package/dist/services/dispatch-daemon.d.ts.map +1 -1
  127. package/dist/services/dispatch-daemon.js +387 -59
  128. package/dist/services/dispatch-daemon.js.map +1 -1
  129. package/dist/services/index.d.ts +1 -2
  130. package/dist/services/index.d.ts.map +1 -1
  131. package/dist/services/index.js +6 -11
  132. package/dist/services/index.js.map +1 -1
  133. package/dist/services/merge-steward-service.d.ts.map +1 -1
  134. package/dist/services/merge-steward-service.js +6 -4
  135. package/dist/services/merge-steward-service.js.map +1 -1
  136. package/dist/services/settings-service.d.ts +56 -0
  137. package/dist/services/settings-service.d.ts.map +1 -0
  138. package/dist/services/settings-service.js +92 -0
  139. package/dist/services/settings-service.js.map +1 -0
  140. package/dist/services/steward-scheduler.d.ts +37 -5
  141. package/dist/services/steward-scheduler.d.ts.map +1 -1
  142. package/dist/services/steward-scheduler.js +224 -41
  143. package/dist/services/steward-scheduler.js.map +1 -1
  144. package/dist/services/task-assignment-service.d.ts.map +1 -1
  145. package/dist/services/task-assignment-service.js +3 -0
  146. package/dist/services/task-assignment-service.js.map +1 -1
  147. package/dist/testing/test-context.d.ts +1 -1
  148. package/dist/testing/test-context.d.ts.map +1 -1
  149. package/dist/types/agent-pool.d.ts +4 -0
  150. package/dist/types/agent-pool.d.ts.map +1 -1
  151. package/dist/types/agent-pool.js +8 -1
  152. package/dist/types/agent-pool.js.map +1 -1
  153. package/dist/types/agent.d.ts +37 -7
  154. package/dist/types/agent.d.ts.map +1 -1
  155. package/dist/types/agent.js +2 -2
  156. package/dist/types/agent.js.map +1 -1
  157. package/dist/types/role-definition.d.ts +1 -1
  158. package/dist/types/role-definition.js +1 -1
  159. package/dist/types/role-definition.js.map +1 -1
  160. package/dist/types/task-meta.d.ts +6 -0
  161. package/dist/types/task-meta.d.ts.map +1 -1
  162. package/dist/types/task-meta.js.map +1 -1
  163. package/dist/utils/logger.d.ts +66 -0
  164. package/dist/utils/logger.d.ts.map +1 -0
  165. package/dist/utils/logger.js +133 -0
  166. package/dist/utils/logger.js.map +1 -0
  167. package/package.json +7 -7
  168. package/web/assets/{index-R1cylSgw.js → index-8dBly5AJ.js} +697 -437
  169. package/web/assets/index-CNcjZKzg.css +32 -0
  170. package/web/assets/{utils-vendor-DaJ2Dubl.js → utils-vendor-B7jOGaxP.js} +1 -1
  171. package/web/index.html +3 -3
  172. package/dist/prompts/steward-health.md +0 -39
  173. package/dist/prompts/steward-ops.md +0 -28
  174. package/dist/prompts/steward-reminder.md +0 -26
  175. package/dist/services/health-steward-service.d.ts +0 -446
  176. package/dist/services/health-steward-service.d.ts.map +0 -1
  177. package/dist/services/health-steward-service.js +0 -866
  178. package/dist/services/health-steward-service.js.map +0 -1
  179. package/web/assets/index-DqP-_E4F.css +0 -32
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Settings Service
3
+ *
4
+ * Server-side key-value settings persisted to SQLite.
5
+ * Used for workspace-wide configuration that needs to be accessible server-side,
6
+ * such as default executable paths for agent providers.
7
+ *
8
+ * Settings are stored in the `settings` table as JSON-encoded values.
9
+ */
10
+ import { createLogger } from '../utils/logger.js';
11
+ const logger = createLogger('settings-service');
12
+ /**
13
+ * Well-known setting keys
14
+ */
15
+ export const SETTING_KEYS = {
16
+ AGENT_DEFAULTS: 'agentDefaults',
17
+ };
18
+ // ============================================================================
19
+ // Implementation
20
+ // ============================================================================
21
+ function dbToSetting(row) {
22
+ let parsedValue;
23
+ try {
24
+ parsedValue = JSON.parse(row.value);
25
+ }
26
+ catch {
27
+ parsedValue = row.value;
28
+ }
29
+ return {
30
+ key: row.key,
31
+ value: parsedValue,
32
+ updatedAt: row.updated_at,
33
+ };
34
+ }
35
+ const DEFAULT_AGENT_DEFAULTS = {
36
+ defaultExecutablePaths: {},
37
+ };
38
+ export function createSettingsService(storage) {
39
+ return {
40
+ getSetting(key) {
41
+ const row = storage.queryOne('SELECT key, value, updated_at FROM settings WHERE key = ?', [key]);
42
+ if (!row)
43
+ return undefined;
44
+ return dbToSetting(row);
45
+ },
46
+ setSetting(key, value) {
47
+ const jsonValue = JSON.stringify(value);
48
+ const updatedAt = new Date().toISOString();
49
+ storage.run('INSERT INTO settings (key, value, updated_at) VALUES (?, ?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at', [key, jsonValue, updatedAt]);
50
+ logger.debug(`Setting updated: ${key}`);
51
+ return {
52
+ key,
53
+ value,
54
+ updatedAt,
55
+ };
56
+ },
57
+ deleteSetting(key) {
58
+ const result = storage.run('DELETE FROM settings WHERE key = ?', [key]);
59
+ return result.changes > 0;
60
+ },
61
+ getAgentDefaults() {
62
+ const setting = this.getSetting(SETTING_KEYS.AGENT_DEFAULTS);
63
+ if (!setting) {
64
+ return { ...DEFAULT_AGENT_DEFAULTS };
65
+ }
66
+ // Validate shape — ensure defaultExecutablePaths exists and is an object
67
+ const value = setting.value;
68
+ const paths = value?.defaultExecutablePaths;
69
+ return {
70
+ defaultExecutablePaths: paths && typeof paths === 'object' && !Array.isArray(paths)
71
+ ? paths
72
+ : {},
73
+ };
74
+ },
75
+ setAgentDefaults(defaults) {
76
+ // Validate that defaultExecutablePaths is a plain object of strings
77
+ const paths = defaults.defaultExecutablePaths ?? {};
78
+ const sanitized = {};
79
+ for (const [provider, path] of Object.entries(paths)) {
80
+ if (typeof path === 'string') {
81
+ sanitized[provider] = path;
82
+ }
83
+ }
84
+ const validated = {
85
+ defaultExecutablePaths: sanitized,
86
+ };
87
+ this.setSetting(SETTING_KEYS.AGENT_DEFAULTS, validated);
88
+ return validated;
89
+ },
90
+ };
91
+ }
92
+ //# sourceMappingURL=settings-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-service.js","sourceRoot":"","sources":["../../src/services/settings-service.ts"],"names":[],"mappings":"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"}
@@ -16,9 +16,9 @@
16
16
  */
17
17
  import type { EntityId, Timestamp } from '@stoneforge/core';
18
18
  import type { StewardTrigger, CronTrigger, EventTrigger } from '../types/index.js';
19
+ import type { SessionManager } from '../runtime/session-manager.js';
19
20
  import type { AgentRegistry, AgentEntity } from './agent-registry.js';
20
21
  import type { MergeStewardService } from './merge-steward-service.js';
21
- import type { HealthStewardService } from './health-steward-service.js';
22
22
  import type { DocsStewardService } from './docs-steward-service.js';
23
23
  /**
24
24
  * Result of a steward execution
@@ -326,22 +326,54 @@ export declare class StewardSchedulerImpl implements StewardScheduler {
326
326
  * @param config - Optional configuration
327
327
  */
328
328
  export declare function createStewardScheduler(agentRegistry: AgentRegistry, executor: StewardExecutor, config?: StewardSchedulerConfig): StewardScheduler;
329
+ /**
330
+ * Default idle timeout for steward sessions in milliseconds (2 minutes).
331
+ * If a steward session receives no events for this duration, it is
332
+ * assumed to be stuck and will be force-terminated.
333
+ */
334
+ export declare const STEWARD_SESSION_DEFAULT_IDLE_TIMEOUT_MS = 120000;
335
+ /**
336
+ * Default maximum duration for steward sessions in milliseconds (30 minutes).
337
+ * Steward sessions exceeding this duration are force-terminated regardless
338
+ * of activity, as a safety net.
339
+ */
340
+ export declare const STEWARD_SESSION_DEFAULT_MAX_DURATION_MS: number;
329
341
  /**
330
342
  * Dependencies required by the real steward executor.
331
343
  */
332
344
  export interface StewardExecutorDeps {
333
345
  mergeStewardService: MergeStewardService;
334
- healthStewardService: HealthStewardService;
335
346
  docsStewardService: DocsStewardService;
347
+ sessionManager: SessionManager;
348
+ projectRoot: string;
349
+ /**
350
+ * Optional callback to resolve a playbook (workflow template) by ID.
351
+ * Returns the playbook content as a markdown string for the steward prompt,
352
+ * or undefined if not found. Used when a custom steward has `playbookId` set.
353
+ */
354
+ resolvePlaybookContent?: (playbookId: string) => Promise<string | undefined>;
355
+ /**
356
+ * Idle timeout in ms for spawned steward sessions (docs, custom).
357
+ * If no session events are received within this window, the session
358
+ * is force-terminated. Default: 120000 (2 minutes).
359
+ */
360
+ stewardSessionIdleTimeoutMs?: number;
361
+ /**
362
+ * Maximum duration in ms for spawned steward sessions (docs, custom).
363
+ * Sessions exceeding this duration are force-terminated regardless of
364
+ * activity. Default: 1800000 (30 minutes).
365
+ */
366
+ stewardSessionMaxDurationMs?: number;
336
367
  }
337
368
  /**
338
369
  * Creates a steward executor that dispatches to the appropriate service
339
370
  * based on the steward's focus.
340
371
  *
341
372
  * - 'merge' focus → MergeStewardService.processAllPending()
342
- * - 'health' focus HealthStewardService.runHealthCheck()
343
- * - 'docs' focus → DocsStewardService.scanAll()
344
- * - 'reminder' / 'ops' no-op (require agent sessions)
373
+ * - 'docs' → spawns an agent session via sessionManager
374
+ *
375
+ * Session-based stewards check for an existing active session before spawning
376
+ * to prevent overlapping runs across cron ticks.
345
377
  *
346
378
  * Each case is wrapped in try/catch so one failing steward doesn't crash
347
379
  * the scheduler.
@@ -1 +1 @@
1
- {"version":3,"file":"steward-scheduler.d.ts","sourceRoot":"","sources":["../../src/services/steward-scheduler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"steward-scheduler.d.ts","sourceRoot":"","sources":["../../src/services/steward-scheduler.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,10 @@
17
17
  import { EventEmitter } from 'node:events';
18
18
  import { createTimestamp } from '@stoneforge/core';
19
19
  import { isCronTrigger, isEventTrigger, } from '../types/index.js';
20
+ import { loadRolePrompt } from '../prompts/index.js';
20
21
  import { getAgentMetadata } from './agent-registry.js';
22
+ import { createLogger } from '../utils/logger.js';
23
+ const logger = createLogger('steward-scheduler');
21
24
  // ============================================================================
22
25
  // Cron Schedule Utilities
23
26
  // ============================================================================
@@ -172,6 +175,7 @@ export class StewardSchedulerImpl {
172
175
  if (this.config.startImmediately) {
173
176
  await this.registerAllStewards();
174
177
  }
178
+ logger.info(`Started with ${this.cronJobs.size} cron job(s) and ${[...this.eventSubscriptions.values()].flat().length} event subscription(s)`);
175
179
  }
176
180
  async stop() {
177
181
  if (!this.running) {
@@ -238,6 +242,9 @@ export class StewardSchedulerImpl {
238
242
  });
239
243
  }
240
244
  }
245
+ const cronCount = triggers.filter(t => isCronTrigger(t)).length;
246
+ const eventCount = triggers.filter(t => isEventTrigger(t)).length;
247
+ logger.info(`Registered steward '${agent.name}' (${stewardId}) with ${cronCount} cron trigger(s) and ${eventCount} event trigger(s)`);
241
248
  this.emitter.emit('steward:registered', stewardId);
242
249
  return true;
243
250
  }
@@ -282,6 +289,7 @@ export class StewardSchedulerImpl {
282
289
  registered++;
283
290
  }
284
291
  }
292
+ logger.info(`Registered ${registered}/${stewards.length} steward(s)`);
285
293
  return registered;
286
294
  }
287
295
  // ----------------------------------------
@@ -335,8 +343,8 @@ export class StewardSchedulerImpl {
335
343
  const agent = await this.agentRegistry.getAgent(sub.stewardId);
336
344
  if (agent) {
337
345
  // Run execution asynchronously
338
- this.runExecution(agent, sub.trigger, false, eventData).catch(() => {
339
- // Errors are handled in runExecution
346
+ this.runExecution(agent, sub.trigger, false, eventData).catch((error) => {
347
+ logger.error(`Event-triggered execution failed for steward '${sub.stewardName}':`, error);
340
348
  });
341
349
  triggered++;
342
350
  }
@@ -449,27 +457,40 @@ export class StewardSchedulerImpl {
449
457
  }
450
458
  scheduleNextRun(job) {
451
459
  const nextTime = this.getNextCronTime(job.trigger.schedule);
452
- if (!nextTime)
460
+ if (!nextTime) {
461
+ logger.warn(`Failed to compute next run time for steward '${job.stewardName}' with schedule '${job.trigger.schedule}'`);
453
462
  return;
463
+ }
454
464
  job.nextRunAt = nextTime;
455
465
  const delayMs = Math.max(0, nextTime.getTime() - Date.now());
466
+ logger.debug(`Scheduled next run for steward '${job.stewardName}' at ${nextTime.toISOString()} (in ${Math.round(delayMs / 1000)}s)`);
456
467
  job.intervalId = setTimeout(async () => {
457
- if (!this.running)
458
- return;
459
- if (job.isRunning) {
460
- // Skip this run but schedule the next one
461
- job.intervalId = undefined;
462
- this.scheduleNextRun(job);
463
- return;
464
- }
465
- const agent = await this.agentRegistry.getAgent(job.stewardId);
466
- if (agent && this.running) {
467
- await this.runExecution(agent, job.trigger, false);
468
- job.lastRunAt = createTimestamp();
469
- }
470
- if (this.running) {
471
- job.intervalId = undefined;
472
- this.scheduleNextRun(job);
468
+ try {
469
+ if (!this.running)
470
+ return;
471
+ if (job.isRunning) {
472
+ logger.warn(`Skipping overlapping execution for steward '${job.stewardName}'`);
473
+ return; // finally block will schedule the next run
474
+ }
475
+ logger.debug(`Cron firing for steward '${job.stewardName}' (schedule: ${job.trigger.schedule})`);
476
+ const agent = await this.agentRegistry.getAgent(job.stewardId);
477
+ if (!agent) {
478
+ logger.warn(`Agent not found for steward '${job.stewardId}', skipping cron execution`);
479
+ }
480
+ if (agent && this.running) {
481
+ const result = await this.runExecution(agent, job.trigger, false);
482
+ job.lastRunAt = createTimestamp();
483
+ logger.info(`Cron execution completed for steward '${job.stewardName}': success=${result.success}${result.error ? `, error=${result.error}` : ''}`);
484
+ }
485
+ }
486
+ catch (error) {
487
+ logger.error(`Unhandled error in cron callback for steward '${job.stewardName}':`, error);
488
+ }
489
+ finally {
490
+ if (this.running) {
491
+ job.intervalId = undefined;
492
+ this.scheduleNextRun(job);
493
+ }
473
494
  }
474
495
  }, delayMs);
475
496
  }
@@ -704,14 +725,112 @@ export class StewardSchedulerImpl {
704
725
  export function createStewardScheduler(agentRegistry, executor, config) {
705
726
  return new StewardSchedulerImpl(agentRegistry, executor, config);
706
727
  }
728
+ // ============================================================================
729
+ // Steward Executor Factory
730
+ // ============================================================================
731
+ /**
732
+ * Default idle timeout for steward sessions in milliseconds (2 minutes).
733
+ * If a steward session receives no events for this duration, it is
734
+ * assumed to be stuck and will be force-terminated.
735
+ */
736
+ export const STEWARD_SESSION_DEFAULT_IDLE_TIMEOUT_MS = 120_000;
737
+ /**
738
+ * Default maximum duration for steward sessions in milliseconds (30 minutes).
739
+ * Steward sessions exceeding this duration are force-terminated regardless
740
+ * of activity, as a safety net.
741
+ */
742
+ export const STEWARD_SESSION_DEFAULT_MAX_DURATION_MS = 30 * 60 * 1000;
743
+ /**
744
+ * Sets up idle timeout and max duration monitoring for a spawned steward session.
745
+ * Watches for session activity via the session manager's event emitter and
746
+ * force-terminates the session if it goes idle or exceeds the max duration.
747
+ *
748
+ * @param sessionId - The session ID to monitor
749
+ * @param sessionEvents - The session's event emitter (from startSession)
750
+ * @param deps - Steward executor dependencies (for session manager and config)
751
+ * @param stewardName - Name of the steward (for logging)
752
+ */
753
+ function monitorStewardSession(sessionId, sessionEvents, deps, stewardName) {
754
+ const idleTimeoutMs = deps.stewardSessionIdleTimeoutMs ?? STEWARD_SESSION_DEFAULT_IDLE_TIMEOUT_MS;
755
+ const maxDurationMs = deps.stewardSessionMaxDurationMs ?? STEWARD_SESSION_DEFAULT_MAX_DURATION_MS;
756
+ const startTime = Date.now();
757
+ let lastActivityAt = Date.now();
758
+ let cleanedUp = false;
759
+ // Update last activity on any session event
760
+ const onEvent = () => {
761
+ lastActivityAt = Date.now();
762
+ };
763
+ // Clean up watchers
764
+ const cleanup = () => {
765
+ if (cleanedUp)
766
+ return;
767
+ cleanedUp = true;
768
+ clearInterval(checkInterval);
769
+ sessionEvents.removeListener('event', onEvent);
770
+ sessionEvents.removeListener('exit', onExit);
771
+ sessionEvents.removeListener('status', onStatus);
772
+ };
773
+ // Session exited naturally — clean up watchers
774
+ const onExit = () => {
775
+ cleanup();
776
+ };
777
+ // Session status changed to terminated — clean up watchers
778
+ const onStatus = (status) => {
779
+ if (status === 'terminated') {
780
+ cleanup();
781
+ }
782
+ };
783
+ sessionEvents.on('event', onEvent);
784
+ sessionEvents.on('exit', onExit);
785
+ sessionEvents.on('status', onStatus);
786
+ // Periodically check idle time and max duration
787
+ const checkIntervalMs = Math.min(idleTimeoutMs / 2, 30_000);
788
+ const checkInterval = setInterval(() => {
789
+ const now = Date.now();
790
+ const idleMs = now - lastActivityAt;
791
+ const totalMs = now - startTime;
792
+ if (idleMs > idleTimeoutMs) {
793
+ logger.warn(`Steward '${stewardName}' session ${sessionId} idle for ${Math.round(idleMs / 1000)}s (timeout: ${Math.round(idleTimeoutMs / 1000)}s), force-terminating`);
794
+ cleanup();
795
+ deps.sessionManager.stopSession(sessionId, {
796
+ graceful: false,
797
+ reason: `Steward session idle for ${Math.round(idleMs / 1000)}s (timeout: ${Math.round(idleTimeoutMs / 1000)}s)`,
798
+ }).catch((err) => {
799
+ const msg = err instanceof Error ? err.message : String(err);
800
+ if (!msg.includes('not found')) {
801
+ logger.warn(`Failed to stop idle steward session ${sessionId}:`, err);
802
+ }
803
+ });
804
+ return;
805
+ }
806
+ if (totalMs > maxDurationMs) {
807
+ logger.warn(`Steward '${stewardName}' session ${sessionId} exceeded max duration ${Math.round(maxDurationMs / 1000)}s, force-terminating`);
808
+ cleanup();
809
+ deps.sessionManager.stopSession(sessionId, {
810
+ graceful: false,
811
+ reason: `Steward session exceeded max duration (${Math.round(totalMs / 1000)}s)`,
812
+ }).catch((err) => {
813
+ const msg = err instanceof Error ? err.message : String(err);
814
+ if (!msg.includes('not found')) {
815
+ logger.warn(`Failed to stop over-duration steward session ${sessionId}:`, err);
816
+ }
817
+ });
818
+ }
819
+ }, checkIntervalMs);
820
+ // Prevent the interval from keeping the process alive
821
+ if (checkInterval.unref) {
822
+ checkInterval.unref();
823
+ }
824
+ }
707
825
  /**
708
826
  * Creates a steward executor that dispatches to the appropriate service
709
827
  * based on the steward's focus.
710
828
  *
711
829
  * - 'merge' focus → MergeStewardService.processAllPending()
712
- * - 'health' focus HealthStewardService.runHealthCheck()
713
- * - 'docs' focus → DocsStewardService.scanAll()
714
- * - 'reminder' / 'ops' no-op (require agent sessions)
830
+ * - 'docs' → spawns an agent session via sessionManager
831
+ *
832
+ * Session-based stewards check for an existing active session before spawning
833
+ * to prevent overlapping runs across cron ticks.
715
834
  *
716
835
  * Each case is wrapped in try/catch so one failing steward doesn't crash
717
836
  * the scheduler.
@@ -742,55 +861,119 @@ export function createStewardExecutor(deps) {
742
861
  };
743
862
  }
744
863
  }
745
- case 'health': {
864
+ case 'docs': {
746
865
  try {
747
- const result = await deps.healthStewardService.runHealthCheck();
866
+ const stewardId = steward.id;
867
+ const activeSession = deps.sessionManager.getActiveSession(stewardId);
868
+ if (activeSession) {
869
+ return {
870
+ success: true,
871
+ output: `Steward '${steward.name}' already has active session ${activeSession.id}, skipping`,
872
+ durationMs: Date.now() - startTime,
873
+ itemsProcessed: 0,
874
+ };
875
+ }
876
+ const roleResult = loadRolePrompt('steward', focus, {
877
+ projectRoot: deps.projectRoot,
878
+ });
879
+ const initialPrompt = roleResult?.prompt ?? '';
880
+ const { session, events } = await deps.sessionManager.startSession(stewardId, {
881
+ workingDirectory: deps.projectRoot,
882
+ initialPrompt,
883
+ interactive: false,
884
+ });
885
+ // Monitor session for idle timeout and max duration
886
+ monitorStewardSession(session.id, events, deps, steward.name);
748
887
  return {
749
888
  success: true,
750
- output: `Checked ${result.agentsChecked} agents, ${result.newIssues.length} new issues, ${result.actionsTaken.length} actions taken`,
889
+ output: `Spawned ${focus} steward session ${session.id}`,
751
890
  durationMs: Date.now() - startTime,
752
- itemsProcessed: result.agentsChecked,
891
+ itemsProcessed: 1,
753
892
  };
754
893
  }
755
894
  catch (error) {
756
895
  return {
757
896
  success: false,
758
897
  error: error instanceof Error ? error.message : String(error),
759
- output: `Health steward '${steward.name}' failed: ${error instanceof Error ? error.message : String(error)}`,
898
+ output: `${focus} steward '${steward.name}' failed: ${error instanceof Error ? error.message : String(error)}`,
760
899
  durationMs: Date.now() - startTime,
761
900
  itemsProcessed: 0,
762
901
  };
763
902
  }
764
903
  }
765
- case 'docs': {
904
+ case 'custom': {
766
905
  try {
767
- const result = await deps.docsStewardService.scanAll();
906
+ const stewardId = steward.id;
907
+ const activeSession = deps.sessionManager.getActiveSession(stewardId);
908
+ if (activeSession) {
909
+ return {
910
+ success: true,
911
+ output: `Steward '${steward.name}' already has active session ${activeSession.id}, skipping`,
912
+ durationMs: Date.now() - startTime,
913
+ itemsProcessed: 0,
914
+ };
915
+ }
916
+ // Build prompt from steward base + custom playbook
917
+ // Resolve playbook content: prefer playbookId (template reference), fall back to inline playbook
918
+ let playbook;
919
+ if (metadata?.playbookId && deps.resolvePlaybookContent) {
920
+ try {
921
+ playbook = await deps.resolvePlaybookContent(metadata.playbookId);
922
+ if (!playbook) {
923
+ logger.warn(`Custom steward '${steward.name}': playbook template ${metadata.playbookId} not found, falling back to inline playbook`);
924
+ playbook = metadata?.playbook;
925
+ }
926
+ }
927
+ catch (err) {
928
+ logger.warn(`Custom steward '${steward.name}': failed to resolve playbook template ${metadata.playbookId}: ${err}, falling back to inline playbook`);
929
+ playbook = metadata?.playbook;
930
+ }
931
+ }
932
+ else {
933
+ playbook = metadata?.playbook;
934
+ }
935
+ if (!playbook) {
936
+ return {
937
+ success: false,
938
+ error: 'Custom steward has no playbook configured',
939
+ output: `Custom steward '${steward.name}' has no playbook configured`,
940
+ durationMs: Date.now() - startTime,
941
+ itemsProcessed: 0,
942
+ };
943
+ }
944
+ // Load the steward base prompt for shared context
945
+ const roleResult = loadRolePrompt('steward', undefined, {
946
+ projectRoot: deps.projectRoot,
947
+ });
948
+ const basePrompt = roleResult?.prompt ?? '';
949
+ // Combine base steward prompt with the custom playbook
950
+ const initialPrompt = basePrompt
951
+ ? `${basePrompt}\n\n---\n\n## Custom Steward Playbook\n\n${playbook}`
952
+ : `## Custom Steward Playbook\n\n${playbook}`;
953
+ const { session, events } = await deps.sessionManager.startSession(stewardId, {
954
+ workingDirectory: deps.projectRoot,
955
+ initialPrompt,
956
+ interactive: false,
957
+ });
958
+ // Monitor session for idle timeout and max duration
959
+ monitorStewardSession(session.id, events, deps, steward.name);
768
960
  return {
769
961
  success: true,
770
- output: `Scanned docs: ${result.issues.length} issues found`,
962
+ output: `Spawned custom steward session ${session.id}`,
771
963
  durationMs: Date.now() - startTime,
772
- itemsProcessed: result.issues.length,
964
+ itemsProcessed: 1,
773
965
  };
774
966
  }
775
967
  catch (error) {
776
968
  return {
777
969
  success: false,
778
970
  error: error instanceof Error ? error.message : String(error),
779
- output: `Docs steward '${steward.name}' failed: ${error instanceof Error ? error.message : String(error)}`,
971
+ output: `Custom steward '${steward.name}' failed: ${error instanceof Error ? error.message : String(error)}`,
780
972
  durationMs: Date.now() - startTime,
781
973
  itemsProcessed: 0,
782
974
  };
783
975
  }
784
976
  }
785
- case 'reminder':
786
- case 'ops':
787
- // These focus types don't have dedicated services yet
788
- return {
789
- success: true,
790
- output: `Steward focus '${focus}' has no automated service — requires agent session`,
791
- durationMs: Date.now() - startTime,
792
- itemsProcessed: 0,
793
- };
794
977
  default:
795
978
  return {
796
979
  success: false,