@telora/daemon 0.15.13 → 0.15.17

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 (97) hide show
  1. package/build-info.json +2 -2
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +0 -50
  4. package/dist/config.js.map +1 -1
  5. package/dist/delivery-lifecycle.d.ts +22 -0
  6. package/dist/delivery-lifecycle.d.ts.map +1 -1
  7. package/dist/delivery-lifecycle.js +51 -0
  8. package/dist/delivery-lifecycle.js.map +1 -1
  9. package/dist/directive-executor.d.ts +92 -0
  10. package/dist/directive-executor.d.ts.map +1 -1
  11. package/dist/directive-executor.js +172 -11
  12. package/dist/directive-executor.js.map +1 -1
  13. package/dist/focus-completion.d.ts.map +1 -1
  14. package/dist/focus-completion.js +12 -1
  15. package/dist/focus-completion.js.map +1 -1
  16. package/dist/focus-engine.d.ts.map +1 -1
  17. package/dist/focus-engine.js +0 -43
  18. package/dist/focus-engine.js.map +1 -1
  19. package/dist/focus-executor.d.ts.map +1 -1
  20. package/dist/focus-executor.js +8 -2
  21. package/dist/focus-executor.js.map +1 -1
  22. package/dist/focus-lifecycle.d.ts +3 -4
  23. package/dist/focus-lifecycle.d.ts.map +1 -1
  24. package/dist/focus-lifecycle.js +6 -79
  25. package/dist/focus-lifecycle.js.map +1 -1
  26. package/dist/focus-phase.d.ts +26 -0
  27. package/dist/focus-phase.d.ts.map +1 -1
  28. package/dist/focus-phase.js +43 -0
  29. package/dist/focus-phase.js.map +1 -1
  30. package/dist/focus-provisioning.d.ts.map +1 -1
  31. package/dist/focus-provisioning.js +1 -7
  32. package/dist/focus-provisioning.js.map +1 -1
  33. package/dist/focus-worktree-state.d.ts.map +1 -1
  34. package/dist/focus-worktree-state.js +0 -1
  35. package/dist/focus-worktree-state.js.map +1 -1
  36. package/dist/listener-auto-advance.d.ts.map +1 -1
  37. package/dist/listener-auto-advance.js +16 -1
  38. package/dist/listener-auto-advance.js.map +1 -1
  39. package/dist/listener.d.ts.map +1 -1
  40. package/dist/listener.js +0 -6
  41. package/dist/listener.js.map +1 -1
  42. package/dist/queries/shared.d.ts.map +1 -1
  43. package/dist/queries/shared.js +0 -3
  44. package/dist/queries/shared.js.map +1 -1
  45. package/dist/supabase.d.ts +0 -4
  46. package/dist/supabase.d.ts.map +1 -1
  47. package/dist/supabase.js +0 -8
  48. package/dist/supabase.js.map +1 -1
  49. package/dist/team-spawner.d.ts.map +1 -1
  50. package/dist/team-spawner.js +8 -2
  51. package/dist/team-spawner.js.map +1 -1
  52. package/dist/templates/claude-md.d.ts.map +1 -1
  53. package/dist/templates/claude-md.js +0 -2
  54. package/dist/templates/claude-md.js.map +1 -1
  55. package/dist/templates/claude-settings.d.ts.map +1 -1
  56. package/dist/templates/claude-settings.js +0 -5
  57. package/dist/templates/claude-settings.js.map +1 -1
  58. package/dist/types/config.d.ts +0 -10
  59. package/dist/types/config.d.ts.map +1 -1
  60. package/dist/types/focus.d.ts +11 -2
  61. package/dist/types/focus.d.ts.map +1 -1
  62. package/dist/unified-shell-config.d.ts.map +1 -1
  63. package/dist/unified-shell-config.js +0 -39
  64. package/dist/unified-shell-config.js.map +1 -1
  65. package/package.json +1 -1
  66. package/dist/qa-crash-recovery.d.ts +0 -77
  67. package/dist/qa-crash-recovery.d.ts.map +0 -1
  68. package/dist/qa-crash-recovery.js +0 -243
  69. package/dist/qa-crash-recovery.js.map +0 -1
  70. package/dist/qa-dev-server.d.ts +0 -73
  71. package/dist/qa-dev-server.d.ts.map +0 -1
  72. package/dist/qa-dev-server.js +0 -279
  73. package/dist/qa-dev-server.js.map +0 -1
  74. package/dist/qa-orchestrator.d.ts +0 -107
  75. package/dist/qa-orchestrator.d.ts.map +0 -1
  76. package/dist/qa-orchestrator.js +0 -518
  77. package/dist/qa-orchestrator.js.map +0 -1
  78. package/dist/qa-port-allocator.d.ts +0 -34
  79. package/dist/qa-port-allocator.d.ts.map +0 -1
  80. package/dist/qa-port-allocator.js +0 -75
  81. package/dist/qa-port-allocator.js.map +0 -1
  82. package/dist/qa-provisioner.d.ts +0 -33
  83. package/dist/qa-provisioner.d.ts.map +0 -1
  84. package/dist/qa-provisioner.js +0 -139
  85. package/dist/qa-provisioner.js.map +0 -1
  86. package/dist/qa-state.d.ts +0 -118
  87. package/dist/qa-state.d.ts.map +0 -1
  88. package/dist/qa-state.js +0 -88
  89. package/dist/qa-state.js.map +0 -1
  90. package/dist/queries/qa.d.ts +0 -120
  91. package/dist/queries/qa.d.ts.map +0 -1
  92. package/dist/queries/qa.js +0 -118
  93. package/dist/queries/qa.js.map +0 -1
  94. package/dist/save-point-restore.d.ts +0 -35
  95. package/dist/save-point-restore.d.ts.map +0 -1
  96. package/dist/save-point-restore.js +0 -146
  97. package/dist/save-point-restore.js.map +0 -1
