@telora/daemon 0.13.28 → 0.13.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build-info.json +2 -2
- package/dist/pm-engine.d.ts +42 -13
- package/dist/pm-engine.d.ts.map +1 -1
- package/dist/pm-engine.js +306 -43
- package/dist/pm-engine.js.map +1 -1
- package/dist/pm-process.d.ts +45 -0
- package/dist/pm-process.d.ts.map +1 -0
- package/dist/pm-process.js +191 -0
- package/dist/pm-process.js.map +1 -0
- package/dist/pm-prompt-builder.d.ts +23 -0
- package/dist/pm-prompt-builder.d.ts.map +1 -0
- package/dist/pm-prompt-builder.js +64 -0
- package/dist/pm-prompt-builder.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/pm.d.ts +53 -0
- package/dist/types/pm.d.ts.map +1 -0
- package/dist/types/pm.js +10 -0
- package/dist/types/pm.js.map +1 -0
- package/package.json +1 -1
package/build-info.json
CHANGED
package/dist/pm-engine.d.ts
CHANGED
|
@@ -1,28 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PMEngine -- ExecutionEngine adapter for the PM (Project Manager)
|
|
2
|
+
* PMEngine -- ExecutionEngine adapter for the PM (Project Manager) engine.
|
|
3
3
|
*
|
|
4
|
-
* The PM engine
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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).
|
|
7
8
|
*
|
|
8
9
|
* Lifecycle (called by the process shell):
|
|
9
10
|
* 1. init(config) -- validate config, initialize API client
|
|
10
|
-
* 2. recoverFromCrash() --
|
|
11
|
-
* 3. start() -- begin
|
|
11
|
+
* 2. recoverFromCrash() -- detect orphaned PM sessions, restart
|
|
12
|
+
* 3. start() -- spawn PM processes, begin risk poll loop
|
|
12
13
|
* 4. stop() -- clear intervals, set shutting-down flag
|
|
13
|
-
* 5. shutdown() --
|
|
14
|
+
* 5. shutdown() -- terminate PM processes gracefully
|
|
14
15
|
*/
|
|
15
16
|
import type { ExecutionEngine, EngineHealth, ResourceUsage, BaseConfig, ResourceGovernor } from '@telora/daemon-core';
|
|
16
17
|
export declare class PMEngine implements ExecutionEngine {
|
|
17
18
|
readonly name = "pm";
|
|
18
19
|
/** Daemon config, set during init(). */
|
|
19
20
|
private config;
|
|
20
|
-
/**
|
|
21
|
+
/** Resource governor for slot management. */
|
|
21
22
|
private governor;
|
|
22
|
-
/**
|
|
23
|
+
/** PM process-specific configuration. */
|
|
24
|
+
private pmProcessConfig;
|
|
25
|
+
/** Poll cadence configuration (for risk monitoring). */
|
|
23
26
|
private pollCadence;
|
|
24
27
|
/** Active poll timeout handle (for adaptive interval). */
|
|
25
28
|
private pollTimeout;
|
|
29
|
+
/** Session status poll interval handle. */
|
|
30
|
+
private sessionPollInterval;
|
|
31
|
+
/** Pending restart timeouts (for backoff). */
|
|
32
|
+
private restartTimeouts;
|
|
26
33
|
/** Whether the engine is shutting down. */
|
|
27
34
|
private shuttingDown;
|
|
28
35
|
/** Count of active (non-resolved, non-draft) risks from last scan. */
|
|
@@ -43,6 +50,32 @@ export declare class PMEngine implements ExecutionEngine {
|
|
|
43
50
|
shutdown(): Promise<void>;
|
|
44
51
|
healthCheck(): EngineHealth;
|
|
45
52
|
getResourceUsage(): ResourceUsage;
|
|
53
|
+
/**
|
|
54
|
+
* Poll pm_sessions.status for each product and spawn/terminate PM processes
|
|
55
|
+
* accordingly. This allows runtime control of the PM agent via UI toggle
|
|
56
|
+
* or MCP tool without requiring a daemon restart.
|
|
57
|
+
*
|
|
58
|
+
* - status=active && no process running → spawn
|
|
59
|
+
* - status=stopped/paused && process running → terminate
|
|
60
|
+
* - no session → no action (user hasn't started PM yet)
|
|
61
|
+
*/
|
|
62
|
+
private pollSessionStatuses;
|
|
63
|
+
/**
|
|
64
|
+
* Set up monitoring for a PM process. When it exits, attempt restart
|
|
65
|
+
* with exponential backoff. Also triggers a health restart when the
|
|
66
|
+
* process exceeds maxSessionAgeMs.
|
|
67
|
+
*/
|
|
68
|
+
private setupProcessMonitor;
|
|
69
|
+
/**
|
|
70
|
+
* Handle PM process exit -- check session status before scheduling restart.
|
|
71
|
+
* Only restarts if the session is still active. If stopped/paused, the
|
|
72
|
+
* exit is intentional and no restart is scheduled.
|
|
73
|
+
*/
|
|
74
|
+
private handleProcessExit;
|
|
75
|
+
/** Restart count tracking (simple in-memory map). */
|
|
76
|
+
private restartCounts;
|
|
77
|
+
private getRestartCount;
|
|
78
|
+
private incrementRestartCount;
|
|
46
79
|
/**
|
|
47
80
|
* Run a single poll cycle: scan dependencies, correlate mitigation, log results.
|
|
48
81
|
*/
|
|
@@ -53,10 +86,6 @@ export declare class PMEngine implements ExecutionEngine {
|
|
|
53
86
|
private pollProduct;
|
|
54
87
|
/**
|
|
55
88
|
* Create communication drafts for high-urgency follow-up actions.
|
|
56
|
-
*
|
|
57
|
-
* Only drafts for 'high' urgency actions with a 'send_followup' recommendation.
|
|
58
|
-
* Drafts are stored via the API with status='draft' for human approval.
|
|
59
|
-
* Returns the number of drafts successfully created.
|
|
60
89
|
*/
|
|
61
90
|
private createFollowupDrafts;
|
|
62
91
|
/**
|
package/dist/pm-engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pm-engine.d.ts","sourceRoot":"","sources":["../src/pm-engine.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"pm-engine.d.ts","sourceRoot":"","sources":["../src/pm-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,aAAa,EACb,UAAU,EACV,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AA0D7B,qBAAa,QAAS,YAAW,eAAe;IAC9C,QAAQ,CAAC,IAAI,QAAQ;IAErB,wCAAwC;IACxC,OAAO,CAAC,MAAM,CAA6B;IAE3C,6CAA6C;IAC7C,OAAO,CAAC,QAAQ,CAAiC;IAEjD,yCAAyC;IACzC,OAAO,CAAC,eAAe,CAA8C;IAErE,wDAAwD;IACxD,OAAO,CAAC,WAAW,CAA2C;IAE9D,0DAA0D;IAC1D,OAAO,CAAC,WAAW,CAA8C;IAEjE,2CAA2C;IAC3C,OAAO,CAAC,mBAAmB,CAA+C;IAE1E,8CAA8C;IAC9C,OAAO,CAAC,eAAe,CAAoD;IAE3E,2CAA2C;IAC3C,OAAO,CAAC,YAAY,CAAS;IAE7B,sEAAsE;IACtE,OAAO,CAAC,eAAe,CAAK;IAE5B,gDAAgD;IAChD,OAAO,CAAC,UAAU,CAAqB;IAEvC,2DAA2D;IAC3D,OAAO,CAAC,cAAc,CAAgB;IAEtC,8CAA8C;IAC9C,OAAO,CAAC,uBAAuB,CAAK;IAEpC,oDAAoD;IACpD,OAAO,CAAC,qBAAqB,CAA8B;IAM3D,WAAW,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI;IAQlC,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDjE,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAsDjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC5B,IAAI,IAAI,IAAI;IAsBN,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAc/B,WAAW,IAAI,YAAY;IA+B3B,gBAAgB,IAAI,aAAa;IAYjC;;;;;;;;OAQG;YACW,mBAAmB;IAoDjC;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAmC3B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IA8DzB,qDAAqD;IACrD,OAAO,CAAC,aAAa,CAA6B;IAElD,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,qBAAqB;IAS7B;;OAEG;YACW,YAAY;IAiB1B;;OAEG;YACW,WAAW;IAuDzB;;OAEG;YACW,oBAAoB;IA4DlC;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAoBzB"}
|
package/dist/pm-engine.js
CHANGED
|
@@ -1,22 +1,50 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PMEngine -- ExecutionEngine adapter for the PM (Project Manager)
|
|
2
|
+
* PMEngine -- ExecutionEngine adapter for the PM (Project Manager) engine.
|
|
3
3
|
*
|
|
4
|
-
* The PM engine
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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).
|
|
7
8
|
*
|
|
8
9
|
* Lifecycle (called by the process shell):
|
|
9
10
|
* 1. init(config) -- validate config, initialize API client
|
|
10
|
-
* 2. recoverFromCrash() --
|
|
11
|
-
* 3. start() -- begin
|
|
11
|
+
* 2. recoverFromCrash() -- detect orphaned PM sessions, restart
|
|
12
|
+
* 3. start() -- spawn PM processes, begin risk poll loop
|
|
12
13
|
* 4. stop() -- clear intervals, set shutting-down flag
|
|
13
|
-
* 5. shutdown() --
|
|
14
|
+
* 5. shutdown() -- terminate PM processes gracefully
|
|
14
15
|
*/
|
|
16
|
+
import { DEFAULT_PM_PROCESS_CONFIG } from './types/pm.js';
|
|
15
17
|
import { initSupabase, callApi } from './queries/shared.js';
|
|
16
18
|
import { scanRiskDependencies } from './pm/risk-scanner.js';
|
|
17
19
|
import { correlateMitigationProgress } from './pm/mitigation-correlator.js';
|
|
18
20
|
import { computePollInterval, DEFAULT_POLL_CADENCE, } from './pm/adaptive-poller.js';
|
|
19
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
|
+
}
|
|
20
48
|
// ---------------------------------------------------------------------------
|
|
21
49
|
// PMEngine
|
|
22
50
|
// ---------------------------------------------------------------------------
|
|
@@ -24,12 +52,18 @@ export class PMEngine {
|
|
|
24
52
|
name = 'pm';
|
|
25
53
|
/** Daemon config, set during init(). */
|
|
26
54
|
config = null;
|
|
27
|
-
/**
|
|
55
|
+
/** Resource governor for slot management. */
|
|
28
56
|
governor = null;
|
|
29
|
-
/**
|
|
57
|
+
/** PM process-specific configuration. */
|
|
58
|
+
pmProcessConfig = DEFAULT_PM_PROCESS_CONFIG;
|
|
59
|
+
/** Poll cadence configuration (for risk monitoring). */
|
|
30
60
|
pollCadence = DEFAULT_POLL_CADENCE;
|
|
31
61
|
/** Active poll timeout handle (for adaptive interval). */
|
|
32
62
|
pollTimeout = null;
|
|
63
|
+
/** Session status poll interval handle. */
|
|
64
|
+
sessionPollInterval = null;
|
|
65
|
+
/** Pending restart timeouts (for backoff). */
|
|
66
|
+
restartTimeouts = new Map();
|
|
33
67
|
/** Whether the engine is shutting down. */
|
|
34
68
|
shuttingDown = false;
|
|
35
69
|
/** Count of active (non-resolved, non-draft) risks from last scan. */
|
|
@@ -47,54 +81,111 @@ export class PMEngine {
|
|
|
47
81
|
// -----------------------------------------------------------------------
|
|
48
82
|
setGovernor(gov) {
|
|
49
83
|
this.governor = gov;
|
|
50
|
-
// PM engine does not acquire governor slots (no Claude processes)
|
|
51
84
|
}
|
|
52
85
|
// -----------------------------------------------------------------------
|
|
53
86
|
// init
|
|
54
87
|
// -----------------------------------------------------------------------
|
|
55
88
|
async init(config) {
|
|
56
89
|
this.config = config;
|
|
57
|
-
// Resolve
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
+
};
|
|
74
114
|
}
|
|
75
115
|
// Initialize API client (reuse shared infrastructure -- may already be
|
|
76
116
|
// initialized by the strategy engine, but initSupabase is idempotent)
|
|
77
117
|
initSupabase(this.config);
|
|
78
|
-
console.log(
|
|
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'})`);
|
|
79
121
|
}
|
|
80
122
|
// -----------------------------------------------------------------------
|
|
81
123
|
// recoverFromCrash
|
|
82
124
|
// -----------------------------------------------------------------------
|
|
83
125
|
async recoverFromCrash() {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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);
|
|
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');
|
|
87
162
|
}
|
|
88
163
|
// -----------------------------------------------------------------------
|
|
89
164
|
// start
|
|
90
165
|
// -----------------------------------------------------------------------
|
|
91
166
|
async start() {
|
|
92
167
|
this.shuttingDown = false;
|
|
93
|
-
//
|
|
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
|
|
94
184
|
await this.runPollCycle();
|
|
95
|
-
// Schedule next poll with adaptive interval
|
|
185
|
+
// Schedule next risk poll with adaptive interval
|
|
96
186
|
this.scheduleNextPoll();
|
|
97
|
-
|
|
187
|
+
const processCount = getActivePMProcesses().size;
|
|
188
|
+
console.log(`[PM] Engine started (${processCount} PM process(es), risk polling active)`);
|
|
98
189
|
}
|
|
99
190
|
// -----------------------------------------------------------------------
|
|
100
191
|
// stop
|
|
@@ -105,12 +196,24 @@ export class PMEngine {
|
|
|
105
196
|
clearTimeout(this.pollTimeout);
|
|
106
197
|
this.pollTimeout = null;
|
|
107
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();
|
|
108
208
|
}
|
|
109
209
|
// -----------------------------------------------------------------------
|
|
110
210
|
// shutdown
|
|
111
211
|
// -----------------------------------------------------------------------
|
|
112
212
|
async shutdown() {
|
|
113
|
-
//
|
|
213
|
+
// Terminate all PM processes gracefully
|
|
214
|
+
terminateAllPMProcesses();
|
|
215
|
+
// Wait briefly for processes to exit
|
|
216
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
114
217
|
console.log('[PM] Shutdown complete');
|
|
115
218
|
}
|
|
116
219
|
// -----------------------------------------------------------------------
|
|
@@ -121,6 +224,11 @@ export class PMEngine {
|
|
|
121
224
|
if (this.config === null) {
|
|
122
225
|
status = 'unhealthy';
|
|
123
226
|
}
|
|
227
|
+
const processes = getActivePMProcesses();
|
|
228
|
+
const processStatuses = {};
|
|
229
|
+
for (const [productId, state] of processes) {
|
|
230
|
+
processStatuses[productId] = state.phase;
|
|
231
|
+
}
|
|
124
232
|
return {
|
|
125
233
|
status,
|
|
126
234
|
activeWorkItems: this.activeRiskCount,
|
|
@@ -130,6 +238,8 @@ export class PMEngine {
|
|
|
130
238
|
lastFollowupActions: this.lastFollowupActionCount,
|
|
131
239
|
mitigationSummary: this.lastMitigationSummary,
|
|
132
240
|
currentPollIntervalMs: computePollInterval(this.lastRiskStages, this.pollCadence),
|
|
241
|
+
pmProcesses: processStatuses,
|
|
242
|
+
processSupervisionEnabled: this.pmProcessConfig.processEnabled,
|
|
133
243
|
},
|
|
134
244
|
};
|
|
135
245
|
}
|
|
@@ -137,13 +247,172 @@ export class PMEngine {
|
|
|
137
247
|
// getResourceUsage
|
|
138
248
|
// -----------------------------------------------------------------------
|
|
139
249
|
getResourceUsage() {
|
|
250
|
+
const processCount = getActivePMProcesses().size;
|
|
140
251
|
return {
|
|
141
|
-
activeClaudeProcesses:
|
|
252
|
+
activeClaudeProcesses: processCount,
|
|
142
253
|
activeWorktrees: 0,
|
|
143
254
|
};
|
|
144
255
|
}
|
|
145
256
|
// -----------------------------------------------------------------------
|
|
146
|
-
// Private:
|
|
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);
|
|
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)
|
|
147
416
|
// -----------------------------------------------------------------------
|
|
148
417
|
/**
|
|
149
418
|
* Run a single poll cycle: scan dependencies, correlate mitigation, log results.
|
|
@@ -205,10 +474,6 @@ export class PMEngine {
|
|
|
205
474
|
}
|
|
206
475
|
/**
|
|
207
476
|
* Create communication drafts for high-urgency follow-up actions.
|
|
208
|
-
*
|
|
209
|
-
* Only drafts for 'high' urgency actions with a 'send_followup' recommendation.
|
|
210
|
-
* Drafts are stored via the API with status='draft' for human approval.
|
|
211
|
-
* Returns the number of drafts successfully created.
|
|
212
477
|
*/
|
|
213
478
|
async createFollowupDrafts(productId, actions) {
|
|
214
479
|
const highUrgencyFollowups = actions.filter(a => a.urgency === 'high' && a.action === 'send_followup');
|
|
@@ -216,7 +481,6 @@ export class PMEngine {
|
|
|
216
481
|
return 0;
|
|
217
482
|
let created = 0;
|
|
218
483
|
for (const action of highUrgencyFollowups) {
|
|
219
|
-
// Calculate days past due
|
|
220
484
|
const daysPastDue = action.nextFollowupAt
|
|
221
485
|
? Math.max(0, Math.floor((Date.now() - new Date(action.nextFollowupAt).getTime()) / (24 * 60 * 60 * 1000)))
|
|
222
486
|
: 0;
|
|
@@ -230,7 +494,6 @@ export class PMEngine {
|
|
|
230
494
|
ownerName: action.ownerName,
|
|
231
495
|
ownerContact: action.ownerContact,
|
|
232
496
|
}, 'email');
|
|
233
|
-
// Set the dependency ID on the draft
|
|
234
497
|
draft.riskDependencyId = action.dependencyId;
|
|
235
498
|
try {
|
|
236
499
|
await callApi('risk_communication_create', {
|
package/dist/pm-engine.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pm-engine.js","sourceRoot":"","sources":["../src/pm-engine.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pm-engine.js","sourceRoot":"","sources":["../src/pm-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
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): 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
|
|
@@ -0,0 +1 @@
|
|
|
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,GACpD,OAAO,CAAC,cAAc,CAAC,CAwGzB;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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
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 { spawn } from 'node:child_process';
|
|
9
|
+
import { buildStreamJsonArgs, stripClaudeCodeEnvVars, sendMessage, } from '@telora/daemon-core';
|
|
10
|
+
import { DEFAULT_PM_PROCESS_CONFIG } from './types/pm.js';
|
|
11
|
+
import { buildPMPrompt } from './pm-prompt-builder.js';
|
|
12
|
+
import { callApi } from './queries/shared.js';
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Active processes
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
/** Map of productId -> PMProcessState for active PM processes. */
|
|
17
|
+
const activeProcesses = new Map();
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Spawn
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/**
|
|
22
|
+
* Spawn a PM Claude Code process for a product.
|
|
23
|
+
*
|
|
24
|
+
* The process runs in the product's repo directory with the PM CLAUDE.md
|
|
25
|
+
* as context, and is given a /loop command to run the PM cycle periodically.
|
|
26
|
+
*/
|
|
27
|
+
export async function spawnPMProcess(config, productId, repoPath, governor, pmConfig = DEFAULT_PM_PROCESS_CONFIG) {
|
|
28
|
+
// Acquire governor slot
|
|
29
|
+
await governor.acquireSlot('pm');
|
|
30
|
+
// Create PM session in database
|
|
31
|
+
let pmSessionId;
|
|
32
|
+
try {
|
|
33
|
+
const result = await callApi('pm_session_create', {
|
|
34
|
+
productId,
|
|
35
|
+
});
|
|
36
|
+
pmSessionId = result?.session?.id ?? `pm-${productId}`;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// If session creation fails, use a synthetic ID
|
|
40
|
+
pmSessionId = `pm-${productId}`;
|
|
41
|
+
}
|
|
42
|
+
// Fetch product info
|
|
43
|
+
let productName = productId;
|
|
44
|
+
try {
|
|
45
|
+
const productResult = await callApi('product_get', {
|
|
46
|
+
productId,
|
|
47
|
+
});
|
|
48
|
+
productName = productResult?.name ?? productId;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Use productId as fallback name
|
|
52
|
+
}
|
|
53
|
+
// Build initial prompt
|
|
54
|
+
const initialPrompt = await buildPMPrompt(repoPath, { id: productId, name: productName }, pmConfig.loopIntervalMinutes);
|
|
55
|
+
// Build CLI args
|
|
56
|
+
const args = buildStreamJsonArgs();
|
|
57
|
+
// Build environment (strip inherited Claude Code vars)
|
|
58
|
+
const spawnEnv = stripClaudeCodeEnvVars(process.env, {
|
|
59
|
+
preserve: ['CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS'],
|
|
60
|
+
});
|
|
61
|
+
// Spawn Claude Code process in the product repo
|
|
62
|
+
const proc = spawn(config.claudeCodePath, args, {
|
|
63
|
+
cwd: repoPath,
|
|
64
|
+
env: spawnEnv,
|
|
65
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
66
|
+
});
|
|
67
|
+
const state = {
|
|
68
|
+
productId,
|
|
69
|
+
proc,
|
|
70
|
+
pmSessionId,
|
|
71
|
+
phase: 'starting',
|
|
72
|
+
restartCount: 0,
|
|
73
|
+
lastRestartAt: null,
|
|
74
|
+
stdin: proc.stdin,
|
|
75
|
+
spawnedAt: new Date(),
|
|
76
|
+
};
|
|
77
|
+
activeProcesses.set(productId, state);
|
|
78
|
+
// Send initial prompt
|
|
79
|
+
sendMessage(proc.stdin, initialPrompt);
|
|
80
|
+
state.phase = 'running';
|
|
81
|
+
// Log stdout (simple line-by-line)
|
|
82
|
+
proc.stdout.on('data', (data) => {
|
|
83
|
+
const lines = data.toString().split('\n').filter(Boolean);
|
|
84
|
+
for (const line of lines) {
|
|
85
|
+
try {
|
|
86
|
+
const event = JSON.parse(line);
|
|
87
|
+
// Capture Claude session ID from init event
|
|
88
|
+
if (event.type === 'system' && event.sessionId) {
|
|
89
|
+
state.claudeSessionId = event.sessionId;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// Non-JSON output -- log as-is
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
proc.stderr.on('data', (data) => {
|
|
98
|
+
console.log(`[PM] stderr (${productId}): ${data.toString().trim()}`);
|
|
99
|
+
});
|
|
100
|
+
// Handle process exit
|
|
101
|
+
proc.on('close', (code) => {
|
|
102
|
+
console.log(`[PM] Process exited for product ${productId} (code: ${code})`);
|
|
103
|
+
state.phase = 'crashed';
|
|
104
|
+
governor.releaseSlot('pm');
|
|
105
|
+
activeProcesses.delete(productId);
|
|
106
|
+
});
|
|
107
|
+
proc.on('error', (err) => {
|
|
108
|
+
console.log(`[PM] Process error for product ${productId}: ${err.message}`);
|
|
109
|
+
state.phase = 'crashed';
|
|
110
|
+
governor.releaseSlot('pm');
|
|
111
|
+
activeProcesses.delete(productId);
|
|
112
|
+
});
|
|
113
|
+
console.log(`[PM] Spawned process for product ${productId} (pid: ${proc.pid})`);
|
|
114
|
+
return state;
|
|
115
|
+
}
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
// Terminate
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
/**
|
|
120
|
+
* Gracefully terminate a PM process for a product.
|
|
121
|
+
*/
|
|
122
|
+
export function terminatePMProcess(productId) {
|
|
123
|
+
const state = activeProcesses.get(productId);
|
|
124
|
+
if (!state)
|
|
125
|
+
return false;
|
|
126
|
+
state.phase = 'stopping';
|
|
127
|
+
// Try graceful shutdown: close stdin, then SIGTERM
|
|
128
|
+
try {
|
|
129
|
+
state.stdin.end();
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// Already closed
|
|
133
|
+
}
|
|
134
|
+
setTimeout(() => {
|
|
135
|
+
if (state.proc.exitCode === null) {
|
|
136
|
+
state.proc.kill('SIGTERM');
|
|
137
|
+
}
|
|
138
|
+
}, 5000);
|
|
139
|
+
setTimeout(() => {
|
|
140
|
+
if (state.proc.exitCode === null) {
|
|
141
|
+
state.proc.kill('SIGKILL');
|
|
142
|
+
}
|
|
143
|
+
}, 15000);
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Terminate all active PM processes.
|
|
148
|
+
*/
|
|
149
|
+
export function terminateAllPMProcesses() {
|
|
150
|
+
for (const productId of activeProcesses.keys()) {
|
|
151
|
+
terminatePMProcess(productId);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
// Query
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
/**
|
|
158
|
+
* Get the active PM process for a product, or undefined if none.
|
|
159
|
+
*/
|
|
160
|
+
export function getPMProcess(productId) {
|
|
161
|
+
return activeProcesses.get(productId);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get all active PM processes.
|
|
165
|
+
*/
|
|
166
|
+
export function getActivePMProcesses() {
|
|
167
|
+
return activeProcesses;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Check if a PM process is running for a product.
|
|
171
|
+
*/
|
|
172
|
+
export function isPMProcessRunning(productId) {
|
|
173
|
+
const state = activeProcesses.get(productId);
|
|
174
|
+
return state !== undefined && state.phase === 'running';
|
|
175
|
+
}
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
// Backoff
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
/**
|
|
180
|
+
* Calculate exponential backoff delay for PM process restart.
|
|
181
|
+
*
|
|
182
|
+
* Backoff schedule: 1m, 2m, 4m, 8m, 16m, 30m (capped)
|
|
183
|
+
* Returns delay in milliseconds.
|
|
184
|
+
*/
|
|
185
|
+
export function calculateRestartDelay(restartCount) {
|
|
186
|
+
const baseMs = 60_000; // 1 minute
|
|
187
|
+
const maxMs = 30 * 60_000; // 30 minutes
|
|
188
|
+
const delay = Math.min(baseMs * Math.pow(2, restartCount), maxMs);
|
|
189
|
+
return delay;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=pm-process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pm-process.js","sourceRoot":"","sources":["../src/pm-process.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PM prompt builder -- builds the initial prompt for a PM Claude Code process.
|
|
3
|
+
*
|
|
4
|
+
* Reads pm/CLAUDE.md from the product repo, fetches product details and PM
|
|
5
|
+
* session state, and composes the initial prompt that boots the PM agent
|
|
6
|
+
* with /loop at the configured interval.
|
|
7
|
+
*/
|
|
8
|
+
interface ProductInfo {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Build the initial prompt for a PM Claude Code process.
|
|
14
|
+
*
|
|
15
|
+
* The prompt includes:
|
|
16
|
+
* 1. pm/CLAUDE.md contents (the PM agent's system instructions)
|
|
17
|
+
* 2. Product context (name, ID)
|
|
18
|
+
* 3. PM session state (last assessment, pending items)
|
|
19
|
+
* 4. /loop instruction at the configured interval
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildPMPrompt(repoPath: string, product: ProductInfo, loopIntervalMinutes: number): Promise<string>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=pm-prompt-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pm-prompt-builder.d.ts","sourceRoot":"","sources":["../src/pm-prompt-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAYD;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,WAAW,EACpB,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PM prompt builder -- builds the initial prompt for a PM Claude Code process.
|
|
3
|
+
*
|
|
4
|
+
* Reads pm/CLAUDE.md from the product repo, fetches product details and PM
|
|
5
|
+
* session state, and composes the initial prompt that boots the PM agent
|
|
6
|
+
* with /loop at the configured interval.
|
|
7
|
+
*/
|
|
8
|
+
import { readFile } from 'node:fs/promises';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
import { callApi } from './queries/shared.js';
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Builder
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
/**
|
|
15
|
+
* Build the initial prompt for a PM Claude Code process.
|
|
16
|
+
*
|
|
17
|
+
* The prompt includes:
|
|
18
|
+
* 1. pm/CLAUDE.md contents (the PM agent's system instructions)
|
|
19
|
+
* 2. Product context (name, ID)
|
|
20
|
+
* 3. PM session state (last assessment, pending items)
|
|
21
|
+
* 4. /loop instruction at the configured interval
|
|
22
|
+
*/
|
|
23
|
+
export async function buildPMPrompt(repoPath, product, loopIntervalMinutes) {
|
|
24
|
+
const parts = [];
|
|
25
|
+
// 1. Read pm/CLAUDE.md from the product repo
|
|
26
|
+
const pmClaudeMdPath = join(repoPath, 'pm', 'CLAUDE.md');
|
|
27
|
+
let pmInstructions = '';
|
|
28
|
+
try {
|
|
29
|
+
pmInstructions = await readFile(pmClaudeMdPath, 'utf-8');
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// If pm/CLAUDE.md doesn't exist, use a minimal fallback
|
|
33
|
+
pmInstructions = '# PM Agent\n\nYou are a PM agent. Run your cycle to check inbox, review action plan, and generate reports.';
|
|
34
|
+
}
|
|
35
|
+
parts.push(pmInstructions);
|
|
36
|
+
// 2. Product context
|
|
37
|
+
parts.push(`\n## Product\n\n- **Name**: ${product.name}\n- **ID**: ${product.id}`);
|
|
38
|
+
// 3. PM session state
|
|
39
|
+
let sessionState = null;
|
|
40
|
+
try {
|
|
41
|
+
const sessionResult = await callApi('pm_session_get', {
|
|
42
|
+
productId: product.id,
|
|
43
|
+
});
|
|
44
|
+
sessionState = sessionResult?.session ?? null;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Session may not exist yet -- PM will create it during first cycle
|
|
48
|
+
}
|
|
49
|
+
if (sessionState) {
|
|
50
|
+
parts.push('\n## Session State\n');
|
|
51
|
+
if (sessionState.lastCycleAt) {
|
|
52
|
+
parts.push(`- **Last cycle**: ${sessionState.lastCycleAt}`);
|
|
53
|
+
}
|
|
54
|
+
if (sessionState.lastAssessment) {
|
|
55
|
+
parts.push(`- **Last assessment**: ${JSON.stringify(sessionState.lastAssessment, null, 2)}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// 4. /loop instruction
|
|
59
|
+
parts.push(`\n## Instructions\n\n` +
|
|
60
|
+
`Run the PM cycle now, then continue running it on a loop.\n\n` +
|
|
61
|
+
`/loop ${loopIntervalMinutes}m /pm-cycle`);
|
|
62
|
+
return parts.join('\n');
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=pm-prompt-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pm-prompt-builder.js","sourceRoot":"","sources":["../src/pm-prompt-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAiB9C,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,OAAoB,EACpB,mBAA2B;IAE3B,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,6CAA6C;IAC7C,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IACzD,IAAI,cAAc,GAAG,EAAE,CAAC;IACxB,IAAI,CAAC;QACH,cAAc,GAAG,MAAM,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,wDAAwD;QACxD,cAAc,GAAG,4GAA4G,CAAC;IAChI,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAE3B,qBAAqB;IACrB,KAAK,CAAC,IAAI,CAAC,+BAA+B,OAAO,CAAC,IAAI,eAAe,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;IAEnF,sBAAsB;IACtB,IAAI,YAAY,GAA0B,IAAI,CAAC;IAC/C,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,gBAAgB,EAAE;YACpD,SAAS,EAAE,OAAO,CAAC,EAAE;SACtB,CAAiC,CAAC;QACnC,YAAY,GAAG,aAAa,EAAE,OAAO,IAAI,IAAI,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;IACtE,CAAC;IAED,IAAI,YAAY,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACnC,IAAI,YAAY,CAAC,WAAW,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,qBAAqB,YAAY,CAAC,WAAW,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,YAAY,CAAC,cAAc,EAAE,CAAC;YAChC,KAAK,CAAC,IAAI,CAAC,0BAA0B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,KAAK,CAAC,IAAI,CACR,uBAAuB;QACvB,+DAA+D;QAC/D,SAAS,mBAAmB,aAAa,CAC1C,CAAC;IAEF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC"}
|
package/dist/types/index.js
CHANGED
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PM process supervision types.
|
|
3
|
+
*/
|
|
4
|
+
import type { ChildProcess } from 'node:child_process';
|
|
5
|
+
import type { Writable } from 'node:stream';
|
|
6
|
+
/**
|
|
7
|
+
* State of a supervised PM Claude Code process.
|
|
8
|
+
*/
|
|
9
|
+
export interface PMProcessState {
|
|
10
|
+
/** Product this PM process manages. */
|
|
11
|
+
productId: string;
|
|
12
|
+
/** Spawned child process handle. */
|
|
13
|
+
proc: ChildProcess;
|
|
14
|
+
/** PM session ID from the database. */
|
|
15
|
+
pmSessionId: string;
|
|
16
|
+
/** Claude Code session ID (set after stream init event). */
|
|
17
|
+
claudeSessionId?: string;
|
|
18
|
+
/** Current phase of the PM process. */
|
|
19
|
+
phase: 'starting' | 'running' | 'stopping' | 'crashed';
|
|
20
|
+
/** Number of times this process has been restarted. */
|
|
21
|
+
restartCount: number;
|
|
22
|
+
/** Timestamp of last restart (for backoff calculation). */
|
|
23
|
+
lastRestartAt: Date | null;
|
|
24
|
+
/** Stdin writable for sending messages. */
|
|
25
|
+
stdin: Writable;
|
|
26
|
+
/** Timestamp when this process was spawned (for maxSessionAge checks). */
|
|
27
|
+
spawnedAt: Date;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* PM-specific configuration fields (resolved from daemon.json engines.pm section).
|
|
31
|
+
*
|
|
32
|
+
* Fields resolve with priority: env var > daemon.json engines.pm > default.
|
|
33
|
+
* - loopIntervalMinutes: TELORA_PM_LOOP_INTERVAL (in minutes)
|
|
34
|
+
* - maxRestarts: TELORA_PM_MAX_RESTARTS
|
|
35
|
+
* - maxSessionAgeMs: TELORA_PM_MAX_SESSION_AGE (in minutes, converted to ms)
|
|
36
|
+
*/
|
|
37
|
+
export interface PMProcessConfig {
|
|
38
|
+
/** Interval for the /loop command in minutes. Default: 240 (4 hours). */
|
|
39
|
+
loopIntervalMinutes: number;
|
|
40
|
+
/** Maximum restart attempts before giving up. Default: 5. */
|
|
41
|
+
maxRestarts: number;
|
|
42
|
+
/** Whether process supervision is enabled. Default: true. */
|
|
43
|
+
processEnabled: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Maximum age (ms) of a PM session before a health restart is triggered.
|
|
46
|
+
* When a running PM process exceeds this age, the engine terminates and
|
|
47
|
+
* respawns it to keep the session fresh. Default: 86400000 (24 hours).
|
|
48
|
+
* Set to 0 to disable age-based restarts.
|
|
49
|
+
*/
|
|
50
|
+
maxSessionAgeMs: number;
|
|
51
|
+
}
|
|
52
|
+
export declare const DEFAULT_PM_PROCESS_CONFIG: PMProcessConfig;
|
|
53
|
+
//# sourceMappingURL=pm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pm.d.ts","sourceRoot":"","sources":["../../src/types/pm.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,uCAAuC;IACvC,SAAS,EAAE,MAAM,CAAC;IAElB,oCAAoC;IACpC,IAAI,EAAE,YAAY,CAAC;IAEnB,uCAAuC;IACvC,WAAW,EAAE,MAAM,CAAC;IAEpB,4DAA4D;IAC5D,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,uCAAuC;IACvC,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IAEvD,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IAErB,2DAA2D;IAC3D,aAAa,EAAE,IAAI,GAAG,IAAI,CAAC;IAE3B,2CAA2C;IAC3C,KAAK,EAAE,QAAQ,CAAC;IAEhB,0EAA0E;IAC1E,SAAS,EAAE,IAAI,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,mBAAmB,EAAE,MAAM,CAAC;IAE5B,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IAEpB,6DAA6D;IAC7D,cAAc,EAAE,OAAO,CAAC;IAExB;;;;;OAKG;IACH,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,yBAAyB,EAAE,eAKvC,CAAC"}
|
package/dist/types/pm.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pm.js","sourceRoot":"","sources":["../../src/types/pm.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgEH,MAAM,CAAC,MAAM,yBAAyB,GAAoB;IACxD,mBAAmB,EAAE,GAAG;IACxB,WAAW,EAAE,CAAC;IACd,cAAc,EAAE,IAAI;IACpB,eAAe,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,WAAW;CAClD,CAAC"}
|