@planu/cli 0.81.1 → 0.82.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 (30) hide show
  1. package/dist/engine/worker-config-loader.d.ts +48 -0
  2. package/dist/engine/worker-config-loader.d.ts.map +1 -0
  3. package/dist/engine/worker-config-loader.js +167 -0
  4. package/dist/engine/worker-config-loader.js.map +1 -0
  5. package/dist/engine/workers/index.d.ts +3 -0
  6. package/dist/engine/workers/index.d.ts.map +1 -1
  7. package/dist/engine/workers/index.js +2 -0
  8. package/dist/engine/workers/index.js.map +1 -1
  9. package/dist/engine/workers/worker-crash-recovery.d.ts +30 -0
  10. package/dist/engine/workers/worker-crash-recovery.d.ts.map +1 -0
  11. package/dist/engine/workers/worker-crash-recovery.js +115 -0
  12. package/dist/engine/workers/worker-crash-recovery.js.map +1 -0
  13. package/dist/engine/workers/worker-engine.d.ts +1 -1
  14. package/dist/engine/workers/worker-engine.d.ts.map +1 -1
  15. package/dist/engine/workers/worker-engine.js +11 -1
  16. package/dist/engine/workers/worker-engine.js.map +1 -1
  17. package/dist/engine/workers/worker-heartbeat.d.ts +34 -0
  18. package/dist/engine/workers/worker-heartbeat.d.ts.map +1 -0
  19. package/dist/engine/workers/worker-heartbeat.js +84 -0
  20. package/dist/engine/workers/worker-heartbeat.js.map +1 -0
  21. package/dist/storage/worker-metrics-store.d.ts +20 -0
  22. package/dist/storage/worker-metrics-store.d.ts.map +1 -0
  23. package/dist/storage/worker-metrics-store.js +103 -0
  24. package/dist/storage/worker-metrics-store.js.map +1 -0
  25. package/dist/types/workers.d.ts +18 -0
  26. package/dist/types/workers.d.ts.map +1 -1
  27. package/package.json +1 -1
  28. package/src/i18n/messages/en.json +14 -0
  29. package/src/i18n/messages/es.json +14 -0
  30. package/src/i18n/messages/pt.json +14 -0
