@telora/daemon 0.17.33 → 0.17.36

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 (92) hide show
  1. package/build-info.json +4 -3
  2. package/dist/cli/connect.d.ts.map +1 -1
  3. package/dist/cli/connect.js +4 -0
  4. package/dist/cli/connect.js.map +1 -1
  5. package/dist/completion/event.d.ts.map +1 -1
  6. package/dist/completion/event.js +2 -8
  7. package/dist/completion/event.js.map +1 -1
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/config.js +70 -41
  10. package/dist/config.js.map +1 -1
  11. package/dist/daemon-process.d.ts.map +1 -1
  12. package/dist/daemon-process.js +8 -0
  13. package/dist/daemon-process.js.map +1 -1
  14. package/dist/focus-engine.d.ts.map +1 -1
  15. package/dist/focus-engine.js +8 -10
  16. package/dist/focus-engine.js.map +1 -1
  17. package/dist/merge-back-loop.d.ts.map +1 -1
  18. package/dist/merge-back-loop.js +4 -10
  19. package/dist/merge-back-loop.js.map +1 -1
  20. package/dist/review-defect-detector.d.ts +4 -1
  21. package/dist/review-defect-detector.d.ts.map +1 -1
  22. package/dist/review-defect-detector.js +6 -8
  23. package/dist/review-defect-detector.js.map +1 -1
  24. package/dist/types/index.d.ts +0 -1
  25. package/dist/types/index.d.ts.map +1 -1
  26. package/dist/types/index.js +0 -1
  27. package/dist/types/index.js.map +1 -1
  28. package/dist/unified-engine-lifecycle.d.ts.map +1 -1
  29. package/dist/unified-engine-lifecycle.js +2 -23
  30. package/dist/unified-engine-lifecycle.js.map +1 -1
  31. package/dist/unified-shell-config.d.ts +2 -7
  32. package/dist/unified-shell-config.d.ts.map +1 -1
  33. package/dist/unified-shell-config.js +2 -23
  34. package/dist/unified-shell-config.js.map +1 -1
  35. package/dist/unified-shell-status.d.ts.map +1 -1
  36. package/dist/unified-shell-status.js +2 -4
  37. package/dist/unified-shell-status.js.map +1 -1
  38. package/dist/unified-shell.d.ts.map +1 -1
  39. package/dist/unified-shell.js +0 -12
  40. package/dist/unified-shell.js.map +1 -1
  41. package/dist/version-check.d.ts.map +1 -1
  42. package/dist/version-check.js +6 -4
  43. package/dist/version-check.js.map +1 -1
  44. package/package.json +3 -3
  45. package/dist/pm/adaptive-poller.d.ts +0 -26
  46. package/dist/pm/adaptive-poller.d.ts.map +0 -1
  47. package/dist/pm/adaptive-poller.js +0 -53
  48. package/dist/pm/adaptive-poller.js.map +0 -1
  49. package/dist/pm/cascade-evaluator.d.ts +0 -29
  50. package/dist/pm/cascade-evaluator.d.ts.map +0 -1
  51. package/dist/pm/cascade-evaluator.js +0 -135
  52. package/dist/pm/cascade-evaluator.js.map +0 -1
  53. package/dist/pm/channel-email.d.ts +0 -42
  54. package/dist/pm/channel-email.d.ts.map +0 -1
  55. package/dist/pm/channel-email.js +0 -47
  56. package/dist/pm/channel-email.js.map +0 -1
  57. package/dist/pm/channel-slack.d.ts +0 -40
  58. package/dist/pm/channel-slack.d.ts.map +0 -1
  59. package/dist/pm/channel-slack.js +0 -46
  60. package/dist/pm/channel-slack.js.map +0 -1
  61. package/dist/pm/communication-drafter.d.ts +0 -44
  62. package/dist/pm/communication-drafter.d.ts.map +0 -1
  63. package/dist/pm/communication-drafter.js +0 -84
  64. package/dist/pm/communication-drafter.js.map +0 -1
  65. package/dist/pm/dialog-handler.d.ts +0 -32
  66. package/dist/pm/dialog-handler.d.ts.map +0 -1
  67. package/dist/pm/dialog-handler.js +0 -107
  68. package/dist/pm/dialog-handler.js.map +0 -1
  69. package/dist/pm/mitigation-correlator.d.ts +0 -29
  70. package/dist/pm/mitigation-correlator.d.ts.map +0 -1
  71. package/dist/pm/mitigation-correlator.js +0 -147
  72. package/dist/pm/mitigation-correlator.js.map +0 -1
  73. package/dist/pm/risk-scanner.d.ts +0 -28
  74. package/dist/pm/risk-scanner.d.ts.map +0 -1
  75. package/dist/pm/risk-scanner.js +0 -112
  76. package/dist/pm/risk-scanner.js.map +0 -1
  77. package/dist/pm-engine.d.ts +0 -96
  78. package/dist/pm-engine.d.ts.map +0 -1
  79. package/dist/pm-engine.js +0 -540
  80. package/dist/pm-engine.js.map +0 -1
  81. package/dist/pm-process.d.ts +0 -45
  82. package/dist/pm-process.d.ts.map +0 -1
  83. package/dist/pm-process.js +0 -195
  84. package/dist/pm-process.js.map +0 -1
  85. package/dist/pm-prompt-builder.d.ts +0 -23
  86. package/dist/pm-prompt-builder.d.ts.map +0 -1
  87. package/dist/pm-prompt-builder.js +0 -64
  88. package/dist/pm-prompt-builder.js.map +0 -1
  89. package/dist/types/pm.d.ts +0 -53
  90. package/dist/types/pm.d.ts.map +0 -1
  91. package/dist/types/pm.js +0 -10
  92. package/dist/types/pm.js.map +0 -1
