@telora/daemon 0.15.3 → 0.15.4

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 (98) hide show
  1. package/build-info.json +2 -2
  2. package/dist/directive-executor.d.ts +18 -3
  3. package/dist/directive-executor.d.ts.map +1 -1
  4. package/dist/directive-executor.js +45 -4
  5. package/dist/directive-executor.js.map +1 -1
  6. package/dist/focus-executor.d.ts.map +1 -1
  7. package/dist/focus-executor.js +30 -13
  8. package/dist/focus-executor.js.map +1 -1
  9. package/dist/focus-phase.d.ts +22 -0
  10. package/dist/focus-phase.d.ts.map +1 -0
  11. package/dist/focus-phase.js +54 -0
  12. package/dist/focus-phase.js.map +1 -0
  13. package/dist/index.js +0 -0
  14. package/dist/queries/focuses.d.ts +3 -0
  15. package/dist/queries/focuses.d.ts.map +1 -1
  16. package/dist/queries/focuses.js +8 -0
  17. package/dist/queries/focuses.js.map +1 -1
  18. package/package.json +2 -2
  19. package/dist/listener-review.d.ts +0 -37
  20. package/dist/listener-review.d.ts.map +0 -1
  21. package/dist/listener-review.js +0 -217
  22. package/dist/listener-review.js.map +0 -1
  23. package/dist/queries/strategies.d.ts +0 -97
  24. package/dist/queries/strategies.d.ts.map +0 -1
  25. package/dist/queries/strategies.js +0 -136
  26. package/dist/queries/strategies.js.map +0 -1
  27. package/dist/review-spawner.d.ts +0 -32
  28. package/dist/review-spawner.d.ts.map +0 -1
  29. package/dist/review-spawner.js +0 -170
  30. package/dist/review-spawner.js.map +0 -1
  31. package/dist/strategy-completion-event.d.ts +0 -63
  32. package/dist/strategy-completion-event.d.ts.map +0 -1
  33. package/dist/strategy-completion-event.js +0 -138
  34. package/dist/strategy-completion-event.js.map +0 -1
  35. package/dist/strategy-completion.d.ts +0 -85
  36. package/dist/strategy-completion.d.ts.map +0 -1
  37. package/dist/strategy-completion.js +0 -459
  38. package/dist/strategy-completion.js.map +0 -1
  39. package/dist/strategy-engine.d.ts +0 -47
  40. package/dist/strategy-engine.d.ts.map +0 -1
  41. package/dist/strategy-engine.js +0 -421
  42. package/dist/strategy-engine.js.map +0 -1
  43. package/dist/strategy-executor.d.ts +0 -55
  44. package/dist/strategy-executor.d.ts.map +0 -1
  45. package/dist/strategy-executor.js +0 -519
  46. package/dist/strategy-executor.js.map +0 -1
  47. package/dist/strategy-lifecycle.d.ts +0 -61
  48. package/dist/strategy-lifecycle.d.ts.map +0 -1
  49. package/dist/strategy-lifecycle.js +0 -544
  50. package/dist/strategy-lifecycle.js.map +0 -1
  51. package/dist/strategy-merge.d.ts +0 -77
  52. package/dist/strategy-merge.d.ts.map +0 -1
  53. package/dist/strategy-merge.js +0 -378
  54. package/dist/strategy-merge.js.map +0 -1
  55. package/dist/strategy-prompt-builder.d.ts +0 -24
  56. package/dist/strategy-prompt-builder.d.ts.map +0 -1
  57. package/dist/strategy-prompt-builder.js +0 -87
  58. package/dist/strategy-prompt-builder.js.map +0 -1
  59. package/dist/strategy-provisioning.d.ts +0 -16
  60. package/dist/strategy-provisioning.d.ts.map +0 -1
  61. package/dist/strategy-provisioning.js +0 -119
  62. package/dist/strategy-provisioning.js.map +0 -1
  63. package/dist/strategy-spawn-helpers.d.ts +0 -67
  64. package/dist/strategy-spawn-helpers.d.ts.map +0 -1
  65. package/dist/strategy-spawn-helpers.js +0 -160
  66. package/dist/strategy-spawn-helpers.js.map +0 -1
  67. package/dist/strategy-team-lifecycle.d.ts +0 -50
  68. package/dist/strategy-team-lifecycle.d.ts.map +0 -1
  69. package/dist/strategy-team-lifecycle.js +0 -256
  70. package/dist/strategy-team-lifecycle.js.map +0 -1
  71. package/dist/strategy-team-state.d.ts +0 -24
  72. package/dist/strategy-team-state.d.ts.map +0 -1
  73. package/dist/strategy-team-state.js +0 -43
  74. package/dist/strategy-team-state.js.map +0 -1
  75. package/dist/strategy-teardown.d.ts +0 -24
  76. package/dist/strategy-teardown.d.ts.map +0 -1
  77. package/dist/strategy-teardown.js +0 -158
  78. package/dist/strategy-teardown.js.map +0 -1
  79. package/dist/strategy-worktree-state.d.ts +0 -47
  80. package/dist/strategy-worktree-state.d.ts.map +0 -1
  81. package/dist/strategy-worktree-state.js +0 -104
  82. package/dist/strategy-worktree-state.js.map +0 -1
  83. package/dist/team-prompt-variants.d.ts +0 -17
  84. package/dist/team-prompt-variants.d.ts.map +0 -1
  85. package/dist/team-prompt-variants.js +0 -79
  86. package/dist/team-prompt-variants.js.map +0 -1
  87. package/dist/types/strategy.d.ts +0 -180
  88. package/dist/types/strategy.d.ts.map +0 -1
  89. package/dist/types/strategy.js +0 -5
  90. package/dist/types/strategy.js.map +0 -1
  91. package/dist/worktree-merge.d.ts +0 -23
  92. package/dist/worktree-merge.d.ts.map +0 -1
  93. package/dist/worktree-merge.js +0 -57
  94. package/dist/worktree-merge.js.map +0 -1
  95. package/dist/worktree-strategy.d.ts +0 -69
  96. package/dist/worktree-strategy.d.ts.map +0 -1
  97. package/dist/worktree-strategy.js +0 -214
  98. package/dist/worktree-strategy.js.map +0 -1