@@ -0,0 +1,48 @@
1
+ import type { WorkerOverride } from '../types/index.js';
2
+ export type { WorkerOverride } from '../types/index.js';
3
+ /**
4
+ * 3-layer configuration loader specific to workers.
5
+ *
6
+ * Layer 1: registry defaults (passed via load() calls externally)
7
+ * Layer 2: planu/workers.json (project-level overrides)
8
+ * Layer 3: PLANU_WORKER_<NAME>_<SETTING> environment variables
9
+ *
10
+ * Higher-precedence layers win field by field.
11
+ */
12
+ export declare class WorkerConfigLoader {
13
+ private readonly projectPath;
14
+ constructor(projectPath: string);
15
+ /**
16
+ * Load and merge all 3 layers. Returns final resolved override per worker.
17
+ * The returned Map contains only workers that have at least one override.
18
+ * Workers with no overrides in any layer are not present (use defaults as-is).
19
+ *
20
+ * @param workerNames - names of all known workers (to scan env for each)
21
+ */
22
+ load(workerNames?: string[]): Promise<Map<string, WorkerOverride>>;
23
+ /**
24
+ * Get the merged override for a specific worker (layers 2 + 3 only).
25
+ * Returns an empty object if no override is defined anywhere.
26
+ */
27
+ getOverride(workerName: string): Promise<WorkerOverride>;
28
+ /** Load planu/workers.json. Returns empty object if file doesn't exist. */
29
+ private loadProjectFile;
30
+ /** Coerce raw file content to Record<string, WorkerOverride>, ignoring unknown keys. */
31
+ private coerceFileContent;
32
+ /** Coerce a raw object to WorkerOverride, ignoring unknown keys. */
33
+ private coerceOverride;
34
+ /**
35
+ * Parse environment variables for a specific worker.
36
+ *
37
+ * Slug-to-env: 'test-gaps' → 'TEST_GAPS'
38
+ * Full pattern: PLANU_WORKER_{WORKER_ENV}_{SETTING}
39
+ * Known settings: ENABLED (bool), COOLDOWNMS (number), PRIORITY (number), TIER (string)
40
+ */
41
+ parseEnvOverride(workerName: string): WorkerOverride;
42
+ /**
43
+ * Merge two override objects. Right-hand side wins for defined fields.
44
+ * Returns a new object — zero mutation guarantee.
45
+ */
46
+ private merge;
47
+ }
48
+ //# sourceMappingURL=worker-config-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-config-loader.d.ts","sourceRoot":"","sources":["../../src/engine/worker-config-loader.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,WAAW,EAAE,MAAM;IAI/B;;;;;;OAMG;IACG,IAAI,CAAC,WAAW,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAqB5E;;;OAGG;IACG,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAW9D,2EAA2E;YAC7D,eAAe;IAe7B,wFAAwF;IACxF,OAAO,CAAC,iBAAiB;IAUzB,oEAAoE;IACpE,OAAO,CAAC,cAAc;IAiBtB;;;;;;OAMG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc;IAkCpD;;;OAGG;IACH,OAAO,CAAC,KAAK;CAgBd"}
@@ -0,0 +1,167 @@
1
+ // engine/worker-config-loader.ts — 3-layer configuration merge for workers (SPEC-138)
2
+ //
3
+ // THE PATTERN (specific to workers):
4
+ // Layer 1 (lowest): defaults from workers-registry.json (loaded separately, passed in)
5
+ // Layer 2: planu/workers.json — project-level overrides (optional, graceful if missing)
6
+ // Layer 3 (highest): PLANU_WORKER_<NAME>_<SETTING> env vars
7
+ //
8
+ // Env var format:
9
+ // PLANU_WORKER_TEST_GAPS_ENABLED=false
10
+ // PLANU_WORKER_SECURITY_AUDIT_COOLDOWNMS=60000
11
+ // PLANU_WORKER_OPTIMIZATION_PRIORITY=3
12
+ //
13
+ // Slug-to-env conversion: 'test-gaps' → 'TEST_GAPS' (hyphens → underscores, uppercase)
14
+ //
15
+ // Zero mutation guarantee: all returned values are new objects.
16
+ import { readFile } from 'node:fs/promises';
17
+ import { join } from 'node:path';
18
+ /**
19
+ * 3-layer configuration loader specific to workers.
20
+ *
21
+ * Layer 1: registry defaults (passed via load() calls externally)
22
+ * Layer 2: planu/workers.json (project-level overrides)
23
+ * Layer 3: PLANU_WORKER_<NAME>_<SETTING> environment variables
24
+ *
25
+ * Higher-precedence layers win field by field.
26
+ */
27
+ export class WorkerConfigLoader {
28
+ projectPath;
29
+ constructor(projectPath) {
30
+ this.projectPath = projectPath;
31
+ }
32
+ /**
33
+ * Load and merge all 3 layers. Returns final resolved override per worker.
34
+ * The returned Map contains only workers that have at least one override.
35
+ * Workers with no overrides in any layer are not present (use defaults as-is).
36
+ *
37
+ * @param workerNames - names of all known workers (to scan env for each)
38
+ */
39
+ async load(workerNames = []) {
40
+ const fileOverrides = await this.loadProjectFile();
41
+ const result = new Map();
42
+ // Collect all relevant worker names (from file + provided list)
43
+ const allNames = new Set([...Object.keys(fileOverrides), ...workerNames]);
44
+ for (const name of allNames) {
45
+ const fileLayer = fileOverrides[name] ?? {};
46
+ const envLayer = this.parseEnvOverride(name);
47
+ const merged = this.merge(fileLayer, envLayer);
48
+ // Only include if there is at least one defined field
49
+ if (Object.keys(merged).length > 0) {
50
+ result.set(name, merged);
51
+ }
52
+ }
53
+ return result;
54
+ }
55
+ /**
56
+ * Get the merged override for a specific worker (layers 2 + 3 only).
57
+ * Returns an empty object if no override is defined anywhere.
58
+ */
59
+ async getOverride(workerName) {
60
+ const fileOverrides = await this.loadProjectFile();
61
+ const fileLayer = fileOverrides[workerName] ?? {};
62
+ const envLayer = this.parseEnvOverride(workerName);
63
+ return this.merge(fileLayer, envLayer);
64
+ }
65
+ // -------------------------------------------------------------------------
66
+ // Private helpers
67
+ // -------------------------------------------------------------------------
68
+ /** Load planu/workers.json. Returns empty object if file doesn't exist. */
69
+ async loadProjectFile() {
70
+ const filePath = join(this.projectPath, 'planu', 'workers.json');
71
+ try {
72
+ const content = await readFile(filePath, 'utf-8');
73
+ const parsed = JSON.parse(content);
74
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
75
+ return {};
76
+ }
77
+ return this.coerceFileContent(parsed);
78
+ }
79
+ catch {
80
+ // File does not exist or is unreadable — graceful fallback
81
+ return {};
82
+ }
83
+ }
84
+ /** Coerce raw file content to Record<string, WorkerOverride>, ignoring unknown keys. */
85
+ coerceFileContent(raw) {
86
+ const result = {};
87
+ for (const [name, value] of Object.entries(raw)) {
88
+ if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
89
+ result[name] = this.coerceOverride(value);
90
+ }
91
+ }
92
+ return result;
93
+ }
94
+ /** Coerce a raw object to WorkerOverride, ignoring unknown keys. */
95
+ coerceOverride(raw) {
96
+ const override = {};
97
+ if (typeof raw.enabled === 'boolean') {
98
+ override.enabled = raw.enabled;
99
+ }
100
+ if (typeof raw.cooldownMs === 'number') {
101
+ override.cooldownMs = raw.cooldownMs;
102
+ }
103
+ if (typeof raw.priority === 'number') {
104
+ override.priority = raw.priority;
105
+ }
106
+ if (raw.tier === 'free' || raw.tier === 'pro') {
107
+ override.tier = raw.tier;
108
+ }
109
+ return override;
110
+ }
111
+ /**
112
+ * Parse environment variables for a specific worker.
113
+ *
114
+ * Slug-to-env: 'test-gaps' → 'TEST_GAPS'
115
+ * Full pattern: PLANU_WORKER_{WORKER_ENV}_{SETTING}
116
+ * Known settings: ENABLED (bool), COOLDOWNMS (number), PRIORITY (number), TIER (string)
117
+ */
118
+ parseEnvOverride(workerName) {
119
+ const envName = workerName.toUpperCase().replace(/-/g, '_');
120
+ const prefix = `PLANU_WORKER_${envName}_`;
121
+ const override = {};
122
+ const enabledRaw = process.env[`${prefix}ENABLED`];
123
+ if (enabledRaw !== undefined) {
124
+ override.enabled = enabledRaw.toLowerCase() === 'true';
125
+ }
126
+ const cooldownRaw = process.env[`${prefix}COOLDOWNMS`];
127
+ if (cooldownRaw !== undefined) {
128
+ const parsed = Number(cooldownRaw);
129
+ if (!Number.isNaN(parsed)) {
130
+ override.cooldownMs = parsed;
131
+ }
132
+ }
133
+ const priorityRaw = process.env[`${prefix}PRIORITY`];
134
+ if (priorityRaw !== undefined) {
135
+ const parsed = Number(priorityRaw);
136
+ if (!Number.isNaN(parsed)) {
137
+ override.priority = parsed;
138
+ }
139
+ }
140
+ const tierRaw = process.env[`${prefix}TIER`];
141
+ if (tierRaw === 'free' || tierRaw === 'pro') {
142
+ override.tier = tierRaw;
143
+ }
144
+ return override;
145
+ }
146
+ /**
147
+ * Merge two override objects. Right-hand side wins for defined fields.
148
+ * Returns a new object — zero mutation guarantee.
149
+ */
150
+ merge(base, override) {
151
+ const result = { ...base };
152
+ if (override.enabled !== undefined) {
153
+ result.enabled = override.enabled;
154
+ }
155
+ if (override.cooldownMs !== undefined) {
156
+ result.cooldownMs = override.cooldownMs;
157
+ }
158
+ if (override.priority !== undefined) {
159
+ result.priority = override.priority;
160
+ }
161
+ if (override.tier !== undefined) {
162
+ result.tier = override.tier;
163
+ }
164
+ return result;
165
+ }
166
+ }
167
+ //# sourceMappingURL=worker-config-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-config-loader.js","sourceRoot":"","sources":["../../src/engine/worker-config-loader.ts"],"names":[],"mappings":"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"}
@@ -5,4 +5,7 @@ export { runOptimization } from './handlers/optimization.js';
5
5
  export { runCodeMap } from './handlers/code-map.js';
6
6
  export { runDocumentation } from './handlers/documentation.js';
7
7
  export { runDependencyHealth } from './handlers/dependency-health.js';
8
+ export { WorkerHeartbeat } from './worker-heartbeat.js';
9
+ export { WorkerCrashRecovery } from './worker-crash-recovery.js';
10
+ export type { WorkerCrashMetrics } from './worker-crash-recovery.js';
8
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engine/workers/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engine/workers/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -6,4 +6,6 @@ export { runOptimization } from './handlers/optimization.js';
6
6
  export { runCodeMap } from './handlers/code-map.js';