package/dist/pm-engine.js DELETED
@@ -1,540 +0,0 @@
1
- /**
2
- * PMEngine -- ExecutionEngine adapter for the PM (Project Manager) engine.
3
- *
4
- * The PM engine now serves dual roles:
5
- * 1. Process supervision: Spawns a persistent Claude Code session per product
6
- * that runs /loop for its PM cycle (report generation, inbox, action plan).
7
- * 2. Risk monitoring: Polls risk states and dependencies (unchanged from before).
8
- *
9
- * Lifecycle (called by the process shell):
10
- * 1. init(config) -- validate config, initialize API client
11
- * 2. recoverFromCrash() -- detect orphaned PM sessions, restart
12
- * 3. start() -- spawn PM processes, begin risk poll loop
13
- * 4. stop() -- clear intervals, set shutting-down flag
14
- * 5. shutdown() -- terminate PM processes gracefully
15
- */
16
- import { DEFAULT_PM_PROCESS_CONFIG } from './types/pm.js';
17
- import { initSupabase, callApi } from './queries/shared.js';
18
- import { scanRiskDependencies } from './pm/risk-scanner.js';
19
- import { correlateMitigationProgress } from './pm/mitigation-correlator.js';
20
- import { computePollInterval, DEFAULT_POLL_CADENCE, } from './pm/adaptive-poller.js';
21
- import { draftCommunication } from './pm/communication-drafter.js';
22
- import { spawnPMProcess, terminateAllPMProcesses, terminatePMProcess, getActivePMProcesses, isPMProcessRunning, calculateRestartDelay, } from './pm-process.js';
23
- // ---------------------------------------------------------------------------
24
- // Helpers
25
- // ---------------------------------------------------------------------------
26
- /** Resolve an integer from env string > file config value > default. */
27
- function resolveEnvInt(envVal, fileVal, defaultVal) {
28
- if (envVal !== undefined && envVal !== '') {
29
- const parsed = parseInt(envVal, 10);
30
- if (!isNaN(parsed))
31
- return parsed;
32
- }
33
- if (typeof fileVal === 'number')
34
- return fileVal;
35
- return defaultVal;
36
- }
37
- /** Resolve an env var in minutes to milliseconds, with file fallback (already ms). */
38
- function resolveEnvMinutesToMs(envMinutes, fileMs, defaultMs) {
39
- if (envMinutes !== undefined && envMinutes !== '') {
40
- const parsed = parseInt(envMinutes, 10);
41
- if (!isNaN(parsed))
42
- return parsed * 60 * 1000;
43
- }
44
- if (typeof fileMs === 'number')
45
- return fileMs;
46
- return defaultMs;
47
- }
48
- // ---------------------------------------------------------------------------
49
- // PMEngine
50
- // ---------------------------------------------------------------------------
51
- export class PMEngine {
52
- name = 'pm';
53
- /** Daemon config, set during init(). */
54
- config = null;
55
- /** Resource governor for slot management. */
56
- governor = null;
57
- /** PM process-specific configuration. */
58
- pmProcessConfig = DEFAULT_PM_PROCESS_CONFIG;
59
- /** Poll cadence configuration (for risk monitoring). */
60
- pollCadence = DEFAULT_POLL_CADENCE;
61
- /** Active poll timeout handle (for adaptive interval). */
62
- pollTimeout = null;
63
- /** Session status poll interval handle. */
64
- sessionPollInterval = null;
65
- /** Pending restart timeouts (for backoff). */
66
- restartTimeouts = new Map();
67
- /** Whether the engine is shutting down. */
68
- shuttingDown = false;
69
- /** Count of active (non-resolved, non-draft) risks from last scan. */
70
- activeRiskCount = 0;
71
- /** Last poll timestamp for health reporting. */
72
- lastPollAt = null;
73
- /** Last set of risk stages seen (for adaptive polling). */
74
- lastRiskStages = [];
75
- /** Total follow-up actions from last scan. */
76
- lastFollowupActionCount = 0;
77
- /** Mitigation assessment summary from last scan. */
78
- lastMitigationSummary = {};
79
- // -----------------------------------------------------------------------
80
- // setGovernor
81
- // -----------------------------------------------------------------------
82
- setGovernor(gov) {
83
- this.governor = gov;
84
- }
85
- // -----------------------------------------------------------------------
86
- // init
87
- // -----------------------------------------------------------------------
88
- async init(config) {
89
- this.config = config;
90
- // Resolve PM process config from flat engine config + env var overrides.
91
- // Fields come from daemon.json engines.pm section, spread flat by buildEngineConfig().
92
- const flat = config;
93
- const env = process.env;
94
- this.pmProcessConfig = {
95
- loopIntervalMinutes: resolveEnvInt(env.TELORA_PM_LOOP_INTERVAL, flat.loopIntervalMinutes, DEFAULT_PM_PROCESS_CONFIG.loopIntervalMinutes),
96
- maxRestarts: resolveEnvInt(env.TELORA_PM_MAX_RESTARTS, flat.maxRestarts, DEFAULT_PM_PROCESS_CONFIG.maxRestarts),
97
- processEnabled: typeof flat.processEnabled === 'boolean'
98
- ? flat.processEnabled : DEFAULT_PM_PROCESS_CONFIG.processEnabled,
99
- maxSessionAgeMs: resolveEnvMinutesToMs(env.TELORA_PM_MAX_SESSION_AGE, flat.maxSessionAgeMs, DEFAULT_PM_PROCESS_CONFIG.maxSessionAgeMs),
100
- };
101
- // Poll cadence config (for risk monitoring)
102
- if (flat.pollCadence && typeof flat.pollCadence === 'object') {
103
- const cadence = flat.pollCadence;
104
- this.pollCadence = {
105
- activeIntervalMs: typeof cadence.activeIntervalMs === 'number'
106
- ? cadence.activeIntervalMs : DEFAULT_POLL_CADENCE.activeIntervalMs,
107
- imminentIntervalMs: typeof cadence.imminentIntervalMs === 'number'
108
- ? cadence.imminentIntervalMs : DEFAULT_POLL_CADENCE.imminentIntervalMs,
109
- trackingIntervalMs: typeof cadence.trackingIntervalMs === 'number'
110
- ? cadence.trackingIntervalMs : DEFAULT_POLL_CADENCE.trackingIntervalMs,
111
- defaultIntervalMs: typeof cadence.defaultIntervalMs === 'number'
112
- ? cadence.defaultIntervalMs : DEFAULT_POLL_CADENCE.defaultIntervalMs,
113
- };
114
- }
115
- // Initialize API client (reuse shared infrastructure -- may already be
116
- // initialized by the focus engine, but initSupabase is idempotent)
117
- initSupabase(this.config);
118
- console.log(`[PM] Engine initialized (process supervision: ${this.pmProcessConfig.processEnabled ? 'enabled' : 'disabled'}, ` +
119
- `loop: ${this.pmProcessConfig.loopIntervalMinutes}m, ` +
120
- `maxSessionAge: ${this.pmProcessConfig.maxSessionAgeMs > 0 ? `${Math.round(this.pmProcessConfig.maxSessionAgeMs / 60_000)}m` : 'disabled'})`);
121
- }
122
- // -----------------------------------------------------------------------
123
- // recoverFromCrash
124
- // -----------------------------------------------------------------------
125
- async recoverFromCrash() {
126
- if (!this.pmProcessConfig.processEnabled) {
127
- console.log('[PM] Process supervision disabled, skipping crash recovery');
128
- return;
129
- }
130
- // Check for orphaned PM sessions in the database
131
- const config = this.config;
132
- if (!config)
133
- return;
134
- for (const product of config.products) {
135
- try {
136
- // Check if there's an active PM session but no process running
137
- const result = await callApi('pm_session_list', {
138
- productId: product.id,
139
- });
140
- const session = result?.pmSessions?.[0]; // Most recent session
141
- if (session && session.status === 'active' && !isPMProcessRunning(product.id)) {
142
- console.log(`[PM] Found orphaned active PM session for product ${product.id} ` +
143
- `(last cycle: ${session.lastCycleAt ?? 'never'}), restarting`);
144
- if (this.governor) {
145
- try {
146
- await spawnPMProcess(config, product.id, product.repoPath, this.governor, this.pmProcessConfig, session.id);
147
- this.setupProcessMonitor(product.id, product.repoPath);
148
- console.log(`[PM] Restarted PM process for product ${product.id}`);
149
- }
150
- catch (spawnErr) {
151
- console.log(`[PM] Failed to restart PM process for product ${product.id}: ` +
152
- `${spawnErr instanceof Error ? spawnErr.message : String(spawnErr)}`);
153
- }
154
- }
155
- }
156
- }
157
- catch {
158
- // No session found -- will be created on spawn
159
- }
160
- }
161
- console.log('[PM] Crash recovery complete');
162
- }
163
- // -----------------------------------------------------------------------
164
- // start
165
- // -----------------------------------------------------------------------
166
- async start() {
167
- this.shuttingDown = false;
168
- // Check session statuses and spawn PM processes for active sessions
169
- if (this.pmProcessConfig.processEnabled && this.config && this.governor) {
170
- await this.pollSessionStatuses();
171
- // Poll session statuses periodically (30s) to react to UI toggle changes
172
- this.sessionPollInterval = setInterval(async () => {
173
- if (this.shuttingDown)
174
- return;
175
- try {
176
- await this.pollSessionStatuses();
177
- }
178
- catch (err) {
179
- console.log(`[PM] Session status poll error: ${err instanceof Error ? err.message : String(err)}`);
180
- }
181
- }, 30_000);
182
- }
183
- // Run initial risk poll immediately
184
- await this.runPollCycle();
185
- // Schedule next risk poll with adaptive interval
186
- this.scheduleNextPoll();
187
- const processCount = getActivePMProcesses().size;
188
- console.log(`[PM] Engine started (${processCount} PM process(es), risk polling active)`);
189
- }
190
- // -----------------------------------------------------------------------
191
- // stop
192
- // -----------------------------------------------------------------------
193
- stop() {
194
- this.shuttingDown = true;
195
- if (this.pollTimeout !== null) {
196
- clearTimeout(this.pollTimeout);
197
- this.pollTimeout = null;
198
- }
199
- if (this.sessionPollInterval !== null) {
200
- clearInterval(this.sessionPollInterval);
201
- this.sessionPollInterval = null;
202
- }
203
- // Clear all restart timeouts
204
- for (const timeout of this.restartTimeouts.values()) {
205
- clearTimeout(timeout);
206
- }
207
- this.restartTimeouts.clear();
208
- }
209
- // -----------------------------------------------------------------------
210
- // shutdown
211
- // -----------------------------------------------------------------------
212
- async shutdown() {
213
- // Terminate all PM processes gracefully
214
- terminateAllPMProcesses();
215
- // Wait briefly for processes to exit
216
- await new Promise(resolve => setTimeout(resolve, 2000));
217
- console.log('[PM] Shutdown complete');
218
- }
219
- // -----------------------------------------------------------------------
220
- // healthCheck
221
- // -----------------------------------------------------------------------
222
- healthCheck() {
223
- let status = 'healthy';
224
- if (this.config === null) {
225
- status = 'unhealthy';
226
- }
227
- const processes = getActivePMProcesses();
228
- const processStatuses = {};
229
- for (const [productId, state] of processes) {
230
- processStatuses[productId] = state.phase;
231
- }
232
- return {
233
- status,
234
- activeWorkItems: this.activeRiskCount,
235
- details: {
236
- activeRiskCount: this.activeRiskCount,
237
- lastPollAt: this.lastPollAt?.toISOString() ?? null,
238
- lastFollowupActions: this.lastFollowupActionCount,
239
- mitigationSummary: this.lastMitigationSummary,
240
- currentPollIntervalMs: computePollInterval(this.lastRiskStages, this.pollCadence),
241
- pmProcesses: processStatuses,
242
- processSupervisionEnabled: this.pmProcessConfig.processEnabled,
243
- },
244
- };
245
- }
246
- // -----------------------------------------------------------------------
247
- // getResourceUsage
248
- // -----------------------------------------------------------------------
249
- getResourceUsage() {
250
- const processCount = getActivePMProcesses().size;
251
- return {
252
- activeClaudeProcesses: processCount,
253
- activeWorktrees: 0,
254
- };
255
- }
256
- // -----------------------------------------------------------------------
257
- // Private: session status polling
258
- // -----------------------------------------------------------------------
259
- /**
260
- * Poll pm_sessions.status for each product and spawn/terminate PM processes
261
- * accordingly. This allows runtime control of the PM agent via UI toggle
262
- * or MCP tool without requiring a daemon restart.
263
- *
264
- * - status=active && no process running → spawn
265
- * - status=stopped/paused && process running → terminate
266
- * - no session → no action (user hasn't started PM yet)
267
- */
268
- async pollSessionStatuses() {
269
- const config = this.config;
270
- const governor = this.governor;
271
- if (!config || !governor)
272
- return;
273
- for (const product of config.products) {
274
- try {
275
- const result = await callApi('pm_session_list', {
276
- productId: product.id,
277
- });
278
- const session = result?.pmSessions?.[0]; // Most recent session
279
- const isRunning = isPMProcessRunning(product.id);
280
- if (session?.status === 'active' && !isRunning && !this.restartTimeouts.has(product.id)) {
281
- // Session is active but no process — spawn one
282
- console.log(`[PM] Session active for product ${product.id}, spawning PM process`);
283
- this.restartCounts.delete(product.id); // Fresh start, not a crash restart
284
- try {
285
- await spawnPMProcess(config, product.id, product.repoPath, governor, this.pmProcessConfig, session.id);
286
- this.setupProcessMonitor(product.id, product.repoPath);
287
- }
288
- catch (err) {
289
- console.log(`[PM] Failed to spawn PM process for product ${product.id}: ` +
290
- `${err instanceof Error ? err.message : String(err)}`);
291
- }
292
- }
293
- else if (session && session.status !== 'active' && isRunning) {
294
- // Session is stopped/paused but process is running — terminate
295
- console.log(`[PM] Session ${session.status} for product ${product.id}, terminating PM process`);
296
- terminatePMProcess(product.id);
297
- // Cancel any pending restart for this product
298
- const pendingRestart = this.restartTimeouts.get(product.id);
299
- if (pendingRestart) {
300
- clearTimeout(pendingRestart);
301
- this.restartTimeouts.delete(product.id);
302
- }
303
- }
304
- }
305
- catch (err) {
306
- // Session query failed — skip this product this cycle
307
- console.log(`[PM] Failed to check session status for product ${product.id}: ` +
308
- `${err instanceof Error ? err.message : String(err)}`);
309
- }
310
- }
311
- }
312
- // -----------------------------------------------------------------------
313
- // Private: process monitoring
314
- // -----------------------------------------------------------------------
315
- /**
316
- * Set up monitoring for a PM process. When it exits, attempt restart
317
- * with exponential backoff. Also triggers a health restart when the
318
- * process exceeds maxSessionAgeMs.
319
- */
320
- setupProcessMonitor(productId, repoPath) {
321
- const checkInterval = setInterval(() => {
322
- if (this.shuttingDown) {
323
- clearInterval(checkInterval);
324
- return;
325
- }
326
- // Check for age-based health restart
327
- if (this.pmProcessConfig.maxSessionAgeMs > 0) {
328
- const proc = getActivePMProcesses().get(productId);
329
- if (proc && proc.phase === 'running') {
330
- const age = Date.now() - proc.spawnedAt.getTime();
331
- if (age >= this.pmProcessConfig.maxSessionAgeMs) {
332
- console.log(`[PM] Session age (${Math.round(age / 60_000)}m) exceeds maxSessionAge ` +
333
- `(${Math.round(this.pmProcessConfig.maxSessionAgeMs / 60_000)}m) for product ${productId}. ` +
334
- `Triggering health restart.`);
335
- clearInterval(checkInterval);
336
- terminatePMProcess(productId);
337
- // Reset restart count -- this is a planned restart, not a crash
338
- this.restartCounts.delete(productId);
339
- this.handleProcessExit(productId, repoPath);
340
- return;
341
- }
342
- }
343
- }
344
- if (!isPMProcessRunning(productId) && !this.restartTimeouts.has(productId)) {
345
- clearInterval(checkInterval);
346
- this.handleProcessExit(productId, repoPath);
347
- }
348
- }, 10_000); // Check every 10 seconds
349
- }
350
- /**
351
- * Handle PM process exit -- check session status before scheduling restart.
352
- * Only restarts if the session is still active. If stopped/paused, the
353
- * exit is intentional and no restart is scheduled.
354
- */
355
- handleProcessExit(productId, repoPath) {
356
- if (this.shuttingDown)
357
- return;
358
- const config = this.config;
359
- const governor = this.governor;
360
- if (!config || !governor)
361
- return;
362
- // Track restart count (use a simple counter)
363
- const restartCount = this.getRestartCount(productId);
364
- if (restartCount >= this.pmProcessConfig.maxRestarts) {
365
- console.log(`[PM] Max restarts (${this.pmProcessConfig.maxRestarts}) reached for product ${productId}. ` +
366
- `PM process will not be restarted.`);
367
- return;
368
- }
369
- const delay = calculateRestartDelay(restartCount);
370
- console.log(`[PM] Scheduling PM process restart for product ${productId} ` +
371
- `in ${Math.round(delay / 1000)}s (attempt ${restartCount + 1}/${this.pmProcessConfig.maxRestarts})`);
372
- const timeout = setTimeout(async () => {
373
- this.restartTimeouts.delete(productId);
374
- if (this.shuttingDown)
375
- return;
376
- // Check session status before restarting — if user stopped/paused, don't restart
377
- try {
378
- const result = await callApi('pm_session_list', {
379
- productId,
380
- });
381
- const session = result?.pmSessions?.[0];
382
- if (session && session.status !== 'active') {
383
- console.log(`[PM] Session ${session.status} for product ${productId}, skipping restart`);
384
- return;
385
- }
386
- }
387
- catch {
388
- // If we can't check status, proceed with restart attempt
389
- }
390
- try {
391
- await spawnPMProcess(config, productId, repoPath, governor, this.pmProcessConfig);
392
- this.incrementRestartCount(productId);
393
- this.setupProcessMonitor(productId, repoPath);
394
- console.log(`[PM] PM process restarted for product ${productId}`);
395
- }
396
- catch (err) {
397
- console.log(`[PM] Failed to restart PM process for product ${productId}: ` +
398
- `${err instanceof Error ? err.message : String(err)}`);
399
- // Try again
400
- this.handleProcessExit(productId, repoPath);
401
- }
402
- }, delay);
403
- this.restartTimeouts.set(productId, timeout);
404
- }
405
- /** Restart count tracking (simple in-memory map). */
406
- restartCounts = new Map();
407
- getRestartCount(productId) {
408
- return this.restartCounts.get(productId) ?? 0;
409
- }
410
- incrementRestartCount(productId) {
411
- const current = this.restartCounts.get(productId) ?? 0;
412
- this.restartCounts.set(productId, current + 1);
413
- }
414
- // -----------------------------------------------------------------------
415
- // Private: risk poll cycle (unchanged from monitoring-only engine)
416
- // -----------------------------------------------------------------------
417
- /**
418
- * Run a single poll cycle: scan dependencies, correlate mitigation, log results.
419
- */
420
- async runPollCycle() {
421
- const config = this.config;
422
- if (!config)
423
- return;
424
- this.lastPollAt = new Date();
425
- for (const product of config.products) {
426
- try {
427
- await this.pollProduct(product.id);
428
- }
429
- catch (err) {
430
- console.log(`[PM] Poll failed for product ${product.id}: ${err instanceof Error ? err.message : String(err)}`);
431
- }
432
- }
433
- }
434
- /**
435
- * Poll a single product for risk states and follow-up actions.
436
- */
437
- async pollProduct(productId) {
438
- // 1. Scan risk dependencies for follow-up actions
439
- const followupActions = await scanRiskDependencies(productId);
440
- this.lastFollowupActionCount = followupActions.length;
441
- if (followupActions.length > 0) {
442
- console.log(`[PM] ${followupActions.length} follow-up action(s) for product ${productId}:`);
443
- for (const action of followupActions) {
444
- console.log(`[PM] [${action.urgency.toUpperCase()}] ${action.action}: "${action.dependencyTitle}" ` +
445
- `(risk: "${action.riskTitle}", owner: ${action.ownerName ?? 'unassigned'})`);
446
- }
447
- }
448
- // 2. Draft communications for high-urgency follow-ups
449
- const draftsCreated = await this.createFollowupDrafts(productId, followupActions);
450
- if (draftsCreated > 0) {
451
- console.log(`[PM] Created ${draftsCreated} communication draft(s) for product ${productId}`);
452
- }
453
- // 3. Correlate mitigation progress
454
- const mitigationReports = await correlateMitigationProgress(productId);
455
- // Track risk stages for adaptive polling
456
- const riskStages = [];
457
- const assessmentCounts = {};
458
- for (const report of mitigationReports) {
459
- riskStages.push(report.riskStage);
460
- assessmentCounts[report.assessment] = (assessmentCounts[report.assessment] ?? 0) + 1;
461
- // Log non-trivial assessments
462
- if (report.assessment === 'behind' || report.assessment === 'no_mitigation') {
463
- console.log(`[PM] Risk "${report.riskTitle}" (${report.riskStage}): ` +
464
- `mitigation ${report.assessment} (${report.overallCompletionPct}% complete)`);
465
- }
466
- }
467
- this.lastRiskStages = riskStages;
468
- this.activeRiskCount = riskStages.filter(s => s !== 'resolved' && s !== 'draft').length;
469
- this.lastMitigationSummary = assessmentCounts;
470
- if (mitigationReports.length > 0) {
471
- console.log(`[PM] Product ${productId}: ${mitigationReports.length} risk(s) scanned, ` +
472
- `assessments: ${Object.entries(assessmentCounts).map(([k, v]) => `${k}=${v}`).join(', ')}`);
473
- }
474
- }
475
- /**
476
- * Create communication drafts for high-urgency follow-up actions.
477
- */
478
- async createFollowupDrafts(productId, actions) {
479
- const highUrgencyFollowups = actions.filter(a => a.urgency === 'high' && a.action === 'send_followup');
480
- if (highUrgencyFollowups.length === 0)
481
- return 0;
482
- let created = 0;
483
- for (const action of highUrgencyFollowups) {
484
- const daysPastDue = action.nextFollowupAt
485
- ? Math.max(0, Math.floor((Date.now() - new Date(action.nextFollowupAt).getTime()) / (24 * 60 * 60 * 1000)))
486
- : 0;
487
- const draft = draftCommunication({
488
- type: 'followup_due',
489
- dependencyTitle: action.dependencyTitle,
490
- ownerName: action.ownerName ?? 'Unknown',
491
- daysPastDue,
492
- }, {
493
- title: action.dependencyTitle,
494
- ownerName: action.ownerName,
495
- ownerContact: action.ownerContact,
496
- }, 'email');
497
- draft.riskDependencyId = action.dependencyId;
498
- try {
499
- await callApi('risk_communication_create', {
500
- productId,
501
- riskDependencyId: draft.riskDependencyId,
502
- direction: draft.direction,
503
- channel: draft.channel,
504
- subject: draft.subject,
505
- body: draft.body,
506
- sender: draft.sender,
507
- recipient: draft.recipient,
508
- status: draft.status,
509
- });
510
- created++;
511
- }
512
- catch (err) {
513
- console.log(`[PM] Failed to store draft for dependency ${action.dependencyId}: ` +
514
- `${err instanceof Error ? err.message : String(err)}`);
515
- }
516
- }
517
- return created;
518
- }
519
- /**
520
- * Schedule the next poll cycle using the adaptive interval based on current risk stages.
521
- */
522
- scheduleNextPoll() {
523
- if (this.shuttingDown)
524
- return;
525
- const intervalMs = computePollInterval(this.lastRiskStages, this.pollCadence);
526
- this.pollTimeout = setTimeout(async () => {
527
- if (this.shuttingDown)
528
- return;
529
- try {
530
- await this.runPollCycle();
531
- }
532
- catch (err) {
533
- console.log(`[PM] Poll cycle error: ${err instanceof Error ? err.message : String(err)}`);
534
- }
535
- // Schedule the next poll (interval may have changed based on new risk stages)
536
- this.scheduleNextPoll();
537
- }, intervalMs);
538
- }
539
- }
540
- //# sourceMappingURL=pm-engine.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pm-engine.js","sourceRoot":"","sources":["../src/pm-engine.ts"],"names":[],"mappings":"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"}
@@ -1,45 +0,0 @@
1
- /**
2
- * PM process state and lifecycle management.
3
- *
4
- * Manages the spawning, monitoring, and termination of PM Claude Code
5
- * processes. Each product gets one PM process that runs /loop for its
6
- * PM cycle.
7
- */
8
- import type { ResourceGovernor } from '@telora/daemon-core';
9
- import type { DaemonConfig } from './types.js';
10
- import type { PMProcessState, PMProcessConfig } from './types/pm.js';
11
- /**
12
- * Spawn a PM Claude Code process for a product.
13
- *
14
- * The process runs in the product's repo directory with the PM CLAUDE.md
15
- * as context, and is given a /loop command to run the PM cycle periodically.
16
- */
17
- export declare function spawnPMProcess(config: DaemonConfig, productId: string, repoPath: string, governor: ResourceGovernor, pmConfig?: PMProcessConfig, existingSessionId?: string): Promise<PMProcessState>;
18
- /**
19
- * Gracefully terminate a PM process for a product.
20
- */
21
- export declare function terminatePMProcess(productId: string): boolean;
22
- /**
23
- * Terminate all active PM processes.
24
- */
25
- export declare function terminateAllPMProcesses(): void;
26
- /**
27
- * Get the active PM process for a product, or undefined if none.
28
- */
29
- export declare function getPMProcess(productId: string): PMProcessState | undefined;
30
- /**
31
- * Get all active PM processes.
32
- */
33
- export declare function getActivePMProcesses(): Map<string, PMProcessState>;
34
- /**
35
- * Check if a PM process is running for a product.
36
- */
37
- export declare function isPMProcessRunning(productId: string): boolean;
38
- /**
39
- * Calculate exponential backoff delay for PM process restart.
40
- *
41
- * Backoff schedule: 1m, 2m, 4m, 8m, 16m, 30m (capped)
42
- * Returns delay in milliseconds.
43
- */
44
- export declare function calculateRestartDelay(restartCount: number): number;
45
- //# sourceMappingURL=pm-process.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pm-process.d.ts","sourceRoot":"","sources":["../src/pm-process.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAM5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAgBrE;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,GAAE,eAA2C,EACrD,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,cAAc,CAAC,CA2GzB;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CA0B7D;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,IAAI,CAI9C;AAMD;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE1E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAElE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAG7D;AAMD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAKlE"}