@@ -1,256 +0,0 @@
1
- /**
2
- * Strategy team lifecycle management - terminate, wait, detect deactivated.
3
- *
4
- * Extracted from strategy-executor.ts. These functions manage the lifecycle
5
- * of running strategy teams (shutdown, deactivation detection, merge checks).
6
- */
7
- import { getReadyStrategies, } from './supabase.js';
8
- import { sendMessage } from '@telora/daemon-core';
9
- import { clearNarration } from './heartbeat.js';
10
- import { getActiveTeams } from './strategy-team-state.js';
11
- import { mergeStrategyBranch, escalateMergeConflict } from './strategy-merge.js';
12
- import { mergeIntegrationToMain } from './git-merge.js';
13
- import { reportGitState } from './supabase.js';
14
- import { isStatusAgentActionable, isStatusBlocking, isStatusExcludedFromCascade } from './stage-classifier.js';
15
- import { getStrategyDeliveries } from './queries/strategies.js';
16
- import { configForProduct, findProduct } from './config.js';
17
- // ── Team lifecycle ──────────────────────────────────────────────────────
18
- /**
19
- * Terminate a strategy team.
20
- *
21
- * Sends a deactivation message via stdin (if open) before SIGTERM
22
- * to allow the team lead to process the shutdown gracefully.
23
- */
24
- export function terminateTeam(strategyId) {
25
- const activeTeams = getActiveTeams();
26
- const team = activeTeams.get(strategyId);
27
- if (!team || !team.leadPid)
28
- return false;
29
- // Warn if terminating while conflict resolution is in progress
30
- if (team.resolvingMergeConflict) {
31
- console.warn(`[strategy-executor] Terminating team "${team.strategyName}" while merge conflict resolution is in progress`);
32
- }
33
- console.log(`[strategy-executor] Terminating team for strategy "${team.strategyName}" (phase: ${team.phase})`);
34
- team.phase = 'shutting_down';
35
- clearNarration(strategyId);
36
- try {
37
- // Send a deactivation message first to let the team lead process it
38
- if (team.leadStdin) {
39
- sendMessage(team.leadStdin, 'Pipeline deactivated. Exit now.');
40
- // Close stdin after a short delay to let the message be processed
41
- setTimeout(() => {
42
- try {
43
- team.leadStdin?.end();
44
- }
45
- catch (e) {
46
- console.debug('[strategy-executor] stdin.end() failed (may already be closed):', e.message);
47
- }
48
- }, 5000);
49
- }
50
- // SIGTERM to the lead process -- it should clean up workers
51
- process.kill(team.leadPid, 'SIGTERM');
52
- // Escalate to SIGKILL after timeout
53
- setTimeout(() => {
54
- if (activeTeams.has(strategyId) && team.leadPid) {
55
- try {
56
- process.kill(team.leadPid, 'SIGKILL');
57
- }
58
- catch (e) {
59
- console.debug('[strategy-executor] SIGKILL failed (process may have exited):', e.message);
60
- }
61
- }
62
- }, 30000);
63
- return true;
64
- }
65
- catch (e) {
66
- console.debug(`[strategy-executor] terminateTeam: process may have already exited:`, e.message);
67
- return false;
68
- }
69
- }
70
- /**
71
- * Wait for a team's process to exit (leave activeTeams).
72
- *
73
- * Polls activeTeams until the strategy is no longer present,
74
- * which happens when handleTeamCompletion runs on the 'close' event.
75
- * If the timeout expires, sends SIGKILL and waits briefly.
76
- *
77
- * @param strategyId - Strategy to wait for
78
- * @param timeoutMs - Max wait time in ms (default 30s)
79
- * @returns true if team exited within timeout, false if forced
80
- */
81
- export async function waitForTeamExit(strategyId, timeoutMs = 30000) {
82
- const activeTeams = getActiveTeams();
83
- const team = activeTeams.get(strategyId);
84
- if (!team)
85
- return true; // Already gone
86
- const deadline = Date.now() + timeoutMs;
87
- const pollMs = 500;
88
- while (Date.now() < deadline) {
89
- if (!activeTeams.has(strategyId))
90
- return true;
91
- await new Promise(resolve => setTimeout(resolve, pollMs));
92
- }
93
- // Timeout expired — escalate to SIGKILL
94
- if (team.leadPid) {
95
- console.warn(`[strategy-executor] Team "${team.strategyName}" did not exit within ${timeoutMs}ms, sending SIGKILL`);
96
- try {
97
- process.kill(team.leadPid, 'SIGKILL');
98
- }
99
- catch { /* process may already be gone */ }
100
- // Brief wait for SIGKILL to take effect
101
- await new Promise(resolve => setTimeout(resolve, 2000));
102
- }
103
- return !activeTeams.has(strategyId);
104
- }
105
- /**
106
- * Terminate all active teams.
107
- */
108
- export function terminateAllTeams() {
109
- const activeTeams = getActiveTeams();
110
- for (const strategyId of activeTeams.keys()) {
111
- terminateTeam(strategyId);
112
- }
113
- }
114
- /**
115
- * Detect strategies that have been deactivated (agent role removed)
116
- * and shut down their active teams.
117
- */
118
- export async function detectDeactivatedStrategies(config) {
119
- const activeTeams = getActiveTeams();
120
- if (activeTeams.size === 0)
121
- return;
122
- try {
123
- // Aggregate ready strategies across all configured products
124
- const allReadyStrategies = [];
125
- for (const product of config.products) {
126
- const strategies = await getReadyStrategies(config.organizationId, product.id);
127
- allReadyStrategies.push(...strategies);
128
- }
129
- const activeStrategyIds = new Set(allReadyStrategies.map(s => s.strategy_id));
130
- for (const [strategyId, team] of activeTeams) {
131
- if (!activeStrategyIds.has(strategyId) && team.phase !== 'shutting_down' && team.phase !== 'terminated') {
132
- console.log(`[strategy-executor] Strategy "${team.strategyName}" deactivated -- shutting down team`);
133
- // Mark the shutdown reason so handleTeamCompletion can skip the merge
134
- // attempt cleanly when a planning team is cancelled mid-flight.
135
- team.shutdownReason = 'deactivated';
136
- terminateTeam(strategyId);
137
- }
138
- }
139
- }
140
- catch (err) {
141
- console.warn(`[strategy-executor] Failed to check for deactivated strategies:`, err.message);
142
- }
143
- }
144
- /**
145
- * Check active teams for newly completed deliveries and merge
146
- * the strategy branch to integration incrementally.
147
- *
148
- * Called from the poll loop. For each active team, queries delivery
149
- * statuses and triggers a merge when any delivery reaches verify/done
150
- * that hasn't already been merged mid-flight.
151
- *
152
- * After processing merges, checks if ALL active deliveries are terminal
153
- * and merged. If so, terminates the team proactively since no more work
154
- * remains. The strategy stays active in the DB -- if new deliveries
155
- * arrive later, the next poll cycle spawns a fresh team.
156
- */
157
- export async function checkAndMergeCompletedDeliveries(config) {
158
- const activeTeams = getActiveTeams();
159
- if (activeTeams.size === 0)
160
- return;
161
- for (const [strategyId, team] of activeTeams) {
162
- // Only check teams that are actively executing
163
- if (team.phase !== 'executing')
164
- continue;
165
- // Skip merge attempts while team lead is resolving a merge conflict
166
- if (team.resolvingMergeConflict) {
167
- console.log(`[strategy-executor] Skipping merge check for "${team.strategyName}" -- conflict resolution in progress`);
168
- continue;
169
- }
170
- // Use product-scoped config for this team's merge operations
171
- const teamProduct = findProduct(config, team.productId);
172
- const teamConfig = teamProduct ? configForProduct(config, teamProduct) : config;
173
- try {
174
- const deliveries = await getStrategyDeliveries(strategyId);
175
- // Find deliveries in verify/done that we haven't merged for yet
176
- const newlyCompleted = deliveries.filter(d => !isStatusAgentActionable(d.executionStatus ?? '') && !isStatusBlocking(d.executionStatus ?? '')
177
- && !team.mergedDeliveryIds.has(d.id));
178
- if (newlyCompleted.length > 0) {
179
- const completedNames = newlyCompleted.map(d => d.name).join(', ');
180
- console.log(`[strategy-executor] ${newlyCompleted.length} delivery(ies) completed mid-flight for "${team.strategyName}": ${completedNames} -- merging to integration`);
181
- // One merge covers all completed deliveries (same branch).
182
- // Pass the newly-completed IDs so git state is recorded only for
183
- // these — never for queued/planning deliveries on the same branch.
184
- const mergeResult = await mergeStrategyBranch(teamConfig, team, team.leadSessionId ?? '', team.branchName, newlyCompleted.map(d => d.id));
185
- if (mergeResult.mergeSucceeded) {
186
- // Track merged deliveries (git state already reported by mergeStrategyBranch)
187
- for (const d of newlyCompleted) {
188
- team.mergedDeliveryIds.add(d.id);
189
- }
190
- // ── Eager CI: merge integration → main when all deliveries are merged ──
191
- // Don't wait for team exit — run CI as soon as all work reaches integration.
192
- if (team.pipelineConfig?.ci?.enabled) {
193
- const activeDeliveries = deliveries.filter(d => !isStatusExcludedFromCascade(d.executionStatus ?? ''));
194
- const allMerged = activeDeliveries.length > 0 && activeDeliveries.every(d => team.mergedDeliveryIds.has(d.id));
195
- if (allMerged) {
196
- const pushToRemote = team.pipelineConfig?.cd?.enabled ?? false;
197
- const ciLabel = pushToRemote ? 'CI+CD' : 'CI';
198
- console.log(`[${ciLabel}] All deliveries merged for "${team.strategyName}" -- merging integration to main${pushToRemote ? ' (will push to remote)' : ''}`);
199
- try {
200
- const ciResult = await mergeIntegrationToMain({
201
- config: teamConfig,
202
- strategyName: team.strategyName,
203
- pushToRemote,
204
- });
205
- if (ciResult.success) {
206
- console.log(`[${ciLabel}] Successfully merged integration to main for "${team.strategyName}"`);
207
- for (const d of activeDeliveries) {
208
- const newState = pushToRemote ? 'pushed_to_remote' : 'merged_to_main';
209
- reportGitState(d.id, newState).catch(err => console.warn(`[${ciLabel}] reportGitState ${newState} failed for ${d.id}:`, err.message));
210
- }
211
- }
212
- else {
213
- console.error(`[${ciLabel}] Failed to merge integration to main for "${team.strategyName}": ${ciResult.error}`);
214
- }
215
- }
216
- catch (err) {
217
- console.error(`[${ciLabel}] Error merging integration to main for "${team.strategyName}":`, err.message);
218
- }
219
- }
220
- }
221
- }
222
- else {
223
- console.warn(`[strategy-executor] Mid-flight merge failed for "${team.strategyName}": ${mergeResult.exitReason}`);
224
- // Escalate merge conflict for each unmerged delivery
225
- for (const d of newlyCompleted) {
226
- escalateMergeConflict({
227
- organizationId: team.organizationId,
228
- sessionId: team.leadSessionId ?? '',
229
- deliveryId: d.id,
230
- deliveryName: d.name,
231
- branchName: team.branchName,
232
- integrationBranch: config.integrationBranch,
233
- mergeError: mergeResult.exitReason,
234
- }).catch(err => console.warn(`[strategy-executor] escalateMergeConflict failed for ${d.id}:`, err.message));
235
- }
236
- // Don't mark as merged -- will retry next poll. Team continues working.
237
- }
238
- }
239
- // ── All-done detection ──────────────────────────────────────
240
- // If any delivery is queued or running, the team still has work.
241
- // Otherwise the team is idle, waiting for the daemon to push new work.
242
- const teamWork = deliveries.filter(d => isStatusAgentActionable(d.executionStatus ?? ''));
243
- if (teamWork.length > 0) {
244
- console.log(`[strategy-executor] ${teamWork.length} delivery(ies) still queued/running for "${team.strategyName}" -- team continues`);
245
- continue;
246
- }
247
- // No queued/running deliveries -- team is idle, completion detector
248
- // handles the actual idle transition. Log for observability.
249
- console.log(`[strategy-executor] All deliveries complete for "${team.strategyName}" -- team is idle`);
250
- }
251
- catch (err) {
252
- console.warn(`[strategy-executor] Failed to check completed deliveries for "${team.strategyName}":`, err.message);
253
- }
254
- }
255
- }
256
- //# sourceMappingURL=strategy-team-lifecycle.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"strategy-team-lifecycle.js","sourceRoot":"","sources":["../src/strategy-team-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -1,24 +0,0 @@
1
- /**
2
- * Strategy team state management.
3
- *
4
- * Tracks active strategy teams in memory and provides
5
- * query/mutation helpers for the active teams map.
6
- */
7
- import type { StrategyTeamState, StrategyExecutionConfig, PipelineConfig } from './types.js';
8
- /**
9
- * Get all active strategy teams.
10
- */
11
- export declare function getActiveTeams(): Map<string, StrategyTeamState>;
12
- /**
13
- * Check if a strategy already has an active team.
14
- */
15
- export declare function hasActiveTeam(strategyId: string): boolean;
16
- /**
17
- * Get count of active teams.
18
- */
19
- export declare function getActiveTeamCount(): number;
20
- /**
21
- * Derive execution config from strategy pipeline config.
22
- */
23
- export declare function deriveExecutionConfig(_pipelineConfig: PipelineConfig | null): StrategyExecutionConfig;
24
- //# sourceMappingURL=strategy-team-state.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"strategy-team-state.d.ts","sourceRoot":"","sources":["../src/strategy-team-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,uBAAuB,EACvB,cAAc,EACf,MAAM,YAAY,CAAC;AAOpB;;GAEG;AACH,wBAAgB,cAAc,IAAI,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAE/D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAUD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,eAAe,EAAE,cAAc,GAAG,IAAI,GAAG,uBAAuB,CAKrG"}
@@ -1,43 +0,0 @@
1
- /**
2
- * Strategy team state management.
3
- *
4
- * Tracks active strategy teams in memory and provides
5
- * query/mutation helpers for the active teams map.
6
- */
7
- // ── Active teams tracking ────────────────────────────────────────────
8
- /** Active strategy teams: strategyId -> StrategyTeamState */
9
- const activeTeams = new Map();
10
- /**
11
- * Get all active strategy teams.
12
- */
13
- export function getActiveTeams() {
14
- return activeTeams;
15
- }
16
- /**
17
- * Check if a strategy already has an active team.
18
- */
19
- export function hasActiveTeam(strategyId) {
20
- return activeTeams.has(strategyId);
21
- }
22
- /**
23
- * Get count of active teams.
24
- */
25
- export function getActiveTeamCount() {
26
- return activeTeams.size;
27
- }
28
- // ── Default execution config ─────────────────────────────────────────
29
- const DEFAULT_EXECUTION_CONFIG = {
30
- maxWorkers: 3,
31
- idlePollIntervalMs: 30000,
32
- activePollIntervalMs: 60000,
33
- };
34
- /**
35
- * Derive execution config from strategy pipeline config.
36
- */
37
- export function deriveExecutionConfig(_pipelineConfig) {
38
- // For now, use defaults. The teams.enabled flag in pipelineConfig
39
- // is deprecated — teams are always the execution model.
40
- // Future: pipelineConfig could specify maxWorkers or parallelism level.
41
- return { ...DEFAULT_EXECUTION_CONFIG };
42
- }
43
- //# sourceMappingURL=strategy-team-state.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"strategy-team-state.js","sourceRoot":"","sources":["../src/strategy-team-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,wEAAwE;AAExE,6DAA6D;AAC7D,MAAM,WAAW,GAAG,IAAI,GAAG,EAA6B,CAAC;AAEzD;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,OAAO,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,WAAW,CAAC,IAAI,CAAC;AAC1B,CAAC;AAED,wEAAwE;AAExE,MAAM,wBAAwB,GAA4B;IACxD,UAAU,EAAE,CAAC;IACb,kBAAkB,EAAE,KAAK;IACzB,oBAAoB,EAAE,KAAK;CAC5B,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,eAAsC;IAC1E,kEAAkE;IAClE,wDAAwD;IACxD,wEAAwE;IACxE,OAAO,EAAE,GAAG,wBAAwB,EAAE,CAAC;AACzC,CAAC"}
@@ -1,24 +0,0 @@
1
- /**
2
- * Strategy teardown and deactivation detection.
3
- *
4
- * Coordinated teardown stops QA, terminates the team, commits WIP,
5
- * and removes the worktree. Deactivation detection polls for strategies
6
- * that have been unassigned and triggers their teardown.
7
- */
8
- import type { DaemonConfig } from './types.js';
9
- /**
10
- * Tear down a single strategy: stop QA, terminate team, remove worktree.
11
- *
12
- * Each step is independently try/caught so a failure in one
13
- * does not prevent the others from running.
14
- */
15
- export declare function teardownStrategy(config: DaemonConfig, strategyId: string, strategyName: string): Promise<void>;
16
- /**
17
- * Detect deactivated strategies and tear them down.
18
- *
19
- * Replaces both detectDeactivatedStrategies() from strategy-executor.ts
20
- * and checkQaForDeactivatedStrategies() from qa-orchestrator.ts.
21
- * A single pass handles both team termination and QA cleanup.
22
- */
23
- export declare function checkForDeactivatedStrategies(config: DaemonConfig): Promise<void>;
24
- //# sourceMappingURL=strategy-teardown.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"strategy-teardown.d.ts","sourceRoot":"","sources":["../src/strategy-teardown.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAa/C;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,YAAY,EACpB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAgGf;AAED;;;;;;GAMG;AACH,wBAAsB,6BAA6B,CACjD,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,CAuCf"}
@@ -1,158 +0,0 @@
1
- /**
2
- * Strategy teardown and deactivation detection.
3
- *
4
- * Coordinated teardown stops QA, terminates the team, commits WIP,
5
- * and removes the worktree. Deactivation detection polls for strategies
6
- * that have been unassigned and triggers their teardown.
7
- */
8
- import { getActiveStrategies, updateQaStatus } from './supabase.js';
9
- import { safeRemoveStrategyWorktree, commitWipChanges } from './git.js';
10
- import { terminateTeam, waitForTeamExit } from './strategy-executor.js';
11
- import { getActiveTeams } from './strategy-team-state.js';
12
- import { getStrategyWorktree, getAllStrategyWorktrees, } from './strategy-worktree-state.js';
13
- import { escalateMergeConflict } from './strategy-merge.js';
14
- import { getQaEnvironment, removeQaEnvironment } from './qa-state.js';
15
- import { stopQaDevServer } from './qa-dev-server.js';
16
- /**
17
- * Tear down a single strategy: stop QA, terminate team, remove worktree.
18
- *
19
- * Each step is independently try/caught so a failure in one
20
- * does not prevent the others from running.
21
- */
22
- export async function teardownStrategy(config, strategyId, strategyName) {
23
- console.log(`[strategy-lifecycle] Tearing down strategy "${strategyName}"`);
24
- // 1. Stop QA dev server if running
25
- try {
26
- const qaState = getQaEnvironment(strategyId);
27
- if (qaState?.pid) {
28
- console.log(`[strategy-lifecycle] Stopping QA dev server for "${strategyName}" (PID: ${qaState.pid})`);
29
- await stopQaDevServer(qaState.pid);
30
- }
31
- }
32
- catch (err) {
33
- console.warn(`[strategy-lifecycle] Failed to stop QA dev server for "${strategyName}": ${err.message}`);
34
- }
35
- // 2. Clear QA in-memory state
36
- try {
37
- removeQaEnvironment(strategyId);
38
- }
39
- catch (err) {
40
- console.warn(`[strategy-lifecycle] Failed to clear QA state for "${strategyName}": ${err.message}`);
41
- }
42
- // 3. Clear QA DB state
43
- try {
44
- await updateQaStatus(strategyId, {
45
- qaStatus: null,
46
- qaUrl: null,
47
- qaPort: null,
48
- qaWorktreePath: null,
49
- qaReadyAt: null,
50
- qaError: null,
51
- });
52
- }
53
- catch (err) {
54
- console.warn(`[strategy-lifecycle] Failed to clear QA DB state for "${strategyName}": ${err.message}`);
55
- }
56
- // 4. Terminate agent team and wait for process exit
57
- try {
58
- const activeTeams = getActiveTeams();
59
- const team = activeTeams.get(strategyId);
60
- if (team && team.phase !== 'shutting_down' && team.phase !== 'terminated') {
61
- console.log(`[strategy-lifecycle] Terminating team for "${strategyName}"`);
62
- terminateTeam(strategyId);
63
- // Wait for process to actually exit (default 30s, then SIGKILL)
64
- const exited = await waitForTeamExit(strategyId);
65
- if (!exited) {
66
- console.warn(`[strategy-lifecycle] Team for "${strategyName}" did not exit cleanly after SIGKILL`);
67
- }
68
- }
69
- }
70
- catch (err) {
71
- console.warn(`[strategy-lifecycle] Failed to terminate team for "${strategyName}": ${err.message}`);
72
- }
73
- // 4b. Commit any uncommitted WIP changes left by the agent
74
- try {
75
- const worktreeInfo = getStrategyWorktree(strategyId);
76
- if (worktreeInfo) {
77
- commitWipChanges(worktreeInfo.worktreePath, strategyName);
78
- }
79
- }
80
- catch (err) {
81
- console.warn(`[strategy-lifecycle] WIP commit failed for "${strategyName}": ${err.message}`);
82
- }
83
- // 5. Remove strategy worktree via canonical path (merge-before-remove + conditional state cleanup).
84
- try {
85
- const worktreeInfo = getStrategyWorktree(strategyId);
86
- if (worktreeInfo) {
87
- console.log(`[strategy-lifecycle] Removing worktree for "${strategyName}": ${worktreeInfo.worktreePath}`);
88
- const removeResult = await safeRemoveStrategyWorktree({
89
- config,
90
- worktreePath: worktreeInfo.worktreePath,
91
- branchName: worktreeInfo.branchName,
92
- deliveryName: strategyName,
93
- deliveryId: strategyId,
94
- strategyId,
95
- });
96
- // Escalate if merge failed (worktree preserved with unmerged work)
97
- if (removeResult.merged && removeResult.mergeError) {
98
- escalateMergeConflict({
99
- organizationId: config.organizationId,
100
- sessionId: '',
101
- deliveryId: strategyId,
102
- deliveryName: strategyName,
103
- branchName: worktreeInfo.branchName,
104
- integrationBranch: config.integrationBranch,
105
- mergeError: removeResult.mergeError,
106
- }).catch(err => console.warn(`[strategy-lifecycle] escalateMergeConflict failed for "${strategyName}": ${err.message}`));
107
- }
108
- }
109
- }
110
- catch (err) {
111
- console.warn(`[strategy-lifecycle] Failed to remove worktree for "${strategyName}": ${err.message}`);
112
- }
113
- console.log(`[strategy-lifecycle] Teardown complete for "${strategyName}"`);
114
- }
115
- /**
116
- * Detect deactivated strategies and tear them down.
117
- *
118
- * Replaces both detectDeactivatedStrategies() from strategy-executor.ts
119
- * and checkQaForDeactivatedStrategies() from qa-orchestrator.ts.
120
- * A single pass handles both team termination and QA cleanup.
121
- */
122
- export async function checkForDeactivatedStrategies(config) {
123
- const allWorktrees = getAllStrategyWorktrees();
124
- const activeTeams = getActiveTeams();
125
- // Nothing to check if no worktrees and no teams
126
- if (allWorktrees.size === 0 && activeTeams.size === 0)
127
- return;
128
- let activeStrategyIds;
129
- try {
130
- // Use getActiveStrategies (not getReadyStrategies) -- a strategy is "active" even
131
- // when all deliveries are done. Worktrees must persist for QA and idle queues.
132
- const activeStrategies = await getActiveStrategies(config.organizationId, config.productId);
133
- activeStrategyIds = new Set(activeStrategies.map(s => s.strategy_id));
134
- }
135
- catch (err) {
136
- console.warn(`[strategy-lifecycle] Cannot determine active strategies (skipping deactivation check): ${err.message}`);
137
- return;
138
- }
139
- // Collect all strategy IDs that have either a worktree or an active team
140
- const trackedStrategyIds = new Set([
141
- ...allWorktrees.keys(),
142
- ...activeTeams.keys(),
143
- ]);
144
- for (const strategyId of trackedStrategyIds) {
145
- if (activeStrategyIds.has(strategyId))
146
- continue;
147
- const worktreeInfo = getStrategyWorktree(strategyId);
148
- const team = activeTeams.get(strategyId);
149
- const name = worktreeInfo?.strategyName ?? team?.strategyName ?? strategyId;
150
- // Skip teams already shutting down
151
- if (team && (team.phase === 'shutting_down' || team.phase === 'terminated') && !worktreeInfo) {
152
- continue;
153
- }
154
- console.log(`[strategy-lifecycle] Strategy "${name}" deactivated -- coordinated teardown`);
155
- await teardownStrategy(config, strategyId, name);
156
- }
157
- }
158
- //# sourceMappingURL=strategy-teardown.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"strategy-teardown.js","sourceRoot":"","sources":["../src/strategy-teardown.ts"],"names":[],"mappings":"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"}
@@ -1,47 +0,0 @@
1
- /**
2
- * Strategy worktree state management — write-through cache.
3
- *
4
- * Tracks persistent strategy worktrees using a local Map as the
5
- * synchronous read cache, backed by the strategy_worktrees DB table.
6
- *
7
- * Read path: all get/has/getAll calls are synchronous (Map lookup).
8
- * Write path: update Map immediately, then fire async DB write.
9
- * Startup: hydrateFromDb() loads all records from DB into the Map.
10
- *
11
- * The Map is authoritative during runtime. The DB is authoritative
12
- * across restarts. Async DB writes are fire-and-forget with logging.
13
- */
14
- import type { StrategyWorktreeInfo } from './types.js';
15
- /**
16
- * Hydrate the in-memory cache from the database.
17
- *
18
- * Call once during daemon startup, BEFORE rebuildStrategyWorktreeState.
19
- * Stores the productId for subsequent write-through operations.
20
- */
21
- export declare function hydrateFromDb(productId: string): Promise<void>;
22
- /**
23
- * Get a single strategy worktree by strategy ID.
24
- */
25
- export declare function getStrategyWorktree(strategyId: string): StrategyWorktreeInfo | undefined;
26
- /**
27
- * Add or update a strategy worktree entry.
28
- *
29
- * Updates the Map synchronously, then fires an async DB upsert.
30
- */
31
- export declare function setStrategyWorktree(strategyId: string, info: StrategyWorktreeInfo): void;
32
- /**
33
- * Remove a strategy worktree entry.
34
- * Returns whether the entry existed.
35
- *
36
- * Deletes from Map synchronously, then fires an async DB remove.
37
- */
38
- export declare function removeStrategyWorktree(strategyId: string): boolean;
39
- /**
40
- * Get all strategy worktrees.
41
- */
42
- export declare function getAllStrategyWorktrees(): Map<string, StrategyWorktreeInfo>;
43
- /**
44
- * Check if a strategy has a persistent worktree.
45
- */
46
- export declare function hasStrategyWorktree(strategyId: string): boolean;
47
- //# sourceMappingURL=strategy-worktree-state.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"strategy-worktree-state.d.ts","sourceRoot":"","sources":["../src/strategy-worktree-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAgBvD;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BpE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAExF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAgBxF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAclE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAE3E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE/D"}