7
7
  export { runDocumentation } from './handlers/documentation.js';
8
8
  export { runDependencyHealth } from './handlers/dependency-health.js';
9
+ export { WorkerHeartbeat } from './worker-heartbeat.js';
10
+ export { WorkerCrashRecovery } from './worker-crash-recovery.js';
9
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engine/workers/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,OAAO,EACL,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engine/workers/index.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,OAAO,EACL,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { WorkerCrashMetrics } from '../../types/index.js';
2
+ import type { WorkerEngine } from './worker-engine.js';
3
+ import type { WorkerHeartbeat } from './worker-heartbeat.js';
4
+ export type { WorkerCrashMetrics };
5
+ /**
6
+ * Listens for 'worker-dead' events from WorkerHeartbeat instances and
7
+ * auto-restarts the dead worker via WorkerEngine with exponential backoff.
8
+ * Stops restarting after maxRestarts consecutive crashes.
9
+ */
10
+ export declare class WorkerCrashRecovery {
11
+ private readonly engine;
12
+ private readonly maxRestarts;
13
+ private readonly metricsMap;
14
+ private readonly timers;
15
+ constructor(engine: WorkerEngine, options?: {
16
+ maxRestarts?: number;
17
+ });
18
+ /**
19
+ * Register a worker and its heartbeat monitor.
20
+ * The recovery manager will listen for 'worker-dead' events and react.
21
+ */
22
+ registerWorker(workerName: string, heartbeat: WorkerHeartbeat): void;
23
+ /** Returns current crash metrics for a given worker. */
24
+ getMetrics(workerName: string): WorkerCrashMetrics;
25
+ /** Reset crash counter for a worker (e.g. after manual intervention). */
26
+ resetMetrics(workerName: string): void;
27
+ private handleCrash;
28
+ private computeBackoff;
29
+ }
30
+ //# sourceMappingURL=worker-crash-recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-crash-recovery.d.ts","sourceRoot":"","sources":["../../../src/engine/workers/worker-crash-recovery.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAcnC;;;;GAIG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyC;IACpE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoD;gBAE/D,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE;IAKpE;;;OAGG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,GAAG,IAAI;IAgBpE,wDAAwD;IACxD,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB;IAYlD,yEAAyE;IACzE,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;YAoBxB,WAAW;IA+CzB,OAAO,CAAC,cAAc;CAIvB"}
@@ -0,0 +1,115 @@
1
+ // engine/workers/worker-crash-recovery.ts — Auto-restart on crash with backoff (SPEC-137)
2
+ // ---------------------------------------------------------------------------
3
+ // Constants
4
+ // ---------------------------------------------------------------------------
5
+ const DEFAULT_MAX_RESTARTS = 5;
6
+ const BASE_BACKOFF_MS = 1_000;
7
+ const MAX_BACKOFF_MS = 300_000; // 5 minutes
8
+ // ---------------------------------------------------------------------------
9
+ // WorkerCrashRecovery
10
+ // ---------------------------------------------------------------------------
11
+ /**
12
+ * Listens for 'worker-dead' events from WorkerHeartbeat instances and
13
+ * auto-restarts the dead worker via WorkerEngine with exponential backoff.
14
+ * Stops restarting after maxRestarts consecutive crashes.
15
+ */
16
+ export class WorkerCrashRecovery {
17
+ engine;
18
+ maxRestarts;
19
+ metricsMap = new Map();
20
+ timers = new Map();
21
+ constructor(engine, options) {
22
+ this.engine = engine;
23
+ this.maxRestarts = options?.maxRestarts ?? DEFAULT_MAX_RESTARTS;
24
+ }
25
+ /**
26
+ * Register a worker and its heartbeat monitor.
27
+ * The recovery manager will listen for 'worker-dead' events and react.
28
+ */
29
+ registerWorker(workerName, heartbeat) {
30
+ if (!this.metricsMap.has(workerName)) {
31
+ this.metricsMap.set(workerName, {
32
+ workerName,
33
+ restartCount: 0,
34
+ lastCrashAt: null,
35
+ lastRestartAt: null,
36
+ status: 'healthy',
37
+ });
38
+ }
39
+ heartbeat.on('worker-dead', (deadWorkerName) => {
40
+ void this.handleCrash(deadWorkerName);
41
+ });
42
+ }
43
+ /** Returns current crash metrics for a given worker. */
44
+ getMetrics(workerName) {
45
+ return (this.metricsMap.get(workerName) ?? {
46
+ workerName,
47
+ restartCount: 0,
48
+ lastCrashAt: null,
49
+ lastRestartAt: null,
50
+ status: 'healthy',
51
+ });
52
+ }
53
+ /** Reset crash counter for a worker (e.g. after manual intervention). */
54
+ resetMetrics(workerName) {
55
+ this.metricsMap.set(workerName, {
56
+ workerName,
57
+ restartCount: 0,
58
+ lastCrashAt: null,
59
+ lastRestartAt: null,
60
+ status: 'healthy',
61
+ });
62
+ const pendingTimer = this.timers.get(workerName);
63
+ if (pendingTimer !== undefined) {
64
+ clearTimeout(pendingTimer);
65
+ this.timers.delete(workerName);
66
+ }
67
+ }
68
+ // ---------------------------------------------------------------------------
69
+ // Private
70
+ // ---------------------------------------------------------------------------
71
+ async handleCrash(workerName) {
72
+ const current = this.metricsMap.get(workerName);
73
+ if (!current) {
74
+ return;
75
+ }
76
+ if (current.restartCount >= this.maxRestarts) {
77
+ this.metricsMap.set(workerName, {
78
+ ...current,
79
+ lastCrashAt: new Date().toISOString(),
80
+ status: 'dead',
81
+ });
82
+ return;
83
+ }
84
+ const backoffMs = this.computeBackoff(current.restartCount);
85
+ this.metricsMap.set(workerName, {
86
+ ...current,
87
+ lastCrashAt: new Date().toISOString(),
88
+ status: 'recovering',
89
+ });
90
+ await new Promise((resolve) => {
91
+ const timer = setTimeout(() => {
92
+ this.timers.delete(workerName);
93
+ resolve();
94
+ }, backoffMs);
95
+ this.timers.set(workerName, timer);
96
+ });
97
+ // Re-check in case resetMetrics was called during backoff
98
+ const afterBackoff = this.metricsMap.get(workerName);
99
+ if (!afterBackoff || afterBackoff.restartCount >= this.maxRestarts) {
100
+ return;
101
+ }
102
+ this.metricsMap.set(workerName, {
103
+ ...afterBackoff,
104
+ restartCount: afterBackoff.restartCount + 1,
105
+ lastRestartAt: new Date().toISOString(),
106
+ status: 'healthy',
107
+ });
108
+ this.engine.enqueue(workerName);
109
+ }
110
+ computeBackoff(restartCount) {
111
+ const backoff = BASE_BACKOFF_MS * Math.pow(2, restartCount);
112
+ return Math.min(backoff, MAX_BACKOFF_MS);
113
+ }
114
+ }
115
+ //# sourceMappingURL=worker-crash-recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-crash-recovery.js","sourceRoot":"","sources":["../../../src/engine/workers/worker-crash-recovery.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ export declare class WorkerEngine {
7
7
  private active;