@@ -1,518 +0,0 @@
1
- /**
2
- * QA environment orchestration.
3
- *
4
- * Called by the daemon poll loop to process pending QA requests.
5
- * Coordinates provisioning and teardown using the lower-level modules.
6
- */
7
- import { getQaRequests, updateQaStatus, getDeactivatedQaFocuses, getProductQaRequests, updateProductQaStatus, getSavePointQaRequests, updateSavePointQaStatus } from './supabase.js';
8
- import { symlinkEnvFiles, createQaWorktree, removeQaWorktree } from './qa-provisioner.js';
9
- import { getDefaultBranch } from './git-branch.js';
10
- import { getFocusWorktree as getFocusWorktreeImpl } from './focus-worktree-state.js';
11
- import { allocatePort, buildQaUrl } from './qa-port-allocator.js';
12
- import { startQaDevServer, stopQaDevServer } from './qa-dev-server.js';
13
- import { getQaEnvironment, setQaEnvironment, removeQaEnvironment, hasActiveQaEnvironment, getProductQaEnvironment, setProductQaEnvironment, removeProductQaEnvironment, hasActiveProductQaEnvironment, getSavePointQaEnvironment, setSavePointQaEnvironment, removeSavePointQaEnvironment, hasActiveSavePointQaEnvironment, } from './qa-state.js';
14
- /** Default deps wired to real implementations. */
15
- const defaultDeps = {
16
- getQaRequests,
17
- getDeactivatedQaFocuses,
18
- updateQaStatus,
19
- getFocusWorktree: getFocusWorktreeImpl,
20
- symlinkEnvFiles,
21
- allocatePort,
22
- buildQaUrl,
23
- startQaDevServer,
24
- stopQaDevServer,
25
- getQaEnvironment,
26
- setQaEnvironment,
27
- removeQaEnvironment,
28
- hasActiveQaEnvironment,
29
- };
30
- /**
31
- * Check for and process pending QA requests.
32
- * Called each poll cycle from listener.ts.
33
- */
34
- export async function checkQaRequests(config, deps = defaultDeps) {
35
- let requests;
36
- try {
37
- requests = await deps.getQaRequests(config.productId);
38
- }
39
- catch (err) {
40
- console.warn(`[qa] Failed to fetch QA requests: ${err.message}`);
41
- return;
42
- }
43
- if (requests.length === 0)
44
- return;
45
- for (const req of requests) {
46
- try {
47
- if (req.qa_status === 'requested') {
48
- await handleQaProvision(config, req, deps);
49
- }
50
- else if (req.qa_status === 'stop_requested') {
51
- await handleQaTeardown(config, req, deps);
52
- }
53
- }
54
- catch (err) {
55
- console.error(`[qa] Error processing QA request for focus ${req.focus_name}: ${err.message}`);
56
- // Update DB to failed state
57
- try {
58
- await deps.updateQaStatus(req.focus_id, {
59
- qaStatus: 'failed',
60
- qaError: err.message,
61
- });
62
- }
63
- catch (updateErr) {
64
- console.warn(`[qa] Failed to update error state: ${updateErr.message}`);
65
- }
66
- }
67
- }
68
- }
69
- /**
70
- * Provision a QA environment for a focus.
71
- *
72
- * 1. If already active (refresh case), tear down first.
73
- * 2. Set DB status to 'provisioning'.
74
- * 3. Allocate a port and create a worktree.
75
- * 4. Install deps and start the dev server.
76
- * 5. Update in-memory state and DB to 'ready'.
77
- */
78
- async function handleQaProvision(config, req, deps) {
79
- const { focus_id: focusId, focus_name: focusName } = req;
80
- // If already active (refresh), tear down first
81
- if (deps.hasActiveQaEnvironment(focusId)) {
82
- console.log(`[qa] Refreshing QA environment for "${focusName}"`);
83
- await handleQaTeardown(config, req, deps);
84
- }
85
- // 1. Set provisioning in DB
86
- await deps.updateQaStatus(focusId, { qaStatus: 'provisioning' });
87
- // 2. Allocate port
88
- const port = await deps.allocatePort(config);
89
- const url = deps.buildQaUrl(config, port);
90
- // 3. Look up the persistent focus worktree (QA runs inside it)
91
- const worktreeInfo = deps.getFocusWorktree(focusId);
92
- if (!worktreeInfo) {
93
- throw new Error(`No persistent worktree found for focus "${focusName}" (${focusId})`);
94
- }
95
- const worktreePath = worktreeInfo.worktreePath;
96
- deps.symlinkEnvFiles(config.repoPath, worktreePath);
97
- // 4. Track in memory (status provisioning, dev server not yet started)
98
- const state = {
99
- focusId,
100
- focusName,
101
- worktreePath,
102
- pid: null,
103
- port,
104
- url,
105
- status: 'provisioning',
106
- createdAt: new Date(),
107
- lastError: null,
108
- };
109
- deps.setQaEnvironment(focusId, state);
110
- // 5. Start dev server (npm install + npm run dev)
111
- const result = deps.startQaDevServer({
112
- config,
113
- focusId,
114
- worktreePath,
115
- port,
116
- onUnexpectedExit: (error) => {
117
- console.error(`[qa] Dev server crashed for "${focusName}": ${error}`);
118
- deps.setQaEnvironment(focusId, { ...state, pid: null, status: 'failed', lastError: error });
119
- deps.updateQaStatus(focusId, { qaStatus: 'failed', qaError: error }).catch((e) => {
120
- console.warn(`[qa] Failed to report dev server crash: ${e.message}`);
121
- });
122
- },
123
- });
124
- // 6. Update state with PID and mark ready
125
- const readyState = {
126
- ...state,
127
- pid: result.pid,
128
- status: 'ready',
129
- };
130
- deps.setQaEnvironment(focusId, readyState);
131
- // 7. Update DB to ready
132
- await deps.updateQaStatus(focusId, {
133
- qaStatus: 'ready',
134
- qaUrl: url,
135
- qaPort: port,
136
- qaWorktreePath: worktreePath,
137
- qaReadyAt: new Date().toISOString(),
138
- });
139
- console.log(`[qa] QA environment ready for "${focusName}" at ${url}`);
140
- }
141
- /**
142
- * Tear down a QA environment for a focus.
143
- *
144
- * 1. Kill the dev server process if running.
145
- * 2. Remove the worktree.
146
- * 3. Clear in-memory and DB state.
147
- */
148
- async function handleQaTeardown(config, req, deps) {
149
- const { focus_id: focusId, focus_name: focusName } = req;
150
- console.log(`[qa] Tearing down QA environment for "${focusName}"`);
151
- // Kill dev server if running
152
- const state = deps.getQaEnvironment(focusId);
153
- if (state?.pid) {
154
- await deps.stopQaDevServer(state.pid);
155
- }
156
- // Worktree is focus-owned -- do NOT remove here.
157
- // Removal happens via coordinated teardown when the focus is deactivated.
158
- // Clear in-memory state
159
- deps.removeQaEnvironment(focusId);
160
- // Clear DB state
161
- await deps.updateQaStatus(focusId, {
162
- qaStatus: null,
163
- qaUrl: null,
164
- qaPort: null,
165
- qaWorktreePath: null,
166
- qaReadyAt: null,
167
- qaError: null,
168
- });
169
- console.log(`[qa] QA environment torn down for "${focusName}"`);
170
- }
171
- /**
172
- * Check for focuses that have been deactivated while QA was running.
173
- * Tears down any QA environment whose focus is no longer in 'active' status.
174
- * Called each poll cycle from listener.ts.
175
- */
176
- export async function checkQaForDeactivatedFocuses(config, deps = defaultDeps) {
177
- let deactivated;
178
- try {
179
- deactivated = await deps.getDeactivatedQaFocuses(config.productId);
180
- }
181
- catch (err) {
182
- console.warn(`[qa] Failed to fetch deactivated QA focuses: ${err.message}`);
183
- return;
184
- }
185
- if (deactivated.length === 0)
186
- return;
187
- for (const focus of deactivated) {
188
- console.log(`[qa] Focus "${focus.focus_name}" is ${focus.focus_status} but has QA state "${focus.qa_status}" -- tearing down`);
189
- try {
190
- await handleQaTeardown(config, {
191
- focus_id: focus.focus_id,
192
- focus_name: focus.focus_name,
193
- qa_status: focus.qa_status,
194
- product_id: focus.product_id,
195
- }, deps);
196
- }
197
- catch (err) {
198
- console.error(`[qa] Error tearing down QA for deactivated focus "${focus.focus_name}": ${err.message}`);
199
- }
200
- }
201
- }
202
- /** Default deps wired to real implementations. */
203
- const defaultProductDeps = {
204
- getProductQaRequests,
205
- updateProductQaStatus,
206
- createQaWorktree,
207
- removeQaWorktree,
208
- symlinkEnvFiles,
209
- allocatePort,
210
- buildQaUrl,
211
- startQaDevServer,
212
- stopQaDevServer,
213
- getProductQaEnvironment,
214
- setProductQaEnvironment,
215
- removeProductQaEnvironment,
216
- hasActiveProductQaEnvironment,
217
- };
218
- /**
219
- * Check for and process pending product QA requests.
220
- * Called each poll cycle from listener.ts.
221
- */
222
- export async function checkProductQaRequests(config, deps = defaultProductDeps) {
223
- let requests;
224
- try {
225
- requests = await deps.getProductQaRequests(config.productId);
226
- }
227
- catch (err) {
228
- console.warn(`[product-qa] Failed to fetch product QA requests: ${err.message}`);
229
- return;
230
- }
231
- if (requests.length === 0)
232
- return;
233
- for (const req of requests) {
234
- try {
235
- if (req.qa_status === 'requested') {
236
- await handleProductQaProvision(config, req, deps);
237
- }
238
- else if (req.qa_status === 'refresh_requested') {
239
- await handleProductQaRefresh(config, req, deps);
240
- }
241
- else if (req.qa_status === 'stop_requested') {
242
- await handleProductQaTeardown(config, req, deps);
243
- }
244
- }
245
- catch (err) {
246
- console.error(`[product-qa] Error processing product QA request for "${req.product_name}": ${err.message}`);
247
- try {
248
- await deps.updateProductQaStatus(req.product_id, {
249
- qaStatus: 'failed',
250
- qaError: err.message,
251
- });
252
- }
253
- catch (updateErr) {
254
- console.warn(`[product-qa] Failed to update error state: ${updateErr.message}`);
255
- }
256
- }
257
- }
258
- }
259
- /**
260
- * Provision a product-level QA environment.
261
- *
262
- * Creates a QA worktree on the default branch (main) so the dev server
263
- * reflects the latest promoted state of the product.
264
- */
265
- async function handleProductQaProvision(config, req, deps) {
266
- const { product_id: productId, product_name: productName } = req;
267
- // If already active (refresh), tear down first
268
- if (deps.hasActiveProductQaEnvironment(productId)) {
269
- console.log(`[product-qa] Refreshing QA environment for product "${productName}"`);
270
- await handleProductQaTeardown(config, req, deps);
271
- }
272
- // 1. Set provisioning in DB
273
- await deps.updateProductQaStatus(productId, { qaStatus: 'provisioning' });
274
- // 2. Allocate port
275
- const port = await deps.allocatePort(config);
276
- const url = deps.buildQaUrl(config, port);
277
- // 3. Create QA worktree on default branch (main)
278
- const defaultBranch = getDefaultBranch(config.repoPath);
279
- const worktreePath = deps.createQaWorktree(config, defaultBranch, `product-${productId}`);
280
- deps.symlinkEnvFiles(config.repoPath, worktreePath);
281
- // 4. Track in memory
282
- const state = {
283
- productId,
284
- productName,
285
- worktreePath,
286
- pid: null,
287
- port,
288
- url,
289
- status: 'provisioning',
290
- createdAt: new Date(),
291
- lastError: null,
292
- };
293
- deps.setProductQaEnvironment(productId, state);
294
- // 5. Start dev server in integration worktree
295
- const result = deps.startQaDevServer({
296
- config,
297
- focusId: `product-${productId}`,
298
- worktreePath,
299
- port,
300
- onUnexpectedExit: (error) => {
301
- console.error(`[product-qa] Dev server crashed for product "${productName}": ${error}`);
302
- deps.setProductQaEnvironment(productId, { ...state, pid: null, status: 'failed', lastError: error });
303
- deps.updateProductQaStatus(productId, { qaStatus: 'failed', qaError: error }).catch((e) => {
304
- console.warn(`[product-qa] Failed to report dev server crash: ${e.message}`);
305
- });
306
- },
307
- });
308
- // 6. Update state with PID and mark ready
309
- const readyState = {
310
- ...state,
311
- pid: result.pid,
312
- status: 'ready',
313
- };
314
- deps.setProductQaEnvironment(productId, readyState);
315
- // 7. Update DB to ready
316
- await deps.updateProductQaStatus(productId, {
317
- qaStatus: 'ready',
318
- qaUrl: url,
319
- qaPort: port,
320
- qaWorktreePath: worktreePath,
321
- qaReadyAt: new Date().toISOString(),
322
- });
323
- console.log(`[product-qa] QA environment ready for product "${productName}" at ${url} (${defaultBranch})`);
324
- }
325
- /**
326
- * Lightweight refresh of a product-level QA environment.
327
- * Updates the worktree to the latest commit on the default branch
328
- * without restarting the dev server (Vite picks up changes via HMR).
329
- */
330
- async function handleProductQaRefresh(config, req, deps) {
331
- const { product_id: productId, product_name: productName } = req;
332
- const envState = deps.getProductQaEnvironment(productId);
333
- if (!envState?.worktreePath) {
334
- console.warn(`[product-qa] No active QA environment to refresh for "${productName}", falling back to full provision`);
335
- await handleProductQaProvision(config, req, deps);
336
- return;
337
- }
338
- console.log(`[product-qa] Refreshing worktree for product "${productName}"`);
339
- // Update worktree to latest commit on default branch (detached HEAD checkout)
340
- const defaultBranch = getDefaultBranch(config.repoPath);
341
- deps.createQaWorktree(config, defaultBranch, `product-${productId}`);
342
- // Set back to ready
343
- await deps.updateProductQaStatus(productId, { qaStatus: 'ready' });
344
- console.log(`[product-qa] QA worktree refreshed for product "${productName}" (${defaultBranch})`);
345
- }
346
- /**
347
- * Tear down a product-level QA environment.
348
- * Kills the dev server and removes the integration worktree.
349
- */
350
- async function handleProductQaTeardown(config, req, deps) {
351
- const { product_id: productId, product_name: productName } = req;
352
- console.log(`[product-qa] Tearing down QA environment for product "${productName}"`);
353
- // Kill dev server if running
354
- const state = deps.getProductQaEnvironment(productId);
355
- if (state?.pid) {
356
- await deps.stopQaDevServer(state.pid);
357
- }
358
- // Remove QA worktree (read-only checkout, no safety commits needed)
359
- if (state?.worktreePath) {
360
- deps.removeQaWorktree(config.repoPath, state.worktreePath);
361
- }
362
- // Clear in-memory state
363
- deps.removeProductQaEnvironment(productId);
364
- // Clear DB state
365
- await deps.updateProductQaStatus(productId, {
366
- qaStatus: null,
367
- qaUrl: null,
368
- qaPort: null,
369
- qaWorktreePath: null,
370
- qaReadyAt: null,
371
- qaError: null,
372
- });
373
- console.log(`[product-qa] QA environment torn down for product "${productName}"`);
374
- }
375
- /** Default deps wired to real implementations. */
376
- const defaultSavePointDeps = {
377
- getSavePointQaRequests,
378
- updateSavePointQaStatus,
379
- symlinkEnvFiles,
380
- allocatePort,
381
- buildQaUrl,
382
- startQaDevServer,
383
- stopQaDevServer,
384
- getSavePointQaEnvironment,
385
- setSavePointQaEnvironment,
386
- removeSavePointQaEnvironment,
387
- hasActiveSavePointQaEnvironment,
388
- };
389
- /**
390
- * Check for and process pending save point QA requests.
391
- * Called each poll cycle from listener.ts.
392
- */
393
- export async function checkSavePointQaRequests(config, deps = defaultSavePointDeps) {
394
- let requests;
395
- try {
396
- requests = await deps.getSavePointQaRequests(config.productId);
397
- }
398
- catch (err) {
399
- console.warn(`[save-point-qa] Failed to fetch save point QA requests: ${err.message}`);
400
- return;
401
- }
402
- if (requests.length === 0)
403
- return;
404
- for (const req of requests) {
405
- try {
406
- if (req.qa_status === 'requested') {
407
- await handleSavePointQaProvision(config, req, deps);
408
- }
409
- else if (req.qa_status === 'stop_requested') {
410
- await handleSavePointQaTeardown(config, req, deps);
411
- }
412
- }
413
- catch (err) {
414
- console.error(`[save-point-qa] Error processing QA request for save point "${req.name}": ${err.message}`);
415
- try {
416
- await deps.updateSavePointQaStatus(req.save_point_id, {
417
- qaStatus: 'failed',
418
- qaError: err.message,
419
- });
420
- }
421
- catch (updateErr) {
422
- console.warn(`[save-point-qa] Failed to update error state: ${updateErr.message}`);
423
- }
424
- }
425
- }
426
- }
427
- /**
428
- * Provision a QA environment for a save point.
429
- *
430
- * The worktree already exists (created by MCP view action).
431
- * We just need to start a dev server in it.
432
- */
433
- async function handleSavePointQaProvision(config, req, deps) {
434
- const { save_point_id: savePointId, name: spName, worktree_path: worktreePath } = req;
435
- if (!worktreePath) {
436
- throw new Error(`Save point "${spName}" has no active worktree -- view it first`);
437
- }
438
- // If already active (refresh), tear down first
439
- if (deps.hasActiveSavePointQaEnvironment(savePointId)) {
440
- console.log(`[save-point-qa] Refreshing QA environment for "${spName}"`);
441
- await handleSavePointQaTeardown(config, req, deps);
442
- }
443
- // 1. Set provisioning in DB
444
- await deps.updateSavePointQaStatus(savePointId, { qaStatus: 'provisioning' });
445
- // 2. Allocate port
446
- const port = await deps.allocatePort(config);
447
- const url = deps.buildQaUrl(config, port);
448
- // 3. Symlink env files into the worktree
449
- deps.symlinkEnvFiles(config.repoPath, worktreePath);
450
- // 4. Track in memory
451
- const state = {
452
- savePointId,
453
- name: spName,
454
- worktreePath,
455
- pid: null,
456
- port,
457
- url,
458
- status: 'provisioning',
459
- createdAt: new Date(),
460
- lastError: null,
461
- };
462
- deps.setSavePointQaEnvironment(savePointId, state);
463
- // 5. Start dev server
464
- const result = deps.startQaDevServer({
465
- config,
466
- focusId: `save-point-${savePointId}`,
467
- worktreePath,
468
- port,
469
- onUnexpectedExit: (error) => {
470
- console.error(`[save-point-qa] Dev server crashed for "${spName}": ${error}`);
471
- deps.setSavePointQaEnvironment(savePointId, { ...state, pid: null, status: 'failed', lastError: error });
472
- deps.updateSavePointQaStatus(savePointId, { qaStatus: 'failed', qaError: error }).catch((e) => {
473
- console.warn(`[save-point-qa] Failed to report dev server crash: ${e.message}`);
474
- });
475
- },
476
- });
477
- // 6. Update state with PID and mark ready
478
- const readyState = {
479
- ...state,
480
- pid: result.pid,
481
- status: 'ready',
482
- };
483
- deps.setSavePointQaEnvironment(savePointId, readyState);
484
- // 7. Update DB to ready
485
- await deps.updateSavePointQaStatus(savePointId, {
486
- qaStatus: 'ready',
487
- qaUrl: url,
488
- qaPort: port,
489
- qaReadyAt: new Date().toISOString(),
490
- });
491
- console.log(`[save-point-qa] QA environment ready for "${spName}" at ${url}`);
492
- }
493
- /**
494
- * Tear down a save point QA environment.
495
- * Kills the dev server but does NOT remove the worktree
496
- * (that's managed by the MCP close action).
497
- */
498
- async function handleSavePointQaTeardown(config, req, deps) {
499
- const { save_point_id: savePointId, name: spName } = req;
500
- console.log(`[save-point-qa] Tearing down QA environment for "${spName}"`);
501
- // Kill dev server if running
502
- const state = deps.getSavePointQaEnvironment(savePointId);
503
- if (state?.pid) {
504
- await deps.stopQaDevServer(state.pid);
505
- }
506
- // Clear in-memory state
507
- deps.removeSavePointQaEnvironment(savePointId);
508
- // Clear DB QA state (keep worktree_path -- that's managed by MCP view/close)
509
- await deps.updateSavePointQaStatus(savePointId, {
510
- qaStatus: null,
511
- qaUrl: null,
512
- qaPort: null,
513
- qaReadyAt: null,
514
- qaError: null,
515
- });
516
- console.log(`[save-point-qa] QA environment torn down for "${spName}"`);
517
- }
518
- //# sourceMappingURL=qa-orchestrator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"qa-orchestrator.js","sourceRoot":"","sources":["../src/qa-orchestrator.ts"],"names":[],"mappings":"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"}
@@ -1,34 +0,0 @@
1
- /**
2
- * QA environment port allocation and URL construction.
3
- *
4
- * Allocates ports from the configured range for QA dev servers,
5
- * checking both in-memory state and OS-level availability.
6
- */
7
- import type { DaemonConfig } from './types.js';
8
- /**
9
- * Allocate an available port from the configured QA port range.
10
- *
11
- * 1. Collects ports already in use by active QA environments (in-memory).
12
- * 2. Iterates through [qaPortRangeStart, qaPortRangeEnd].
13
- * 3. For each port not already allocated, verifies OS-level availability.
14
- * 4. Returns the first available port.
15
- *
16
- * @throws Error if no port is available in the configured range.
17
- */
18
- export declare function allocatePort(config: DaemonConfig): Promise<number>;
19
- /**
20
- * Release a port allocation.
21
- *
22
- * Currently a no-op: ports are tracked in qa-state.ts via QaEnvironmentState.
23
- * When removeQaEnvironment() is called, the port is implicitly released.
24
- * This is a placeholder for future explicit port reservation tracking.
25
- */
26
- export declare function releasePort(_port: number): void;
27
- /**
28
- * Build the full QA URL for a given port using the configured host.
29
- *
30
- * Uses qaHost from config, which is either an auto-detected LAN IP
31
- * or an explicitly configured hostname.
32
- */
33
- export declare function buildQaUrl(config: DaemonConfig, port: number): string;
34
- //# sourceMappingURL=qa-port-allocator.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"qa-port-allocator.d.ts","sourceRoot":"","sources":["../src/qa-port-allocator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAkB/C;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBxE;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAG/C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAErE"}
@@ -1,75 +0,0 @@
1
- /**
2
- * QA environment port allocation and URL construction.
3
- *
4
- * Allocates ports from the configured range for QA dev servers,
5
- * checking both in-memory state and OS-level availability.
6
- */
7
- import { createServer } from 'node:net';
8
- import { getActiveQaEnvironments } from './qa-state.js';
9
- /**
10
- * Check whether a port is available by briefly binding to it.
11
- * Returns true if the port can be bound, false if it is in use.
12
- */
13
- function isPortAvailable(port) {
14
- return new Promise((resolve) => {
15
- const server = createServer();
16
- server.once('error', () => resolve(false));
17
- server.once('listening', () => {
18
- server.close(() => resolve(true));
19
- });
20
- server.listen(port, '0.0.0.0');
21
- });
22
- }
23
- /**
24
- * Allocate an available port from the configured QA port range.
25
- *
26
- * 1. Collects ports already in use by active QA environments (in-memory).
27
- * 2. Iterates through [qaPortRangeStart, qaPortRangeEnd].
28
- * 3. For each port not already allocated, verifies OS-level availability.
29
- * 4. Returns the first available port.
30
- *
31
- * @throws Error if no port is available in the configured range.
32
- */
33
- export async function allocatePort(config) {
34
- const { qaPortRangeStart: start, qaPortRangeEnd: end } = config;
35
- // Collect ports already allocated to active QA environments
36
- const activeEnvironments = getActiveQaEnvironments();
37
- const allocatedPorts = new Set();
38
- for (const env of activeEnvironments.values()) {
39
- allocatedPorts.add(env.port);
40
- }
41
- // Iterate through the range looking for an available port
42
- for (let port = start; port <= end; port++) {
43
- // Skip ports already tracked in memory
44
- if (allocatedPorts.has(port)) {
45
- continue;
46
- }
47
- // Verify the port is actually free at the OS level
48
- const available = await isPortAvailable(port);
49
- if (available) {
50
- return port;
51
- }
52
- }
53
- throw new Error(`No available port in range ${start}-${end}`);
54
- }
55
- /**
56
- * Release a port allocation.
57
- *
58
- * Currently a no-op: ports are tracked in qa-state.ts via QaEnvironmentState.
59
- * When removeQaEnvironment() is called, the port is implicitly released.
60
- * This is a placeholder for future explicit port reservation tracking.
61
- */
62
- export function releasePort(_port) {
63
- // Port is released implicitly when QA environment state is removed.
64
- // This is a placeholder for future explicit port reservation tracking.
65
- }
66
- /**
67
- * Build the full QA URL for a given port using the configured host.
68
- *
69
- * Uses qaHost from config, which is either an auto-detected LAN IP
70
- * or an explicitly configured hostname.
71
- */
72
- export function buildQaUrl(config, port) {
73
- return `http://${config.qaHost}:${port}`;
74
- }
75
- //# sourceMappingURL=qa-port-allocator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"qa-port-allocator.js","sourceRoot":"","sources":["../src/qa-port-allocator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAExD;;;GAGG;AACH,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE;YAC5B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAoB;IACrD,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,MAAM,CAAC;IAEhE,4DAA4D;IAC5D,MAAM,kBAAkB,GAAG,uBAAuB,EAAE,CAAC;IACrD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAAC;QAC9C,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,0DAA0D;IAC1D,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC;QAC3C,uCAAuC;QACvC,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,SAAS;QACX,CAAC;QAED,mDAAmD;QACnD,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,8BAA8B,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,oEAAoE;IACpE,uEAAuE;AACzE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,MAAoB,EAAE,IAAY;IAC3D,OAAO,UAAU,MAAM,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;AAC3C,CAAC"}