8
8
  private totalRunsCompleted;
9
9
  private readonly overrides;
10
- loadRegistry(registryPath?: string): Promise<void>;
10
+ loadRegistry(registryPath?: string, projectPath?: string): Promise<void>;
11
11
  start(): void;
12
12
  stop(): void;
13
13
  isActive(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"worker-engine.d.ts","sourceRoot":"","sources":["../../../src/engine/workers/worker-engine.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EAErB,MAAM,sBAAsB,CAAC;AAiC9B,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAC5D,OAAO,CAAC,KAAK,CAAyD;IACtE,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2C;IAE/D,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBxD,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI;IAKZ,QAAQ,IAAI,OAAO;IAInB,oBAAoB,IAAI,gBAAgB,EAAE;IAI1C,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAwBvE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO;IA4CvD,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;YA6BpD,aAAa;IAoE3B,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAAG,YAAY,GAAG,SAAS;IAa7E,cAAc,IAAI,MAAM;CAGzB;AAQD,wBAAgB,eAAe,IAAI,YAAY,CAG9C;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAY/D"}
1
+ {"version":3,"file":"worker-engine.d.ts","sourceRoot":"","sources":["../../../src/engine/workers/worker-engine.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,oBAAoB,EAErB,MAAM,sBAAsB,CAAC;AAkC9B,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAC5D,OAAO,CAAC,KAAK,CAAyD;IACtE,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA2C;IAE/D,YAAY,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B9E,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI;IAKZ,QAAQ,IAAI,OAAO;IAInB,oBAAoB,IAAI,gBAAgB,EAAE;IAI1C,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAwBvE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO;IA4CvD,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;YA6BpD,aAAa;IAoE3B,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAAG,YAAY,GAAG,SAAS;IAa7E,cAAc,IAAI,MAAM;CAGzB;AAQD,wBAAgB,eAAe,IAAI,YAAY,CAG9C;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAKxC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAY/D"}
@@ -2,6 +2,7 @@
2
2
  import { readFile } from 'node:fs/promises';
3
3
  import { join } from 'node:path';
4
4
  import { WorkerRegistrySchema } from './schema.js';
5
+ import { WorkerConfigLoader } from '../worker-config-loader.js';
5
6
  import { runTestGaps } from './handlers/test-gaps.js';
6
7
  import { runSecurityAudit } from './handlers/security-audit.js';
7
8
  import { runOptimization } from './handlers/optimization.js';
@@ -35,7 +36,7 @@ export class WorkerEngine {
35
36
  active = false;
36
37
  totalRunsCompleted = 0;
37
38
  overrides = new Map();
38
- async loadRegistry(registryPath) {
39
+ async loadRegistry(registryPath, projectPath) {
39
40
  /* v8 ignore next */
40
41
  const path = registryPath ?? join(import.meta.dirname, '../../config/workers-registry.json');
41
42
  const raw = await readFile(path, 'utf-8');
@@ -53,6 +54,15 @@ export class WorkerEngine {
53
54
  });
54
55
  }
55
56
  }
57
+ // Apply 3-layer config overrides (project file + env vars) — SPEC-138
58
+ if (projectPath) {
59
+ const configLoader = new WorkerConfigLoader(projectPath);
60
+ const workerNames = this.workers.map((w) => w.name);
61
+ const overrides = await configLoader.load(workerNames);
62
+ for (const [name, override] of overrides) {
63
+ this.applyOverride(name, override);
64
+ }
65
+ }
56
66
  }
57
67
  start() {
58
68
  this.active = true;
@@ -1 +1 @@
1
- {"version":3,"file":"worker-engine.js","sourceRoot":"","sources":["../../../src/engine/workers/worker-engine.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAEhG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AASjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,WAAW,GAAoC;IACnD,oBAAoB,EAAE,WAAW;IACjC,yBAAyB,EAAE,gBAAgB;IAC3C,uBAAuB,EAAE,eAAe;IACxC,mBAAmB,EAAE,UAAU;IAC/B,wBAAwB,EAAE,gBAAgB;IAC1C,4BAA4B,EAAE,mBAAmB;CAClD,CAAC;AAEF,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC,YAAY;AAC5C,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAEnC,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E,MAAM,OAAO,YAAY;IACf,OAAO,GAAuB,EAAE,CAAC;IACxB,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;IACpD,KAAK,GAAsD,EAAE,CAAC;IAC9D,UAAU,GAAG,KAAK,CAAC;IACnB,MAAM,GAAG,KAAK,CAAC;IACf,kBAAkB,GAAG,CAAC,CAAC;IACd,SAAS,GAAG,IAAI,GAAG,EAAgC,CAAC;IAErE,KAAK,CAAC,YAAY,CAAC,YAAqB;QACtC,oBAAoB;QACpB,MAAM,IAAI,GAAG,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;QAC7F,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;QAEjC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE;oBACxB,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,OAAO,EAAE,CAAC,CAAC,OAAO;oBAClB,OAAO,EAAE,KAAK;oBACd,mBAAmB,EAAE,CAAC;oBACtB,mBAAmB,EAAE,CAAC,CAAC,UAAU;iBAClC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,oBAAoB;QAClB,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,aAAa,CAAC,UAAkB,EAAE,QAA8B;QAC9D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,MAAM,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC7C,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QACpC,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAC/D,IAAI,MAAM,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC7C,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QACpC,CAAC;QACD,IAAI,MAAM,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAChD,MAAM,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;QAC1C,CAAC;QACD,IAAI,MAAM,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC9C,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;QACtC,CAAC;QACD,IAAI,MAAM,IAAI,QAAQ,CAAC,eAAe,EAAE,CAAC;YACvC,MAAM,CAAC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,eAAe,CAAC;QACrD,CAAC;QACD,IAAI,MAAM,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAChD,MAAM,CAAC,mBAAmB,GAAG,QAAQ,CAAC,UAAU,CAAC;QACnD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,UAAkB,EAAE,YAAuB;QACjD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC;QACf,CAAC;QAED,iBAAiB;QACjB,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;YACnE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC;YACzC,IAAI,OAAO,GAAG,MAAM,CAAC,mBAAmB,EAAE,CAAC;gBACzC,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,yEAAyE;QACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;QACrE,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,YAAY,EAAE,CAAC;gBACjB,QAAQ,CAAC,YAAY,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5F,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC;QAC9C,wCAAwC;QACxC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACvB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,UAAU,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC;YAC5E,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,UAAU,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC;YAC5E,OAAO,EAAE,GAAG,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,UAAkB;QACnC,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,MAAM,OAAO,GAAsB,EAAE,CAAC;QAEtC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChC,kEAAkE;gBAClE,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,MAAM;gBACR,CAAC;gBACD,oBAAoB;gBAEpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;gBACxF,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC1B,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,UAAkB,EAClB,UAAkB,EAClB,YAAuB;QAEvB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAC/D,0EAA0E;QAC1E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,oBAAoB;QAEpB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,4EAA4E;QAC5E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,oBAAoB;QAEpB,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,UAAU;gBACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACrC,UAAU,EAAE,CAAC;gBACb,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,EAAE;gBACZ,KAAK,EAAE,yBAAyB,MAAM,CAAC,OAAO,GAAG;gBACjD,aAAa,EAAE,CAAC;aACjB,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QAEtB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;YACvD,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;YACvB,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC;YACxB,MAAM,CAAC,mBAAmB,GAAG,CAAC,CAAC;YAC/B,MAAM,CAAC,mBAAmB,GAAG,MAAM,CAAC,UAAU,CAAC;YAC/C,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;YACvB,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAE7B,kCAAkC;YAClC,IAAI,MAAM,CAAC,mBAAmB,IAAI,wBAAwB,EAAE,CAAC;gBAC3D,MAAM,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,mBAAmB,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;YACxF,CAAC;YAED,MAAM,WAAW,GAAoB;gBACnC,UAAU;gBACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACrC,UAAU,EAAE,CAAC;gBACb,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,EAAE;gBACZ,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;gBACvD,aAAa,EAAE,CAAC;aACjB,CAAC;YACF,MAAM,CAAC,OAAO,GAAG,WAAW,CAAC;YAC7B,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,OAAO,WAAW,CAAC;QACrB,CAAC;IACH,CAAC;IAED,SAAS,CAAC,UAAmB;QAC3B,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;QAED,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC3C,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YAC9B,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;SAC5C,CAAC;IACJ,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;CACF;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,IAAI,cAAwC,CAAC;AAE7C,MAAM,UAAU,eAAe;IAC7B,cAAc,KAAK,IAAI,YAAY,EAAE,CAAC;IACtC,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,IAAI,cAAc,EAAE,CAAC;QACnB,cAAc,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC;IACD,cAAc,GAAG,SAAS,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,YAAoB;IACvD,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QACtB,OAAO;IACT,CAAC;IACD,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;QAC5B,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QAC1B,8CAA8C;QAC9C,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,GAAG,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"worker-engine.js","sourceRoot":"","sources":["../../../src/engine/workers/worker-engine.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAEhG,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AASjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAEtE,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,WAAW,GAAoC;IACnD,oBAAoB,EAAE,WAAW;IACjC,yBAAyB,EAAE,gBAAgB;IAC3C,uBAAuB,EAAE,eAAe;IACxC,mBAAmB,EAAE,UAAU;IAC/B,wBAAwB,EAAE,gBAAgB;IAC1C,4BAA4B,EAAE,mBAAmB;CAClD,CAAC;AAEF,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,cAAc,GAAG,OAAO,CAAC,CAAC,YAAY;AAC5C,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAEnC,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E,MAAM,OAAO,YAAY;IACf,OAAO,GAAuB,EAAE,CAAC;IACxB,QAAQ,GAAG,IAAI,GAAG,EAAwB,CAAC;IACpD,KAAK,GAAsD,EAAE,CAAC;IAC9D,UAAU,GAAG,KAAK,CAAC;IACnB,MAAM,GAAG,KAAK,CAAC;IACf,kBAAkB,GAAG,CAAC,CAAC;IACd,SAAS,GAAG,IAAI,GAAG,EAAgC,CAAC;IAErE,KAAK,CAAC,YAAY,CAAC,YAAqB,EAAE,WAAoB;QAC5D,oBAAoB;QACpB,MAAM,IAAI,GAAG,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,oCAAoC,CAAC,CAAC;QAC7F,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;QAEjC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE;oBACxB,IAAI,EAAE,CAAC,CAAC,IAAI;oBACZ,OAAO,EAAE,CAAC,CAAC,OAAO;oBAClB,OAAO,EAAE,KAAK;oBACd,mBAAmB,EAAE,CAAC;oBACtB,mBAAmB,EAAE,CAAC,CAAC,UAAU;iBAClC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,YAAY,GAAG,IAAI,kBAAkB,CAAC,WAAW,CAAC,CAAC;YACzD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACpD,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACvD,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;gBACzC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;IAClB,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,oBAAoB;QAClB,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,aAAa,CAAC,UAAkB,EAAE,QAA8B;QAC9D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,MAAM,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC7C,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QACpC,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAC/D,IAAI,MAAM,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC7C,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QACpC,CAAC;QACD,IAAI,MAAM,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAChD,MAAM,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;QAC1C,CAAC;QACD,IAAI,MAAM,IAAI,QAAQ,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC9C,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC;QACtC,CAAC;QACD,IAAI,MAAM,IAAI,QAAQ,CAAC,eAAe,EAAE,CAAC;YACvC,MAAM,CAAC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,eAAe,CAAC;QACrD,CAAC;QACD,IAAI,MAAM,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAChD,MAAM,CAAC,mBAAmB,GAAG,QAAQ,CAAC,UAAU,CAAC;QACnD,CAAC;IACH,CAAC;IAED,OAAO,CAAC,UAAkB,EAAE,YAAuB;QACjD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YACrB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,KAAK,CAAC;QACf,CAAC;QAED,iBAAiB;QACjB,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC;YACnE,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,CAAC;YACzC,IAAI,OAAO,GAAG,MAAM,CAAC,mBAAmB,EAAE,CAAC;gBACzC,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QAED,yEAAyE;QACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;QACrE,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,YAAY,EAAE,CAAC;gBACjB,QAAQ,CAAC,YAAY,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;YAC5F,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC;QAC9C,wCAAwC;QACxC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACvB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,UAAU,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC;YAC5E,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,UAAU,CAAC,EAAE,QAAQ,IAAI,CAAC,CAAC;YAC5E,OAAO,EAAE,GAAG,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,UAAkB;QACnC,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,MAAM,OAAO,GAAsB,EAAE,CAAC;QAEtC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChC,kEAAkE;gBAClE,IAAI,CAAC,IAAI,EAAE,CAAC;oBACV,MAAM;gBACR,CAAC;gBACD,oBAAoB;gBAEpB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;gBACxF,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QAC1B,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,KAAK,CAAC,aAAa,CACzB,UAAkB,EAClB,UAAkB,EAClB,YAAuB;QAEvB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAC/D,0EAA0E;QAC1E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,oBAAoB;QAEpB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC7C,4EAA4E;QAC5E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,oBAAoB;QAEpB,MAAM,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,UAAU;gBACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACrC,UAAU,EAAE,CAAC;gBACb,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,EAAE;gBACZ,KAAK,EAAE,yBAAyB,MAAM,CAAC,OAAO,GAAG;gBACjD,aAAa,EAAE,CAAC;aACjB,CAAC;QACJ,CAAC;QAED,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QAEtB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;YACvD,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;YACvB,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC;YACxB,MAAM,CAAC,mBAAmB,GAAG,CAAC,CAAC;YAC/B,MAAM,CAAC,mBAAmB,GAAG,MAAM,CAAC,UAAU,CAAC;YAC/C,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;YACvB,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAE7B,kCAAkC;YAClC,IAAI,MAAM,CAAC,mBAAmB,IAAI,wBAAwB,EAAE,CAAC;gBAC3D,MAAM,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,mBAAmB,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;YACxF,CAAC;YAED,MAAM,WAAW,GAAoB;gBACnC,UAAU;gBACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACrC,UAAU,EAAE,CAAC;gBACb,MAAM,EAAE,OAAO;gBACf,QAAQ,EAAE,EAAE;gBACZ,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;gBACvD,aAAa,EAAE,CAAC;aACjB,CAAC;YACF,MAAM,CAAC,OAAO,GAAG,WAAW,CAAC;YAC7B,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC1B,OAAO,WAAW,CAAC;QACrB,CAAC;IACH,CAAC;IAED,SAAS,CAAC,UAAmB;QAC3B,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;QAED,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC3C,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM;YAC9B,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;SAC5C,CAAC;IACJ,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;CACF;AAED,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E,IAAI,cAAwC,CAAC;AAE7C,MAAM,UAAU,eAAe;IAC7B,cAAc,KAAK,IAAI,YAAY,EAAE,CAAC;IACtC,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,IAAI,cAAc,EAAE,CAAC;QACnB,cAAc,CAAC,IAAI,EAAE,CAAC;IACxB,CAAC;IACD,cAAc,GAAG,SAAS,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,YAAoB;IACvD,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;QACtB,OAAO;IACT,CAAC;IACD,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;QAC5B,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QAC1B,8CAA8C;QAC9C,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,GAAG,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { EventEmitter } from 'node:events';
2
+ /**
3
+ * Monitors a single worker via periodic ping checks.
4
+ * Emits 'worker-dead' when the worker has been silent beyond maxSilenceMs.
5
+ * Uses setTimeout loops (not setInterval) for clean teardown.
6
+ */
7
+ export declare class WorkerHeartbeat extends EventEmitter {
8
+ private readonly workerName;
9
+ private readonly intervalMs;
10
+ private readonly maxSilenceMs;
11
+ private lastPing;
12
+ private timer;
13
+ private running;
14
+ constructor(workerName: string, options?: {
15
+ intervalMs?: number;
16
+ maxSilenceMs?: number;
17
+ });
18
+ /** Start the heartbeat monitoring loop. Idempotent. */
19
+ start(): void;
20
+ /** Stop the heartbeat loop. Safe to call multiple times. */
21
+ stop(): void;
22
+ /**
23
+ * Called by the worker process to signal it is alive.
24
+ * Resets the silence counter.
25
+ */
26
+ ping(): void;
27
+ /** Returns true if the worker pinged recently (within maxSilenceMs). */
28
+ isAlive(): boolean;
29
+ /** Returns the timestamp of the last ping, or null if never pinged. */
30
+ getLastPing(): Date | null;
31
+ private scheduleCheck;
32
+ private check;
33
+ }
34
+ //# sourceMappingURL=worker-heartbeat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-heartbeat.d.ts","sourceRoot":"","sources":["../../../src/engine/workers/worker-heartbeat.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAa3C;;;;GAIG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,OAAO,CAAS;gBAEZ,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE;IAOxF,uDAAuD;IACvD,KAAK,IAAI,IAAI;IAQb,4DAA4D;IAC5D,IAAI,IAAI,IAAI;IAQZ;;;OAGG;IACH,IAAI,IAAI,IAAI;IAIZ,wEAAwE;IACxE,OAAO,IAAI,OAAO;IAOlB,uEAAuE;IACvE,WAAW,IAAI,IAAI,GAAG,IAAI;IAQ1B,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,KAAK;CAWd"}
@@ -0,0 +1,84 @@
1
+ // engine/workers/worker-heartbeat.ts — Heartbeat monitor for background workers (SPEC-137)
2
+ import { EventEmitter } from 'node:events';
3
+ // ---------------------------------------------------------------------------
4
+ // Constants
5
+ // ---------------------------------------------------------------------------
6
+ const DEFAULT_INTERVAL_MS = 30_000; // 30 seconds
7
+ const DEFAULT_MAX_SILENCE_MS = 90_000; // 3 x interval
8
+ // ---------------------------------------------------------------------------
9
+ // WorkerHeartbeat
10
+ // ---------------------------------------------------------------------------
11
+ /**
12
+ * Monitors a single worker via periodic ping checks.
13
+ * Emits 'worker-dead' when the worker has been silent beyond maxSilenceMs.
14
+ * Uses setTimeout loops (not setInterval) for clean teardown.
15
+ */
16
+ export class WorkerHeartbeat extends EventEmitter {
17
+ workerName;
18
+ intervalMs;
19
+ maxSilenceMs;
20
+ lastPing = null;
21
+ timer = null;
22
+ running = false;
23
+ constructor(workerName, options) {
24
+ super();
25
+ this.workerName = workerName;
26
+ this.intervalMs = options?.intervalMs ?? DEFAULT_INTERVAL_MS;
27
+ this.maxSilenceMs = options?.maxSilenceMs ?? DEFAULT_MAX_SILENCE_MS;
28
+ }
29
+ /** Start the heartbeat monitoring loop. Idempotent. */
30
+ start() {
31
+ if (this.running) {
32
+ return;
33
+ }
34
+ this.running = true;
35
+ this.scheduleCheck();
36
+ }
37
+ /** Stop the heartbeat loop. Safe to call multiple times. */
38
+ stop() {
39
+ this.running = false;
40
+ if (this.timer !== null) {
41
+ clearTimeout(this.timer);
42
+ this.timer = null;
43
+ }
44
+ }
45
+ /**
46
+ * Called by the worker process to signal it is alive.
47
+ * Resets the silence counter.
48
+ */
49
+ ping() {
50
+ this.lastPing = new Date();
51
+ }
52
+ /** Returns true if the worker pinged recently (within maxSilenceMs). */
53
+ isAlive() {
54
+ if (this.lastPing === null) {
55
+ return false;
56
+ }
57
+ return Date.now() - this.lastPing.getTime() < this.maxSilenceMs;
58
+ }
59
+ /** Returns the timestamp of the last ping, or null if never pinged. */
60
+ getLastPing() {
61
+ return this.lastPing;
62
+ }
63
+ // ---------------------------------------------------------------------------
64
+ // Private
65
+ // ---------------------------------------------------------------------------
66
+ scheduleCheck() {
67
+ if (!this.running) {
68
+ return;
69
+ }
70
+ this.timer = setTimeout(() => {
71
+ this.check();
72
+ }, this.intervalMs);
73
+ }
74
+ check() {
75
+ if (!this.running) {
76
+ return;
77
+ }
78
+ if (this.lastPing !== null && !this.isAlive()) {
79
+ this.emit('worker-dead', this.workerName);
80
+ }
81
+ this.scheduleCheck();
82
+ }
83
+ }
84
+ //# sourceMappingURL=worker-heartbeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-heartbeat.js","sourceRoot":"","sources":["../../../src/engine/workers/worker-heartbeat.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAE3F,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,mBAAmB,GAAG,MAAM,CAAC,CAAC,aAAa;AACjD,MAAM,sBAAsB,GAAG,MAAM,CAAC,CAAC,eAAe;AAEtD,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,OAAO,eAAgB,SAAQ,YAAY;IAC9B,UAAU,CAAS;IACnB,UAAU,CAAS;IACnB,YAAY,CAAS;IAC9B,QAAQ,GAAgB,IAAI,CAAC;IAC7B,KAAK,GAAyC,IAAI,CAAC;IACnD,OAAO,GAAG,KAAK,CAAC;IAExB,YAAY,UAAkB,EAAE,OAAwD;QACtF,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,mBAAmB,CAAC;QAC7D,IAAI,CAAC,YAAY,GAAG,OAAO,EAAE,YAAY,IAAI,sBAAsB,CAAC;IACtE,CAAC;IAED,uDAAuD;IACvD,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAED,4DAA4D;IAC5D,IAAI;QACF,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,IAAI;QACF,IAAI,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,wEAAwE;IACxE,OAAO;QACL,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC;IAClE,CAAC;IAED,uEAAuE;IACvE,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,8EAA8E;IAC9E,UAAU;IACV,8EAA8E;IAEtE,aAAa;QACnB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACtB,CAAC;IAEO,KAAK;QACX,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YAC9C,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,20 @@
1
+ import type { WorkerCrashMetrics, WorkerMetricsData } from '../types/index.js';
2
+ export type { WorkerMetricsData };
3
+ /**
4
+ * Persists worker crash / restart metrics to
5
+ * data/{projectId}/workers/worker-metrics.json.
6
+ *
7
+ * Follows the same JSON-store pattern used across the storage layer.
8
+ */
9
+ export declare class WorkerMetricsStore {
10
+ private readonly projectId;
11
+ constructor(projectId: string);
12
+ load(): Promise<WorkerMetricsData>;
13
+ save(data: WorkerMetricsData): Promise<void>;
14
+ recordCrash(workerName: string): Promise<void>;
15
+ recordRestart(workerName: string): Promise<void>;
16
+ getMetrics(workerName: string): Promise<WorkerCrashMetrics>;
17
+ reset(workerName: string): Promise<void>;
18
+ private getOrCreate;
19
+ }
20
+ //# sourceMappingURL=worker-metrics-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-metrics-store.d.ts","sourceRoot":"","sources":["../../src/storage/worker-metrics-store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI/E,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAclC;;;;;GAKG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,SAAS,EAAE,MAAM;IAIvB,IAAI,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAOlC,IAAI,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB9C,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBhD,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAa3D,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB9C,OAAO,CAAC,WAAW;CAWpB"}
@@ -0,0 +1,103 @@
1
+ // storage/worker-metrics-store.ts — Persists worker crash metrics (SPEC-137)
2
+ import { readJson, writeJson, projectDataDir } from './base-store.js';
3
+ import { withFileLock } from './file-mutex.js';
4
+ // ---------------------------------------------------------------------------
5
+ // File path
6
+ // ---------------------------------------------------------------------------
7
+ function metricsFile(projectId) {
8
+ return `${projectDataDir(projectId)}/workers/worker-metrics.json`;
9
+ }
10
+ // ---------------------------------------------------------------------------
11
+ // WorkerMetricsStore
12
+ // ---------------------------------------------------------------------------
13
+ /**
14
+ * Persists worker crash / restart metrics to
15
+ * data/{projectId}/workers/worker-metrics.json.
16
+ *
17
+ * Follows the same JSON-store pattern used across the storage layer.
18
+ */
19
+ export class WorkerMetricsStore {
20
+ projectId;
21
+ constructor(projectId) {
22
+ this.projectId = projectId;
23
+ }
24
+ async load() {
25
+ return readJson(metricsFile(this.projectId), {
26
+ workers: {},
27
+ lastUpdated: new Date().toISOString(),
28
+ });
29
+ }
30
+ async save(data) {
31
+ await writeJson(metricsFile(this.projectId), data);
32
+ }
33
+ async recordCrash(workerName) {
34
+ await withFileLock(metricsFile(this.projectId), async () => {
35
+ const data = await this.load();
36
+ const entry = this.getOrCreate(data, workerName);
37
+ const updated = {
38
+ ...entry,
39
+ lastCrashAt: new Date().toISOString(),
40
+ status: 'recovering',
41
+ };
42
+ await this.save({
43
+ workers: { ...data.workers, [workerName]: updated },
44
+ lastUpdated: new Date().toISOString(),
45
+ });
46
+ });
47
+ }
48
+ async recordRestart(workerName) {
49
+ await withFileLock(metricsFile(this.projectId), async () => {
50
+ const data = await this.load();
51
+ const entry = this.getOrCreate(data, workerName);
52
+ const updated = {
53
+ ...entry,
54
+ restartCount: entry.restartCount + 1,
55
+ lastRestartAt: new Date().toISOString(),
56
+ status: 'healthy',
57
+ };
58
+ await this.save({
59
+ workers: { ...data.workers, [workerName]: updated },
60
+ lastUpdated: new Date().toISOString(),
61
+ });
62
+ });
63
+ }
64
+ async getMetrics(workerName) {
65
+ const data = await this.load();
66
+ return (data.workers[workerName] ?? {
67
+ workerName,
68
+ restartCount: 0,
69
+ lastCrashAt: null,
70
+ lastRestartAt: null,
71
+ status: 'healthy',
72
+ });
73
+ }
74
+ async reset(workerName) {
75
+ await withFileLock(metricsFile(this.projectId), async () => {
76
+ const data = await this.load();
77
+ const clean = {
78
+ workerName,
79
+ restartCount: 0,
80
+ lastCrashAt: null,
81
+ lastRestartAt: null,
82
+ status: 'healthy',
83
+ };
84
+ await this.save({
85
+ workers: { ...data.workers, [workerName]: clean },
86
+ lastUpdated: new Date().toISOString(),
87
+ });
88
+ });
89
+ }
90
+ // ---------------------------------------------------------------------------
91
+ // Private helpers
92
+ // ---------------------------------------------------------------------------
93
+ getOrCreate(data, workerName) {
94
+ return (data.workers[workerName] ?? {
95
+ workerName,
96
+ restartCount: 0,
97
+ lastCrashAt: null,
98
+ lastRestartAt: null,
99
+ status: 'healthy',
100
+ });
101
+ }
102
+ }
103
+ //# sourceMappingURL=worker-metrics-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-metrics-store.js","sourceRoot":"","sources":["../../src/storage/worker-metrics-store.ts"],"names":[],"mappings":"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"}
@@ -61,6 +61,13 @@ export interface WorkerConfigOverride {
61
61
  priority?: number;
62
62
  triggerPatterns?: string[];
63
63
  }
64
+ /** Lightweight override used by WorkerConfigLoader (SPEC-138) — no triggerPatterns */
65
+ export interface WorkerOverride {
66
+ enabled?: boolean;
67
+ cooldownMs?: number;
68
+ priority?: number;
69
+ tier?: WorkerTier;
70
+ }
64
71
  export interface WorkerProjectConfig {
65
72
  overrides: Record<string, WorkerConfigOverride>;
66
73
  lastUpdated: string;
@@ -129,4 +136,15 @@ export interface ConfigureWorkersInput {
129
136
  action: ConfigureWorkersAction;
130
137
  value?: string | number;
131
138
  }
139
+ export interface WorkerCrashMetrics {
140
+ workerName: string;
141
+ restartCount: number;
142
+ lastCrashAt: string | null;
143
+ lastRestartAt: string | null;
144
+ status: 'healthy' | 'recovering' | 'dead';
145
+ }
146
+ export interface WorkerMetricsData {
147
+ workers: Record<string, WorkerCrashMetrics>;
148
+ lastUpdated: string;
149
+ }
132
150
  //# sourceMappingURL=workers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"workers.d.ts","sourceRoot":"","sources":["../../src/types/workers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workers.d.ts","sourceRoot":"","sources":["../../src/types/workers.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planu/cli",
3
- "version": "0.81.1",
3
+ "version": "0.82.0",
4
4
  "description": "Planu — MCP Server for Spec Driven Development. Manages specs, estimations, reverse engineering, and auto-learning across any language/framework.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -488,6 +488,20 @@
488
488
  "workerTitle": "⚙️ **Worker Status**",
489
489
  "swarmTitle": "🐝 **Agent Swarm Status**",
490
490
  "sessionsTitle": "📋 **Sessions**"
491
+ },
492
+ "reconcileSpec": {
493
+ "description": "Reconcile a spec with the current implementation state",
494
+ "specId": "Spec ID",
495
+ "totalChanges": "Total Changes",
496
+ "approvedChanges": "Approved Changes",
497
+ "pendingChanges": "Pending Changes",
498
+ "versionCreated": "Version Created",
499
+ "changelogUpdated": "Changelog Updated",
500
+ "yes": "Yes",
501
+ "livingSpec": "Living Spec",
502
+ "coverage": "coverage",
503
+ "nextValidate": "Run `validate` to check implementation coverage",
504
+ "nextDrift": "Run `detect_drift` to check for recent divergence"
491
505
  }
492
506
  },
493
507
  "resources": {
@@ -488,6 +488,20 @@
488
488
  "workerTitle": "⚙️ **Estado de Workers**",
489
489
  "swarmTitle": "🐝 **Estado del Enjambre de Agentes**",
490
490
  "sessionsTitle": "📋 **Sesiones**"
491
+ },
492
+ "reconcileSpec": {
493
+ "description": "Reconcilia una spec con el estado actual de la implementación",
494
+ "specId": "ID de Spec",
495
+ "totalChanges": "Total de Cambios",
496
+ "approvedChanges": "Cambios Aprobados",
497
+ "pendingChanges": "Cambios Pendientes",
498
+ "versionCreated": "Versión Creada",
499
+ "changelogUpdated": "Changelog Actualizado",
500
+ "yes": "Sí",
501
+ "livingSpec": "Spec Viva",
502
+ "coverage": "cobertura",
503
+ "nextValidate": "Ejecuta `validate` para verificar la cobertura de implementación",
504
+ "nextDrift": "Ejecuta `detect_drift` para verificar divergencia reciente"
491
505
  }
492
506
  },
493
507
  "resources": {
@@ -488,6 +488,20 @@
488
488
  "workerTitle": "⚙️ **Status dos Workers**",
489
489
  "swarmTitle": "🐝 **Status do Enxame de Agentes**",
490
490
  "sessionsTitle": "📋 **Sessões**"
491
+ },
492
+ "reconcileSpec": {
493
+ "description": "Reconcilia uma spec com o estado atual da implementação",
494
+ "specId": "ID da Spec",
495
+ "totalChanges": "Total de Mudanças",
496
+ "approvedChanges": "Mudanças Aprovadas",
497
+ "pendingChanges": "Mudanças Pendentes",
498
+ "versionCreated": "Versão Criada",
499
+ "changelogUpdated": "Changelog Atualizado",
500
+ "yes": "Sim",
501
+ "livingSpec": "Spec Viva",
502
+ "coverage": "cobertura",
503
+ "nextValidate": "Execute `validate` para verificar a cobertura da implementação",
504
+ "nextDrift": "Execute `detect_drift` para verificar divergência recente"
491
505
  }
492
506
  },
493
507
  "resources": {