infra-kit 0.1.128 → 0.1.129

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 (762) hide show
  1. package/dist/chunk-2PZRQHWF.js +2 -0
  2. package/dist/chunk-2PZRQHWF.js.map +7 -0
  3. package/dist/chunk-6RRAK2QO.js +5 -0
  4. package/dist/chunk-6RRAK2QO.js.map +7 -0
  5. package/dist/chunk-IX2A34UU.js +2 -0
  6. package/dist/chunk-IX2A34UU.js.map +7 -0
  7. package/dist/chunk-V5IDN7ZM.js +162 -0
  8. package/dist/chunk-V5IDN7ZM.js.map +7 -0
  9. package/dist/{chunk-YSBF5C7C.js → chunk-Z6KTUVIC.js} +2 -2
  10. package/dist/chunk-Z6KTUVIC.js.map +7 -0
  11. package/dist/cli.js +4 -4
  12. package/dist/cli.js.map +3 -3
  13. package/dist/dev-server.js +15 -10
  14. package/dist/dev-server.js.map +4 -4
  15. package/dist/entry/index.d.ts +1 -1
  16. package/dist/entry/vite.d.ts +2 -0
  17. package/dist/index.js +1 -1
  18. package/dist/lib/package-config/package-config-schema.d.ts +35 -0
  19. package/dist/lib/package-config/package-config.d.ts +28 -0
  20. package/dist/lib/release-slug/release-slug.d.ts +19 -0
  21. package/dist/lib/vite/vite.d.ts +135 -0
  22. package/dist/mcp.js +1 -1
  23. package/dist/mcp.js.map +1 -1
  24. package/dist/vite.js +2 -0
  25. package/dist/vite.js.map +7 -0
  26. package/package.json +10 -2
  27. package/.eslintcache +0 -1
  28. package/.omc/state/agent-replay-036daa78-5fee-4c7d-9b44-53584acb0d87.jsonl +0 -26
  29. package/.omc/state/agent-replay-0a58307d-2a37-4c69-851c-83a646502d62.jsonl +0 -1
  30. package/.omc/state/agent-replay-0a65ec83-9de7-458d-9d0f-e56e1a26c68e.jsonl +0 -2
  31. package/.omc/state/agent-replay-0d1515ce-4ebe-4ce8-a865-2897f68de168.jsonl +0 -1
  32. package/.omc/state/agent-replay-11c41aa0-51fa-49e1-a1dc-26dcd6ac26cc.jsonl +0 -16
  33. package/.omc/state/agent-replay-127837d3-a000-4656-9453-2324ab353723.jsonl +0 -5
  34. package/.omc/state/agent-replay-15c409af-24fa-4026-88d3-a82dd1e68b87.jsonl +0 -11
  35. package/.omc/state/agent-replay-1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a.jsonl +0 -17
  36. package/.omc/state/agent-replay-1fcfe0ec-7567-41c3-9bfd-501e99e86819.jsonl +0 -19
  37. package/.omc/state/agent-replay-2ac0dcd0-01f7-41a8-a8c9-f2195599817b.jsonl +0 -5
  38. package/.omc/state/agent-replay-2ccbd177-0d5d-4d4a-ab94-a22464786221.jsonl +0 -1
  39. package/.omc/state/agent-replay-36d91435-50b4-442f-9f4e-3cc68d776236.jsonl +0 -2
  40. package/.omc/state/agent-replay-38382db5-3088-4b5a-aff7-2561a60827c7.jsonl +0 -17
  41. package/.omc/state/agent-replay-4cf1c186-81b2-497c-b002-d7f84e7839f3.jsonl +0 -9
  42. package/.omc/state/agent-replay-50c36be9-a3a2-42b9-9c85-5a06d3e22f6a.jsonl +0 -5
  43. package/.omc/state/agent-replay-5c4ab554-64f1-42ae-83e3-21e0237e955c.jsonl +0 -11
  44. package/.omc/state/agent-replay-6be1264f-8069-4412-8119-86118ed1943e.jsonl +0 -3
  45. package/.omc/state/agent-replay-707b4784-2117-4b19-ae68-68a031f0d76d.jsonl +0 -2
  46. package/.omc/state/agent-replay-74afa912-1443-4011-b4f2-db9f055cdd9f.jsonl +0 -3
  47. package/.omc/state/agent-replay-8198b3e5-fad6-4ee0-9c59-ef773ad89af4.jsonl +0 -1
  48. package/.omc/state/agent-replay-8cd7652a-b8b5-49cf-9b1f-bee8e5972458.jsonl +0 -3
  49. package/.omc/state/agent-replay-8dd0ad2f-3a90-4158-b9de-ec8e19a7c983.jsonl +0 -3
  50. package/.omc/state/agent-replay-9bea518f-a9ee-4d14-bb53-a936ebaf647c.jsonl +0 -7
  51. package/.omc/state/agent-replay-a60ac2ec-afbd-449f-a540-6df287392fc2.jsonl +0 -1
  52. package/.omc/state/agent-replay-afc6290b-40d3-4bef-b3b6-14484c034ab9.jsonl +0 -14
  53. package/.omc/state/agent-replay-b52d89fb-0e24-4901-bc66-27e3c1697126.jsonl +0 -2
  54. package/.omc/state/agent-replay-be37e426-6fc8-47f4-8178-221c8494551c.jsonl +0 -3
  55. package/.omc/state/agent-replay-c967c819-3d1c-447b-ab48-56a8448ef9f8.jsonl +0 -2
  56. package/.omc/state/agent-replay-d02e6565-5168-40c8-8629-de219a29fa43.jsonl +0 -2
  57. package/.omc/state/agent-replay-d367c3be-9c2a-48e7-bcea-b45861af568c.jsonl +0 -2
  58. package/.omc/state/agent-replay-d5aae73c-340d-4aa2-9fe0-1bf2d79b69dc.jsonl +0 -10
  59. package/.omc/state/agent-replay-e947a3c6-989d-4a60-91dd-6b0ddd827b2d.jsonl +0 -3
  60. package/.omc/state/agent-replay-eb44055b-c2fa-4e66-b491-a1d9b44f51c7.jsonl +0 -1
  61. package/.omc/state/agent-replay-f2846d8f-974c-486c-b16f-4bdaa28ca45f.jsonl +0 -2
  62. package/.omc/state/agent-replay-f581a1ae-0ee4-48a3-96f3-ce31a0633bb0.jsonl +0 -1
  63. package/.omc/state/agent-replay-f99d8dad-81d1-4987-8183-62edf0843d0c.jsonl +0 -2
  64. package/.omc/state/agent-replay-fe1057b4-9a25-4e8e-8c3f-3e11652ee697.jsonl +0 -5
  65. package/.omc/state/idle-notif-cooldown.json +0 -3
  66. package/.omc/state/last-tool-error.json +0 -7
  67. package/.omc/state/mission-state.json +0 -53
  68. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/last-tool-error-state.json +0 -7
  69. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/mission-state.json +0 -129
  70. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/pre-tool-advisory-throttle.json +0 -34
  71. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/ralph-state.json +0 -13
  72. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/ralplan-state.json +0 -11
  73. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/subagent-tracking-state.json +0 -80
  74. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/ultrawork-state.json +0 -11
  75. package/.omc/state/sessions/0a58307d-2a37-4c69-851c-83a646502d62/pre-tool-advisory-throttle.json +0 -18
  76. package/.omc/state/sessions/0a58307d-2a37-4c69-851c-83a646502d62/subagent-tracking-state.json +0 -7
  77. package/.omc/state/sessions/0a65ec83-9de7-458d-9d0f-e56e1a26c68e/pre-tool-advisory-throttle.json +0 -18
  78. package/.omc/state/sessions/0a65ec83-9de7-458d-9d0f-e56e1a26c68e/skill-active-state.json +0 -15
  79. package/.omc/state/sessions/0d1515ce-4ebe-4ce8-a865-2897f68de168/pre-tool-advisory-throttle.json +0 -10
  80. package/.omc/state/sessions/11c41aa0-51fa-49e1-a1dc-26dcd6ac26cc/last-tool-error-state.json +0 -7
  81. package/.omc/state/sessions/11c41aa0-51fa-49e1-a1dc-26dcd6ac26cc/mission-state.json +0 -117
  82. package/.omc/state/sessions/11c41aa0-51fa-49e1-a1dc-26dcd6ac26cc/pre-tool-advisory-throttle.json +0 -42
  83. package/.omc/state/sessions/11c41aa0-51fa-49e1-a1dc-26dcd6ac26cc/subagent-tracking-state.json +0 -53
  84. package/.omc/state/sessions/127837d3-a000-4656-9453-2324ab353723/mission-state.json +0 -61
  85. package/.omc/state/sessions/127837d3-a000-4656-9453-2324ab353723/pre-tool-advisory-throttle.json +0 -22
  86. package/.omc/state/sessions/127837d3-a000-4656-9453-2324ab353723/skill-active-state.json +0 -15
  87. package/.omc/state/sessions/127837d3-a000-4656-9453-2324ab353723/subagent-tracking-state.json +0 -26
  88. package/.omc/state/sessions/15c409af-24fa-4026-88d3-a82dd1e68b87/last-tool-error-state.json +0 -7
  89. package/.omc/state/sessions/15c409af-24fa-4026-88d3-a82dd1e68b87/mission-state.json +0 -89
  90. package/.omc/state/sessions/15c409af-24fa-4026-88d3-a82dd1e68b87/pre-tool-advisory-throttle.json +0 -34
  91. package/.omc/state/sessions/15c409af-24fa-4026-88d3-a82dd1e68b87/ralph-state.json +0 -13
  92. package/.omc/state/sessions/15c409af-24fa-4026-88d3-a82dd1e68b87/skill-active-state.json +0 -15
  93. package/.omc/state/sessions/15c409af-24fa-4026-88d3-a82dd1e68b87/subagent-tracking-state.json +0 -44
  94. package/.omc/state/sessions/15c409af-24fa-4026-88d3-a82dd1e68b87/ultrawork-state.json +0 -11
  95. package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/last-tool-error-state.json +0 -7
  96. package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/mission-state.json +0 -139
  97. package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/pre-tool-advisory-throttle.json +0 -50
  98. package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/ralplan-state.json +0 -11
  99. package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/subagent-tracking-state.json +0 -90
  100. package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/last-tool-error-state.json +0 -7
  101. package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/mission-state.json +0 -109
  102. package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/pre-tool-advisory-throttle.json +0 -42
  103. package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/ralph-state.json +0 -13
  104. package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/skill-active-state.json +0 -15
  105. package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/subagent-tracking-state.json +0 -62
  106. package/.omc/state/sessions/1fcfe0ec-7567-41c3-9bfd-501e99e86819/ultrawork-state.json +0 -11
  107. package/.omc/state/sessions/23d0ff82-17e5-428b-8743-38f7979bb6f3/last-tool-error-state.json +0 -7
  108. package/.omc/state/sessions/23d0ff82-17e5-428b-8743-38f7979bb6f3/pre-tool-advisory-throttle.json +0 -18
  109. package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/last-tool-error-state.json +0 -7
  110. package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/mission-state.json +0 -79
  111. package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/pre-tool-advisory-throttle.json +0 -10
  112. package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/skill-active-state.json +0 -15
  113. package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/subagent-tracking-state.json +0 -26
  114. package/.omc/state/sessions/2ccbd177-0d5d-4d4a-ab94-a22464786221/pre-tool-advisory-throttle.json +0 -18
  115. package/.omc/state/sessions/2ccbd177-0d5d-4d4a-ab94-a22464786221/subagent-tracking-state.json +0 -17
  116. package/.omc/state/sessions/36d91435-50b4-442f-9f4e-3cc68d776236/pre-tool-advisory-throttle.json +0 -18
  117. package/.omc/state/sessions/36d91435-50b4-442f-9f4e-3cc68d776236/subagent-tracking-state.json +0 -17
  118. package/.omc/state/sessions/38382db5-3088-4b5a-aff7-2561a60827c7/last-tool-error-state.json +0 -7
  119. package/.omc/state/sessions/38382db5-3088-4b5a-aff7-2561a60827c7/mission-state.json +0 -145
  120. package/.omc/state/sessions/38382db5-3088-4b5a-aff7-2561a60827c7/pre-tool-advisory-throttle.json +0 -38
  121. package/.omc/state/sessions/38382db5-3088-4b5a-aff7-2561a60827c7/ralplan-state.json +0 -11
  122. package/.omc/state/sessions/38382db5-3088-4b5a-aff7-2561a60827c7/subagent-tracking-state.json +0 -98
  123. package/.omc/state/sessions/3a844fbd-ace8-4af1-8516-33d611839886/pre-tool-advisory-throttle.json +0 -18
  124. package/.omc/state/sessions/41336850-028c-476b-be1a-2164e1e46cac/last-tool-error-state.json +0 -7
  125. package/.omc/state/sessions/41336850-028c-476b-be1a-2164e1e46cac/pre-tool-advisory-throttle.json +0 -18
  126. package/.omc/state/sessions/4cf1c186-81b2-497c-b002-d7f84e7839f3/last-tool-error-state.json +0 -7
  127. package/.omc/state/sessions/4cf1c186-81b2-497c-b002-d7f84e7839f3/pre-tool-advisory-throttle.json +0 -18
  128. package/.omc/state/sessions/4cf1c186-81b2-497c-b002-d7f84e7839f3/subagent-tracking-state.json +0 -7
  129. package/.omc/state/sessions/50c36be9-a3a2-42b9-9c85-5a06d3e22f6a/mission-state.json +0 -61
  130. package/.omc/state/sessions/50c36be9-a3a2-42b9-9c85-5a06d3e22f6a/pre-tool-advisory-throttle.json +0 -22
  131. package/.omc/state/sessions/50c36be9-a3a2-42b9-9c85-5a06d3e22f6a/skill-active-state.json +0 -15
  132. package/.omc/state/sessions/50c36be9-a3a2-42b9-9c85-5a06d3e22f6a/subagent-tracking-state.json +0 -26
  133. package/.omc/state/sessions/560ea519-574a-4713-b134-5bf6cfaf3c33/pre-tool-advisory-throttle.json +0 -18
  134. package/.omc/state/sessions/5c4ab554-64f1-42ae-83e3-21e0237e955c/mission-state.json +0 -117
  135. package/.omc/state/sessions/5c4ab554-64f1-42ae-83e3-21e0237e955c/pre-tool-advisory-throttle.json +0 -18
  136. package/.omc/state/sessions/5c4ab554-64f1-42ae-83e3-21e0237e955c/subagent-tracking-state.json +0 -17
  137. package/.omc/state/sessions/6be1264f-8069-4412-8119-86118ed1943e/last-tool-error-state.json +0 -7
  138. package/.omc/state/sessions/6be1264f-8069-4412-8119-86118ed1943e/mission-state.json +0 -53
  139. package/.omc/state/sessions/6be1264f-8069-4412-8119-86118ed1943e/pre-tool-advisory-throttle.json +0 -22
  140. package/.omc/state/sessions/6be1264f-8069-4412-8119-86118ed1943e/skill-active-state.json +0 -15
  141. package/.omc/state/sessions/6be1264f-8069-4412-8119-86118ed1943e/subagent-tracking-state.json +0 -17
  142. package/.omc/state/sessions/707b4784-2117-4b19-ae68-68a031f0d76d/pre-tool-advisory-throttle.json +0 -18
  143. package/.omc/state/sessions/707b4784-2117-4b19-ae68-68a031f0d76d/subagent-tracking-state.json +0 -17
  144. package/.omc/state/sessions/74afa912-1443-4011-b4f2-db9f055cdd9f/pre-tool-advisory-throttle.json +0 -18
  145. package/.omc/state/sessions/74afa912-1443-4011-b4f2-db9f055cdd9f/skill-active-state.json +0 -15
  146. package/.omc/state/sessions/74afa912-1443-4011-b4f2-db9f055cdd9f/subagent-tracking-state.json +0 -17
  147. package/.omc/state/sessions/7772f972-4ec1-4287-bf42-a92c14cf3ffc/pre-tool-advisory-throttle.json +0 -10
  148. package/.omc/state/sessions/8198b3e5-fad6-4ee0-9c59-ef773ad89af4/pre-tool-advisory-throttle.json +0 -14
  149. package/.omc/state/sessions/8198b3e5-fad6-4ee0-9c59-ef773ad89af4/subagent-tracking-state.json +0 -17
  150. package/.omc/state/sessions/8cd7652a-b8b5-49cf-9b1f-bee8e5972458/pre-tool-advisory-throttle.json +0 -18
  151. package/.omc/state/sessions/8cd7652a-b8b5-49cf-9b1f-bee8e5972458/ralplan-state.json +0 -11
  152. package/.omc/state/sessions/8cd7652a-b8b5-49cf-9b1f-bee8e5972458/subagent-tracking-state.json +0 -35
  153. package/.omc/state/sessions/8dd0ad2f-3a90-4158-b9de-ec8e19a7c983/pre-tool-advisory-throttle.json +0 -14
  154. package/.omc/state/sessions/8dd0ad2f-3a90-4158-b9de-ec8e19a7c983/ralph-state.json +0 -13
  155. package/.omc/state/sessions/8dd0ad2f-3a90-4158-b9de-ec8e19a7c983/subagent-tracking-state.json +0 -17
  156. package/.omc/state/sessions/8dd0ad2f-3a90-4158-b9de-ec8e19a7c983/ultrawork-state.json +0 -11
  157. package/.omc/state/sessions/9bea518f-a9ee-4d14-bb53-a936ebaf647c/last-tool-error-state.json +0 -7
  158. package/.omc/state/sessions/9bea518f-a9ee-4d14-bb53-a936ebaf647c/mission-state.json +0 -79
  159. package/.omc/state/sessions/9bea518f-a9ee-4d14-bb53-a936ebaf647c/pre-tool-advisory-throttle.json +0 -22
  160. package/.omc/state/sessions/9bea518f-a9ee-4d14-bb53-a936ebaf647c/progress.txt +0 -7
  161. package/.omc/state/sessions/9bea518f-a9ee-4d14-bb53-a936ebaf647c/skill-active-state.json +0 -15
  162. package/.omc/state/sessions/9bea518f-a9ee-4d14-bb53-a936ebaf647c/subagent-tracking-state.json +0 -26
  163. package/.omc/state/sessions/a60ac2ec-afbd-449f-a540-6df287392fc2/pre-tool-advisory-throttle.json +0 -18
  164. package/.omc/state/sessions/a60ac2ec-afbd-449f-a540-6df287392fc2/subagent-tracking-state.json +0 -7
  165. package/.omc/state/sessions/afc6290b-40d3-4bef-b3b6-14484c034ab9/last-tool-error-state.json +0 -7
  166. package/.omc/state/sessions/afc6290b-40d3-4bef-b3b6-14484c034ab9/mission-state.json +0 -89
  167. package/.omc/state/sessions/afc6290b-40d3-4bef-b3b6-14484c034ab9/pre-tool-advisory-throttle.json +0 -34
  168. package/.omc/state/sessions/afc6290b-40d3-4bef-b3b6-14484c034ab9/ralph-state.json +0 -13
  169. package/.omc/state/sessions/afc6290b-40d3-4bef-b3b6-14484c034ab9/skill-active-state.json +0 -15
  170. package/.omc/state/sessions/afc6290b-40d3-4bef-b3b6-14484c034ab9/subagent-tracking-state.json +0 -35
  171. package/.omc/state/sessions/afc6290b-40d3-4bef-b3b6-14484c034ab9/ultrawork-state.json +0 -11
  172. package/.omc/state/sessions/b52d89fb-0e24-4901-bc66-27e3c1697126/pre-tool-advisory-throttle.json +0 -14
  173. package/.omc/state/sessions/b52d89fb-0e24-4901-bc66-27e3c1697126/subagent-tracking-state.json +0 -17
  174. package/.omc/state/sessions/c513ef38-cc3e-4a29-9c4c-1e0137245dd5/pre-tool-advisory-throttle.json +0 -18
  175. package/.omc/state/sessions/c967c819-3d1c-447b-ab48-56a8448ef9f8/pre-tool-advisory-throttle.json +0 -10
  176. package/.omc/state/sessions/c967c819-3d1c-447b-ab48-56a8448ef9f8/subagent-tracking-state.json +0 -7
  177. package/.omc/state/sessions/d02e6565-5168-40c8-8629-de219a29fa43/last-tool-error-state.json +0 -7
  178. package/.omc/state/sessions/d02e6565-5168-40c8-8629-de219a29fa43/mission-state.json +0 -53
  179. package/.omc/state/sessions/d02e6565-5168-40c8-8629-de219a29fa43/pre-tool-advisory-throttle.json +0 -18
  180. package/.omc/state/sessions/d02e6565-5168-40c8-8629-de219a29fa43/subagent-tracking-state.json +0 -17
  181. package/.omc/state/sessions/d5aae73c-340d-4aa2-9fe0-1bf2d79b69dc/last-tool-error-state.json +0 -7
  182. package/.omc/state/sessions/d5aae73c-340d-4aa2-9fe0-1bf2d79b69dc/mission-state.json +0 -103
  183. package/.omc/state/sessions/d5aae73c-340d-4aa2-9fe0-1bf2d79b69dc/pre-tool-advisory-throttle.json +0 -30
  184. package/.omc/state/sessions/d5aae73c-340d-4aa2-9fe0-1bf2d79b69dc/ralph-state.json +0 -13
  185. package/.omc/state/sessions/d5aae73c-340d-4aa2-9fe0-1bf2d79b69dc/subagent-tracking-state.json +0 -62
  186. package/.omc/state/sessions/d5aae73c-340d-4aa2-9fe0-1bf2d79b69dc/ultrawork-state.json +0 -11
  187. package/.omc/state/sessions/e947a3c6-989d-4a60-91dd-6b0ddd827b2d/last-tool-error-state.json +0 -7
  188. package/.omc/state/sessions/e947a3c6-989d-4a60-91dd-6b0ddd827b2d/pre-tool-advisory-throttle.json +0 -10
  189. package/.omc/state/sessions/e947a3c6-989d-4a60-91dd-6b0ddd827b2d/subagent-tracking-state.json +0 -26
  190. package/.omc/state/sessions/eb44055b-c2fa-4e66-b491-a1d9b44f51c7/last-tool-error-state.json +0 -7
  191. package/.omc/state/sessions/eb44055b-c2fa-4e66-b491-a1d9b44f51c7/pre-tool-advisory-throttle.json +0 -18
  192. package/.omc/state/sessions/eb44055b-c2fa-4e66-b491-a1d9b44f51c7/subagent-tracking-state.json +0 -17
  193. package/.omc/state/sessions/ed3e2cfb-a666-4bb1-bcc1-569d5d0b837a/pre-tool-advisory-throttle.json +0 -18
  194. package/.omc/state/sessions/f581a1ae-0ee4-48a3-96f3-ce31a0633bb0/pre-tool-advisory-throttle.json +0 -18
  195. package/.omc/state/sessions/f581a1ae-0ee4-48a3-96f3-ce31a0633bb0/subagent-tracking-state.json +0 -17
  196. package/.omc/state/sessions/f99d8dad-81d1-4987-8183-62edf0843d0c/pre-tool-advisory-throttle.json +0 -14
  197. package/.omc/state/sessions/f99d8dad-81d1-4987-8183-62edf0843d0c/ralph-state.json +0 -13
  198. package/.omc/state/sessions/f99d8dad-81d1-4987-8183-62edf0843d0c/ultrawork-state.json +0 -11
  199. package/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/pre-tool-advisory-throttle.json +0 -10
  200. package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/last-tool-error-state.json +0 -7
  201. package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/mission-state.json +0 -61
  202. package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/prd.json +0 -22
  203. package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/pre-tool-advisory-throttle.json +0 -22
  204. package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/progress.txt +0 -22
  205. package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/skill-active-state.json +0 -15
  206. package/.omc/state/sessions/fe1057b4-9a25-4e8e-8c3f-3e11652ee697/subagent-tracking-state.json +0 -26
  207. package/.omc/state/subagent-tracking.json +0 -17
  208. package/.turbo/turbo-build.log +0 -7
  209. package/.turbo/turbo-check.log +0 -14
  210. package/.turbo/turbo-eslint-check.log +0 -2
  211. package/.turbo/turbo-eslint-fix.log +0 -1
  212. package/.turbo/turbo-infra-kit-check.log +0 -14
  213. package/.turbo/turbo-prettier-check.log +0 -1
  214. package/.turbo/turbo-prettier-fix.log +0 -1
  215. package/.turbo/turbo-test.log +0 -406
  216. package/.turbo/turbo-ts-check.log +0 -1
  217. package/.turbo/turbo-validate.log +0 -14
  218. package/coverage/base.css +0 -224
  219. package/coverage/block-navigation.js +0 -87
  220. package/coverage/cli/index.html +0 -116
  221. package/coverage/cli/package.json.html +0 -283
  222. package/coverage/cli/src/commands/audit/audit.ts.html +0 -616
  223. package/coverage/cli/src/commands/audit/index.html +0 -131
  224. package/coverage/cli/src/commands/audit/index.ts.html +0 -88
  225. package/coverage/cli/src/commands/doctor/doctor.ts.html +0 -1654
  226. package/coverage/cli/src/commands/doctor/index.html +0 -131
  227. package/coverage/cli/src/commands/doctor/index.ts.html +0 -88
  228. package/coverage/cli/src/commands/env-clear/env-clear.ts.html +0 -370
  229. package/coverage/cli/src/commands/env-clear/index.html +0 -131
  230. package/coverage/cli/src/commands/env-clear/index.ts.html +0 -88
  231. package/coverage/cli/src/commands/env-list/env-list.ts.html +0 -229
  232. package/coverage/cli/src/commands/env-list/index.html +0 -131
  233. package/coverage/cli/src/commands/env-list/index.ts.html +0 -88
  234. package/coverage/cli/src/commands/env-load/env-load.ts.html +0 -1201
  235. package/coverage/cli/src/commands/env-load/index.html +0 -131
  236. package/coverage/cli/src/commands/env-load/index.ts.html +0 -91
  237. package/coverage/cli/src/commands/env-status/env-status.ts.html +0 -409
  238. package/coverage/cli/src/commands/env-status/index.html +0 -131
  239. package/coverage/cli/src/commands/env-status/index.ts.html +0 -88
  240. package/coverage/cli/src/commands/gh-merge-dev/gh-merge-dev.ts.html +0 -694
  241. package/coverage/cli/src/commands/gh-merge-dev/index.html +0 -131
  242. package/coverage/cli/src/commands/gh-merge-dev/index.ts.html +0 -88
  243. package/coverage/cli/src/commands/gh-release-deliver/gh-release-deliver.ts.html +0 -1495
  244. package/coverage/cli/src/commands/gh-release-deliver/index.html +0 -131
  245. package/coverage/cli/src/commands/gh-release-deliver/index.ts.html +0 -88
  246. package/coverage/cli/src/commands/gh-release-deploy-all/gh-release-deploy-all.ts.html +0 -706
  247. package/coverage/cli/src/commands/gh-release-deploy-all/index.html +0 -131
  248. package/coverage/cli/src/commands/gh-release-deploy-all/index.ts.html +0 -88
  249. package/coverage/cli/src/commands/gh-release-deploy-selected/gh-release-deploy-selected.ts.html +0 -994
  250. package/coverage/cli/src/commands/gh-release-deploy-selected/index.html +0 -131
  251. package/coverage/cli/src/commands/gh-release-deploy-selected/index.ts.html +0 -88
  252. package/coverage/cli/src/commands/gh-release-list/gh-release-list.ts.html +0 -355
  253. package/coverage/cli/src/commands/gh-release-list/index.html +0 -131
  254. package/coverage/cli/src/commands/gh-release-list/index.ts.html +0 -88
  255. package/coverage/cli/src/commands/init/agent-files.ts.html +0 -742
  256. package/coverage/cli/src/commands/init/index.html +0 -146
  257. package/coverage/cli/src/commands/init/init.ts.html +0 -1159
  258. package/coverage/cli/src/commands/init/migrate-config.ts.html +0 -1219
  259. package/coverage/cli/src/commands/release-create/index.html +0 -131
  260. package/coverage/cli/src/commands/release-create/index.ts.html +0 -88
  261. package/coverage/cli/src/commands/release-create/release-create.ts.html +0 -1426
  262. package/coverage/cli/src/commands/release-desc-edit/index.html +0 -131
  263. package/coverage/cli/src/commands/release-desc-edit/index.ts.html +0 -88
  264. package/coverage/cli/src/commands/release-desc-edit/release-desc-edit.ts.html +0 -766
  265. package/coverage/cli/src/commands/vendor-check/index.html +0 -131
  266. package/coverage/cli/src/commands/vendor-check/index.ts.html +0 -88
  267. package/coverage/cli/src/commands/vendor-check/vendor-check.ts.html +0 -466
  268. package/coverage/cli/src/commands/vendor-config/index.html +0 -116
  269. package/coverage/cli/src/commands/vendor-config/vendor-config.ts.html +0 -571
  270. package/coverage/cli/src/commands/vendor-diff/index.html +0 -131
  271. package/coverage/cli/src/commands/vendor-diff/index.ts.html +0 -88
  272. package/coverage/cli/src/commands/vendor-diff/vendor-diff.ts.html +0 -316
  273. package/coverage/cli/src/commands/vendor-manifest/index.html +0 -131
  274. package/coverage/cli/src/commands/vendor-manifest/index.ts.html +0 -88
  275. package/coverage/cli/src/commands/vendor-manifest/vendor-manifest.ts.html +0 -265
  276. package/coverage/cli/src/commands/vendor-sync/index.html +0 -131
  277. package/coverage/cli/src/commands/vendor-sync/index.ts.html +0 -88
  278. package/coverage/cli/src/commands/vendor-sync/vendor-sync.ts.html +0 -355
  279. package/coverage/cli/src/commands/version/index.html +0 -131
  280. package/coverage/cli/src/commands/version/index.ts.html +0 -88
  281. package/coverage/cli/src/commands/version/version.ts.html +0 -184
  282. package/coverage/cli/src/commands/worktrees-add/index.html +0 -131
  283. package/coverage/cli/src/commands/worktrees-add/index.ts.html +0 -88
  284. package/coverage/cli/src/commands/worktrees-add/worktrees-add.ts.html +0 -1183
  285. package/coverage/cli/src/commands/worktrees-list/index.html +0 -131
  286. package/coverage/cli/src/commands/worktrees-list/index.ts.html +0 -88
  287. package/coverage/cli/src/commands/worktrees-list/worktrees-list.ts.html +0 -400
  288. package/coverage/cli/src/commands/worktrees-reload/index.html +0 -131
  289. package/coverage/cli/src/commands/worktrees-reload/index.ts.html +0 -88
  290. package/coverage/cli/src/commands/worktrees-reload/worktrees-reload.ts.html +0 -775
  291. package/coverage/cli/src/commands/worktrees-remove/index.html +0 -131
  292. package/coverage/cli/src/commands/worktrees-remove/index.ts.html +0 -88
  293. package/coverage/cli/src/commands/worktrees-remove/worktrees-remove.ts.html +0 -682
  294. package/coverage/cli/src/commands/worktrees-sync/index.html +0 -131
  295. package/coverage/cli/src/commands/worktrees-sync/index.ts.html +0 -88
  296. package/coverage/cli/src/commands/worktrees-sync/worktrees-sync.ts.html +0 -679
  297. package/coverage/cli/src/dev/__tests__/fixtures.ts.html +0 -787
  298. package/coverage/cli/src/dev/__tests__/index.html +0 -116
  299. package/coverage/cli/src/dev/dev-server.ts.html +0 -1855
  300. package/coverage/cli/src/dev/discovery.ts.html +0 -598
  301. package/coverage/cli/src/dev/index.html +0 -191
  302. package/coverage/cli/src/dev/interfaces.ts.html +0 -223
  303. package/coverage/cli/src/dev/logger.ts.html +0 -1102
  304. package/coverage/cli/src/dev/ports.ts.html +0 -430
  305. package/coverage/cli/src/dev/serverless-local-run.ts.html +0 -916
  306. package/coverage/cli/src/entry/dev-server.ts.html +0 -409
  307. package/coverage/cli/src/entry/index.html +0 -116
  308. package/coverage/cli/src/index.html +0 -116
  309. package/coverage/cli/src/integrations/cmux/canonicalize-cmux-title.ts.html +0 -178
  310. package/coverage/cli/src/integrations/cmux/close-workspace-by-title.ts.html +0 -262
  311. package/coverage/cli/src/integrations/cmux/index.html +0 -191
  312. package/coverage/cli/src/integrations/cmux/index.ts.html +0 -100
  313. package/coverage/cli/src/integrations/cmux/list-workspace-titles.ts.html +0 -226
  314. package/coverage/cli/src/integrations/cmux/open-workspace-with-layout.ts.html +0 -325
  315. package/coverage/cli/src/integrations/cmux/workspace-title.ts.html +0 -154
  316. package/coverage/cli/src/integrations/cursor/add-folders-to-workspace.ts.html +0 -337
  317. package/coverage/cli/src/integrations/cursor/index.html +0 -206
  318. package/coverage/cli/src/integrations/cursor/index.ts.html +0 -103
  319. package/coverage/cli/src/integrations/cursor/launch-cursor.ts.html +0 -121
  320. package/coverage/cli/src/integrations/cursor/open-cursor-workspace.ts.html +0 -277
  321. package/coverage/cli/src/integrations/cursor/reconcile-workspace-folders.ts.html +0 -355
  322. package/coverage/cli/src/integrations/cursor/remove-folders-from-workspace.ts.html +0 -364
  323. package/coverage/cli/src/integrations/cursor/resolve-workspace-path.ts.html +0 -124
  324. package/coverage/cli/src/integrations/doppler/doppler-cli-auth.ts.html +0 -178
  325. package/coverage/cli/src/integrations/doppler/doppler-errors.ts.html +0 -349
  326. package/coverage/cli/src/integrations/doppler/doppler-project.ts.html +0 -355
  327. package/coverage/cli/src/integrations/doppler/index.html +0 -161
  328. package/coverage/cli/src/integrations/doppler/index.ts.html +0 -97
  329. package/coverage/cli/src/integrations/gh/gh-cli-auth/gh-cli-auth.ts.html +0 -172
  330. package/coverage/cli/src/integrations/gh/gh-cli-auth/index.html +0 -131
  331. package/coverage/cli/src/integrations/gh/gh-cli-auth/index.ts.html +0 -88
  332. package/coverage/cli/src/integrations/gh/gh-release-prs/gh-release-prs.ts.html +0 -703
  333. package/coverage/cli/src/integrations/gh/gh-release-prs/index.html +0 -131
  334. package/coverage/cli/src/integrations/gh/gh-release-prs/index.ts.html +0 -91
  335. package/coverage/cli/src/integrations/gh/index.html +0 -116
  336. package/coverage/cli/src/integrations/gh/index.ts.html +0 -94
  337. package/coverage/cli/src/integrations/ide/add-ide-worktree-folders.ts.html +0 -316
  338. package/coverage/cli/src/integrations/ide/index.html +0 -191
  339. package/coverage/cli/src/integrations/ide/index.ts.html +0 -103
  340. package/coverage/cli/src/integrations/ide/open-ide-workspace.ts.html +0 -238
  341. package/coverage/cli/src/integrations/ide/provider-label.ts.html +0 -157
  342. package/coverage/cli/src/integrations/ide/remove-ide-worktree-folders.ts.html +0 -520
  343. package/coverage/cli/src/integrations/ide/types.ts.html +0 -208
  344. package/coverage/cli/src/integrations/jira/api.ts.html +0 -1060
  345. package/coverage/cli/src/integrations/jira/index.html +0 -131
  346. package/coverage/cli/src/integrations/jira/index.ts.html +0 -142
  347. package/coverage/cli/src/integrations/zed/add-folders-to-zed-workspace.ts.html +0 -175
  348. package/coverage/cli/src/integrations/zed/index.html +0 -161
  349. package/coverage/cli/src/integrations/zed/index.ts.html +0 -94
  350. package/coverage/cli/src/integrations/zed/open-zed-workspace.ts.html +0 -238
  351. package/coverage/cli/src/integrations/zed/reuse-zed-workspace.ts.html +0 -256
  352. package/coverage/cli/src/lib/assert-never/assert-never.ts.html +0 -130
  353. package/coverage/cli/src/lib/assert-never/index.html +0 -131
  354. package/coverage/cli/src/lib/assert-never/index.ts.html +0 -88
  355. package/coverage/cli/src/lib/command-catalog/command-catalog.ts.html +0 -523
  356. package/coverage/cli/src/lib/command-catalog/index.html +0 -116
  357. package/coverage/cli/src/lib/command-echo/command-echo.ts.html +0 -319
  358. package/coverage/cli/src/lib/command-echo/index.html +0 -131
  359. package/coverage/cli/src/lib/command-echo/index.ts.html +0 -88
  360. package/coverage/cli/src/lib/constants/constants.ts.html +0 -472
  361. package/coverage/cli/src/lib/constants/index.html +0 -131
  362. package/coverage/cli/src/lib/constants/index.ts.html +0 -139
  363. package/coverage/cli/src/lib/env-autoload/env-autoload.ts.html +0 -1111
  364. package/coverage/cli/src/lib/env-autoload/index.html +0 -116
  365. package/coverage/cli/src/lib/errors/format-zx-error.ts.html +0 -247
  366. package/coverage/cli/src/lib/errors/index.html +0 -146
  367. package/coverage/cli/src/lib/errors/is-prompt-cancellation.ts.html +0 -199
  368. package/coverage/cli/src/lib/errors/operation-error.ts.html +0 -325
  369. package/coverage/cli/src/lib/git-guard/git-guard.ts.html +0 -250
  370. package/coverage/cli/src/lib/git-guard/index.html +0 -131
  371. package/coverage/cli/src/lib/git-guard/index.ts.html +0 -91
  372. package/coverage/cli/src/lib/git-utils/git-utils.ts.html +0 -622
  373. package/coverage/cli/src/lib/git-utils/index.html +0 -131
  374. package/coverage/cli/src/lib/git-utils/index.ts.html +0 -115
  375. package/coverage/cli/src/lib/infra-kit-config/index.html +0 -131
  376. package/coverage/cli/src/lib/infra-kit-config/index.ts.html +0 -142
  377. package/coverage/cli/src/lib/infra-kit-config/infra-kit-config.ts.html +0 -1447
  378. package/coverage/cli/src/lib/json-output/index.html +0 -116
  379. package/coverage/cli/src/lib/json-output/json-output.ts.html +0 -226
  380. package/coverage/cli/src/lib/logger/index.html +0 -116
  381. package/coverage/cli/src/lib/logger/index.ts.html +0 -205
  382. package/coverage/cli/src/lib/managed-block/index.html +0 -131
  383. package/coverage/cli/src/lib/managed-block/index.ts.html +0 -109
  384. package/coverage/cli/src/lib/managed-block/managed-block.ts.html +0 -520
  385. package/coverage/cli/src/lib/package-config/index.html +0 -146
  386. package/coverage/cli/src/lib/package-config/index.ts.html +0 -94
  387. package/coverage/cli/src/lib/package-config/package-config-schema.ts.html +0 -142
  388. package/coverage/cli/src/lib/package-config/package-config.ts.html +0 -376
  389. package/coverage/cli/src/lib/package-validator/checks/config-check.ts.html +0 -175
  390. package/coverage/cli/src/lib/package-validator/checks/files-check.ts.html +0 -172
  391. package/coverage/cli/src/lib/package-validator/checks/index.html +0 -176
  392. package/coverage/cli/src/lib/package-validator/checks/index.ts.html +0 -97
  393. package/coverage/cli/src/lib/package-validator/checks/scripts-check.ts.html +0 -154
  394. package/coverage/cli/src/lib/package-validator/checks/turbo-check.ts.html +0 -226
  395. package/coverage/cli/src/lib/package-validator/fs-utils.ts.html +0 -139
  396. package/coverage/cli/src/lib/package-validator/index.html +0 -146
  397. package/coverage/cli/src/lib/package-validator/index.ts.html +0 -94
  398. package/coverage/cli/src/lib/package-validator/loader/config-loader.ts.html +0 -316
  399. package/coverage/cli/src/lib/package-validator/loader/index.html +0 -146
  400. package/coverage/cli/src/lib/package-validator/loader/index.ts.html +0 -91
  401. package/coverage/cli/src/lib/package-validator/loader/package-discovery.ts.html +0 -379
  402. package/coverage/cli/src/lib/package-validator/package-validator.ts.html +0 -229
  403. package/coverage/cli/src/lib/path-display/index.html +0 -131
  404. package/coverage/cli/src/lib/path-display/index.ts.html +0 -88
  405. package/coverage/cli/src/lib/path-display/path-display.ts.html +0 -211
  406. package/coverage/cli/src/lib/release-id/index.html +0 -131
  407. package/coverage/cli/src/lib/release-id/index.ts.html +0 -130
  408. package/coverage/cli/src/lib/release-id/release-id.ts.html +0 -859
  409. package/coverage/cli/src/lib/release-utils/index.html +0 -131
  410. package/coverage/cli/src/lib/release-utils/index.ts.html +0 -130
  411. package/coverage/cli/src/lib/release-utils/release-utils.ts.html +0 -778
  412. package/coverage/cli/src/lib/render/index.html +0 -116
  413. package/coverage/cli/src/lib/render/render.ts.html +0 -157
  414. package/coverage/cli/src/lib/vendor/__tests__/index.html +0 -116
  415. package/coverage/cli/src/lib/vendor/__tests__/zx-mock.ts.html +0 -181
  416. package/coverage/cli/src/lib/vendor/config-schema.ts.html +0 -319
  417. package/coverage/cli/src/lib/vendor/config.ts.html +0 -259
  418. package/coverage/cli/src/lib/vendor/factory-config-schema.ts.html +0 -190
  419. package/coverage/cli/src/lib/vendor/factory-config.ts.html +0 -358
  420. package/coverage/cli/src/lib/vendor/hash.ts.html +0 -133
  421. package/coverage/cli/src/lib/vendor/index.html +0 -251
  422. package/coverage/cli/src/lib/vendor/index.ts.html +0 -154
  423. package/coverage/cli/src/lib/vendor/manifest.ts.html +0 -538
  424. package/coverage/cli/src/lib/vendor/skip-sets.ts.html +0 -229
  425. package/coverage/cli/src/lib/vendor/sync-ops.ts.html +0 -955
  426. package/coverage/cli/src/lib/vendor/walk.ts.html +0 -253
  427. package/coverage/cli/src/lib/version-utils/index.html +0 -161
  428. package/coverage/cli/src/lib/version-utils/index.ts.html +0 -139
  429. package/coverage/cli/src/lib/version-utils/load-existing-versions.ts.html +0 -343
  430. package/coverage/cli/src/lib/version-utils/next-version.ts.html +0 -934
  431. package/coverage/cli/src/lib/version-utils/version-utils.ts.html +0 -178
  432. package/coverage/cli/src/lib/worktrees/index.html +0 -131
  433. package/coverage/cli/src/lib/worktrees/index.ts.html +0 -88
  434. package/coverage/cli/src/lib/worktrees/remove-worktrees.ts.html +0 -283
  435. package/coverage/cli/src/tui/boot.tsx.html +0 -265
  436. package/coverage/cli/src/tui/index.html +0 -116
  437. package/coverage/cli/src/tui/screens/command-palette.tsx.html +0 -562
  438. package/coverage/cli/src/tui/screens/index.html +0 -116
  439. package/coverage/cli/src/types.ts.html +0 -283
  440. package/coverage/clover.xml +0 -4488
  441. package/coverage/coverage-final.json +0 -156
  442. package/coverage/favicon.png +0 -0
  443. package/coverage/index.html +0 -1076
  444. package/coverage/prettify.css +0 -1
  445. package/coverage/prettify.js +0 -2
  446. package/coverage/sort-arrow-sprite.png +0 -0
  447. package/coverage/sorter.js +0 -210
  448. package/dist/chunk-DB6CTNBS.js +0 -3
  449. package/dist/chunk-DB6CTNBS.js.map +0 -7
  450. package/dist/chunk-QBHCWAAG.js +0 -164
  451. package/dist/chunk-QBHCWAAG.js.map +0 -7
  452. package/dist/chunk-YSBF5C7C.js.map +0 -7
  453. package/eslint.config.js +0 -35
  454. package/infra-kit.config.ts +0 -5
  455. package/scripts/build.js +0 -75
  456. package/src/.omc/state/agent-replay-2ac0dcd0-01f7-41a8-a8c9-f2195599817b.jsonl +0 -5
  457. package/src/.omc/state/agent-replay-2ccbd177-0d5d-4d4a-ab94-a22464786221.jsonl +0 -2
  458. package/src/.omc/state/agent-replay-707b4784-2117-4b19-ae68-68a031f0d76d.jsonl +0 -2
  459. package/src/.omc/state/agent-replay-8dd0ad2f-3a90-4158-b9de-ec8e19a7c983.jsonl +0 -11
  460. package/src/.omc/state/agent-replay-c513ef38-cc3e-4a29-9c4c-1e0137245dd5.jsonl +0 -4
  461. package/src/.omc/state/agent-replay-ed3e2cfb-a666-4bb1-bcc1-569d5d0b837a.jsonl +0 -2
  462. package/src/.omc/state/idle-notif-cooldown.json +0 -3
  463. package/src/.omc/state/sessions/0a58307d-2a37-4c69-851c-83a646502d62/pre-tool-advisory-throttle.json +0 -18
  464. package/src/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/mission-state.json +0 -79
  465. package/src/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/pre-tool-advisory-throttle.json +0 -26
  466. package/src/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/subagent-tracking-state.json +0 -26
  467. package/src/.omc/state/sessions/2ccbd177-0d5d-4d4a-ab94-a22464786221/last-tool-error-state.json +0 -7
  468. package/src/.omc/state/sessions/2ccbd177-0d5d-4d4a-ab94-a22464786221/mission-state.json +0 -53
  469. package/src/.omc/state/sessions/2ccbd177-0d5d-4d4a-ab94-a22464786221/pre-tool-advisory-throttle.json +0 -22
  470. package/src/.omc/state/sessions/2ccbd177-0d5d-4d4a-ab94-a22464786221/subagent-tracking-state.json +0 -17
  471. package/src/.omc/state/sessions/707b4784-2117-4b19-ae68-68a031f0d76d/last-tool-error-state.json +0 -7
  472. package/src/.omc/state/sessions/707b4784-2117-4b19-ae68-68a031f0d76d/mission-state.json +0 -53
  473. package/src/.omc/state/sessions/707b4784-2117-4b19-ae68-68a031f0d76d/pre-tool-advisory-throttle.json +0 -22
  474. package/src/.omc/state/sessions/707b4784-2117-4b19-ae68-68a031f0d76d/subagent-tracking-state.json +0 -17
  475. package/src/.omc/state/sessions/8dd0ad2f-3a90-4158-b9de-ec8e19a7c983/mission-state.json +0 -79
  476. package/src/.omc/state/sessions/8dd0ad2f-3a90-4158-b9de-ec8e19a7c983/pre-tool-advisory-throttle.json +0 -22
  477. package/src/.omc/state/sessions/8dd0ad2f-3a90-4158-b9de-ec8e19a7c983/ralph-state.json +0 -13
  478. package/src/.omc/state/sessions/8dd0ad2f-3a90-4158-b9de-ec8e19a7c983/subagent-tracking-state.json +0 -26
  479. package/src/.omc/state/sessions/8dd0ad2f-3a90-4158-b9de-ec8e19a7c983/ultrawork-state.json +0 -11
  480. package/src/.omc/state/sessions/c513ef38-cc3e-4a29-9c4c-1e0137245dd5/mission-state.json +0 -79
  481. package/src/.omc/state/sessions/c513ef38-cc3e-4a29-9c4c-1e0137245dd5/pre-tool-advisory-throttle.json +0 -22
  482. package/src/.omc/state/sessions/c513ef38-cc3e-4a29-9c4c-1e0137245dd5/subagent-tracking-state.json +0 -26
  483. package/src/.omc/state/sessions/ed3e2cfb-a666-4bb1-bcc1-569d5d0b837a/pre-tool-advisory-throttle.json +0 -18
  484. package/src/.omc/state/sessions/ed3e2cfb-a666-4bb1-bcc1-569d5d0b837a/ralph-state.json +0 -13
  485. package/src/.omc/state/sessions/ed3e2cfb-a666-4bb1-bcc1-569d5d0b837a/ultrawork-state.json +0 -11
  486. package/src/.omc/state/sessions/f99d8dad-81d1-4987-8183-62edf0843d0c/pre-tool-advisory-throttle.json +0 -14
  487. package/src/commands/.omc/state/sessions/afc6290b-40d3-4bef-b3b6-14484c034ab9/pre-tool-advisory-throttle.json +0 -14
  488. package/src/commands/.omc/state/sessions/c967c819-3d1c-447b-ab48-56a8448ef9f8/pre-tool-advisory-throttle.json +0 -18
  489. package/src/commands/.omc/state/sessions/f09f401f-56c6-42cd-97be-c742c1956468/pre-tool-advisory-throttle.json +0 -14
  490. package/src/commands/audit/.omc/state/agent-replay-f9c17a0e-2dd8-4f7d-badf-631f266c5d4c.jsonl +0 -4
  491. package/src/commands/audit/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/mission-state.json +0 -79
  492. package/src/commands/audit/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/pre-tool-advisory-throttle.json +0 -22
  493. package/src/commands/audit/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/subagent-tracking-state.json +0 -26
  494. package/src/commands/audit/__tests__/audit.test.ts +0 -59
  495. package/src/commands/audit/audit.ts +0 -177
  496. package/src/commands/audit/index.ts +0 -1
  497. package/src/commands/config/.omc/state/sessions/41336850-028c-476b-be1a-2164e1e46cac/last-tool-error-state.json +0 -7
  498. package/src/commands/config/.omc/state/sessions/41336850-028c-476b-be1a-2164e1e46cac/pre-tool-advisory-throttle.json +0 -18
  499. package/src/commands/config/config.ts +0 -137
  500. package/src/commands/config/index.ts +0 -1
  501. package/src/commands/doctor/.omc/state/sessions/8dd0ad2f-3a90-4158-b9de-ec8e19a7c983/pre-tool-advisory-throttle.json +0 -14
  502. package/src/commands/doctor/__tests__/agent-files.test.ts +0 -88
  503. package/src/commands/doctor/__tests__/check-ide-installed.test.ts +0 -142
  504. package/src/commands/doctor/__tests__/check-legacy-user-global-config.test.ts +0 -110
  505. package/src/commands/doctor/doctor.ts +0 -576
  506. package/src/commands/doctor/index.ts +0 -1
  507. package/src/commands/env-autoload/env-autoload.ts +0 -24
  508. package/src/commands/env-autoload/index.ts +0 -1
  509. package/src/commands/env-clear/__tests__/env-clear.test.ts +0 -27
  510. package/src/commands/env-clear/env-clear.ts +0 -136
  511. package/src/commands/env-clear/index.ts +0 -1
  512. package/src/commands/env-list/env-list.ts +0 -48
  513. package/src/commands/env-list/index.ts +0 -1
  514. package/src/commands/env-load/__tests__/env-load.test.ts +0 -200
  515. package/src/commands/env-load/env-load.ts +0 -394
  516. package/src/commands/env-load/index.ts +0 -2
  517. package/src/commands/env-status/__tests__/env-status.test.ts +0 -78
  518. package/src/commands/env-status/env-status.ts +0 -108
  519. package/src/commands/env-status/index.ts +0 -1
  520. package/src/commands/gh-merge-dev/gh-merge-dev.ts +0 -203
  521. package/src/commands/gh-merge-dev/index.ts +0 -1
  522. package/src/commands/gh-release-deliver/gh-release-deliver.ts +0 -470
  523. package/src/commands/gh-release-deliver/index.ts +0 -1
  524. package/src/commands/gh-release-deploy-all/gh-release-deploy-all.ts +0 -207
  525. package/src/commands/gh-release-deploy-all/index.ts +0 -1
  526. package/src/commands/gh-release-deploy-selected/gh-release-deploy-selected.ts +0 -303
  527. package/src/commands/gh-release-deploy-selected/index.ts +0 -1
  528. package/src/commands/gh-release-list/gh-release-list.ts +0 -90
  529. package/src/commands/gh-release-list/index.ts +0 -1
  530. package/src/commands/init/.omc/state/sessions/8dd0ad2f-3a90-4158-b9de-ec8e19a7c983/pre-tool-advisory-throttle.json +0 -18
  531. package/src/commands/init/__tests__/agent-files.test.ts +0 -265
  532. package/src/commands/init/__tests__/migrate-config.test.ts +0 -422
  533. package/src/commands/init/__tests__/migrate-factory-config.test.ts +0 -93
  534. package/src/commands/init/__tests__/seed-user-global-config.test.ts +0 -64
  535. package/src/commands/init/__tests__/shell-body.test.ts +0 -131
  536. package/src/commands/init/agent-files.ts +0 -219
  537. package/src/commands/init/index.ts +0 -8
  538. package/src/commands/init/init.ts +0 -440
  539. package/src/commands/init/migrate-config.ts +0 -378
  540. package/src/commands/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  541. package/src/commands/release-create/__tests__/release-create.test.ts +0 -92
  542. package/src/commands/release-create/index.ts +0 -1
  543. package/src/commands/release-create/release-create.ts +0 -447
  544. package/src/commands/release-desc-edit/index.ts +0 -1
  545. package/src/commands/release-desc-edit/release-desc-edit.ts +0 -227
  546. package/src/commands/vendor-check/__tests__/runtime-isolation.test.ts +0 -71
  547. package/src/commands/vendor-check/__tests__/vendor-check.test.ts +0 -87
  548. package/src/commands/vendor-check/index.ts +0 -1
  549. package/src/commands/vendor-check/vendor-check.ts +0 -127
  550. package/src/commands/vendor-config/__tests__/vendor-config.test.ts +0 -103
  551. package/src/commands/vendor-config/index.ts +0 -1
  552. package/src/commands/vendor-config/vendor-config.ts +0 -162
  553. package/src/commands/vendor-diff/__tests__/vendor-diff.test.ts +0 -74
  554. package/src/commands/vendor-diff/index.ts +0 -1
  555. package/src/commands/vendor-diff/vendor-diff.ts +0 -77
  556. package/src/commands/vendor-manifest/index.ts +0 -1
  557. package/src/commands/vendor-manifest/vendor-manifest.ts +0 -60
  558. package/src/commands/vendor-sync/__tests__/vendor-write.test.ts +0 -86
  559. package/src/commands/vendor-sync/index.ts +0 -1
  560. package/src/commands/vendor-sync/vendor-sync.ts +0 -90
  561. package/src/commands/version/index.ts +0 -1
  562. package/src/commands/version/version.ts +0 -33
  563. package/src/commands/worktrees-add/index.ts +0 -1
  564. package/src/commands/worktrees-add/worktrees-add.ts +0 -366
  565. package/src/commands/worktrees-list/index.ts +0 -1
  566. package/src/commands/worktrees-list/worktrees-list.ts +0 -105
  567. package/src/commands/worktrees-reload/__tests__/reload-cmux.test.ts +0 -119
  568. package/src/commands/worktrees-reload/index.ts +0 -1
  569. package/src/commands/worktrees-reload/worktrees-reload.ts +0 -230
  570. package/src/commands/worktrees-remove/index.ts +0 -1
  571. package/src/commands/worktrees-remove/worktrees-remove.ts +0 -199
  572. package/src/commands/worktrees-sync/index.ts +0 -1
  573. package/src/commands/worktrees-sync/worktrees-sync.ts +0 -198
  574. package/src/dev/__tests__/dev-server-options.test.ts +0 -57
  575. package/src/dev/__tests__/dev-server.test.ts +0 -420
  576. package/src/dev/__tests__/discovery.test.ts +0 -181
  577. package/src/dev/__tests__/fixtures.ts +0 -257
  578. package/src/dev/__tests__/ports.test.ts +0 -98
  579. package/src/dev/__tests__/serverless-local-run.test.ts +0 -533
  580. package/src/dev/dev-server.ts +0 -796
  581. package/src/dev/discovery.ts +0 -229
  582. package/src/dev/interfaces.ts +0 -11
  583. package/src/dev/managed-child.ts +0 -73
  584. package/src/dev/ports.ts +0 -100
  585. package/src/dev/serverless-local-run.ts +0 -329
  586. package/src/dev/turbo-watch.ts +0 -62
  587. package/src/dev/ui-dev.ts +0 -62
  588. package/src/entry/cli.ts +0 -630
  589. package/src/entry/dev-server.ts +0 -103
  590. package/src/entry/index.ts +0 -11
  591. package/src/entry/mcp.ts +0 -43
  592. package/src/integrations/cmux/__tests__/canonicalize-cmux-title.test.ts +0 -56
  593. package/src/integrations/cmux/__tests__/close-workspace-by-title.test.ts +0 -63
  594. package/src/integrations/cmux/__tests__/list-workspace-titles.test.ts +0 -65
  595. package/src/integrations/cmux/__tests__/open-workspace-with-layout.test.ts +0 -127
  596. package/src/integrations/cmux/canonicalize-cmux-title.ts +0 -31
  597. package/src/integrations/cmux/close-workspace-by-title.ts +0 -59
  598. package/src/integrations/cmux/index.ts +0 -5
  599. package/src/integrations/cmux/list-workspace-titles.ts +0 -47
  600. package/src/integrations/cmux/open-workspace-with-layout.ts +0 -80
  601. package/src/integrations/cmux/workspace-title.ts +0 -23
  602. package/src/integrations/cursor/.omc/state/agent-replay-f99d8dad-81d1-4987-8183-62edf0843d0c.jsonl +0 -2
  603. package/src/integrations/cursor/.omc/state/idle-notif-cooldown.json +0 -3
  604. package/src/integrations/cursor/.omc/state/sessions/f99d8dad-81d1-4987-8183-62edf0843d0c/pre-tool-advisory-throttle.json +0 -18
  605. package/src/integrations/cursor/.omc/state/sessions/f99d8dad-81d1-4987-8183-62edf0843d0c/subagent-tracking-state.json +0 -17
  606. package/src/integrations/cursor/add-folders-to-workspace.ts +0 -84
  607. package/src/integrations/cursor/index.ts +0 -6
  608. package/src/integrations/cursor/launch-cursor.ts +0 -12
  609. package/src/integrations/cursor/open-cursor-workspace.ts +0 -64
  610. package/src/integrations/cursor/reconcile-workspace-folders.ts +0 -90
  611. package/src/integrations/cursor/remove-folders-from-workspace.ts +0 -93
  612. package/src/integrations/cursor/resolve-workspace-path.ts +0 -13
  613. package/src/integrations/doppler/__tests__/doppler-errors.test.ts +0 -76
  614. package/src/integrations/doppler/doppler-cli-auth.ts +0 -31
  615. package/src/integrations/doppler/doppler-errors.ts +0 -88
  616. package/src/integrations/doppler/doppler-project.ts +0 -90
  617. package/src/integrations/doppler/index.ts +0 -4
  618. package/src/integrations/gh/gh-cli-auth/gh-cli-auth.ts +0 -29
  619. package/src/integrations/gh/gh-cli-auth/index.ts +0 -1
  620. package/src/integrations/gh/gh-release-prs/.omc/state/sessions/c6ed6186-1aac-48e0-aa2a-edc6da8e0410/pre-tool-advisory-throttle.json +0 -10
  621. package/src/integrations/gh/gh-release-prs/__tests__/gh-release-prs.test.ts +0 -198
  622. package/src/integrations/gh/gh-release-prs/gh-release-prs.ts +0 -206
  623. package/src/integrations/gh/gh-release-prs/index.ts +0 -2
  624. package/src/integrations/gh/index.ts +0 -3
  625. package/src/integrations/ide/__tests__/ide-facade.test.ts +0 -289
  626. package/src/integrations/ide/add-ide-worktree-folders.ts +0 -77
  627. package/src/integrations/ide/index.ts +0 -6
  628. package/src/integrations/ide/open-ide-workspace.ts +0 -51
  629. package/src/integrations/ide/provider-label.ts +0 -24
  630. package/src/integrations/ide/remove-ide-worktree-folders.ts +0 -145
  631. package/src/integrations/ide/types.ts +0 -41
  632. package/src/integrations/jira/api.ts +0 -325
  633. package/src/integrations/jira/index.ts +0 -19
  634. package/src/integrations/jira/types.ts +0 -85
  635. package/src/integrations/linear/.gitkeep +0 -0
  636. package/src/integrations/zed/__tests__/open-zed-workspace.test.ts +0 -69
  637. package/src/integrations/zed/__tests__/reuse-zed-workspace.test.ts +0 -86
  638. package/src/integrations/zed/add-folders-to-zed-workspace.ts +0 -30
  639. package/src/integrations/zed/index.ts +0 -3
  640. package/src/integrations/zed/open-zed-workspace.ts +0 -51
  641. package/src/integrations/zed/reuse-zed-workspace.ts +0 -57
  642. package/src/lib/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/pre-tool-advisory-throttle.json +0 -18
  643. package/src/lib/assert-never/assert-never.ts +0 -15
  644. package/src/lib/assert-never/index.ts +0 -1
  645. package/src/lib/command-catalog/__tests__/__snapshots__/command-catalog.test.ts.snap +0 -213
  646. package/src/lib/command-catalog/__tests__/command-catalog.test.ts +0 -193
  647. package/src/lib/command-catalog/command-catalog.ts +0 -146
  648. package/src/lib/command-catalog/index.ts +0 -2
  649. package/src/lib/command-echo/__tests__/command-echo.test.ts +0 -127
  650. package/src/lib/command-echo/command-echo.ts +0 -78
  651. package/src/lib/command-echo/index.ts +0 -1
  652. package/src/lib/constants/__tests__/constants.test.ts +0 -182
  653. package/src/lib/constants/constants.ts +0 -167
  654. package/src/lib/constants/index.ts +0 -22
  655. package/src/lib/env-autoload/__tests__/env-autoload.test.ts +0 -327
  656. package/src/lib/env-autoload/env-autoload.ts +0 -373
  657. package/src/lib/env-autoload/index.ts +0 -9
  658. package/src/lib/error-handlers/index.ts +0 -36
  659. package/src/lib/errors/__tests__/is-prompt-cancellation.test.ts +0 -48
  660. package/src/lib/errors/__tests__/operation-error.test.ts +0 -62
  661. package/src/lib/errors/format-zx-error.ts +0 -54
  662. package/src/lib/errors/is-prompt-cancellation.ts +0 -38
  663. package/src/lib/errors/operation-error.ts +0 -80
  664. package/src/lib/git-guard/__tests__/git-guard.test.ts +0 -92
  665. package/src/lib/git-guard/git-guard.ts +0 -55
  666. package/src/lib/git-guard/index.ts +0 -2
  667. package/src/lib/git-utils/__tests__/git-primitives.test.ts +0 -217
  668. package/src/lib/git-utils/__tests__/git-utils.test.ts +0 -49
  669. package/src/lib/git-utils/git-utils.ts +0 -179
  670. package/src/lib/git-utils/index.ts +0 -10
  671. package/src/lib/infra-kit-config/.omc/state/sessions/8dd0ad2f-3a90-4158-b9de-ec8e19a7c983/pre-tool-advisory-throttle.json +0 -18
  672. package/src/lib/infra-kit-config/__tests__/env-autoload-schema.test.ts +0 -71
  673. package/src/lib/infra-kit-config/__tests__/infra-kit-config.test.ts +0 -504
  674. package/src/lib/infra-kit-config/index.ts +0 -19
  675. package/src/lib/infra-kit-config/infra-kit-config.ts +0 -454
  676. package/src/lib/json-output/__tests__/json-output.test.ts +0 -139
  677. package/src/lib/json-output/index.ts +0 -1
  678. package/src/lib/json-output/json-output.ts +0 -47
  679. package/src/lib/logger/index.ts +0 -40
  680. package/src/lib/managed-block/__tests__/managed-block.test.ts +0 -121
  681. package/src/lib/managed-block/index.ts +0 -8
  682. package/src/lib/managed-block/managed-block.ts +0 -145
  683. package/src/lib/package-config/.omc/state/sessions/dde22a92-a0e9-4948-905d-25c9a812ab35/last-tool-error-state.json +0 -7
  684. package/src/lib/package-config/.omc/state/sessions/dde22a92-a0e9-4948-905d-25c9a812ab35/pre-tool-advisory-throttle.json +0 -10
  685. package/src/lib/package-config/__tests__/package-config.test.ts +0 -95
  686. package/src/lib/package-config/index.ts +0 -3
  687. package/src/lib/package-config/package-config-schema.ts +0 -19
  688. package/src/lib/package-config/package-config.ts +0 -97
  689. package/src/lib/package-validator/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/pre-tool-advisory-throttle.json +0 -10
  690. package/src/lib/package-validator/__tests__/package-validator.test.ts +0 -270
  691. package/src/lib/package-validator/checks/__tests__/checks.test.ts +0 -130
  692. package/src/lib/package-validator/checks/config-check.ts +0 -30
  693. package/src/lib/package-validator/checks/files-check.ts +0 -29
  694. package/src/lib/package-validator/checks/index.ts +0 -4
  695. package/src/lib/package-validator/checks/scripts-check.ts +0 -23
  696. package/src/lib/package-validator/checks/turbo-check.ts +0 -47
  697. package/src/lib/package-validator/fs-utils.ts +0 -18
  698. package/src/lib/package-validator/index.ts +0 -3
  699. package/src/lib/package-validator/loader/config-loader.ts +0 -77
  700. package/src/lib/package-validator/loader/index.ts +0 -2
  701. package/src/lib/package-validator/loader/package-discovery.ts +0 -98
  702. package/src/lib/package-validator/package-validator.ts +0 -48
  703. package/src/lib/package-validator/types.ts +0 -15
  704. package/src/lib/path-display/index.ts +0 -1
  705. package/src/lib/path-display/path-display.ts +0 -42
  706. package/src/lib/release-id/__tests__/release-id.test.ts +0 -359
  707. package/src/lib/release-id/__tests__/versioned-regression.test.ts +0 -69
  708. package/src/lib/release-id/index.ts +0 -15
  709. package/src/lib/release-id/release-id.ts +0 -258
  710. package/src/lib/release-utils/__tests__/release-utils.test.ts +0 -122
  711. package/src/lib/release-utils/index.ts +0 -15
  712. package/src/lib/release-utils/release-utils.ts +0 -231
  713. package/src/lib/render/__tests__/render.test.ts +0 -48
  714. package/src/lib/render/index.ts +0 -1
  715. package/src/lib/render/render.ts +0 -24
  716. package/src/lib/tool-handler/index.ts +0 -1
  717. package/src/lib/tool-handler/tool-handler.ts +0 -30
  718. package/src/lib/vendor/.omc/state/sessions/f09f401f-56c6-42cd-97be-c742c1956468/pre-tool-advisory-throttle.json +0 -10
  719. package/src/lib/vendor/__tests__/config-schema.test.ts +0 -31
  720. package/src/lib/vendor/__tests__/config.test.ts +0 -63
  721. package/src/lib/vendor/__tests__/factory-config.test.ts +0 -92
  722. package/src/lib/vendor/__tests__/vendor-lib.test.ts +0 -158
  723. package/src/lib/vendor/__tests__/zx-mock.ts +0 -32
  724. package/src/lib/vendor/config-schema.ts +0 -78
  725. package/src/lib/vendor/config.ts +0 -58
  726. package/src/lib/vendor/factory-config-schema.ts +0 -35
  727. package/src/lib/vendor/factory-config.ts +0 -91
  728. package/src/lib/vendor/hash.ts +0 -16
  729. package/src/lib/vendor/index.ts +0 -23
  730. package/src/lib/vendor/manifest.ts +0 -151
  731. package/src/lib/vendor/skip-sets.ts +0 -48
  732. package/src/lib/vendor/sync-ops.ts +0 -290
  733. package/src/lib/vendor/walk.ts +0 -56
  734. package/src/lib/version-utils/__tests__/load-existing-versions.test.ts +0 -37
  735. package/src/lib/version-utils/__tests__/next-version.test.ts +0 -407
  736. package/src/lib/version-utils/index.ts +0 -18
  737. package/src/lib/version-utils/load-existing-versions.ts +0 -86
  738. package/src/lib/version-utils/next-version.ts +0 -283
  739. package/src/lib/version-utils/version-utils.ts +0 -31
  740. package/src/lib/warm-cache/__tests__/warm-cache.test.ts +0 -164
  741. package/src/lib/warm-cache/index.ts +0 -7
  742. package/src/lib/warm-cache/warm-cache.ts +0 -136
  743. package/src/lib/worktrees/__tests__/remove-worktrees.test.ts +0 -167
  744. package/src/lib/worktrees/index.ts +0 -1
  745. package/src/lib/worktrees/remove-worktrees.ts +0 -66
  746. package/src/mcp/prompts/index.ts +0 -3
  747. package/src/mcp/resources/index.ts +0 -3
  748. package/src/mcp/server.ts +0 -27
  749. package/src/mcp/tools/index.ts +0 -21
  750. package/src/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  751. package/src/sanity.test.tsx +0 -8
  752. package/src/tui/__tests__/boot.test.tsx +0 -61
  753. package/src/tui/__tests__/no-react-boundary.test.ts +0 -51
  754. package/src/tui/boot.tsx +0 -60
  755. package/src/tui/screens/__tests__/command-palette.test.tsx +0 -136
  756. package/src/tui/screens/command-palette.tsx +0 -159
  757. package/src/tui/types.ts +0 -8
  758. package/src/types.ts +0 -66
  759. package/tsconfig.json +0 -46
  760. package/tsconfig.tsbuildinfo +0 -1
  761. package/vitest.config.ts +0 -26
  762. package/vitest.setup.ts +0 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/entry/dev-server.ts", "../src/dev/dev-server.ts", "../src/dev/discovery.ts", "../src/dev/ports.ts", "../src/dev/serverless-local-run.ts", "../src/dev/turbo-watch.ts", "../src/dev/managed-child.ts", "../src/dev/ui-dev.ts"],
4
- "sourcesContent": ["/**\n * Long-running CLI entry for the local dev-server. Owns flag parsing, OS signal\n * handling, and process exit \u2014 the orchestrator (`src/dev/dev-server`) is signal-\n * and exit-agnostic. Kept off the eager cli.js graph: entry/cli.ts reaches this\n * module (and the fastify/chokidar it pulls in) only via `await import(...)`, so\n * those heavy deps never load on the machine command paths.\n */\nimport { Command } from 'commander'\nimport process from 'node:process'\nimport { pathToFileURL } from 'node:url'\n\nimport { run } from 'src/dev/dev-server'\nimport type { DevServerOptions } from 'src/dev/dev-server'\n\n/** Raw option object as produced by Commander (comma-joined strings). */\nexport interface DevCliOptions {\n watch?: boolean\n app?: string\n ui?: boolean\n}\n\n/** Split a comma-separated flag value into a trimmed, non-empty list (`null` when unset/empty). */\nconst splitList = (value: string | undefined): string[] | null => {\n if (value == null) return null\n\n const parts = value\n .split(',')\n .map((s) => {\n return s.trim()\n })\n .filter(Boolean)\n\n return parts.length > 0 ? parts : null\n}\n\n/**\n * Map raw Commander flags to the orchestrator's typed options. Shared by the\n * `infra-kit dev` subcommand and the standalone entry so the two never diverge.\n */\nexport const toDevServerOptions = (raw: DevCliOptions): DevServerOptions => {\n return {\n watch: raw.watch ?? false,\n include: splitList(raw.app),\n ui: raw.ui ?? false,\n }\n}\n\n/**\n * Start the dev-server, then wait for an OS signal and shut every server down\n * cleanly before exiting. This is the ONLY place SIGINT/SIGTERM handlers and\n * `process.exit` live for the dev-server feature.\n */\nexport const runDevServer = async (options: DevServerOptions): Promise<void> => {\n const runner = await run(options)\n\n let shuttingDown = false\n\n const shutdown = (signal: NodeJS.Signals): void => {\n if (shuttingDown) return\n shuttingDown = true\n\n void (async () => {\n try {\n process.stdout.write(`\\nReceived ${signal}, shutting down dev-server...\\n`)\n await runner.shutdown()\n } finally {\n process.exit(0)\n }\n })()\n }\n\n process.on('SIGINT', () => {\n return shutdown('SIGINT')\n })\n process.on('SIGTERM', () => {\n return shutdown('SIGTERM')\n })\n}\n\n/** Parse `node dist/dev-server.js ...` flags and start the server. */\nconst parseAndRun = async (argv: string[]): Promise<void> => {\n const program = new Command()\n\n program\n .name('infra-kit-dev-server')\n .description('Run local dev servers for every apps/<app>/api that has a serverless.yml')\n .option('-w, --watch', 'Rebuild and restart on file save')\n .option('--app <names>', 'Only run these apps (comma-separated folder names)')\n .option('--ui', 'Also run frontends (apps/<app>/ui with a `dev` script) via turbo run dev')\n\n program.parse(argv)\n\n await runDevServer(toDevServerOptions(program.opts<DevCliOptions>()))\n}\n\n// Self-execute only when run directly (`node dist/dev-server.js`), not when the\n// `infra-kit dev` subcommand imports this module for its exported helpers.\nif (import.meta.url === pathToFileURL(process.argv[1] ?? '').href) {\n parseAndRun(process.argv).catch((error: unknown) => {\n console.error(error)\n process.exit(1)\n })\n}\n", "/**\n * Unified Development Server Runner\n *\n * Discovers and runs API apps under each `apps/<app>/api` folder that contains `serverless.yml`.\n *\n * Ports: `{APP}_PORT`, then `process.env.PORT`, then `dev.<app>.port` from infra-kit.json,\n * else 3010. URL prefix: `dev.<app>.prefixUrl`, else `/api/v1`.\n * Env vars should be provided via secrets manager (e.g. `doppler run -- pnpm dev-server`) or shell.\n *\n * This module is side-effect free on import: call `run()` (or construct `DevServerRunner`\n * directly) to start. Signal handling and process exit are the entry point's responsibility.\n *\n * Runner messages append to `<cwd>/.infra-kit/dev-server.log`. Lambda / Powertools logs from\n * handlers go to stdout.\n */\nimport chokidar from 'chokidar'\nimport type { FSWatcher } from 'chokidar'\nimport { exec } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport process from 'node:process'\nimport util from 'node:util'\n\nimport type { DevConfig } from 'src/lib/infra-kit-config'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\n\nimport {\n classifyDistChange,\n discoverApiApps as discoverApiAppsBare,\n discoverUiApps as discoverUiAppsBare,\n findMonorepoRoot,\n getAppDistDirs,\n getPackageDistDirs,\n normalizeAppInclude as normalizeAppIncludePure,\n} from './discovery.js'\nimport type { DiscoveredUiApp } from './discovery.js'\nimport { findPortConflicts, resolvePort as resolvePortPure, resolvePrefixUrl as resolvePrefixUrlPure } from './ports.js'\nimport { ServerlessLocalRun } from './serverless-local-run.js'\nimport { defaultTurboWatchFactory } from './turbo-watch.js'\nimport type { TurboWatchFactory, TurboWatchHandle } from './turbo-watch.js'\nimport { defaultUiDevFactory } from './ui-dev.js'\nimport type { UiDevFactory, UiDevHandle } from './ui-dev.js'\n\n/** Runner-only log file, resolved under the consumer repo's `.infra-kit/` dir at startup. */\nlet LOG_FILE_PATH = path.join(process.cwd(), '.infra-kit', 'dev-server.log')\n\n/** Resolve `<cwd>/.infra-kit/dev-server.log`, ensure the dir exists, and clear the file. */\nfunction initLogFile(): void {\n LOG_FILE_PATH = path.join(process.cwd(), '.infra-kit', 'dev-server.log')\n fs.mkdirSync(path.dirname(LOG_FILE_PATH), { recursive: true })\n fs.writeFileSync(LOG_FILE_PATH, `=== Dev Server Started: ${new Date().toISOString()} ===\\n\\n`)\n}\n\nconst execFn = util.promisify(exec)\n\ntype LogFn = (msg: string, level?: 'info' | 'warn' | 'error' | 'debug') => void\n\n/**\n * Build seam: shells out to turbo by default ({@link launchScript}); injectable so\n * tests can run the orchestrator without a real build. `logFn` is optional so both\n * the verbose initial build and the terse restart builds keep their current output.\n */\nexport type BuildRunner = (cmd: string, logFn?: LogFn) => Promise<void>\n\nconst launchScript = async (script: string, logFn?: LogFn): Promise<void> => {\n try {\n const { stderr } = await execFn(script)\n\n if (stderr && logFn) logFn(` (build) ${stderr.trim()}`, 'debug')\n if (stderr && !logFn) console.error('stderr:', stderr)\n } catch (error) {\n const err = error as { stdout?: string; stderr?: string; message?: string }\n\n if (logFn && (err.stdout || err.stderr)) {\n if (err.stdout) logFn(` stdout: ${err.stdout.trim()}`, 'error')\n if (err.stderr) logFn(` stderr: ${err.stderr.trim()}`, 'error')\n }\n\n throw error\n }\n}\n\n/** Append raw text to the runner-only log file (the single tee-to-file seam). */\nfunction appendLogFile(text: string): void {\n fs.appendFileSync(LOG_FILE_PATH, text)\n}\n\n/** Write a message to the console (routed by level) and tee it to the log file. */\nfunction log(message: string, level: 'info' | 'warn' | 'error' | 'debug' = 'info'): void {\n if (level === 'error') {\n console.error(message)\n } else if (level === 'warn') {\n console.warn(message)\n } else {\n process.stdout.write(`${message}\\n`)\n }\n\n appendLogFile(`[${new Date().toISOString()}] [${level.toUpperCase()}] ${message}\\n`)\n}\n\n/** Write pre-formatted table lines to stdout and tee them to the log file. */\nfunction logTable(lines: string[]): void {\n const output = `${lines.join('\\n')}\\n`\n\n process.stdout.write(`${output}\\n`)\n appendLogFile(`${output}\\n`)\n}\n\n/** Center `s` within `width` columns (clamped, so a too-long string is never truncated). */\nfunction center(s: string, width: number): string {\n const pad = Math.max(0, width - s.length)\n const left = Math.floor(pad / 2)\n\n return `${' '.repeat(left)}${s}${' '.repeat(pad - left)}`\n}\n\n/**\n * Render a box-drawn table whose column widths are computed from the longest cell in\n * each column, so every emitted line shares one width regardless of app-name length\n * (the old fixed `padEnd` misaligned on long names). Borders are generated from the\n * same widths, so they always match the rows.\n */\nfunction renderTable(title: string, headers: string[], rows: string[][]): string[] {\n const widths = headers.map((header, i) => {\n return Math.max(\n header.length,\n ...rows.map((row) => {\n return (row[i] ?? '').length\n }),\n )\n })\n // Grow the last column if the title is wider than the columns, so the title band never clips.\n const columnsInner =\n widths.reduce((sum, w) => {\n return sum + w + 2\n }, 0) +\n (widths.length - 1)\n\n const lastIdx = widths.length - 1\n\n if (lastIdx >= 0 && title.length + 2 > columnsInner) {\n widths[lastIdx] = (widths[lastIdx] ?? 0) + (title.length + 2 - columnsInner)\n }\n\n const inner =\n widths.reduce((sum, w) => {\n return sum + w + 2\n }, 0) +\n (widths.length - 1)\n const blocks = widths.map((w) => {\n return '\u2500'.repeat(w + 2)\n })\n const rowLine = (cells: string[]): string => {\n return `\u2502 ${cells\n .map((c, i) => {\n return (c ?? '').padEnd(widths[i]!)\n })\n .join(' \u2502 ')} \u2502`\n }\n\n return [\n '',\n `\u250C${'\u2500'.repeat(inner)}\u2510`,\n `\u2502${center(title, inner)}\u2502`,\n `\u251C${blocks.join('\u252C')}\u2524`,\n rowLine(headers),\n `\u251C${blocks.join('\u253C')}\u2524`,\n ...rows.map(rowLine),\n `\u2514${blocks.join('\u2534')}\u2518`,\n '',\n ]\n}\n\ninterface IApiAppConfig {\n /** App folder name (e.g. backoffice, client) */\n name: string\n /** Package name from package.json (e.g. sls-trvl-client) */\n packageName: string\n path: string\n port: number\n prefixUrl: string\n}\n\n/**\n * Runner options, parsed by the CLI entry point (`--watch`, `--app`) and threaded\n * through `run()`. The entry owns flag parsing; the runner never reads `process.argv`\n * itself. App selection is `--app` only; ports come from env/config (see `resolvePort`).\n */\nexport interface DevServerOptions {\n /**\n * Watch mode: start a long-lived `turbo watch build` engine (incremental rebuilds\n * + dependency fan-out) and restart the affected server(s) when compiled `dist/`\n * changes. Without it, `dev` builds and serves once and exits on signal.\n */\n watch?: boolean\n /** Only run these app folder names (null/empty = all discovered). Filters BOTH api and ui apps. */\n include?: string[] | null\n /**\n * Also run frontends: discover `apps/<app>/ui` with a `dev` script and start them via one\n * delegated `turbo run dev` child (streamed to the terminal). Default (unset) = api-only,\n * preserving today's behavior.\n */\n ui?: boolean\n}\n\ninterface IAppServer {\n app: IApiAppConfig\n server: ServerlessLocalRun\n}\n\nexport class DevServerRunner {\n private readonly monorepoRoot: string\n private readonly appServers: IAppServer[] = []\n private watchDebounceTimers: Map<string, ReturnType<typeof setTimeout>> = new Map()\n /** Active chokidar watcher in `--watch` mode; closed on {@link shutdown}. */\n private watcher: FSWatcher | null = null\n private static readonly WATCH_DEBOUNCE_MS = 400\n /** Serialized restarts so rapid saves never bind :port while the previous server is still shutting down. */\n private restartWorkChain: Promise<void> = Promise.resolve()\n private static readonly PORT_RELEASE_DELAY_MS = 200\n private readonly options: DevServerOptions\n /** Build runner seam \u2014 real turbo shell-out by default, injectable for tests. */\n private readonly runBuild: BuildRunner\n /** `turbo watch` spawn seam \u2014 real detached child by default, injectable for tests. */\n private readonly turboWatchFactory: TurboWatchFactory\n /** Live `turbo watch` engine in `--watch` mode; reaped on {@link shutdown}. */\n private turboWatch: TurboWatchHandle | null = null\n /** `turbo run dev` (frontends) spawn seam \u2014 real detached child by default, injectable for tests. */\n private readonly uiDevFactory: UiDevFactory\n /** Live `turbo run dev` frontend engine in `--ui` mode; reaped on {@link shutdown}. */\n private uiDev: UiDevHandle | null = null\n\n constructor(\n options: DevServerOptions = {},\n runBuild: BuildRunner = launchScript,\n turboWatchFactory: TurboWatchFactory = defaultTurboWatchFactory,\n uiDevFactory: UiDevFactory = defaultUiDevFactory,\n ) {\n this.options = options\n this.runBuild = runBuild\n this.turboWatchFactory = turboWatchFactory\n this.uiDevFactory = uiDevFactory\n initLogFile()\n\n // Walk up from the consumer repo cwd to the monorepo root.\n this.monorepoRoot = findMonorepoRoot(process.cwd())\n log(`Monorepo root: ${this.monorepoRoot}`)\n\n if (process.env.DOPPLER_PROJECT != null || process.env.DOPPLER_ENVIRONMENT != null) {\n log('\uD83D\uDD10 Doppler env detected (DOPPLER_PROJECT / DOPPLER_ENVIRONMENT)', 'debug')\n }\n }\n\n /**\n * Discover API apps and resolve each app's port + URL prefix. Delegates bare\n * filesystem discovery to {@link discoverApiAppsBare} and per-app resolution to\n * the pure `resolvePort` / `resolvePrefixUrl`, preserving the original behavior.\n */\n private discoverApiApps(devConfig: DevConfig): IApiAppConfig[] {\n return discoverApiAppsBare(this.monorepoRoot).map((app) => {\n return {\n ...app,\n port: this.resolvePort(app.name, devConfig),\n prefixUrl: this.resolvePrefixUrl(app.name, devConfig),\n }\n })\n }\n\n /**\n * Read the `dev` section from the resolved infra-kit config. Defensive: any\n * failure (not in an infra-kit project, missing/invalid config) resolves to an\n * empty map so the dev-server always falls back to env vars + built-in defaults\n * rather than refusing to start.\n */\n private async loadDevConfig(): Promise<DevConfig> {\n try {\n const config = await getInfraKitConfig()\n\n return config.dev ?? {}\n } catch {\n return {}\n }\n }\n\n /** Thin delegator to the pure {@link normalizeAppIncludePure} over the runner's `--app` list. */\n private normalizeAppInclude(): string[] | null {\n return normalizeAppIncludePure(this.options.include)\n }\n\n /** Thin delegator to the pure {@link resolvePortPure}, threading env + config. */\n private resolvePort(appName: string, devConfig: DevConfig): number {\n return resolvePortPure(appName, process.env, devConfig)\n }\n\n /** Thin delegator to the pure {@link resolvePrefixUrlPure}. */\n private resolvePrefixUrl(appName: string, devConfig: DevConfig): string {\n return resolvePrefixUrlPure(appName, devConfig)\n }\n\n public async start(): Promise<void> {\n const include = this.normalizeAppInclude()\n const watch = this.options.watch ?? false\n const devConfig = await this.loadDevConfig()\n\n process.env.POWERTOOLS_DEV ??= 'true'\n process.env.LOG_LEVEL ??= 'DEBUG'\n\n log('\uD83D\uDE80 Starting Development Server Runner')\n\n if (watch) {\n log('\uD83D\uDC40 Watch mode: will rebuild and restart on file save')\n }\n log(`\uD83D\uDCC2 Monorepo root: ${this.monorepoRoot}`)\n\n const apps = this.selectApps(this.discoverApiApps(devConfig), include)\n const uiApps = (this.options.ui ?? false) ? this.selectUiApps(include) : []\n\n if (apps.length === 0 && uiApps.length === 0) {\n log(this.options.ui ? '\u26A0\uFE0F No API or UI apps found to run' : '\u26A0\uFE0F No API apps found to run', 'warn')\n\n return\n }\n\n // Build the API boot closure (dist must exist before servers import handlers).\n if (apps.length > 0) {\n log(`\uD83D\uDCE6 Discovered ${apps.length} API app(s): ${this.formatAppList(apps)}`)\n this.assertNoPortConflicts(apps)\n await this.buildApps(apps, watch)\n }\n\n // Warm the UI dependency closure BEFORE spawning any persistent child (turbo watch / turbo run\n // dev), so both see a warm cache and the cold-cache double-build race can't corrupt shared dist.\n if (uiApps.length > 0) {\n await this.buildUiApps(uiApps)\n }\n\n if (apps.length > 0) {\n await this.startAllApps(apps)\n log('\uD83C\uDF89 All servers started!')\n this.printServerTable(apps)\n this.printRouteDump()\n log(\n `\uD83D\uDCDD Handler logs (AWS Powertools, logger.info/debug, etc.) \u2192 this terminal. Runner-only file: ${LOG_FILE_PATH}`,\n )\n }\n\n if (watch && this.appServers.length > 0) {\n this.setupWatch(apps)\n }\n\n // Frontends last: their delegated `turbo run dev` streams raw to the terminal below the BE table.\n if (uiApps.length > 0) {\n this.startUiDev(uiApps)\n }\n }\n\n /** Discover `apps/<app>/ui` frontends (with a `dev` script), applying the `--app` include filter. */\n private selectUiApps(include: string[] | null): DiscoveredUiApp[] {\n const uiApps = discoverUiAppsBare(this.monorepoRoot)\n const selected = include\n ? uiApps.filter((a) => {\n return include.includes(a.name)\n })\n : uiApps\n\n if (selected.length > 0) {\n log(\n `\uD83C\uDFA8 Discovered ${selected.length} UI app(s): ${selected\n .map((a) => {\n return a.name\n })\n .join(', ')}`,\n )\n }\n\n return selected\n }\n\n /**\n * Warm ONLY each UI's dependency closure (`<pkg>^...` \u2014 deps, excluding the UI itself, so no full\n * production `vite build`) with a cache-friendly (non-`--force`) turbo build. Non-fatal: if it\n * fails, `turbo run dev`'s own `^build` retries and surfaces the error in its streamed output.\n */\n private async buildUiApps(uiApps: DiscoveredUiApp[]): Promise<void> {\n const filters = uiApps\n .map((a) => {\n return `--filter=${a.packageName}^...`\n })\n .join(' ')\n\n log('\uD83D\uDD28 Warming UI dependency build cache (turbo)...')\n try {\n await this.runBuild(`pnpm exec turbo run build ${filters} --env-mode=loose`, log)\n log('\u2705 UI deps built')\n } catch (error) {\n log(`\u26A0\uFE0F UI dep warm build failed (continuing; turbo run dev will build): ${String(error)}`, 'warn')\n }\n }\n\n /**\n * Start the frontends via ONE delegated `turbo run dev` child (streamed to the terminal). Reaped\n * on {@link shutdown}. Concurrency \u2265 the persistent UI `dev` task count (turbo hard-errors otherwise).\n */\n private startUiDev(uiApps: DiscoveredUiApp[]): void {\n const names = uiApps\n .map((a) => {\n return a.name\n })\n .join(', ')\n\n log(`\uD83C\uDFA8 Starting ${uiApps.length} UI dev server(s) via \\`turbo run dev\\`: ${names}`)\n log(' (framework dev output streams below; each prints its own local URL)')\n\n this.uiDev = this.uiDevFactory({\n packageNames: uiApps.map((a) => {\n return a.packageName\n }),\n cwd: process.cwd(),\n concurrency: Math.max(uiApps.length + 4, 12),\n })\n }\n\n /** Render an app list as `name:port, name:port` for log lines. */\n private formatAppList(apps: Array<{ name: string; port: number }>): string {\n return apps\n .map((a) => {\n return `${a.name}:${a.port}`\n })\n .join(', ')\n }\n\n /** Apply the `--app` include filter (logging it when applied). */\n private selectApps(apps: IApiAppConfig[], include: string[] | null): IApiAppConfig[] {\n if (!include) {\n return apps\n }\n\n log(`\uD83D\uDD0D Filtering to apps: ${include.join(', ')}`)\n\n return apps.filter((app) => {\n return include.includes(app.name)\n })\n }\n\n /** Throw (after logging remediation tips) when two apps resolve to the same port. */\n private assertNoPortConflicts(apps: IApiAppConfig[]): void {\n const { duplicatePorts, conflictingApps } = findPortConflicts(apps)\n\n if (duplicatePorts.length === 0) {\n return\n }\n\n log(`\u26A0\uFE0F Port conflict detected! ${duplicatePorts.join(', ')}`, 'error')\n log(`Conflicting apps: ${this.formatAppList(conflictingApps)}`, 'error')\n log('\\n\uD83D\uDCA1 Tip: give each app a distinct port via `{APP}_PORT` env (e.g. `CLIENT_PORT=`,', 'error')\n log(' `SEARCH_ENGINE_PORT=`) or `dev.<app>.port` in infra-kit.json; or run a subset with', 'error')\n log(' `--app=<name>,<name>`.\\n', 'error')\n throw new Error(`Port conflict detected: ${duplicatePorts.join(', ')}`)\n }\n\n /** Build every app via turbo; rethrows the build error after logging stdout/stderr. */\n private async buildApps(apps: IApiAppConfig[], watch: boolean): Promise<void> {\n const filters = apps\n .map((a) => {\n return `--filter=${a.packageName}`\n })\n .join(' ')\n // With `--watch`, always bypass Turbo cache so `tsc` runs and `dist/` matches disk (otherwise watch restarts can be no-ops).\n const buildCmd = `pnpm exec turbo run build ${filters} --env-mode=loose${watch ? ' --force' : ''}`\n\n log('\uD83D\uDD28 Building API apps (turbo)...')\n try {\n await this.runBuild(buildCmd, log)\n log('\u2705 Build complete')\n } catch (buildError) {\n log(`\u274C Build failed: ${String(buildError)}`, 'error')\n if (buildError instanceof Error && buildError.message) {\n log(` ${buildError.message}`, 'error')\n }\n const err = buildError as { stdout?: string; stderr?: string }\n\n if (err.stdout) log(` stdout: ${err.stdout.trim()}`, 'error')\n if (err.stderr) log(` stderr: ${err.stderr.trim()}`, 'error')\n throw buildError\n }\n }\n\n /**\n * Start every app concurrently, collecting the ones that boot; per-app failures are logged,\n * not fatal. Safe to parallelize because each app has a distinct port (guarded up-front) and a\n * distinct `ServerlessLocalRun`, and `startOneApp` no longer mutates cwd. Push order into\n * `appServers` is non-deterministic but nothing depends on it (the table renders from `apps`).\n */\n private async startAllApps(apps: IApiAppConfig[]): Promise<void> {\n await Promise.all(\n apps.map(async (app) => {\n try {\n const server = await this.startOneApp(app)\n\n if (server) {\n this.appServers.push({ app, server })\n }\n } catch (error) {\n log(`\u274C Failed to start ${app.name}: ${String(error)}`, 'error')\n }\n }),\n )\n }\n\n private async startOneApp(app: IApiAppConfig): Promise<ServerlessLocalRun | null> {\n log(`\uD83D\uDD04 Starting ${app.name}...`)\n\n // No `process.chdir` here: `ServerlessLocalRun` reads `serverless.yml` and imports the\n // compiled handler from `controllersPath` (absolute), so the runner never mutates cwd \u2014\n // which is what makes concurrent boot/restart safe.\n const server = new ServerlessLocalRun({\n controllersPath: app.path,\n prefixUrl: app.prefixUrl,\n port: app.port,\n appName: app.name,\n })\n\n await server.start()\n log(`\u2705 ${app.name} started on port ${app.port}`)\n\n return server\n }\n\n /** Run restart jobs one after another (watch can fire faster than close + listen). */\n private scheduleRestartWork(work: () => Promise<void>): Promise<void> {\n const run = this.restartWorkChain.then(\n () => {\n return work()\n },\n () => {\n return work()\n },\n )\n\n this.restartWorkChain = run.catch(() => {})\n\n return run\n }\n\n private async delayPortRelease(): Promise<void> {\n await new Promise((r) => {\n return setTimeout(r, DevServerRunner.PORT_RELEASE_DELAY_MS)\n })\n }\n\n /**\n * Schedule a restart of the given apps (1 or N), serialized against other restarts via\n * {@link scheduleRestartWork}. A single-app dist change passes `[app]`; a dependency-package\n * dist change passes every running app. The `turbo watch` engine has already rebuilt `dist/`,\n * so the runner only bounces the fastify server(s) \u2014 no build here.\n */\n private restart(apps: IApiAppConfig[]): Promise<void> {\n return this.scheduleRestartWork(() => {\n return this.runRestart(apps)\n })\n }\n\n /** Resolve the requested apps to their live server slots (dropping any not running). */\n private resolveRestartTargets(apps: IApiAppConfig[]): Array<{ idx: number; app: IApiAppConfig }> {\n return apps\n .map((app) => {\n return {\n idx: this.appServers.findIndex((e) => {\n return e.app.name === app.name\n }),\n app,\n }\n })\n .filter((t) => {\n return t.idx >= 0\n })\n }\n\n private async runRestart(apps: IApiAppConfig[]): Promise<void> {\n const targets = this.resolveRestartTargets(apps)\n\n if (targets.length === 0) return\n\n const label = targets.length === 1 ? targets[0]!.app.name : `${targets.length} apps`\n\n log(`\uD83D\uDD04 Restarting ${label}...`)\n await Promise.all(\n targets.map(async ({ idx }) => {\n try {\n await this.appServers[idx]!.server.close()\n } catch (err) {\n log(` Close warning: ${String(err)}`, 'debug')\n }\n }),\n )\n\n await this.delayPortRelease()\n\n await Promise.all(\n targets.map(async ({ idx, app }) => {\n try {\n const newServer = await this.startOneApp(app)\n\n if (newServer) {\n this.appServers[idx] = { app, server: newServer }\n }\n } catch (error) {\n log(`\u274C Failed to restart ${app.name}: ${String(error)}`, 'error')\n }\n }),\n )\n log(`\u2705 Restarted ${label}`)\n }\n\n /**\n * Start the long-lived `turbo watch build` engine, then watch compiled `dist/` output to\n * trigger restarts. A change under an app's `dist` restarts that app; a change under any\n * `packages/<pkg>/dist` restarts every app (editing a shared lib rewrites only the lib's\n * `dist`, so a package-dist change is the lib-rebuild signal). Restarts are build-less \u2014\n * the engine already rebuilt `dist/`.\n */\n private setupWatch(apps: IApiAppConfig[]): void {\n this.turboWatch = this.turboWatchFactory({\n packageNames: apps.map((a) => {\n return a.packageName\n }),\n cwd: process.cwd(),\n logFile: LOG_FILE_PATH,\n })\n log('\uD83D\uDC40 Watch mode: started `turbo watch build` engine; watching dist output')\n\n const appDistDirs = getAppDistDirs(apps)\n const packageDistDirs = getPackageDistDirs(this.monorepoRoot)\n const allDistDirs = [...appDistDirs, ...packageDistDirs]\n\n if (allDistDirs.length === 0) {\n log('\u26A0\uFE0F No app or package dist directories found to watch (were they built?)', 'warn')\n\n return\n }\n\n const usePoll = process.env.DEV_SERVER_CHOKIDAR_POLL === '1'\n\n const watcher = chokidar.watch(allDistDirs, {\n ignoreInitial: true,\n awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 100 },\n // Ignore tsc's incremental bookkeeping + sourcemaps: they rewrite on every build\n // (even content-identical ones) and would bounce fastify onto no real change.\n ignored: (p: string): boolean => {\n return p.endsWith('.tsbuildinfo') || p.endsWith('.map')\n },\n ...(usePoll ? { usePolling: true, interval: 400 } : {}),\n })\n\n this.watcher = watcher\n\n if (usePoll) {\n log('\uD83D\uDC40 chokidar: usePolling enabled (DEV_SERVER_CHOKIDAR_POLL=1)', 'debug')\n }\n\n watcher.on('change', (filePath: string) => {\n log(`\uD83D\uDC40 dist change detected: ${filePath}`, 'debug')\n\n const change = classifyDistChange(filePath, appDistDirs, packageDistDirs)\n\n if (change.kind === 'package') {\n // A dependency package's dist was rebuilt \u2014 restart every app.\n this.scheduleDebounced('__packages__', () => {\n return this.restart(apps)\n })\n\n return\n }\n\n const app = apps.find((a) => {\n return path.join(a.path, 'dist') === change.app\n })\n\n if (!app) return\n\n this.scheduleDebounced(app.name, () => {\n return this.restart([app])\n })\n })\n\n log(`\uD83D\uDC40 Watching ${appDistDirs.length} app dist + ${packageDistDirs.length} package dist dir(s) for changes...`)\n }\n\n /**\n * Debounce a restart under `key`: cancel any pending timer for the same key and start\n * a fresh {@link DevServerRunner.WATCH_DEBOUNCE_MS} timer, so a burst of saves collapses\n * into one restart. Errors from the scheduled work are logged, never thrown.\n */\n private scheduleDebounced(key: string, work: () => Promise<void>): void {\n const existing = this.watchDebounceTimers.get(key)\n\n if (existing) clearTimeout(existing)\n\n const timer = setTimeout(() => {\n this.watchDebounceTimers.delete(key)\n work().catch((err) => {\n log(`Restart error (${key}): ${String(err)}`, 'error')\n })\n }, DevServerRunner.WATCH_DEBOUNCE_MS)\n\n this.watchDebounceTimers.set(key, timer)\n }\n\n /**\n * Print the running-server table. The `Base URL` column carries each app's\n * `prefixUrl` (e.g. `/api/v1`) so it is copy-pasteable \u2014 the old table showed a bare\n * `http://localhost:<port>` that 404s against prefixed handler routes. A `Health`\n * column surfaces the unprefixed `/__health` liveness URL.\n */\n private printServerTable(apps: IApiAppConfig[]): void {\n const rows = apps.map((app) => {\n return [\n app.name,\n String(app.port),\n `http://localhost:${app.port}${app.prefixUrl}`,\n `http://localhost:${app.port}/__health`,\n ]\n })\n\n logTable(renderTable('\uD83D\uDDA5\uFE0F Running Servers', ['App', 'Port', 'Base URL', 'Health'], rows))\n }\n\n /**\n * Dump each running app's registered `METHOD /path` routes at startup so the\n * emulator is self-describing (no need to open `serverless.yml` to learn the routes).\n * Reads the live route set via {@link ServerlessLocalRun.getRegisteredRoutes}.\n */\n private printRouteDump(): void {\n if (this.appServers.length === 0) return\n\n log('\uD83D\uDDFA\uFE0F Registered routes:')\n for (const { app, server } of this.appServers) {\n const routes = server.getRegisteredRoutes()\n\n log(` ${app.name} (${routes.length}): ${routes.length > 0 ? routes.join(', ') : '(none)'}`)\n }\n }\n\n /**\n * Stop watching, cancel any pending debounced restart, and close all running servers.\n * Does not exit the process \u2014 the entry point owns exit.\n */\n public async shutdown(): Promise<void> {\n log('\uD83D\uDED1 Shutting down all servers...')\n\n // Reap the long-lived engines FIRST (group SIGTERM\u2192SIGKILL) so neither writes fresh dist nor\n // holds a port mid-teardown. Reaped here (not only in the entry signal handler) because tests\n // and any non-signal caller invoke shutdown() directly. Awaited so the SIGKILL escalation\n // completes before the entry point's `process.exit`.\n if (this.turboWatch) {\n await this.turboWatch.kill()\n this.turboWatch = null\n }\n\n if (this.uiDev) {\n await this.uiDev.kill()\n this.uiDev = null\n }\n\n for (const timer of this.watchDebounceTimers.values()) {\n clearTimeout(timer)\n }\n this.watchDebounceTimers.clear()\n\n if (this.watcher) {\n await this.watcher.close()\n this.watcher = null\n }\n\n for (const { server } of this.appServers) {\n try {\n await server.close()\n } catch {\n // ignore\n }\n }\n log(`\uD83D\uDCDD Logs saved to: ${LOG_FILE_PATH}`)\n }\n}\n\n/**\n * Construct a {@link DevServerRunner}, start it, and return the instance so the caller\n * (the CLI entry point) can wire signal handlers to `shutdown()` and own process exit.\n */\nexport async function run(options: DevServerOptions = {}): Promise<DevServerRunner> {\n const runner = new DevServerRunner(options)\n\n await runner.start()\n\n return runner\n}\n", "/**\n * Filesystem discovery helpers for the dev-server.\n *\n * These functions read the filesystem (walking for the monorepo root, scanning\n * `apps/` and `packages/`) but never `chdir` and never resolve ports / prefixes \u2014\n * that stays with the pure {@link file://./ports.ts} layer. The starting directory\n * is passed in so discovery is testable against a fixture root.\n */\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\n\n/** Bare metadata for a discovered API app (no resolved port / prefix). */\nexport interface DiscoveredApiApp {\n /** App folder name (e.g. backoffice, client). */\n name: string\n /** Package name from package.json (e.g. sls-trvl-client), or the folder name as fallback. */\n packageName: string\n path: string\n}\n\n/** Walk up from `startDir` (max 10 levels) to the dir containing `pnpm-workspace.yaml`. */\nexport function findMonorepoRoot(startDir: string): string {\n let currentDir = startDir\n\n for (let i = 0; i < 10; i++) {\n const workspaceFile = path.join(currentDir, 'pnpm-workspace.yaml')\n\n if (fs.existsSync(workspaceFile)) {\n return currentDir\n }\n currentDir = path.dirname(currentDir)\n }\n\n throw new Error('Could not find monorepo root (pnpm-workspace.yaml)')\n}\n\n/** Read the `name` field from `<apiPath>/package.json`, falling back to `appName`. */\nexport function getPackageName(apiPath: string, appName: string): string {\n const pkgPath = path.join(apiPath, 'package.json')\n\n if (!fs.existsSync(pkgPath)) return appName\n\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { name?: string }\n\n return typeof pkg.name === 'string' ? pkg.name : appName\n } catch {\n return appName\n }\n}\n\n/** Discover every `apps/<app>` that has an `api/serverless.yml` (bare metadata only). */\nexport function discoverApiApps(root: string): DiscoveredApiApp[] {\n const appsDir = path.join(root, 'apps')\n const apps: DiscoveredApiApp[] = []\n\n if (!fs.existsSync(appsDir)) {\n throw new Error(`Apps directory not found: ${appsDir}`)\n }\n\n const appDirs = fs\n .readdirSync(appsDir, { withFileTypes: true })\n .filter((dirent) => {\n return dirent.isDirectory()\n })\n .map((dirent) => {\n return dirent.name\n })\n\n for (const appName of appDirs) {\n const apiPath = path.join(appsDir, appName, 'api')\n const serverlessPath = path.join(apiPath, 'serverless.yml')\n\n if (fs.existsSync(serverlessPath)) {\n apps.push({\n name: appName,\n packageName: getPackageName(apiPath, appName),\n path: apiPath,\n })\n }\n }\n\n return apps\n}\n\n/** Bare metadata for a discovered UI app (a frontend with its own framework `dev` script). */\nexport interface DiscoveredUiApp {\n /** App folder name (e.g. backoffice, client). */\n name: string\n /** package.json `name` \u2014 used as the exact `turbo run dev --filter` target. */\n packageName: string\n /** Absolute path to `apps/<app>/ui`. */\n path: string\n}\n\n/** True when `<dir>/package.json` declares a non-empty `scripts.dev`. */\nfunction hasDevScript(dir: string): boolean {\n const pkgPath = path.join(dir, 'package.json')\n\n if (!fs.existsSync(pkgPath)) return false\n\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8')) as { scripts?: Record<string, string> }\n\n return typeof pkg.scripts?.dev === 'string' && pkg.scripts.dev.length > 0\n } catch {\n return false\n }\n}\n\n/**\n * Discover every `apps/<app>/ui` whose package.json declares a `dev` script \u2014 the frontends\n * `infra-kit dev --ui` runs (via one delegated `turbo run dev`). Lenient: no `apps/` dir \u2192 `[]`\n * (UIs are optional), unlike {@link discoverApiApps} which requires it.\n */\nexport function discoverUiApps(root: string): DiscoveredUiApp[] {\n const appsDir = path.join(root, 'apps')\n const apps: DiscoveredUiApp[] = []\n\n if (!fs.existsSync(appsDir)) return apps\n\n const appDirs = fs\n .readdirSync(appsDir, { withFileTypes: true })\n .filter((dirent) => {\n return dirent.isDirectory()\n })\n .map((dirent) => {\n return dirent.name\n })\n\n for (const appName of appDirs) {\n const uiPath = path.join(appsDir, appName, 'ui')\n\n if (fs.existsSync(uiPath) && hasDevScript(uiPath)) {\n apps.push({\n name: appName,\n packageName: getPackageName(uiPath, appName),\n path: uiPath,\n })\n }\n }\n\n return apps\n}\n\n/** Normalize the `--app` include list: drop empties, and collapse an empty list to `null`. */\nexport function normalizeAppInclude(include?: string[] | null): string[] | null {\n const filtered = include?.filter(Boolean) ?? []\n\n return filtered.length > 0 ? filtered : null\n}\n\n/**\n * Existing `packages/<pkg>/dist` directories under the monorepo root \u2014 the compiled\n * outputs `turbo watch` rewrites. Watched (alongside app dist) because editing a shared\n * lib rewrites only the lib's `dist`, never the dependent app's, so a package-dist change\n * is the only signal that a lib was rebuilt.\n */\nexport function getPackageDistDirs(root: string): string[] {\n const packagesDir = path.join(root, 'packages')\n\n if (!fs.existsSync(packagesDir)) return []\n\n const names = fs\n .readdirSync(packagesDir, { withFileTypes: true })\n .filter((d) => {\n return d.isDirectory()\n })\n .map((d) => {\n return d.name\n })\n const dirs: string[] = []\n\n for (const name of names) {\n const distDir = path.join(packagesDir, name, 'dist')\n\n if (fs.existsSync(distDir) && fs.statSync(distDir).isDirectory()) {\n dirs.push(distDir)\n }\n }\n\n return dirs\n}\n\n/** Existing `<app.path>/dist` directories for the given apps (order preserved). */\nexport function getAppDistDirs(apps: Array<{ path: string }>): string[] {\n return apps\n .map((app) => {\n return path.join(app.path, 'dist')\n })\n .filter((dir) => {\n return fs.existsSync(dir)\n })\n}\n\n/** How a watched dist change should be routed. */\nexport interface ChangeClassification {\n kind: 'app' | 'package'\n /** For app changes: the matched app dist dir (undefined when nothing matched). */\n app?: string\n}\n\n/**\n * Route a changed compiled-output path: a `packages/<pkg>/dist` change is a shared-package\n * rebuild (restart every app), an `<app>/dist` change restarts only that app (the matched\n * app dist dir is returned; `undefined` when the path matches neither). Package matches take\n * precedence.\n */\nexport function classifyDistChange(\n changedPath: string,\n appDistDirs: string[],\n packageDistDirs: string[],\n): ChangeClassification {\n const normalized = path.normalize(changedPath)\n\n const inPackage = packageDistDirs.some((dir) => {\n return normalized.startsWith(path.normalize(dir))\n })\n\n if (inPackage) {\n return { kind: 'package' }\n }\n\n const matchedDir = appDistDirs.find((dir) => {\n return normalized.startsWith(path.normalize(dir))\n })\n\n return { kind: 'app', app: matchedDir }\n}\n", "/**\n * Pure port / URL-prefix resolution for the dev-server.\n *\n * These functions are intentionally side-effect free: the environment is passed\n * in (never read from `process.env` here) and no cwd / fs access happens. That\n * keeps port precedence and conflict detection unit-testable in isolation.\n */\nimport type { DevConfig } from '../lib/infra-kit-config/index.js'\n\n/** Fallback port when no PORT / {APP}_PORT env var and no config port is set. */\nexport const DEFAULT_PORT = 3010\n\n/**\n * URL prefix applied to each app's routes when nothing is configured. Overridable\n * per app via `dev.<app>.prefixUrl` in infra-kit.json \u2014 this is only the fallback.\n */\nexport const DEFAULT_PREFIX_URL = '/api/v1'\n\n/**\n * Parse a raw port string (env var or config), stripping a single pair of\n * surrounding quotes and treating blank / non-numeric input as \"unset\".\n */\nexport function parsePortString(raw: string | undefined): number | undefined {\n if (raw == null || raw === '') {\n return undefined\n }\n\n const n = parseInt(raw.trim().replace(/^[\"']|[\"']$/g, ''), 10)\n\n return Number.isNaN(n) ? undefined : n\n}\n\n/**\n * Resolve the PORT for an API app (highest priority first):\n *\n * 1. **`{APP}_PORT`** \u2014 e.g. `CLIENT_PORT`, `SEARCH_ENGINE_PORT` (secrets manager or shell)\n * 2. **`PORT`** \u2014 shared fallback (multi-app: use distinct `{APP}_PORT` in env)\n * 3. **`dev.<app>.port`** from infra-kit.json\n * 4. Default {@link DEFAULT_PORT}\n *\n * Per-app env keys use the app folder name in **UPPER_SNAKE_CASE** (hyphens \u2192 underscores).\n */\nexport function resolvePort(appName: string, env: NodeJS.ProcessEnv, devConfig: DevConfig): number {\n const prefix = appName.replace(/-/g, '_').toUpperCase()\n const prefixedKey = `${prefix}_PORT`\n\n const fromPrefixed = parsePortString(env[prefixedKey])\n\n if (fromPrefixed != null) {\n return fromPrefixed\n }\n\n const fromPort = parsePortString(env.PORT)\n\n if (fromPort != null) {\n return fromPort\n }\n\n const fromConfig = devConfig[appName]?.port\n\n if (fromConfig != null) {\n return fromConfig\n }\n\n return DEFAULT_PORT\n}\n\n/**\n * Resolve the URL prefix for an API app: `dev.<app>.prefixUrl` from\n * infra-kit.json, falling back to {@link DEFAULT_PREFIX_URL} (`/api/v1`).\n */\nexport function resolvePrefixUrl(appName: string, devConfig: DevConfig): string {\n return devConfig[appName]?.prefixUrl ?? DEFAULT_PREFIX_URL\n}\n\n/** The apps that collide on a port, plus the raw duplicate-port list for messaging. */\nexport interface PortConflicts {\n /** Ports that appear more than once (one entry per extra occurrence, in scan order). */\n duplicatePorts: number[]\n /** Every app whose resolved port is one of the duplicates. */\n conflictingApps: Array<{ name: string; port: number }>\n}\n\n/**\n * Find apps that resolve to the same port. Returns empty `duplicatePorts` when\n * there is no conflict; the caller decides how to surface / throw.\n */\nexport function findPortConflicts(apps: Array<{ name: string; port: number }>): PortConflicts {\n const ports = apps.map((a) => {\n return a.port\n })\n const duplicatePorts = ports.filter((port, index) => {\n return ports.indexOf(port) !== index\n })\n const conflictingApps = apps.filter((a) => {\n return duplicatePorts.includes(a.port)\n })\n\n return { duplicatePorts, conflictingApps }\n}\n", "import { Logger } from '@aws-lambda-powertools/logger'\nimport type { APIGatewayProxyEvent, APIGatewayProxyEventQueryStringParameters, Context } from 'aws-lambda'\nimport fastify from 'fastify'\nimport * as fs from 'node:fs'\nimport type { Server } from 'node:http'\nimport * as path from 'node:path'\nimport process from 'node:process'\nimport { pathToFileURL } from 'node:url'\nimport { parse as parseYaml } from 'yaml'\n\nimport type { ILogger } from './interfaces.js'\n\nexport interface IServerConfig {\n controllersPath: string\n prefixUrl?: string\n port: number\n /** App folder name, surfaced by the `/__health` endpoint. Optional. */\n appName?: string\n}\n\ntype HandlerResult = Promise<{ body: string; headers: Record<string, string>; statusCode: number }>\n\n/** Default simulated Lambda timeout; overridable via `DEV_SERVER_TIMEOUT_MS`. */\nconst DEFAULT_LAMBDA_TIMEOUT_MS = 30_000\n\n/** Resolve the simulated Lambda timeout (ms), honoring `DEV_SERVER_TIMEOUT_MS` when it parses. */\nconst resolveLambdaTimeoutMs = (): number => {\n const raw = Number.parseInt(process.env.DEV_SERVER_TIMEOUT_MS ?? '', 10)\n\n return Number.isNaN(raw) ? DEFAULT_LAMBDA_TIMEOUT_MS : raw\n}\n\n/**\n * Whether to emit a one-line `<method> <url> \u2192 <status> <ms>ms` log per request.\n * Off by default; opt in with `DEV_SERVER_REQUEST_LOG=1` (kept out of the Powertools\n * JSON logger so the line stays terminal-readable). Mirrors the env-reader precedent\n * of {@link resolveLambdaTimeoutMs}.\n */\nconst isRequestLogEnabled = (): boolean => {\n return process.env.DEV_SERVER_REQUEST_LOG === '1'\n}\n\nexport class ServerlessLocalRun {\n /** Busts Node ESM `import()` cache on each new server instance (watch restart). */\n private readonly importCacheBust: string\n private readonly logger: Logger\n private readonly server: ReturnType<typeof fastify>\n private readonly controllers: Record<\n string,\n {\n action: Record<string, (event: APIGatewayProxyEvent, ctx: Context, log: ILogger) => HandlerResult>\n handler: string\n }\n > = {}\n\n /** `method urlAction` keys reserved synchronously, so duplicates are caught before any async import. */\n private readonly registeredRouteKeys = new Set<string>()\n\n constructor(private readonly serverConfig: IServerConfig) {\n this.importCacheBust = `${Date.now()}`\n this.logger = new Logger({ serviceName: 'LocalServer', logLevel: 'DEBUG' })\n this.serverConfig.prefixUrl = this.serverConfig.prefixUrl ?? ''\n this.server = fastify({ logger: false })\n\n // Add CORS support for local development\n this.server.addHook(\n 'onRequest',\n async (\n request: { method: string },\n reply: { header: (k: string, v: string) => unknown; status: (n: number) => { send: () => void } },\n ) => {\n reply.header('Access-Control-Allow-Origin', '*')\n reply.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS')\n reply.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With')\n\n // Handle preflight OPTIONS requests\n if (request.method === 'OPTIONS') {\n reply.status(204).send()\n }\n },\n )\n\n // Opt-in per-request log line (raw stdout, not the Powertools JSON logger) so live\n // traffic is visible in the dev terminal. Off unless DEV_SERVER_REQUEST_LOG=1.\n if (isRequestLogEnabled()) {\n this.server.addHook(\n 'onResponse',\n async (request: { method: string; url: string }, reply: { statusCode: number; elapsedTime: number }) => {\n const ms = Math.round(reply.elapsedTime)\n\n process.stdout.write(`${request.method} ${request.url} \u2192 ${reply.statusCode} ${ms}ms\\n`)\n },\n )\n }\n }\n\n /**\n * The registered `METHOD /path` route keys (sorted). Excludes the internal\n * `/__health` liveness route, which is registered outside {@link defineRoute} and\n * never added to {@link registeredRouteKeys}. Used by the runner's startup route dump.\n */\n public getRegisteredRoutes(): string[] {\n return [...this.registeredRouteKeys].sort()\n }\n\n public async start(): Promise<void> {\n this.registerHealthRoute()\n\n await Promise.all(this.loadRoutes())\n\n await this.server.listen({ port: this.serverConfig.port, host: '127.0.0.1' })\n\n this.logger.info(`Server listening on http://127.0.0.1:${this.serverConfig.port}`, {\n address: `http://127.0.0.1:${this.serverConfig.port}`,\n })\n }\n\n /** Close the server (for watch/restart). */\n public async close(): Promise<void> {\n const raw = this.server.server as Server\n\n if (typeof raw.closeAllConnections === 'function') {\n raw.closeAllConnections()\n }\n await this.server.close()\n }\n\n /**\n * Register a fixed `GET /__health` liveness route returning 200. The path is\n * unprefixed (serverless.yml routes carry the `prefixUrl`, e.g. `/api/v1/...`),\n * so it never collides with a handler route.\n */\n private registerHealthRoute(): void {\n this.server.route({\n method: 'GET',\n url: '/__health',\n handler: (_request: unknown, reply: { code: (n: number) => { send: (body: unknown) => void } }) => {\n return reply.code(200).send({\n status: 'ok',\n app: this.serverConfig.appName ?? null,\n port: this.serverConfig.port,\n })\n },\n })\n }\n\n private loadRoutes(): Promise<void>[] {\n const serverlessYmlPath = path.join(this.serverConfig.controllersPath, 'serverless.yml')\n const fileContents = fs.readFileSync(serverlessYmlPath, 'utf8')\n const data = parseYaml(fileContents) as {\n functions: Record<string, { events?: Array<{ http?: { method: string; path: string } }>; handler?: string }>\n }\n const p: Promise<void>[] = []\n\n if (!data?.functions) return p\n\n for (const [funcName, funcDef] of Object.entries(data.functions)) {\n if (!funcDef?.events?.length) continue\n for (const element of funcDef.events) {\n const http = element?.http\n\n if (!http) continue\n this.logger.debug(`Registering route: ${http.method} /${http.path} -> ${funcName}`)\n p.push(this.defineRoute(http, funcDef))\n }\n }\n\n return p\n }\n\n private async defineRoute(http: { method: string; path: string }, funcDef: { handler?: string }): Promise<void> {\n let url = http.path.toString()\n\n url = url.replaceAll('{', ':').replaceAll('}', '')\n\n let urlAction = path.posix.join(this.serverConfig.prefixUrl ?? '', url)\n\n urlAction = urlAction[0] === '/' ? urlAction : `/${urlAction}`\n\n const validMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS']\n const method = String(http.method).toUpperCase()\n\n if (!validMethods.includes(method)) {\n throw new Error(`Invalid HTTP method: \"${http.method}\" for URL: ${urlAction}`)\n }\n\n // Key on method + path: two events can share a path but differ by method (e.g. GET/POST /users),\n // so keying on the path alone would let one handler overwrite the other. Reserve the key\n // synchronously (before the first `await`) so concurrent route loads detect a true duplicate.\n const routeKey = `${method} ${urlAction}`\n\n if (this.registeredRouteKeys.has(routeKey)) {\n throw new Error(`Duplicate route: ${routeKey}`)\n }\n this.registeredRouteKeys.add(routeKey)\n\n const handlerStr = funcDef.handler ?? ''\n const parts = handlerStr.split('.')\n const filepath = parts[0] ?? ''\n const handler = parts[1] ?? ''\n\n const controllerPath = path.join(this.serverConfig.controllersPath, `${filepath}.js`)\n const fileUrl = pathToFileURL(controllerPath)\n\n // Search params bust Node's ESM import cache so watch rebuilds load new `dist` output.\n fileUrl.searchParams.set('v', this.importCacheBust)\n const action = (await import(fileUrl.href)) as Record<\n string,\n (event: APIGatewayProxyEvent, ctx: Context, log: ILogger) => HandlerResult\n >\n\n this.controllers[routeKey] = { action, handler }\n\n const traceLogger = this.logger.createChild({ serviceName: 'RequestLogger' })\n\n this.logger.debug(`Adding fastify route: ${method} ${urlAction}`)\n\n this.server.route({\n method: method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS',\n url: urlAction,\n handler: async (\n request: { body?: unknown; query?: unknown; params?: unknown; headers?: unknown },\n reply: {\n headers: (h: Record<string, string>) => unknown\n code: (n: number) => { send: (body: unknown) => void }\n },\n ) => {\n const controller = this.controllers[routeKey]\n\n if (!controller) throw new Error(`No controller for ${routeKey}`)\n const handlerFn = controller.action[controller.handler]\n\n if (!handlerFn) throw new Error(`No handler ${controller.handler} for ${urlAction}`)\n const retVal = await handlerFn(\n this.getEventObj(request.body, request.query, request.params, request.headers, method, urlAction),\n this.getContext(),\n traceLogger,\n )\n const responseBody = JSON.parse(retVal.body)\n\n reply.headers(retVal.headers ?? {})\n\n return reply.code(retVal?.statusCode ?? 500).send(responseBody)\n },\n })\n\n this.logger.debug(`Route added successfully: ${method} ${urlAction}`)\n }\n\n private getEventObj(\n requestBody?: unknown,\n queryParams?: unknown,\n pathParameters?: unknown,\n headers?: unknown,\n httpMethod = '',\n path = '',\n ): APIGatewayProxyEvent {\n const retVal = {\n body: requestBody ? JSON.stringify(requestBody) : null,\n headers: (headers ?? {}) as APIGatewayProxyEvent['headers'],\n multiValueHeaders: {},\n httpMethod,\n isBase64Encoded: false,\n path,\n pathParameters: pathParameters ?? null,\n queryStringParameters: (queryParams as APIGatewayProxyEventQueryStringParameters) ?? null,\n multiValueQueryStringParameters: null,\n stageVariables: null,\n requestContext: {\n accountId: '',\n apiId: '',\n authorizer: undefined,\n protocol: '',\n httpMethod,\n identity: {\n accessKey: null,\n accountId: null,\n apiKey: null,\n apiKeyId: null,\n caller: null,\n clientCert: null,\n cognitoAuthenticationProvider: null,\n cognitoAuthenticationType: null,\n cognitoIdentityId: null,\n cognitoIdentityPoolId: null,\n principalOrgId: null,\n sourceIp: 'devIp',\n user: null,\n userAgent: null,\n userArn: null,\n },\n path,\n stage: '',\n requestId: '',\n requestTimeEpoch: 0,\n resourceId: '',\n resourcePath: path,\n },\n resource: path,\n }\n\n ;(retVal as APIGatewayProxyEvent & { source: string }).source = 'aws.events'\n\n return retVal as APIGatewayProxyEvent\n }\n\n private getContext(): Context {\n const startTime = Date.now()\n const timeoutMs = resolveLambdaTimeoutMs()\n const datePart = new Date().toISOString().split('T')[0] ?? ''\n\n return {\n callbackWaitsForEmptyEventLoop: false,\n functionName: 'local-dev',\n functionVersion: '1.0.0',\n invokedFunctionArn: 'arn:aws:lambda:local:000000000000:function:local-dev',\n memoryLimitInMB: '1024',\n awsRequestId: `local-${Date.now()}`,\n logGroupName: '/aws/lambda/local-dev',\n logStreamName: `${datePart}/local`,\n getRemainingTimeInMillis: (): number => {\n return Math.max(0, timeoutMs - (Date.now() - startTime))\n },\n done: (_error?: Error, _result?: unknown): void => {},\n fail: (_error: string | Error): void => {},\n succeed: (_messageOrObject: unknown): void => {},\n }\n }\n}\n", "/*\n * `pnpm` is resolved from PATH \u2014 the same trust posture as the rest of the dev-server, which\n * already shells out to `pnpm exec turbo \u2026`; the args are fixed literals plus discovered package\n * names, never shell-interpolated. Matches the file-level disable in `scripts/build.js`.\n */\n/* eslint-disable sonarjs/no-os-command-from-path */\n/**\n * `turbo watch build` engine for `infra-kit dev --watch`.\n *\n * Spawns ONE long-lived `turbo watch build` child that owns incremental rebuilds and\n * dependency-graph fan-out. Its stdout is teed to the runner log but NEVER parsed for\n * control flow: piped `turbo watch` block-buffers stdout and emits no per-task completion\n * marker for `tsc -b` tasks, so the dev-server derives \"a build finished\" from watching\n * `dist/` output instead (see {@link file://./dev-server.ts} `setupWatch`).\n *\n * The child is a 5-deep tree (`sh \u2192 pnpm \u2192 node \u2192 turbo \u2192 native binary`); killing the\n * wrapper PID orphans the rest. So it is spawned `detached` (its own process group) and\n * torn down with a process-GROUP signal \u2014 verified to fully reap the tree.\n */\nimport { spawn } from 'node:child_process'\nimport * as fs from 'node:fs'\n\nimport { superviseChild } from './managed-child.js'\nimport type { ManagedChild } from './managed-child.js'\n\n/** Handle to the running `turbo watch` child; `kill()` reaps the whole process group. */\nexport type TurboWatchHandle = ManagedChild\n\n/** Injectable spawn seam so tests run the orchestrator without a real turbo child. */\nexport type TurboWatchFactory = (opts: TurboWatchOptions) => TurboWatchHandle\n\nexport interface TurboWatchOptions {\n /** App package names; each becomes a `--filter=...<pkg>` (dependency-inclusive) arg. */\n packageNames: string[]\n /** Consumer repo cwd the child runs in (turbo resolves the consumer's own pin here). */\n cwd: string\n /** Runner log file; the child's stdout+stderr are appended to it. */\n logFile: string\n}\n\n/**\n * Default factory: spawn `pnpm exec turbo watch build --filter=...<pkg> ... --continue=dependencies-successful\n * --env-mode=loose` detached, tee output to `logFile`, and reap the process group on `kill()`.\n *\n * `--filter=...<pkg>` (the leading `...`) includes each app's dependencies, so editing a\n * shared lib triggers a rebuild. `--continue=dependencies-successful` keeps the watcher\n * alive when one package fails to compile, so a shared-lib type error never tears down the\n * whole engine and the last-good `dist/` keeps serving.\n */\nexport const defaultTurboWatchFactory: TurboWatchFactory = ({ packageNames, cwd, logFile }) => {\n const filters = packageNames.map((name) => {\n return `--filter=...${name}`\n })\n const out = fs.openSync(logFile, 'a')\n const child = spawn(\n 'pnpm',\n ['exec', 'turbo', 'watch', 'build', ...filters, '--continue=dependencies-successful', '--env-mode=loose'],\n { cwd, detached: true, stdio: ['ignore', out, out] },\n )\n\n return superviseChild(child)\n}\n", "/**\n * Shared supervision for the dev-server's long-lived, detached child processes\n * (`turbo watch build`, `turbo run dev`). Both are deep trees\n * (`sh \u2192 pnpm \u2192 node \u2192 turbo \u2192 \u2026`) spawned `detached` so they form their own process\n * group; teardown signals the whole GROUP (`process.kill(-pid, \u2026)`), not just the wrapper.\n *\n * Escalation: SIGTERM first, then \u2014 if the group is still alive after a grace window \u2014\n * SIGKILL. FE dev servers (vite/vike/astro) run async teardown and can straggle on a\n * lone SIGTERM (orphaned port \u2192 next run's `EADDRINUSE`), so the SIGKILL fallback matters.\n */\nimport type { ChildProcess } from 'node:child_process'\nimport process from 'node:process'\n\n/** Handle to a supervised child; `kill()` reaps its whole process group and resolves when gone. */\nexport interface ManagedChild {\n kill: () => Promise<void>\n}\n\n/** Default grace before escalating SIGTERM \u2192 SIGKILL on a stubborn process group. */\nconst DEFAULT_GRACE_MS = 2000\n\n/** Is the process group led by `pid` still alive? (`kill(-pid, 0)` throws ESRCH when gone.) */\nfunction groupAlive(pid: number): boolean {\n try {\n process.kill(-pid, 0)\n\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Wrap a detached child: `unref()` it (so it never keeps the loop alive) and return a\n * handle whose `kill()` sends a group SIGTERM, polls up to `graceMs` for the group to\n * exit, and SIGKILLs any survivor. Resolves once the group is gone (or was never spawned).\n */\nexport function superviseChild(child: ChildProcess, graceMs: number = DEFAULT_GRACE_MS): ManagedChild {\n // Don't keep the parent event loop alive on the child; the runner owns lifecycle via kill().\n child.unref()\n\n return {\n kill: async (): Promise<void> => {\n const pid = child.pid\n\n if (pid == null) return\n\n try {\n // Negative pid \u2192 the whole group (detached made the child a group leader).\n process.kill(-pid, 'SIGTERM')\n } catch {\n // Already exited (ESRCH) \u2014 nothing to reap.\n return\n }\n\n const deadline = Date.now() + graceMs\n\n while (Date.now() < deadline) {\n await new Promise((r) => {\n return setTimeout(r, 100)\n })\n if (!groupAlive(pid)) return\n }\n\n // Still alive after the grace window \u2014 force it.\n try {\n process.kill(-pid, 'SIGKILL')\n } catch {\n // Raced to exit between the last poll and now \u2014 fine.\n }\n },\n }\n}\n", "/*\n * `pnpm` is resolved from PATH \u2014 same trust posture as the rest of the dev-server (which already\n * shells out to `pnpm exec turbo \u2026`); args are fixed literals plus discovered package names, never\n * shell-interpolated. Matches the file-level disable in `scripts/build.js`.\n */\n/* eslint-disable sonarjs/no-os-command-from-path */\n/**\n * Frontend dev engine for `infra-kit dev --ui`.\n *\n * Delegates FE to ONE `turbo run dev` child (turbo owns the `dev` fan-out, `^build` ordering\n * and concurrency) rather than infra-kit spawning each framework itself \u2014 the same delegation\n * choice already made for builds via `turbo watch`. infra-kit treats UIs opaquely: it runs their\n * `dev` script (vite/vike/astro/\u2026) and never encodes per-framework knowledge.\n *\n * Unlike the `turbo watch` child, this one's stdio is INHERITED \u2014 the framework dev servers own\n * their own TTY output (HMR overlays, URLs, spinners), so it streams raw to the terminal below the\n * BE server table rather than being teed into the runner log (which would corrupt it with ANSI).\n *\n * Detached \u2192 its own process group; reaped as a group (SIGTERM\u2192SIGKILL) via {@link superviseChild}.\n */\nimport { spawn } from 'node:child_process'\n\nimport { superviseChild } from './managed-child.js'\nimport type { ManagedChild } from './managed-child.js'\n\n/** Handle to the running `turbo run dev` child; `kill()` reaps the whole process group. */\nexport type UiDevHandle = ManagedChild\n\n/** Injectable spawn seam so tests run the orchestrator without a real turbo child. */\nexport type UiDevFactory = (opts: UiDevOptions) => UiDevHandle\n\nexport interface UiDevOptions {\n /** UI app package names; each becomes an exact `--filter=<pkg>` (turbo runs its `dev` task). */\n packageNames: string[]\n /** Consumer repo cwd the child runs in. */\n cwd: string\n /**\n * Concurrency cap. Must be \u2265 the number of selected UI `dev` tasks (they're persistent) \u2014\n * turbo hard-errors when persistent tasks exceed concurrency (default 10).\n */\n concurrency: number\n}\n\n/**\n * Default factory: spawn `pnpm exec turbo run dev --filter=<pkg> \u2026 --concurrency=N --env-mode=loose`\n * detached, streaming to the parent terminal, and reap the process group on `kill()`.\n *\n * Exact `--filter=<pkg>` (no `...`) selects only the UI packages, so an API app that also defines a\n * `dev` task is never picked up.\n */\nexport const defaultUiDevFactory: UiDevFactory = ({ packageNames, cwd, concurrency }) => {\n const filters = packageNames.map((name) => {\n return `--filter=${name}`\n })\n const child = spawn(\n 'pnpm',\n ['exec', 'turbo', 'run', 'dev', ...filters, `--concurrency=${concurrency}`, '--env-mode=loose'],\n { cwd, detached: true, stdio: ['ignore', 'inherit', 'inherit'] },\n )\n\n return superviseChild(child)\n}\n"],
5
- "mappings": "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",
6
- "names": ["Command", "process", "pathToFileURL", "chokidar", "exec", "fs", "path", "process", "util", "fs", "path", "findMonorepoRoot", "startDir", "currentDir", "i", "workspaceFile", "getPackageName", "apiPath", "appName", "pkgPath", "pkg", "discoverApiApps", "root", "appsDir", "apps", "appDirs", "dirent", "serverlessPath", "hasDevScript", "dir", "discoverUiApps", "uiPath", "normalizeAppInclude", "include", "filtered", "getPackageDistDirs", "packagesDir", "names", "d", "dirs", "name", "distDir", "getAppDistDirs", "app", "classifyDistChange", "changedPath", "appDistDirs", "packageDistDirs", "normalized", "DEFAULT_PREFIX_URL", "parsePortString", "raw", "n", "resolvePort", "appName", "env", "devConfig", "prefixedKey", "fromPrefixed", "fromPort", "fromConfig", "resolvePrefixUrl", "findPortConflicts", "apps", "ports", "a", "duplicatePorts", "port", "index", "conflictingApps", "Logger", "fastify", "fs", "path", "process", "pathToFileURL", "parseYaml", "DEFAULT_LAMBDA_TIMEOUT_MS", "resolveLambdaTimeoutMs", "raw", "isRequestLogEnabled", "ServerlessLocalRun", "serverConfig", "request", "reply", "ms", "_request", "serverlessYmlPath", "fileContents", "data", "p", "funcName", "funcDef", "element", "http", "url", "urlAction", "validMethods", "method", "routeKey", "parts", "filepath", "handler", "controllerPath", "fileUrl", "action", "traceLogger", "controller", "handlerFn", "retVal", "responseBody", "requestBody", "queryParams", "pathParameters", "headers", "httpMethod", "startTime", "timeoutMs", "datePart", "_error", "_result", "_messageOrObject", "spawn", "fs", "process", "DEFAULT_GRACE_MS", "groupAlive", "pid", "superviseChild", "child", "graceMs", "deadline", "r", "defaultTurboWatchFactory", "packageNames", "cwd", "logFile", "filters", "name", "out", "child", "spawn", "superviseChild", "spawn", "defaultUiDevFactory", "packageNames", "cwd", "concurrency", "filters", "name", "child", "spawn", "superviseChild", "LOG_FILE_PATH", "process", "initLogFile", "execFn", "util", "exec", "launchScript", "script", "logFn", "stderr", "error", "err", "appendLogFile", "text", "log", "message", "level", "logTable", "lines", "output", "center", "s", "width", "pad", "left", "renderTable", "title", "headers", "rows", "widths", "header", "i", "row", "columnsInner", "sum", "w", "lastIdx", "inner", "blocks", "rowLine", "cells", "c", "DevServerRunner", "_DevServerRunner", "options", "runBuild", "turboWatchFactory", "defaultTurboWatchFactory", "uiDevFactory", "defaultUiDevFactory", "findMonorepoRoot", "devConfig", "discoverApiApps", "app", "getInfraKitConfig", "normalizeAppInclude", "appName", "resolvePort", "resolvePrefixUrl", "include", "watch", "apps", "uiApps", "discoverUiApps", "selected", "a", "filters", "names", "duplicatePorts", "conflictingApps", "findPortConflicts", "buildCmd", "buildError", "server", "ServerlessLocalRun", "work", "run", "r", "e", "t", "targets", "label", "idx", "newServer", "appDistDirs", "getAppDistDirs", "packageDistDirs", "getPackageDistDirs", "allDistDirs", "usePoll", "watcher", "chokidar", "filePath", "change", "classifyDistChange", "key", "existing", "timer", "routes", "runner", "splitList", "value", "parts", "s", "toDevServerOptions", "raw", "runDevServer", "options", "runner", "run", "shuttingDown", "shutdown", "signal", "process", "parseAndRun", "argv", "program", "Command", "pathToFileURL", "error"]
3
+ "sources": ["../src/entry/dev-server.ts", "../src/dev/cmux-dev.ts", "../src/dev/cmux-layout.ts", "../src/dev/dev-server.ts", "../src/dev/dep-closure.ts", "../src/dev/ports.ts", "../src/dev/serverless-local-run.ts", "../src/dev/turbo-watch.ts", "../src/dev/managed-child.ts", "../src/dev/ui-dev.ts"],
4
+ "sourcesContent": ["/**\n * Long-running CLI entry for the local dev-server. Owns flag parsing, OS signal\n * handling, and process exit \u2014 the orchestrator (`src/dev/dev-server`) is signal-\n * and exit-agnostic. Kept off the eager cli.js graph: entry/cli.ts reaches this\n * module (and the fastify/chokidar it pulls in) only via `await import(...)`, so\n * those heavy deps never load on the machine command paths.\n */\nimport { Command } from 'commander'\nimport process from 'node:process'\nimport { pathToFileURL } from 'node:url'\n\nimport { runCmuxDevServer } from 'src/dev/cmux-dev'\nimport { run } from 'src/dev/dev-server'\nimport type { DevServerOptions } from 'src/dev/dev-server'\nimport { resolveSelfAppName } from 'src/dev/discovery'\nimport { isCmuxAvailable } from 'src/integrations/cmux'\n\n/** Raw option object as produced by Commander (comma-joined strings). */\nexport interface DevCliOptions {\n watch?: boolean\n app?: string\n /** Named preset positional (`infra-kit dev <preset>`); selects launch targets from `devPresets`. */\n preset?: string\n cmux?: boolean\n self?: boolean\n verbose?: boolean\n}\n\n/** Split a comma-separated flag value into a trimmed, non-empty list (`null` when unset/empty). */\nconst splitList = (value: string | undefined): string[] | null => {\n if (value == null) return null\n\n const parts = value\n .split(',')\n .map((s) => {\n return s.trim()\n })\n .filter(Boolean)\n\n return parts.length > 0 ? parts : null\n}\n\n/**\n * Map raw Commander flags to the orchestrator's typed options. Shared by the\n * `infra-kit dev` subcommand and the standalone entry so the two never diverge.\n * `self` is passed through as-is here \u2014 it's resolved to `include` later, in\n * `runDevServer`, where `--app` (if also given) is allowed to win.\n */\nexport const toDevServerOptions = (raw: DevCliOptions): DevServerOptions => {\n return {\n watch: raw.watch ?? false,\n include: splitList(raw.app),\n preset: raw.preset,\n cmux: raw.cmux ?? false,\n self: raw.self ?? false,\n verbose: raw.verbose ?? false,\n }\n}\n\n/**\n * Resolve `--self` into an `include` list, without mutating `options`. `--app` (an\n * explicit `include`) wins over `--self` when both are given \u2014 self is only a\n * convenience default for scripts that don't want to hardcode their app name.\n * Lets `resolveSelfAppName`'s error (not inside `apps/<app>/...`) propagate as-is;\n * the caller's top-level catch turns it into a clean message + non-zero exit.\n */\nconst resolveSelfOptions = (options: DevServerOptions): DevServerOptions => {\n if (!options.self || options.include) {\n return options\n }\n\n return { ...options, include: [resolveSelfAppName(process.cwd())] }\n}\n\n/**\n * Start the dev-server, then wait for an OS signal and shut every server down\n * cleanly before exiting. This is the ONLY place SIGINT/SIGTERM handlers and\n * `process.exit` live for the dev-server feature.\n */\nexport const runDevServer = async (rawOptions: DevServerOptions): Promise<void> => {\n const options = resolveSelfOptions(rawOptions)\n\n // `--cmux`: one workspace, one pane per app. `runCmuxDevServer` owns its own\n // signal handling and never returns, so return before wiring the in-process\n // handlers below. Fall through to single-process dev when cmux isn't installed.\n if (options.cmux) {\n if (await isCmuxAvailable()) {\n await runCmuxDevServer(options)\n\n return\n }\n\n process.stdout.write('cmux not available; falling back to single-terminal dev\\n')\n }\n\n const runner = await run(options)\n\n let shuttingDown = false\n\n const shutdown = (signal: NodeJS.Signals): void => {\n if (shuttingDown) return\n shuttingDown = true\n\n void (async () => {\n try {\n process.stdout.write(`\\nReceived ${signal}, shutting down dev-server...\\n`)\n await runner.shutdown()\n } finally {\n process.exit(0)\n }\n })()\n }\n\n process.on('SIGINT', () => {\n return shutdown('SIGINT')\n })\n process.on('SIGTERM', () => {\n return shutdown('SIGTERM')\n })\n}\n\n/** Parse `node dist/dev-server.js ...` flags and start the server. */\nconst parseAndRun = async (argv: string[]): Promise<void> => {\n const program = new Command()\n\n program\n .name('infra-kit-dev-server')\n .description('Run local dev servers for the apps in a named devPresets preset (or all apps)')\n .argument('[preset]', 'Named preset from devPresets (omit to run every app)')\n .option('-w, --watch', 'Rebuild and restart on file save')\n .option('--app <names>', 'Further narrow to these app folder names (comma-separated)')\n .option(\n '--cmux',\n 'Run each app in its own cmux pane (one workspace, N panes; falls back to single terminal if cmux is unavailable)',\n )\n .option('--self', 'Run only the app of the current directory (infer from cwd; use inside apps/<app>/\u2026)')\n .option(\n '-V, --verbose',\n 'Print full boot narration (default: quiet; full detail always in .infra-kit/dev-server.log)',\n )\n\n program.parse(argv)\n\n await runDevServer(toDevServerOptions({ ...program.opts<DevCliOptions>(), preset: program.args[0] }))\n}\n\n// Self-execute only when run directly (`node dist/dev-server.js`), not when the\n// `infra-kit dev` subcommand imports this module for its exported helpers.\nif (import.meta.url === pathToFileURL(process.argv[1] ?? '').href) {\n parseAndRun(process.argv).catch((error: unknown) => {\n console.error(error)\n process.exit(1)\n })\n}\n", "/**\n * Resident `infra-kit dev --cmux` supervisor.\n *\n * Opens ONE cmux workspace with one pane per discovered backend API app, each\n * pane running the primitive `pnpm exec infra-kit dev --app=<name>` (single-app,\n * single-process). Stays resident: on SIGINT/SIGTERM it closes the workspace\n * (reaping every pane) and exits. The pure command/layout construction lives here\n * and in {@link file://./cmux-layout.ts} so it is unit-testable without a shell.\n */\nimport * as path from 'node:path'\nimport process from 'node:process'\n\nimport { closeCmuxDevWorkspace, openCmuxDevWorkspace } from 'src/integrations/cmux'\nimport { logger } from 'src/lib/logger'\n\nimport { buildCmuxLayout } from './cmux-layout.js'\nimport type { DevServerOptions } from './dev-server.js'\nimport { discoverApiApps, findMonorepoRoot, normalizeAppInclude } from './discovery.js'\nimport type { DiscoveredApiApp } from './discovery.js'\n\n/** Build the per-pane primitive command for each app (append `--watch` when requested). */\nexport const buildPaneCommands = (appNames: string[], watch: boolean): string[] => {\n return appNames.map((name) => {\n return `pnpm exec infra-kit dev --app=${name}${watch ? ' --watch' : ''}`\n })\n}\n\n/** Discover API apps under `root`, applying the optional `--app` include filter. */\nconst selectApiApps = (root: string, include: string[] | null): DiscoveredApiApp[] => {\n const apps = discoverApiApps(root)\n\n if (!include) {\n return apps\n }\n\n return apps.filter((app) => {\n return include.includes(app.name)\n })\n}\n\n/**\n * Log each app pane and the opened workspace ref. Ports are NOT shown here: each\n * pane binds a dynamic (ephemeral) port at runtime and prints its own real port \u2014\n * the supervisor cannot know it at spawn time, so a static resolved port would lie.\n */\nconst logDevWorkspace = (apps: DiscoveredApiApp[], ref: string): void => {\n logger.info(`\uD83E\uDDE9 Opened cmux dev workspace ${ref} with ${apps.length} pane(s):`)\n\n for (const app of apps) {\n logger.info(` \u2022 ${app.name} (infra-kit dev --app=${app.name})`)\n }\n}\n\n/**\n * Register SIGINT/SIGTERM handlers that close the workspace `ref` (once, guarded\n * against a double-fire) and then exit \u2014 this is the supervisor's whole teardown.\n */\nconst registerShutdown = (ref: string): void => {\n let shuttingDown = false\n\n const shutdown = (signal: NodeJS.Signals): void => {\n if (shuttingDown) return\n shuttingDown = true\n\n void (async () => {\n try {\n logger.info(`\\nReceived ${signal}, closing cmux dev workspace ${ref}...`)\n await closeCmuxDevWorkspace(ref)\n } finally {\n process.exit(0)\n }\n })()\n }\n\n process.on('SIGINT', () => {\n return shutdown('SIGINT')\n })\n process.on('SIGTERM', () => {\n return shutdown('SIGTERM')\n })\n}\n\n/**\n * Open a cmux workspace with one pane per API app, then stay resident as a\n * supervisor until a signal tears the workspace down. Falls out early (no\n * workspace) when no apps are discovered. Never returns on the happy path \u2014 it\n * owns its own SIGINT/SIGTERM handling and blocks forever otherwise.\n *\n * @example\n * // Runs until Ctrl-C; opens `pnpm exec infra-kit dev --app=<name>` per app.\n * await runCmuxDevServer({ include: null, watch: false })\n */\nexport const runCmuxDevServer = async (options: DevServerOptions): Promise<void> => {\n const root = findMonorepoRoot(process.cwd())\n const apps = selectApiApps(root, normalizeAppInclude(options.include))\n\n if (apps.length === 0) {\n logger.warn('No API apps found to run')\n\n return\n }\n\n const commands = buildPaneCommands(\n apps.map((app) => {\n return app.name\n }),\n options.watch ?? false,\n )\n const layout = buildCmuxLayout(commands)\n const title = `${path.basename(root)} dev`\n const ref = await openCmuxDevWorkspace({ cwd: root, title, layout })\n\n logDevWorkspace(apps, ref)\n registerShutdown(ref)\n\n // Stay resident until a signal fires. A never-resolving promise alone does NOT\n // keep Node's event loop alive (nothing pending \u2192 the process exits with code\n // 13, \"unsettled top-level await\"); a ref'd heartbeat timer holds it open. The\n // SIGINT/SIGTERM handler in registerShutdown owns the actual exit.\n const heartbeat = setInterval(() => {\n heartbeat.refresh()\n }, 2 ** 30)\n\n await new Promise<never>(() => {})\n}\n", "/**\n * Pure cmux layout construction for `infra-kit dev --cmux`.\n *\n * Turns a flat list of per-pane shell commands into the recursive binary-tree\n * layout JSON cmux's `new-workspace --layout` consumes. Side-effect free (no fs,\n * no cwd, no shell) so the tiling math stays unit-testable in isolation.\n */\n\n/** A single terminal surface inside a pane, running one shell command. */\nexport interface CmuxTerminalSurface {\n type: 'terminal'\n command: string\n}\n\n/** A leaf node: one pane holding one or more terminal surfaces. */\nexport interface CmuxPaneLeaf {\n pane: {\n surfaces: CmuxTerminalSurface[]\n }\n}\n\n/** An internal node: a horizontal/vertical split into exactly two children. */\nexport interface CmuxSplitNode {\n direction: 'horizontal' | 'vertical'\n split: number\n children: [CmuxLayoutNode, CmuxLayoutNode]\n}\n\n/** Either a pane leaf or a two-way split \u2014 the recursive layout tree. */\nexport type CmuxLayoutNode = CmuxPaneLeaf | CmuxSplitNode\n\n/** Wrap a single command in a bare pane leaf. */\nconst makeLeaf = (command: string): CmuxPaneLeaf => {\n return { pane: { surfaces: [{ type: 'terminal', command }] } }\n}\n\n/**\n * Recursively split `commands` into a balanced binary tree: the left half takes\n * `Math.ceil(n / 2)` commands, the split ratio is that count over the total\n * (2-decimal), and the direction alternates by depth (even \u2192 horizontal,\n * odd \u2192 vertical) so panes tile into a grid rather than one axis.\n */\nconst buildNode = (commands: string[], depth: number): CmuxLayoutNode => {\n if (commands.length === 1) {\n return makeLeaf(commands[0]!)\n }\n\n const leftCount = Math.ceil(commands.length / 2)\n const left = commands.slice(0, leftCount)\n const right = commands.slice(leftCount)\n\n return {\n direction: depth % 2 === 0 ? 'horizontal' : 'vertical',\n split: Math.round((leftCount / commands.length) * 100) / 100,\n children: [buildNode(left, depth + 1), buildNode(right, depth + 1)],\n }\n}\n\n/**\n * Build a balanced cmux layout tree with one pane leaf per command. A single\n * command yields a bare leaf; N commands tile into a grid via alternating\n * horizontal/vertical splits. Throws when `commands` is empty.\n *\n * @example\n * buildCmuxLayout(['a', 'b'])\n * // => {\n * // direction: 'horizontal',\n * // split: 0.5,\n * // children: [\n * // { pane: { surfaces: [{ type: 'terminal', command: 'a' }] } },\n * // { pane: { surfaces: [{ type: 'terminal', command: 'b' }] } },\n * // ],\n * // }\n */\nexport const buildCmuxLayout = (commands: string[]): CmuxLayoutNode => {\n if (commands.length === 0) {\n throw new Error('buildCmuxLayout: at least one command is required')\n }\n\n return buildNode(commands, 0)\n}\n", "/**\n * Unified Development Server Runner\n *\n * Discovers and runs API apps under each `apps/<app>/api` folder that contains `serverless.yml`.\n *\n * Ports: `{APP}_PORT`, then `process.env.PORT`, then `dev.<app>.port` from infra-kit.json,\n * else 3010. URL prefix: `dev.<app>.prefixUrl`, else `/api/v1`.\n * Env vars should be provided via secrets manager (e.g. `doppler run -- pnpm dev-server`) or shell.\n *\n * This module is side-effect free on import: call `run()` (or construct `DevServerRunner`\n * directly) to start. Signal handling and process exit are the entry point's responsibility.\n *\n * Runner messages append to `<cwd>/.infra-kit/dev-server.log`. Lambda / Powertools logs from\n * handlers go to stdout.\n */\nimport chokidar from 'chokidar'\nimport type { FSWatcher } from 'chokidar'\nimport { exec, execFileSync } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport process from 'node:process'\nimport util from 'node:util'\n\nimport type { DevConfig, DevPreset, DevPresets } from 'src/lib/infra-kit-config'\nimport { getInfraKitConfig } from 'src/lib/infra-kit-config'\nimport { slugifyRelease } from 'src/lib/release-slug'\n\nimport { buildClosureMap, packageDebounceKey, selectPackageRestartTargets } from './dep-closure.js'\nimport type { ClosureMap, DryRunner } from './dep-closure.js'\nimport {\n classifyDistChange,\n discoverApiApps as discoverApiAppsBare,\n discoverUiApps as discoverUiAppsBare,\n findMonorepoRoot,\n getAppDistDirs,\n getPackageDistDirs,\n normalizeAppInclude as normalizeAppIncludePure,\n} from './discovery.js'\nimport type { DiscoveredUiApp } from './discovery.js'\nimport {\n findPortConflicts,\n resolvePreferredPort as resolvePreferredPortPure,\n resolvePrefixUrl as resolvePrefixUrlPure,\n} from './ports.js'\nimport { resolvePreset } from './presets.js'\nimport { ServerlessLocalRun } from './serverless-local-run.js'\nimport { defaultTurboWatchFactory } from './turbo-watch.js'\nimport type { TurboWatchFactory, TurboWatchHandle } from './turbo-watch.js'\nimport { defaultUiDevFactory } from './ui-dev.js'\nimport type { UiDevFactory, UiDevHandle } from './ui-dev.js'\n\n/** Runner-only log file, resolved under the consumer repo's `.infra-kit/` dir at startup. */\nlet LOG_FILE_PATH = path.join(process.cwd(), '.infra-kit', 'dev-server.log')\n\n/** When false (default), boot-narration steps are suppressed from the terminal but still written to the log file. Set from `--verbose`. */\nlet VERBOSE = false\n\n/** Resolve `<cwd>/.infra-kit/dev-server.log`, ensure the dir exists, and clear the file. */\nfunction initLogFile(): void {\n LOG_FILE_PATH = path.join(process.cwd(), '.infra-kit', 'dev-server.log')\n fs.mkdirSync(path.dirname(LOG_FILE_PATH), { recursive: true })\n fs.writeFileSync(LOG_FILE_PATH, `=== Dev Server Started: ${new Date().toISOString()} ===\\n\\n`)\n}\n\nconst execFn = util.promisify(exec)\n\ntype LogFn = (msg: string, level?: 'info' | 'warn' | 'error' | 'debug') => void\n\n/**\n * Build seam: shells out to turbo by default ({@link launchScript}); injectable so\n * tests can run the orchestrator without a real build. `logFn` is optional so both\n * the verbose initial build and the terse restart builds keep their current output.\n */\nexport type BuildRunner = (cmd: string, logFn?: LogFn) => Promise<void>\n\nconst launchScript = async (script: string, logFn?: LogFn): Promise<void> => {\n try {\n const { stderr } = await execFn(script)\n\n if (stderr && logFn) logFn(` (build) ${stderr.trim()}`, 'debug')\n if (stderr && !logFn) console.error('stderr:', stderr)\n } catch (error) {\n const err = error as { stdout?: string; stderr?: string; message?: string }\n\n if (logFn && (err.stdout || err.stderr)) {\n if (err.stdout) logFn(` stdout: ${err.stdout.trim()}`, 'error')\n if (err.stderr) logFn(` stderr: ${err.stderr.trim()}`, 'error')\n }\n\n throw error\n }\n}\n\n/** Append raw text to the runner-only log file (the single tee-to-file seam). */\nfunction appendLogFile(text: string): void {\n fs.appendFileSync(LOG_FILE_PATH, text)\n}\n\n/** Write a message to the console (routed by level) and tee it to the log file. */\nfunction log(message: string, level: 'info' | 'warn' | 'error' | 'debug' = 'info'): void {\n if (level === 'error') {\n console.error(message)\n } else if (level === 'warn') {\n console.warn(message)\n } else if (level === 'debug') {\n // Debug chatter (dist-change ticks on every save, Doppler banner, build stderr) reaches the\n // terminal only in --verbose \u2014 otherwise it would defeat the quiet default. Always tee'd below.\n if (VERBOSE) process.stdout.write(`${message}\\n`)\n } else {\n process.stdout.write(`${message}\\n`)\n }\n\n appendLogFile(`[${new Date().toISOString()}] [${level.toUpperCase()}] ${message}\\n`)\n}\n\n/**\n * A boot-narration step: ALWAYS tee'd to the log file, but printed to the terminal ONLY when\n * `--verbose` is set. Keeps the default terminal calm while the log file stays complete.\n */\nfunction logStep(message: string): void {\n if (VERBOSE) process.stdout.write(`${message}\\n`)\n appendLogFile(`[${new Date().toISOString()}] [INFO] ${message}\\n`)\n}\n\n/** Write pre-formatted table lines to stdout and tee them to the log file. */\nfunction logTable(lines: string[]): void {\n const output = `${lines.join('\\n')}\\n`\n\n process.stdout.write(`${output}\\n`)\n appendLogFile(`${output}\\n`)\n}\n\n/** Center `s` within `width` columns (clamped, so a too-long string is never truncated). */\nfunction center(s: string, width: number): string {\n const pad = Math.max(0, width - s.length)\n const left = Math.floor(pad / 2)\n\n return `${' '.repeat(left)}${s}${' '.repeat(pad - left)}`\n}\n\n/**\n * Render a box-drawn table whose column widths are computed from the longest cell in\n * each column, so every emitted line shares one width regardless of app-name length\n * (the old fixed `padEnd` misaligned on long names). Borders are generated from the\n * same widths, so they always match the rows.\n */\nfunction renderTable(title: string, headers: string[], rows: string[][]): string[] {\n const widths = headers.map((header, i) => {\n return Math.max(\n header.length,\n ...rows.map((row) => {\n return (row[i] ?? '').length\n }),\n )\n })\n // Grow the last column if the title is wider than the columns, so the title band never clips.\n const columnsInner =\n widths.reduce((sum, w) => {\n return sum + w + 2\n }, 0) +\n (widths.length - 1)\n\n const lastIdx = widths.length - 1\n\n if (lastIdx >= 0 && title.length + 2 > columnsInner) {\n widths[lastIdx] = (widths[lastIdx] ?? 0) + (title.length + 2 - columnsInner)\n }\n\n const inner =\n widths.reduce((sum, w) => {\n return sum + w + 2\n }, 0) +\n (widths.length - 1)\n const blocks = widths.map((w) => {\n return '\u2500'.repeat(w + 2)\n })\n const rowLine = (cells: string[]): string => {\n return `\u2502 ${cells\n .map((c, i) => {\n return (c ?? '').padEnd(widths[i]!)\n })\n .join(' \u2502 ')} \u2502`\n }\n\n return [\n '',\n `\u250C${'\u2500'.repeat(inner)}\u2510`,\n `\u2502${center(title, inner)}\u2502`,\n `\u251C${blocks.join('\u252C')}\u2524`,\n rowLine(headers),\n `\u251C${blocks.join('\u253C')}\u2524`,\n ...rows.map(rowLine),\n `\u2514${blocks.join('\u2534')}\u2518`,\n '',\n ]\n}\n\ninterface IApiAppConfig {\n /** App folder name (e.g. backoffice, client) */\n name: string\n /** Package name from package.json (e.g. sls-trvl-client) */\n packageName: string\n path: string\n /**\n * EXPLICITLY-configured preferred port (`{APP}_PORT`/`PORT`/`dev.<app>.port`), or\n * `undefined` when unconfigured. Under dynamic allocation this is only a bind hint \u2014 the\n * ACTUAL port is the ephemeral one bound at start time (see {@link IAppServer.boundPort}).\n */\n preferredPort: number | undefined\n prefixUrl: string\n /**\n * Whether this backend participates in dependency-closure watching (plan Phase 1): in\n * `--watch`, a rebuild of a package in this app's closure restarts it. Default `true`;\n * a preset `watchDeps: false` opts out (sticky). Resolved from the preset in {@link run}.\n */\n watchDeps: boolean\n}\n\n/**\n * Runner options, parsed by the CLI entry point (`--watch`, `--app`) and threaded\n * through `run()`. The entry owns flag parsing; the runner never reads `process.argv`\n * itself. App selection is `--app` only; ports come from env/config (see `resolvePort`).\n */\nexport interface DevServerOptions {\n /**\n * Watch mode: start a long-lived `turbo watch build` engine (incremental rebuilds\n * + dependency fan-out) and restart the affected server(s) when compiled `dist/`\n * changes. Without it, `dev` builds and serves once and exits on signal.\n */\n watch?: boolean\n /** Only run these app folder names (null/empty = all discovered). Filters BOTH api and ui apps. */\n include?: string[] | null\n /**\n * Named dev preset (`infra-kit dev <preset>`) from `devPresets` in the project's infra-kit config.\n * It selects the launch targets (`apps/<app>/{api,ui}`); resolved by {@link file://./presets.ts}.\n * Unset \u2192 run everything (`*`). `include` (`--app`/`--self`) further narrows the resolved set.\n */\n preset?: string\n /**\n * Run each discovered API app in its own cmux pane (one workspace, N panes), supervised by a\n * resident process that closes the workspace on signal. Falls back to single-process dev when\n * cmux is absent. Handled by `runCmuxDevServer`, not the in-process `DevServerRunner`.\n */\n cmux?: boolean\n /**\n * Infer the single app to run from the current working directory (equivalent to\n * `--app=<that app>`), so every app can share the identical script\n * `pnpm exec infra-kit dev --self` instead of hardcoding its own folder name.\n * Resolved by the entry point (`resolveSelfAppName`) into `include` before this\n * runner ever sees it; the runner itself does not read `self`.\n */\n self?: boolean\n /**\n * Print the full boot narration (build/discovery/watch steps) to the terminal. Default false:\n * the terminal shows only the server panel, warnings, errors, and restart lines. The FULL detail\n * is written to `.infra-kit/dev-server.log` regardless of this flag.\n */\n verbose?: boolean\n}\n\ninterface IAppServer {\n app: IApiAppConfig\n server: ServerlessLocalRun\n /** The ACTUAL port bound at start (ephemeral or preferred), reported by `server.start()`. */\n boundPort: number\n}\n\n/**\n * One `.infra-kit/dev-context/<app>.json` fragment. `package` (feeds the vite helper's\n * `readLocalSet`) is the app's package name; `port` is the ACTUAL bound port (the writer\n * IS the binder). `release` lets the helper prefer the runner-recorded slug over its own\n * git derivation; `pid`/`writtenAt` are staleness metadata.\n */\ninterface DevContextFragment {\n package: string\n port: number\n pid: number\n writtenAt: number\n release?: string\n}\n\n/**\n * Slugified `<release>` for the app's git branch (resolved from the app's own dir), or\n * `undefined` outside a git repo / on an empty slug. Never throws \u2014 a missing repo just\n * omits the recorded slug, and the vite helper falls back to its own git derivation.\n */\nconst readAppRelease = (cwd: string): string | undefined => {\n try {\n // eslint-disable-next-line sonarjs/no-os-command-from-path\n const branch = execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd, encoding: 'utf-8' }).trim()\n const slug = slugifyRelease(branch)\n\n return slug === '' ? undefined : slug\n } catch {\n return undefined\n }\n}\n\nexport class DevServerRunner {\n private readonly monorepoRoot: string\n /**\n * `<cwd>/.infra-kit/dev-context` \u2014 the fragment directory this runner writes its own\n * per-app `<app>.json` into (mirrors {@link LOG_FILE_PATH}'s cwd-relative resolution). The\n * `infra-kit/vite` helper searches up-tree for this dir and merges the fragments.\n */\n private readonly devContextDir: string\n private readonly appServers: IAppServer[] = []\n private watchDebounceTimers: Map<string, ReturnType<typeof setTimeout>> = new Map()\n /** Active chokidar watcher in `--watch` mode; closed on {@link shutdown}. */\n private watcher: FSWatcher | null = null\n private static readonly WATCH_DEBOUNCE_MS = 400\n /** Serialized restarts so rapid saves never bind :port while the previous server is still shutting down. */\n private restartWorkChain: Promise<void> = Promise.resolve()\n private static readonly PORT_RELEASE_DELAY_MS = 200\n private readonly options: DevServerOptions\n /** Build runner seam \u2014 real turbo shell-out by default, injectable for tests. */\n private readonly runBuild: BuildRunner\n /** `turbo watch` spawn seam \u2014 real detached child by default, injectable for tests. */\n private readonly turboWatchFactory: TurboWatchFactory\n /** Live `turbo watch` engine in `--watch` mode; reaped on {@link shutdown}. */\n private turboWatch: TurboWatchHandle | null = null\n /** `turbo run dev` (frontends) spawn seam \u2014 real detached child by default, injectable for tests. */\n private readonly uiDevFactory: UiDevFactory\n /** Live `turbo run dev` frontend engine in `--ui` mode; reaped on {@link shutdown}. */\n private uiDev: UiDevHandle | null = null\n /** `turbo --dry` closure-source seam \u2014 real turbo (via {@link buildClosureMap}'s default) unless injected for tests. */\n private readonly dryRunner: DryRunner | undefined\n\n constructor(\n options: DevServerOptions = {},\n runBuild: BuildRunner = launchScript,\n turboWatchFactory: TurboWatchFactory = defaultTurboWatchFactory,\n uiDevFactory: UiDevFactory = defaultUiDevFactory,\n dryRunner?: DryRunner,\n ) {\n this.options = options\n this.runBuild = runBuild\n this.turboWatchFactory = turboWatchFactory\n this.uiDevFactory = uiDevFactory\n this.dryRunner = dryRunner\n initLogFile()\n VERBOSE = this.options.verbose ?? false\n this.devContextDir = path.join(process.cwd(), '.infra-kit', 'dev-context')\n\n // Walk up from the consumer repo cwd to the monorepo root.\n this.monorepoRoot = findMonorepoRoot(process.cwd())\n logStep(`Monorepo root: ${this.monorepoRoot}`)\n\n if (process.env.DOPPLER_PROJECT != null || process.env.DOPPLER_ENVIRONMENT != null) {\n log('\uD83D\uDD10 Doppler env detected (DOPPLER_PROJECT / DOPPLER_ENVIRONMENT)', 'debug')\n }\n }\n\n /**\n * Discover API apps and resolve each app's port + URL prefix. Delegates bare\n * filesystem discovery to {@link discoverApiAppsBare} and per-app resolution to\n * the pure `resolvePort` / `resolvePrefixUrl`, preserving the original behavior.\n */\n private discoverApiApps(devConfig: DevConfig): IApiAppConfig[] {\n return discoverApiAppsBare(this.monorepoRoot).map((app) => {\n return {\n ...app,\n preferredPort: this.resolvePreferredPort(app.name, devConfig),\n prefixUrl: this.resolvePrefixUrl(app.name, devConfig),\n // Default participate; the resolved preset value overrides this in `run()`.\n watchDeps: true,\n }\n })\n }\n\n /**\n * Read the `dev` section from the resolved infra-kit config. Defensive: any\n * failure (not in an infra-kit project, missing/invalid config) resolves to an\n * empty map so the dev-server always falls back to env vars + built-in defaults\n * rather than refusing to start.\n */\n private async loadDevConfig(): Promise<DevConfig> {\n try {\n const config = await getInfraKitConfig()\n\n return config.dev ?? {}\n } catch {\n return {}\n }\n }\n\n /** Thin delegator to the pure {@link normalizeAppIncludePure} over the runner's `--app` list. */\n private normalizeAppInclude(): string[] | null {\n return normalizeAppIncludePure(this.options.include)\n }\n\n /** Thin delegator to the pure {@link resolvePreferredPortPure}, threading env + config. */\n private resolvePreferredPort(appName: string, devConfig: DevConfig): number | undefined {\n return resolvePreferredPortPure(appName, process.env, devConfig)\n }\n\n /** Thin delegator to the pure {@link resolvePrefixUrlPure}. */\n private resolvePrefixUrl(appName: string, devConfig: DevConfig): string {\n return resolvePrefixUrlPure(appName, devConfig)\n }\n\n /** Load the top-level `devPresets` map from the resolved infra-kit config (defensive: `{}` on failure). */\n private async loadDevPresets(): Promise<DevPresets> {\n try {\n return (await getInfraKitConfig()).devPresets ?? {}\n } catch {\n return {}\n }\n }\n\n /**\n * The preset definition to run: the named preset (`infra-kit dev <preset>`; throws with the\n * available names when unknown), or a default `{ apps: { '*': {} } }` (every discovered app +\n * part) when no preset was given.\n */\n private resolvePresetDef(devPresets: DevPresets): DevPreset {\n const name = this.options.preset\n\n if (name == null) {\n return { apps: { '*': {} } }\n }\n\n const def = devPresets[name]\n\n if (!def) {\n const available = Object.keys(devPresets)\n\n throw new Error(\n `Unknown dev preset \"${name}\". Available: ${available.length > 0 ? available.join(', ') : '(none defined in devPresets)'}`,\n )\n }\n\n return def\n }\n\n public async start(): Promise<void> {\n const include = this.normalizeAppInclude()\n const watch = this.options.watch ?? false\n const devConfig = await this.loadDevConfig()\n\n process.env.POWERTOOLS_DEV ??= 'true'\n process.env.LOG_LEVEL ??= 'DEBUG'\n\n logStep('\uD83D\uDE80 Starting Development Server Runner')\n\n if (watch) {\n logStep('\uD83D\uDC40 Watch mode: will rebuild and restart on file save')\n }\n logStep(`\uD83D\uDCC2 Monorepo root: ${this.monorepoRoot}`)\n\n // What to run is a named preset (`infra-kit dev <preset>`), resolved against the discovered app\n // parts (api/ui). No preset \u2192 run everything (`*`). `--app`/`--self` (`include`) further narrow it.\n const apiAppsAll = this.discoverApiApps(devConfig)\n const uiAppsAll = discoverUiAppsBare(this.monorepoRoot)\n const resolved = resolvePreset(this.resolvePresetDef(await this.loadDevPresets()), {\n api: apiAppsAll.map((a) => {\n return a.name\n }),\n ui: uiAppsAll.map((a) => {\n return a.name\n }),\n })\n\n if (resolved.unmatched.length > 0) {\n log(`\u26A0\uFE0F Preset targets not found (skipped): ${resolved.unmatched.join(', ')}`, 'warn')\n }\n\n const apiNames = new Set(\n resolved.targets\n .filter((t) => {\n return t.part === 'api'\n })\n .map((t) => {\n return t.app\n }),\n )\n const uiNames = new Set(\n resolved.targets\n .filter((t) => {\n return t.part === 'ui'\n })\n .map((t) => {\n return t.app\n }),\n )\n const passesInclude = (name: string): boolean => {\n return !include || include.includes(name)\n }\n const watchDepsByApp = new Map(\n resolved.targets\n .filter((t) => {\n return t.part === 'api'\n })\n .map((t) => {\n return [t.app, t.watchDeps] as const\n }),\n )\n const apps = apiAppsAll\n .filter((a) => {\n return apiNames.has(a.name) && passesInclude(a.name)\n })\n .map((a) => {\n return { ...a, watchDeps: watchDepsByApp.get(a.name) ?? a.watchDeps }\n })\n const uiApps = uiAppsAll.filter((a) => {\n return uiNames.has(a.name) && passesInclude(a.name)\n })\n\n if (apps.length === 0 && uiApps.length === 0) {\n log('\u26A0\uFE0F No API or UI apps to run for this preset', 'warn')\n\n return\n }\n\n // Build the API boot closure (dist must exist before servers import handlers).\n if (apps.length > 0) {\n logStep(\n `\uD83D\uDCE6 Discovered ${apps.length} API app(s): ${apps\n .map((a) => {\n return a.name\n })\n .join(', ')}`,\n )\n this.assertNoPortConflicts(apps)\n await this.buildApps(apps, watch)\n }\n\n // Warm the UI dependency closure BEFORE spawning any persistent child (turbo watch / turbo run\n // dev), so both see a warm cache and the cold-cache double-build race can't corrupt shared dist.\n if (uiApps.length > 0) {\n await this.buildUiApps(uiApps)\n }\n\n if (apps.length > 0) {\n await this.startAllApps(apps)\n logStep('\uD83C\uDF89 All servers started!')\n this.printServerTable()\n this.printRouteDump()\n logStep(\n `\uD83D\uDCDD Handler logs (AWS Powertools, logger.info/debug, etc.) \u2192 this terminal. Runner-only file: ${LOG_FILE_PATH}`,\n )\n }\n\n // Start the watch engine when there's anything to rebuild \u2014 backends OR frontends. A UI-only\n // session (no API app) still needs the engine so a shared-lib edit rebuilds its dist and vite reloads.\n if (watch && (this.appServers.length > 0 || uiApps.length > 0)) {\n const closureMap = await this.buildClosureMapSafe(apps)\n\n this.setupWatch(apps, uiApps, closureMap)\n }\n\n // Frontends last: their delegated `turbo run dev` streams raw to the terminal below the BE table.\n if (uiApps.length > 0) {\n this.startUiDev(uiApps)\n }\n }\n\n /**\n * Warm ONLY each UI's dependency closure (`<pkg>^...` \u2014 deps, excluding the UI itself, so no full\n * production `vite build`) with a cache-friendly (non-`--force`) turbo build. Non-fatal: if it\n * fails, `turbo run dev`'s own `^build` retries and surfaces the error in its streamed output.\n */\n private async buildUiApps(uiApps: DiscoveredUiApp[]): Promise<void> {\n const filters = uiApps\n .map((a) => {\n return `--filter=${a.packageName}^...`\n })\n .join(' ')\n\n logStep('\uD83D\uDD28 Warming UI dependency build cache (turbo)...')\n try {\n await this.runBuild(`pnpm exec turbo run build ${filters} --env-mode=loose`, log)\n logStep('\u2705 UI deps built')\n } catch (error) {\n log(`\u26A0\uFE0F UI dep warm build failed (continuing; turbo run dev will build): ${String(error)}`, 'warn')\n }\n }\n\n /**\n * Start the frontends via ONE delegated `turbo run dev` child (streamed to the terminal). Reaped\n * on {@link shutdown}. Concurrency \u2265 the persistent UI `dev` task count (turbo hard-errors otherwise).\n */\n private startUiDev(uiApps: DiscoveredUiApp[]): void {\n const names = uiApps\n .map((a) => {\n return a.name\n })\n .join(', ')\n\n logStep(`\uD83C\uDFA8 Starting ${uiApps.length} UI dev server(s) via \\`turbo run dev\\`: ${names}`)\n logStep(' (framework dev output streams below; each prints its own local URL)')\n\n this.uiDev = this.uiDevFactory({\n packageNames: uiApps.map((a) => {\n return a.packageName\n }),\n cwd: process.cwd(),\n concurrency: Math.max(uiApps.length + 4, 12),\n })\n }\n\n /** Render an app list as `name:port, name:port` for log lines. */\n private formatAppList(apps: Array<{ name: string; port: number }>): string {\n return apps\n .map((a) => {\n return `${a.name}:${a.port}`\n })\n .join(', ')\n }\n\n /**\n * Throw (after logging remediation tips) when two apps are EXPLICITLY pinned to the same\n * port. Apps with no explicit port bind an ephemeral `listen(0)` port each (collision-free\n * by construction), so they are excluded from the gate \u2014 otherwise the default multi-app\n * run would false-throw on the shared `DEFAULT_PORT` before dynamic allocation de-conflicts.\n */\n private assertNoPortConflicts(apps: IApiAppConfig[]): void {\n const explicitApps = apps\n .filter((app) => {\n return app.preferredPort != null\n })\n .map((app) => {\n return { name: app.name, port: app.preferredPort! }\n })\n const { duplicatePorts, conflictingApps } = findPortConflicts(explicitApps)\n\n if (duplicatePorts.length === 0) {\n return\n }\n\n log(`\u26A0\uFE0F Port conflict detected! ${duplicatePorts.join(', ')}`, 'error')\n log(`Conflicting apps: ${this.formatAppList(conflictingApps)}`, 'error')\n log('\\n\uD83D\uDCA1 Tip: give each app a distinct port via `{APP}_PORT` env (e.g. `CLIENT_PORT=`,', 'error')\n log(' `SEARCH_ENGINE_PORT=`) or `dev.<app>.port` in infra-kit.json; or run a subset with', 'error')\n log(' `--app=<name>,<name>`.\\n', 'error')\n throw new Error(`Port conflict detected: ${duplicatePorts.join(', ')}`)\n }\n\n /** Build every app via turbo; rethrows the build error after logging stdout/stderr. */\n private async buildApps(apps: IApiAppConfig[], watch: boolean): Promise<void> {\n const filters = apps\n .map((a) => {\n return `--filter=${a.packageName}`\n })\n .join(' ')\n // With `--watch`, always bypass Turbo cache so `tsc` runs and `dist/` matches disk (otherwise watch restarts can be no-ops).\n const buildCmd = `pnpm exec turbo run build ${filters} --env-mode=loose${watch ? ' --force' : ''}`\n\n logStep('\uD83D\uDD28 Building API apps (turbo)...')\n try {\n await this.runBuild(buildCmd, log)\n logStep('\u2705 Build complete')\n } catch (buildError) {\n log(`\u274C Build failed: ${String(buildError)}`, 'error')\n if (buildError instanceof Error && buildError.message) {\n log(` ${buildError.message}`, 'error')\n }\n const err = buildError as { stdout?: string; stderr?: string }\n\n if (err.stdout) log(` stdout: ${err.stdout.trim()}`, 'error')\n if (err.stderr) log(` stderr: ${err.stderr.trim()}`, 'error')\n throw buildError\n }\n }\n\n /**\n * Start every app concurrently, collecting the ones that boot; per-app failures are logged,\n * not fatal. Safe to parallelize because each app has a distinct port (guarded up-front) and a\n * distinct `ServerlessLocalRun`, and `startOneApp` no longer mutates cwd. Push order into\n * `appServers` is non-deterministic but nothing depends on it (the table renders from `apps`).\n */\n private async startAllApps(apps: IApiAppConfig[]): Promise<void> {\n await Promise.all(\n apps.map(async (app) => {\n try {\n const started = await this.startOneApp(app)\n\n if (started) {\n this.appServers.push({ app, ...started })\n }\n } catch (error) {\n log(`\u274C Failed to start ${app.name}: ${String(error)}`, 'error')\n }\n }),\n )\n }\n\n private async startOneApp(app: IApiAppConfig): Promise<{ server: ServerlessLocalRun; boundPort: number } | null> {\n logStep(`\uD83D\uDD04 Starting ${app.name}...`)\n\n // No `process.chdir` here: `ServerlessLocalRun` reads `serverless.yml` and imports the\n // compiled handler from `controllersPath` (absolute), so the runner never mutates cwd \u2014\n // which is what makes concurrent boot/restart safe.\n const server = new ServerlessLocalRun({\n controllersPath: app.path,\n prefixUrl: app.prefixUrl,\n port: app.preferredPort,\n appName: app.name,\n })\n\n // `start()` binds an ephemeral (or preferred-then-ephemeral) port and RETURNS the actual\n // one \u2014 consume THAT, never the static preferred hint, so the log/table/health agree.\n const boundPort = await server.start()\n\n // Record the ACTUAL bound port in this runner's own dev-context fragment. Inside startOneApp\n // (the shared start+restart path) so a watch-restart refreshes the port instead of orphaning\n // a stale fragment (M2). Non-fatal: a fragment-write failure must not down the server.\n try {\n this.writeDevContextFragment(app, boundPort)\n } catch (error) {\n log(`\u26A0\uFE0F Failed to write dev-context fragment for ${app.name}: ${String(error)}`, 'warn')\n }\n\n logStep(`\u2705 ${app.name} started on port ${boundPort}`)\n\n return { server, boundPort }\n }\n\n /**\n * Atomically write this runner's `.infra-kit/dev-context/<app>.json` fragment recording the\n * ACTUAL bound port (REV-5: serialize to a same-dir temp file, then `renameSync` into place, so a\n * concurrent reader \u2014 the vite helper's directory merge \u2014 never observes torn JSON). Each runner\n * writes ONLY its own app's fragment, so cmux panes never clobber each other.\n */\n private writeDevContextFragment(app: IApiAppConfig, boundPort: number): void {\n const release = readAppRelease(app.path)\n const fragment: DevContextFragment = {\n package: app.packageName,\n port: boundPort,\n pid: process.pid,\n writtenAt: Date.now(),\n ...(release ? { release } : {}),\n }\n const target = path.join(this.devContextDir, `${app.name}.json`)\n const tmp = path.join(this.devContextDir, `${app.name}.json.${process.pid}.tmp`)\n\n fs.mkdirSync(this.devContextDir, { recursive: true })\n fs.writeFileSync(tmp, JSON.stringify(fragment, null, 2))\n fs.renameSync(tmp, target)\n }\n\n /** Remove THIS runner's own `<app>.json` fragment on shutdown (never another runner's). */\n private removeDevContextFragment(app: IApiAppConfig): void {\n fs.rmSync(path.join(this.devContextDir, `${app.name}.json`), { force: true })\n }\n\n /** Run restart jobs one after another (watch can fire faster than close + listen). */\n private scheduleRestartWork(work: () => Promise<void>): Promise<void> {\n const run = this.restartWorkChain.then(\n () => {\n return work()\n },\n () => {\n return work()\n },\n )\n\n this.restartWorkChain = run.catch(() => {})\n\n return run\n }\n\n private async delayPortRelease(): Promise<void> {\n await new Promise((r) => {\n return setTimeout(r, DevServerRunner.PORT_RELEASE_DELAY_MS)\n })\n }\n\n /**\n * Schedule a restart of the given apps (1 or N), serialized against other restarts via\n * {@link scheduleRestartWork}. A single-app dist change passes `[app]`; a dependency-package\n * dist change passes every running app. The `turbo watch` engine has already rebuilt `dist/`,\n * so the runner only bounces the fastify server(s) \u2014 no build here.\n */\n private restart(apps: IApiAppConfig[]): Promise<void> {\n return this.scheduleRestartWork(() => {\n return this.runRestart(apps)\n })\n }\n\n /** Resolve the requested apps to their live server slots (dropping any not running). */\n private resolveRestartTargets(apps: IApiAppConfig[]): Array<{ idx: number; app: IApiAppConfig }> {\n return apps\n .map((app) => {\n return {\n idx: this.appServers.findIndex((e) => {\n return e.app.name === app.name\n }),\n app,\n }\n })\n .filter((t) => {\n return t.idx >= 0\n })\n }\n\n private async runRestart(apps: IApiAppConfig[]): Promise<void> {\n const targets = this.resolveRestartTargets(apps)\n\n if (targets.length === 0) return\n\n const label = targets.length === 1 ? targets[0]!.app.name : `${targets.length} apps`\n\n log(`\uD83D\uDD04 Restarting ${label}...`)\n await Promise.all(\n targets.map(async ({ idx }) => {\n try {\n await this.appServers[idx]!.server.close()\n } catch (err) {\n log(` Close warning: ${String(err)}`, 'debug')\n }\n }),\n )\n\n await this.delayPortRelease()\n\n await Promise.all(\n targets.map(async ({ idx, app }) => {\n try {\n const restarted = await this.startOneApp(app)\n\n if (restarted) {\n this.appServers[idx] = { app, ...restarted }\n }\n } catch (error) {\n log(`\u274C Failed to restart ${app.name}: ${String(error)}`, 'error')\n }\n }),\n )\n // Show each restarted app's CURRENT bound port: an ephemeral-port app rebinds a fresh port on\n // restart, and the server table is printed only once at boot \u2014 so this line is the only place the\n // new port surfaces in the default (quiet) terminal.\n const restartedSummary = targets\n .map((t) => {\n const entry = this.appServers[t.idx]\n\n return entry ? `${t.app.name}:${entry.boundPort}` : t.app.name\n })\n .join(', ')\n\n log(`\u2705 Restarted ${restartedSummary}`)\n }\n\n /**\n * Build the dependency-closure map ({@link buildClosureMap}) for scoped restarts, or `null` on\n * failure (a `turbo --dry` spawn/parse error). `null` is the fail-safe signal: {@link setupWatch}\n * then restarts every launched app on a package change, exactly as it did before scoping \u2014 never\n * a silent dropped restart.\n */\n private async buildClosureMapSafe(apps: IApiAppConfig[]): Promise<ClosureMap | null> {\n try {\n return await buildClosureMap(this.monorepoRoot, apps, this.dryRunner)\n } catch (err) {\n log(`\u26A0\uFE0F Dependency-closure map unavailable (${String(err)}); package changes restart all apps`, 'warn')\n\n return null\n }\n }\n\n /**\n * Start the long-lived `turbo watch build` engine, then watch compiled `dist/` output to\n * trigger restarts. A change under an app's `dist` restarts that app; a change under a\n * `packages/<pkg>/dist` restarts only the participating backends whose dependency closure\n * includes that package ({@link selectPackageRestartTargets}), keyed per package dir so unrelated\n * packages don't collapse into one debounce bucket. When the closure map is unavailable\n * (`null`) it falls back to restarting every launched app (fail-safe superset). Restarts are\n * build-less \u2014 the engine already rebuilt `dist/`.\n */\n private setupWatch(apps: IApiAppConfig[], uiApps: DiscoveredUiApp[], closureMap: ClosureMap | null): void {\n this.turboWatch = this.turboWatchFactory({\n // API apps: dep-inclusive (`...<pkg>`) \u2014 rebuild the backend + its shared-lib closure and restart it.\n depInclusive: apps.map((a) => {\n return a.packageName\n }),\n // UI apps: dep-closure-only (`<pkg>^...`) \u2014 rebuild the frontend's shared libs (so vite reloads on a\n // FE-only lib edit) WITHOUT production-building the UI; vite owns the UI's own live reload.\n depClosure: uiApps.map((a) => {\n return a.packageName\n }),\n cwd: process.cwd(),\n logFile: LOG_FILE_PATH,\n })\n logStep('\uD83D\uDC40 Watch mode: started `turbo watch build` engine; watching dist output')\n\n const appDistDirs = getAppDistDirs(apps)\n const packageDistDirs = getPackageDistDirs(this.monorepoRoot)\n const allDistDirs = [...appDistDirs, ...packageDistDirs]\n\n if (allDistDirs.length === 0) {\n log('\u26A0\uFE0F No app or package dist directories found to watch (were they built?)', 'warn')\n\n return\n }\n\n const usePoll = process.env.DEV_SERVER_CHOKIDAR_POLL === '1'\n\n const watcher = chokidar.watch(allDistDirs, {\n ignoreInitial: true,\n awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 100 },\n // Ignore tsc's incremental bookkeeping + sourcemaps: they rewrite on every build\n // (even content-identical ones) and would bounce fastify onto no real change.\n ignored: (p: string): boolean => {\n return p.endsWith('.tsbuildinfo') || p.endsWith('.map')\n },\n ...(usePoll ? { usePolling: true, interval: 400 } : {}),\n })\n\n this.watcher = watcher\n\n if (usePoll) {\n log('\uD83D\uDC40 chokidar: usePolling enabled (DEV_SERVER_CHOKIDAR_POLL=1)', 'debug')\n }\n\n watcher.on('change', (filePath: string) => {\n log(`\uD83D\uDC40 dist change detected: ${filePath}`, 'debug')\n\n const change = classifyDistChange(filePath, appDistDirs, packageDistDirs)\n\n if (change.kind === 'package') {\n const targets = selectPackageRestartTargets(apps, closureMap, change.packageDir)\n\n if (targets === null) {\n // Fail-safe: no closure map / no package identity \u2192 restart every launched app. Note this\n // ignores per-app `watchDeps: false` opt-outs \u2014 opt-out is best-effort and yields to the\n // fail-safe superset, so a `turbo --dry` failure never silently drops a needed restart.\n this.scheduleDebounced('__packages__', () => {\n return this.restart(apps)\n })\n\n return\n }\n\n // Empty target set = the package is UI-only or every dependent opted out \u2192 no restart.\n // The `packageDir !== undefined` check narrows it to `string` for `packageDebounceKey`;\n // it is always defined here (a non-null `targets` implies a matched package identity).\n if (targets.length > 0 && change.packageDir !== undefined) {\n this.scheduleDebounced(packageDebounceKey(change.packageDir), () => {\n return this.restart(targets)\n })\n }\n\n return\n }\n\n const app = apps.find((a) => {\n return path.join(a.path, 'dist') === change.app\n })\n\n if (!app) return\n\n this.scheduleDebounced(app.name, () => {\n return this.restart([app])\n })\n })\n\n logStep(`\uD83D\uDC40 Watching ${appDistDirs.length} app dist + ${packageDistDirs.length} package dist dir(s) for changes...`)\n }\n\n /**\n * Debounce a restart under `key`: cancel any pending timer for the same key and start\n * a fresh {@link DevServerRunner.WATCH_DEBOUNCE_MS} timer, so a burst of saves collapses\n * into one restart. Errors from the scheduled work are logged, never thrown.\n */\n private scheduleDebounced(key: string, work: () => Promise<void>): void {\n const existing = this.watchDebounceTimers.get(key)\n\n if (existing) clearTimeout(existing)\n\n const timer = setTimeout(() => {\n this.watchDebounceTimers.delete(key)\n work().catch((err) => {\n log(`Restart error (${key}): ${String(err)}`, 'error')\n })\n }, DevServerRunner.WATCH_DEBOUNCE_MS)\n\n this.watchDebounceTimers.set(key, timer)\n }\n\n /**\n * Print the running-server table. The `Base URL` column carries each app's\n * `prefixUrl` (e.g. `/api/v1`) so it is copy-pasteable \u2014 the old table showed a bare\n * `http://localhost:<port>` that 404s against prefixed handler routes. A `Health`\n * column surfaces the unprefixed `/__health` liveness URL.\n */\n private printServerTable(): void {\n const rows = this.appServers.map(({ app, boundPort }) => {\n return [\n app.name,\n String(boundPort),\n `http://localhost:${boundPort}${app.prefixUrl}`,\n `http://localhost:${boundPort}/__health`,\n ]\n })\n\n logTable(renderTable('\uD83D\uDDA5\uFE0F Running Servers', ['App', 'Port', 'Base URL', 'Health'], rows))\n }\n\n /**\n * Dump each running app's registered `METHOD /path` routes at startup so the\n * emulator is self-describing (no need to open `serverless.yml` to learn the routes).\n * Reads the live route set via {@link ServerlessLocalRun.getRegisteredRoutes}.\n */\n private printRouteDump(): void {\n if (this.appServers.length === 0) return\n\n logStep('\uD83D\uDDFA\uFE0F Registered routes:')\n for (const { app, server } of this.appServers) {\n const routes = server.getRegisteredRoutes()\n\n logStep(` ${app.name} (${routes.length}): ${routes.length > 0 ? routes.join(', ') : '(none)'}`)\n }\n }\n\n /**\n * Stop watching, cancel any pending debounced restart, and close all running servers.\n * Does not exit the process \u2014 the entry point owns exit.\n */\n public async shutdown(): Promise<void> {\n log('\uD83D\uDED1 Shutting down all servers...')\n\n // Reap the long-lived engines FIRST (group SIGTERM\u2192SIGKILL) so neither writes fresh dist nor\n // holds a port mid-teardown. Reaped here (not only in the entry signal handler) because tests\n // and any non-signal caller invoke shutdown() directly. Awaited so the SIGKILL escalation\n // completes before the entry point's `process.exit`.\n if (this.turboWatch) {\n await this.turboWatch.kill()\n this.turboWatch = null\n }\n\n if (this.uiDev) {\n await this.uiDev.kill()\n this.uiDev = null\n }\n\n for (const timer of this.watchDebounceTimers.values()) {\n clearTimeout(timer)\n }\n this.watchDebounceTimers.clear()\n\n if (this.watcher) {\n await this.watcher.close()\n this.watcher = null\n }\n\n for (const { app, server } of this.appServers) {\n try {\n await server.close()\n } catch {\n // ignore\n }\n // Remove this runner's own dev-context fragment so a stopped app drops out of the\n // helper's localSet (only its own \u2014 the directory model keeps runners independent).\n this.removeDevContextFragment(app)\n }\n logStep(`\uD83D\uDCDD Logs saved to: ${LOG_FILE_PATH}`)\n }\n}\n\n/**\n * Construct a {@link DevServerRunner}, start it, and return the instance so the caller\n * (the CLI entry point) can wire signal handlers to `shutdown()` and own process exit.\n */\nexport async function run(options: DevServerOptions = {}): Promise<DevServerRunner> {\n const runner = new DevServerRunner(options)\n\n await runner.start()\n\n return runner\n}\n", "/**\n * Dependency-closure map for scoped `infra-kit dev --watch` restarts (plan Phase 1, Option B).\n *\n * `pnpm` is resolved from PATH \u2014 the same trust posture as the rest of the dev-server, which\n * already shells out to `pnpm exec turbo \u2026`; the args are fixed literals plus discovered package\n * names, never shell-interpolated.\n *\n * Rather than re-derive the workspace graph in-process, infra-kit asks turbo what it would\n * rebuild: `turbo run build --dry=json --filter=...<pkg>` lists every package in an app's build\n * closure (`tasks[].package`). That set is authoritative \u2014 it is exactly what the running\n * `turbo watch build` engine rebuilds \u2014 so there is no drift and no glob-parser/BFS/cycle-guard\n * to maintain here. The runner inverts these per-app closures into `dependentsByPackageDir`\n * (which app folders depend on each `packages/<x>/dist`) and, on a package-dist change, restarts\n * only the dependent backends instead of every one.\n */\nimport { execFile } from 'node:child_process'\nimport * as fs from 'node:fs'\nimport * as path from 'node:path'\nimport { promisify } from 'node:util'\n\nimport { getPackageDistDirs } from './discovery.js'\n\nconst execFileAsync = promisify(execFile)\n\n/** The subset of an app's identity the closure map needs. */\nexport interface ClosureApp {\n /** App folder name (e.g. `client`) \u2014 the restart key in the dependents map. */\n name: string\n /** package.json `name` (e.g. `sls-trvl-client`) \u2014 the turbo `--filter` target. */\n packageName: string\n}\n\n/**\n * Resolve one app's build closure: the set of workspace package **names** turbo would rebuild\n * for it. Injectable so tests drive `buildClosureMap` without spawning a real turbo. A rejection\n * propagates through `Promise.all` so the caller can apply its restart-all fail-safe.\n */\nexport type DryRunner = (packageName: string) => Promise<string[]>\n\n/** The inverted closure: `packages/<x>/dist` \u2192 the app folders that depend on it, plus the dir\u2192name bridge. */\nexport interface ClosureMap {\n /** `packages/<x>/dist` absolute dir \u2192 set of app folder names whose closure includes it. */\n dependentsByPackageDir: Map<string, Set<string>>\n /** `packages/<x>/dist` absolute dir \u2192 that package's package.json `name` (dir \u2260 name for scoped pkgs). */\n packageNameByDir: Map<string, string>\n}\n\n/** Read `<dir>/package.json` `name`, or `undefined` when absent/unreadable (never throws). */\nconst readPackageName = (dir: string): string | undefined => {\n try {\n const parsed = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf-8')) as { name?: unknown }\n\n return typeof parsed.name === 'string' ? parsed.name : undefined\n } catch {\n return undefined\n }\n}\n\n/**\n * Default {@link DryRunner}: `turbo run build --dry=json --filter=...<pkg>` in `root`, returning the\n * unique `tasks[].package` set (the packages turbo would rebuild for `<pkg>`). `...` includes the\n * app's own dependency closure, mirroring the `turbo watch build` filter.\n */\nexport const defaultDryRunner = (root: string): DryRunner => {\n return async (packageName: string): Promise<string[]> => {\n const { stdout } = await execFileAsync(\n 'pnpm',\n ['exec', 'turbo', 'run', 'build', '--dry=json', `--filter=...${packageName}`],\n { cwd: root, maxBuffer: 32 * 1024 * 1024 },\n )\n const parsed = JSON.parse(stdout) as { tasks?: Array<{ package?: unknown }> }\n const names = (parsed.tasks ?? [])\n .map((t) => {\n return t.package\n })\n .filter((p): p is string => {\n return typeof p === 'string'\n })\n\n return [...new Set(names)]\n }\n}\n\n/** Build `packageNameByDir` (and its reverse) for every existing `packages/<x>/dist` under `root`. */\nconst readPackageDirs = (root: string): { packageNameByDir: Map<string, string>; dirByName: Map<string, string> } => {\n const packageNameByDir = new Map<string, string>()\n const dirByName = new Map<string, string>()\n\n for (const distDir of getPackageDistDirs(root)) {\n const name = readPackageName(path.dirname(distDir))\n\n if (name !== undefined) {\n packageNameByDir.set(distDir, name)\n dirByName.set(name, distDir)\n }\n }\n\n return { packageNameByDir, dirByName }\n}\n\n/**\n * Ask turbo for each app's build closure (in parallel) and invert it into {@link ClosureMap}:\n * `packages/<x>/dist` \u2192 the app folders whose closure includes that package. Apps' own packages\n * (not under `packages/`) simply don't appear in the map, so they never scope a package restart.\n *\n * A {@link DryRunner} rejection propagates (via `Promise.all`) so the caller falls back to\n * restart-all \u2014 the map is never silently partial.\n *\n * @example\n * // appX deps pkgA+pkgC; appY deps pkgC only \u2192\n * // dependentsByPackageDir: { '\u2026/pkgA/dist': {appX}, '\u2026/pkgC/dist': {appX, appY} }\n */\nexport const buildClosureMap = async (\n root: string,\n apps: ClosureApp[],\n dryRunner: DryRunner = defaultDryRunner(root),\n): Promise<ClosureMap> => {\n const { packageNameByDir, dirByName } = readPackageDirs(root)\n const dependentsByPackageDir = new Map<string, Set<string>>()\n\n const closures = await Promise.all(\n apps.map(async (app) => {\n return { app, closure: await dryRunner(app.packageName) }\n }),\n )\n\n for (const { app, closure } of closures) {\n for (const pkgName of closure) {\n const distDir = dirByName.get(pkgName)\n\n if (distDir === undefined) continue\n\n const dependents = dependentsByPackageDir.get(distDir) ?? new Set<string>()\n\n dependents.add(app.name)\n dependentsByPackageDir.set(distDir, dependents)\n }\n }\n\n return { dependentsByPackageDir, packageNameByDir }\n}\n\n/** Debounce key for a package-dist change \u2014 distinct per package dir so unrelated packages never collapse into one bucket. */\nexport const packageDebounceKey = (packageDir: string): string => {\n return `__pkg__:${packageDir}`\n}\n\n/**\n * Decide which launched apps a `packages/<pkg>/dist` change should restart. `null` means\n * \"fail-safe: restart all\" \u2014 the closure map is missing (a `--dry` failure) or the change carried\n * no package identity. Otherwise the participating (`watchDeps`) apps whose closure includes that\n * package dir \u2014 possibly an empty array (the package is UI-only, or every dependent opted out),\n * which the caller treats as \"restart nothing\".\n *\n * @example\n * // closure: pkgA \u2192 {appX}; pkgC \u2192 {appX, appY}\n * selectPackageRestartTargets([appX, appY], map, '\u2026/pkgA/dist') // => [appX] (not appY)\n * selectPackageRestartTargets([appX, appY], map, '\u2026/uiOnly/dist') // => [] (restart nothing)\n * selectPackageRestartTargets([appX, appY], null, '\u2026/pkgA/dist') // => null (fail-safe: restart all)\n */\nexport const selectPackageRestartTargets = <T extends { name: string; watchDeps: boolean }>(\n apps: T[],\n closureMap: ClosureMap | null,\n packageDir: string | undefined,\n): T[] | null => {\n if (closureMap === null || packageDir === undefined) return null\n\n const dependents = closureMap.dependentsByPackageDir.get(packageDir) ?? new Set<string>()\n\n return apps.filter((a) => {\n return a.watchDeps && dependents.has(a.name)\n })\n}\n", "/**\n * Pure port / URL-prefix resolution for the dev-server.\n *\n * These functions are intentionally side-effect free: the environment is passed\n * in (never read from `process.env` here) and no cwd / fs access happens. That\n * keeps port precedence and conflict detection unit-testable in isolation.\n */\nimport type { DevConfig } from '../lib/infra-kit-config/index.js'\n\n/** Fallback port when no PORT / {APP}_PORT env var and no config port is set. */\nexport const DEFAULT_PORT = 3010\n\n/**\n * URL prefix applied to each app's routes when nothing is configured. Overridable\n * per app via `dev.<app>.prefixUrl` in infra-kit.json \u2014 this is only the fallback.\n */\nexport const DEFAULT_PREFIX_URL = '/api/v1'\n\n/**\n * Parse a raw port string (env var or config), stripping a single pair of\n * surrounding quotes and treating blank / non-numeric input as \"unset\".\n */\nexport function parsePortString(raw: string | undefined): number | undefined {\n if (raw == null || raw === '') {\n return undefined\n }\n\n const n = parseInt(raw.trim().replace(/^[\"']|[\"']$/g, ''), 10)\n\n return Number.isNaN(n) ? undefined : n\n}\n\n/**\n * Resolve the PORT for an API app (highest priority first):\n *\n * 1. **`{APP}_PORT`** \u2014 e.g. `CLIENT_PORT`, `SEARCH_ENGINE_PORT` (secrets manager or shell)\n * 2. **`PORT`** \u2014 shared fallback (multi-app: use distinct `{APP}_PORT` in env)\n * 3. **`dev.<app>.port`** from infra-kit.json\n * 4. Default {@link DEFAULT_PORT}\n *\n * Per-app env keys use the app folder name in **UPPER_SNAKE_CASE** (hyphens \u2192 underscores).\n */\nexport function resolvePort(appName: string, env: NodeJS.ProcessEnv, devConfig: DevConfig): number {\n return resolvePreferredPort(appName, env, devConfig) ?? DEFAULT_PORT\n}\n\n/**\n * Resolve the EXPLICITLY-configured port for an API app \u2014 `{APP}_PORT`, then `PORT`, then\n * `dev.<app>.port` \u2014 or `undefined` when none is set. Unlike {@link resolvePort} this does\n * NOT fall back to {@link DEFAULT_PORT}: it distinguishes an app the developer pinned to a\n * port (a preferred bind target) from an unconfigured app (which binds ephemeral straight\n * away under dynamic allocation). Used by the dev-server to (a) pick the preferred bind\n * port and (b) relax the conflict gate to explicit ports only.\n */\nexport function resolvePreferredPort(\n appName: string,\n env: NodeJS.ProcessEnv,\n devConfig: DevConfig,\n): number | undefined {\n const prefix = appName.replace(/-/g, '_').toUpperCase()\n const prefixedKey = `${prefix}_PORT`\n\n const fromPrefixed = parsePortString(env[prefixedKey])\n\n if (fromPrefixed != null) {\n return fromPrefixed\n }\n\n const fromPort = parsePortString(env.PORT)\n\n if (fromPort != null) {\n return fromPort\n }\n\n return devConfig[appName]?.port ?? undefined\n}\n\n/**\n * Resolve the URL prefix for an API app: `dev.<app>.prefixUrl` from\n * infra-kit.json, falling back to {@link DEFAULT_PREFIX_URL} (`/api/v1`).\n */\nexport function resolvePrefixUrl(appName: string, devConfig: DevConfig): string {\n return devConfig[appName]?.prefixUrl ?? DEFAULT_PREFIX_URL\n}\n\n/** The apps that collide on a port, plus the raw duplicate-port list for messaging. */\nexport interface PortConflicts {\n /** Ports that appear more than once (one entry per extra occurrence, in scan order). */\n duplicatePorts: number[]\n /** Every app whose resolved port is one of the duplicates. */\n conflictingApps: Array<{ name: string; port: number }>\n}\n\n/**\n * Find apps that resolve to the same port. Returns empty `duplicatePorts` when\n * there is no conflict; the caller decides how to surface / throw.\n */\nexport function findPortConflicts(apps: Array<{ name: string; port: number }>): PortConflicts {\n const ports = apps.map((a) => {\n return a.port\n })\n const duplicatePorts = ports.filter((port, index) => {\n return ports.indexOf(port) !== index\n })\n const conflictingApps = apps.filter((a) => {\n return duplicatePorts.includes(a.port)\n })\n\n return { duplicatePorts, conflictingApps }\n}\n", "import { Logger } from '@aws-lambda-powertools/logger'\nimport type { APIGatewayProxyEvent, APIGatewayProxyEventQueryStringParameters, Context } from 'aws-lambda'\nimport fastify from 'fastify'\nimport * as fs from 'node:fs'\nimport type { Server } from 'node:http'\nimport * as path from 'node:path'\nimport process from 'node:process'\nimport { pathToFileURL } from 'node:url'\nimport { parse as parseYaml } from 'yaml'\n\nimport type { ILogger } from './interfaces.js'\n\nexport interface IServerConfig {\n controllersPath: string\n prefixUrl?: string\n /**\n * PREFERRED bind port. A number is tried first and, on `EADDRINUSE`, the runner falls\n * back to an ephemeral `listen(0)` port. `undefined` (no explicit config) binds an\n * ephemeral port straight away. After {@link ServerlessLocalRun.start} the field is\n * mutated in place to the ACTUAL bound port so `/__health` reports the real port.\n */\n port?: number\n /** App folder name, surfaced by the `/__health` endpoint. Optional. */\n appName?: string\n}\n\n/** True when a listen error is a port-already-in-use (`EADDRINUSE`) failure. */\nconst isAddressInUse = (error: unknown): boolean => {\n return (error as { code?: string } | null)?.code === 'EADDRINUSE'\n}\n\ntype HandlerResult = Promise<{ body: string; headers: Record<string, string>; statusCode: number }>\n\n/** Default simulated Lambda timeout; overridable via `DEV_SERVER_TIMEOUT_MS`. */\nconst DEFAULT_LAMBDA_TIMEOUT_MS = 30_000\n\n/** Resolve the simulated Lambda timeout (ms), honoring `DEV_SERVER_TIMEOUT_MS` when it parses. */\nconst resolveLambdaTimeoutMs = (): number => {\n const raw = Number.parseInt(process.env.DEV_SERVER_TIMEOUT_MS ?? '', 10)\n\n return Number.isNaN(raw) ? DEFAULT_LAMBDA_TIMEOUT_MS : raw\n}\n\n/**\n * Whether to emit a one-line `<method> <url> \u2192 <status> <ms>ms` log per request.\n * Off by default; opt in with `DEV_SERVER_REQUEST_LOG=1` (kept out of the Powertools\n * JSON logger so the line stays terminal-readable). Mirrors the env-reader precedent\n * of {@link resolveLambdaTimeoutMs}.\n */\nconst isRequestLogEnabled = (): boolean => {\n return process.env.DEV_SERVER_REQUEST_LOG === '1'\n}\n\nexport class ServerlessLocalRun {\n /** Busts Node ESM `import()` cache on each new server instance (watch restart). */\n private readonly importCacheBust: string\n private readonly logger: Logger\n private readonly server: ReturnType<typeof fastify>\n private readonly controllers: Record<\n string,\n {\n action: Record<string, (event: APIGatewayProxyEvent, ctx: Context, log: ILogger) => HandlerResult>\n handler: string\n }\n > = {}\n\n /** `method urlAction` keys reserved synchronously, so duplicates are caught before any async import. */\n private readonly registeredRouteKeys = new Set<string>()\n\n constructor(private readonly serverConfig: IServerConfig) {\n this.importCacheBust = `${Date.now()}`\n this.logger = new Logger({ serviceName: 'LocalServer', logLevel: 'DEBUG' })\n this.serverConfig.prefixUrl = this.serverConfig.prefixUrl ?? ''\n this.server = fastify({ logger: false })\n\n // Add CORS support for local development\n this.server.addHook(\n 'onRequest',\n async (\n request: { method: string },\n reply: { header: (k: string, v: string) => unknown; status: (n: number) => { send: () => void } },\n ) => {\n reply.header('Access-Control-Allow-Origin', '*')\n reply.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS')\n reply.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-Requested-With')\n\n // Handle preflight OPTIONS requests\n if (request.method === 'OPTIONS') {\n reply.status(204).send()\n }\n },\n )\n\n // Opt-in per-request log line (raw stdout, not the Powertools JSON logger) so live\n // traffic is visible in the dev terminal. Off unless DEV_SERVER_REQUEST_LOG=1.\n if (isRequestLogEnabled()) {\n this.server.addHook(\n 'onResponse',\n async (request: { method: string; url: string }, reply: { statusCode: number; elapsedTime: number }) => {\n const ms = Math.round(reply.elapsedTime)\n\n process.stdout.write(`${request.method} ${request.url} \u2192 ${reply.statusCode} ${ms}ms\\n`)\n },\n )\n }\n }\n\n /**\n * The registered `METHOD /path` route keys (sorted). Excludes the internal\n * `/__health` liveness route, which is registered outside {@link defineRoute} and\n * never added to {@link registeredRouteKeys}. Used by the runner's startup route dump.\n */\n public getRegisteredRoutes(): string[] {\n return [...this.registeredRouteKeys].sort()\n }\n\n /**\n * Boot the server and RETURN the actual bound port. Under dynamic allocation the port is\n * a runtime fact known only after `listen`, so the caller must consume this return value\n * (never the static config port). {@link serverConfig.port} is mutated in place to the\n * bound port so `/__health` reports the real value.\n */\n public async start(): Promise<number> {\n this.registerHealthRoute()\n\n await Promise.all(this.loadRoutes())\n\n const boundPort = await this.listenWithFallback()\n\n this.serverConfig.port = boundPort\n\n this.logger.info(`Server listening on http://127.0.0.1:${boundPort}`, {\n address: `http://127.0.0.1:${boundPort}`,\n })\n\n return boundPort\n }\n\n /**\n * Bind the server and return the ACTUAL bound port. With an explicitly-configured\n * preferred port, try it first and fall back to an ephemeral `listen(0)` on `EADDRINUSE`\n * so extra worktrees never collide; with no preferred port (`undefined`), bind ephemeral\n * straight away. Non-`EADDRINUSE` errors propagate.\n */\n private async listenWithFallback(): Promise<number> {\n const preferred = this.serverConfig.port\n\n if (preferred != null) {\n try {\n await this.server.listen({ port: preferred, host: '127.0.0.1' })\n\n return this.readBoundPort()\n } catch (error) {\n if (!isAddressInUse(error)) {\n throw error\n }\n }\n }\n\n await this.server.listen({ port: 0, host: '127.0.0.1' })\n\n return this.readBoundPort()\n }\n\n /** Read the concrete bound port from the underlying HTTP server after `listen`. */\n private readBoundPort(): number {\n const address = (this.server.server as Server).address()\n\n if (address == null || typeof address === 'string') {\n throw new Error('Server address unavailable after listen()')\n }\n\n return address.port\n }\n\n /** Close the server (for watch/restart). */\n public async close(): Promise<void> {\n const raw = this.server.server as Server\n\n if (typeof raw.closeAllConnections === 'function') {\n raw.closeAllConnections()\n }\n await this.server.close()\n }\n\n /**\n * Register a fixed `GET /__health` liveness route returning 200. The path is\n * unprefixed (serverless.yml routes carry the `prefixUrl`, e.g. `/api/v1/...`),\n * so it never collides with a handler route.\n */\n private registerHealthRoute(): void {\n this.server.route({\n method: 'GET',\n url: '/__health',\n handler: (_request: unknown, reply: { code: (n: number) => { send: (body: unknown) => void } }) => {\n return reply.code(200).send({\n status: 'ok',\n app: this.serverConfig.appName ?? null,\n port: this.serverConfig.port,\n })\n },\n })\n }\n\n private loadRoutes(): Promise<void>[] {\n const serverlessYmlPath = path.join(this.serverConfig.controllersPath, 'serverless.yml')\n const fileContents = fs.readFileSync(serverlessYmlPath, 'utf8')\n const data = parseYaml(fileContents) as {\n functions: Record<string, { events?: Array<{ http?: { method: string; path: string } }>; handler?: string }>\n }\n const p: Promise<void>[] = []\n\n if (!data?.functions) return p\n\n for (const [funcName, funcDef] of Object.entries(data.functions)) {\n if (!funcDef?.events?.length) continue\n for (const element of funcDef.events) {\n const http = element?.http\n\n if (!http) continue\n this.logger.debug(`Registering route: ${http.method} /${http.path} -> ${funcName}`)\n p.push(this.defineRoute(http, funcDef))\n }\n }\n\n return p\n }\n\n private async defineRoute(http: { method: string; path: string }, funcDef: { handler?: string }): Promise<void> {\n let url = http.path.toString()\n\n url = url.replaceAll('{', ':').replaceAll('}', '')\n\n let urlAction = path.posix.join(this.serverConfig.prefixUrl ?? '', url)\n\n urlAction = urlAction[0] === '/' ? urlAction : `/${urlAction}`\n\n const validMethods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS']\n const method = String(http.method).toUpperCase()\n\n if (!validMethods.includes(method)) {\n throw new Error(`Invalid HTTP method: \"${http.method}\" for URL: ${urlAction}`)\n }\n\n // Key on method + path: two events can share a path but differ by method (e.g. GET/POST /users),\n // so keying on the path alone would let one handler overwrite the other. Reserve the key\n // synchronously (before the first `await`) so concurrent route loads detect a true duplicate.\n const routeKey = `${method} ${urlAction}`\n\n if (this.registeredRouteKeys.has(routeKey)) {\n throw new Error(`Duplicate route: ${routeKey}`)\n }\n this.registeredRouteKeys.add(routeKey)\n\n const handlerStr = funcDef.handler ?? ''\n const parts = handlerStr.split('.')\n const filepath = parts[0] ?? ''\n const handler = parts[1] ?? ''\n\n const controllerPath = path.join(this.serverConfig.controllersPath, `${filepath}.js`)\n const fileUrl = pathToFileURL(controllerPath)\n\n // Search params bust Node's ESM import cache so watch rebuilds load new `dist` output.\n fileUrl.searchParams.set('v', this.importCacheBust)\n const action = (await import(fileUrl.href)) as Record<\n string,\n (event: APIGatewayProxyEvent, ctx: Context, log: ILogger) => HandlerResult\n >\n\n this.controllers[routeKey] = { action, handler }\n\n const traceLogger = this.logger.createChild({ serviceName: 'RequestLogger' })\n\n this.logger.debug(`Adding fastify route: ${method} ${urlAction}`)\n\n this.server.route({\n method: method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS',\n url: urlAction,\n handler: async (\n request: { body?: unknown; query?: unknown; params?: unknown; headers?: unknown },\n reply: {\n headers: (h: Record<string, string>) => unknown\n code: (n: number) => { send: (body: unknown) => void }\n },\n ) => {\n const controller = this.controllers[routeKey]\n\n if (!controller) throw new Error(`No controller for ${routeKey}`)\n const handlerFn = controller.action[controller.handler]\n\n if (!handlerFn) throw new Error(`No handler ${controller.handler} for ${urlAction}`)\n const retVal = await handlerFn(\n this.getEventObj(request.body, request.query, request.params, request.headers, method, urlAction),\n this.getContext(),\n traceLogger,\n )\n const responseBody = JSON.parse(retVal.body)\n\n reply.headers(retVal.headers ?? {})\n\n return reply.code(retVal?.statusCode ?? 500).send(responseBody)\n },\n })\n\n this.logger.debug(`Route added successfully: ${method} ${urlAction}`)\n }\n\n private getEventObj(\n requestBody?: unknown,\n queryParams?: unknown,\n pathParameters?: unknown,\n headers?: unknown,\n httpMethod = '',\n path = '',\n ): APIGatewayProxyEvent {\n const retVal = {\n body: requestBody ? JSON.stringify(requestBody) : null,\n headers: (headers ?? {}) as APIGatewayProxyEvent['headers'],\n multiValueHeaders: {},\n httpMethod,\n isBase64Encoded: false,\n path,\n pathParameters: pathParameters ?? null,\n queryStringParameters: (queryParams as APIGatewayProxyEventQueryStringParameters) ?? null,\n multiValueQueryStringParameters: null,\n stageVariables: null,\n requestContext: {\n accountId: '',\n apiId: '',\n authorizer: undefined,\n protocol: '',\n httpMethod,\n identity: {\n accessKey: null,\n accountId: null,\n apiKey: null,\n apiKeyId: null,\n caller: null,\n clientCert: null,\n cognitoAuthenticationProvider: null,\n cognitoAuthenticationType: null,\n cognitoIdentityId: null,\n cognitoIdentityPoolId: null,\n principalOrgId: null,\n sourceIp: 'devIp',\n user: null,\n userAgent: null,\n userArn: null,\n },\n path,\n stage: '',\n requestId: '',\n requestTimeEpoch: 0,\n resourceId: '',\n resourcePath: path,\n },\n resource: path,\n }\n\n ;(retVal as APIGatewayProxyEvent & { source: string }).source = 'aws.events'\n\n return retVal as APIGatewayProxyEvent\n }\n\n private getContext(): Context {\n const startTime = Date.now()\n const timeoutMs = resolveLambdaTimeoutMs()\n const datePart = new Date().toISOString().split('T')[0] ?? ''\n\n return {\n callbackWaitsForEmptyEventLoop: false,\n functionName: 'local-dev',\n functionVersion: '1.0.0',\n invokedFunctionArn: 'arn:aws:lambda:local:000000000000:function:local-dev',\n memoryLimitInMB: '1024',\n awsRequestId: `local-${Date.now()}`,\n logGroupName: '/aws/lambda/local-dev',\n logStreamName: `${datePart}/local`,\n getRemainingTimeInMillis: (): number => {\n return Math.max(0, timeoutMs - (Date.now() - startTime))\n },\n done: (_error?: Error, _result?: unknown): void => {},\n fail: (_error: string | Error): void => {},\n succeed: (_messageOrObject: unknown): void => {},\n }\n }\n}\n", "/*\n * `pnpm` is resolved from PATH \u2014 the same trust posture as the rest of the dev-server, which\n * already shells out to `pnpm exec turbo \u2026`; the args are fixed literals plus discovered package\n * names, never shell-interpolated. Matches the file-level disable in `scripts/build.js`.\n */\n/* eslint-disable sonarjs/no-os-command-from-path */\n/**\n * `turbo watch build` engine for `infra-kit dev --watch`.\n *\n * Spawns ONE long-lived `turbo watch build` child that owns incremental rebuilds and\n * dependency-graph fan-out. Its stdout is teed to the runner log but NEVER parsed for\n * control flow: piped `turbo watch` block-buffers stdout and emits no per-task completion\n * marker for `tsc -b` tasks, so the dev-server derives \"a build finished\" from watching\n * `dist/` output instead (see {@link file://./dev-server.ts} `setupWatch`).\n *\n * The child is a 5-deep tree (`sh \u2192 pnpm \u2192 node \u2192 turbo \u2192 native binary`); killing the\n * wrapper PID orphans the rest. So it is spawned `detached` (its own process group) and\n * torn down with a process-GROUP signal \u2014 verified to fully reap the tree.\n */\nimport { spawn } from 'node:child_process'\nimport * as fs from 'node:fs'\n\nimport { superviseChild } from './managed-child.js'\nimport type { ManagedChild } from './managed-child.js'\n\n/** Handle to the running `turbo watch` child; `kill()` reaps the whole process group. */\nexport type TurboWatchHandle = ManagedChild\n\n/** Injectable spawn seam so tests run the orchestrator without a real turbo child. */\nexport type TurboWatchFactory = (opts: TurboWatchOptions) => TurboWatchHandle\n\nexport interface TurboWatchOptions {\n /**\n * API app package names, watched DEPENDENCY-INCLUSIVE (`--filter=...<pkg>`): rebuild the app AND its\n * dependency closure, so editing a shared lib the backend uses triggers a rebuild + restart.\n */\n depInclusive: string[]\n /**\n * UI app package names, watched DEP-CLOSURE-ONLY (`--filter=<pkg>^...`): rebuild the frontend's shared-lib\n * dependencies but NEVER the UI's own `build` (that would run a production `vite build` \u2014 the UI's live\n * dev is owned by the separate `turbo run dev`/vite child). Covers FE-only libs + UI-only sessions.\n */\n depClosure: string[]\n /** Consumer repo cwd the child runs in (turbo resolves the consumer's own pin here). */\n cwd: string\n /** Runner log file; the child's stdout+stderr are appended to it. */\n logFile: string\n}\n\n/**\n * Build the `--filter=` arg vector: `...<pkg>` (dependency-inclusive) for each API package, `<pkg>^...`\n * (dependencies only, excluding the package itself) for each UI package. Pure/order-stable so the exact\n * emitted args are unit-testable; API-only input reproduces the historical `--filter=...<pkg>` vector.\n *\n * @example\n * buildTurboWatchFilters(['api-a'], ['ui-a']) // => ['--filter=...api-a', '--filter=ui-a^...']\n */\nexport const buildTurboWatchFilters = (depInclusive: string[], depClosure: string[]): string[] => {\n return [\n ...depInclusive.map((name) => {\n return `--filter=...${name}`\n }),\n ...depClosure.map((name) => {\n return `--filter=${name}^...`\n }),\n ]\n}\n\n/**\n * Default factory: spawn `pnpm exec turbo watch build <filters> --continue=dependencies-successful\n * --env-mode=loose` detached, tee output to `logFile`, and reap the process group on `kill()`.\n *\n * Filters come from {@link buildTurboWatchFilters}: `...<api>` (dep-inclusive) rebuilds a backend + its\n * closure; `<ui>^...` (dep-closure-only) rebuilds the frontend's shared libs without production-building\n * the UI. `--continue=dependencies-successful` keeps the watcher alive when one package fails to compile,\n * so a shared-lib type error never tears down the whole engine and the last-good `dist/` keeps serving.\n */\nexport const defaultTurboWatchFactory: TurboWatchFactory = ({ depInclusive, depClosure, cwd, logFile }) => {\n const filters = buildTurboWatchFilters(depInclusive, depClosure)\n const out = fs.openSync(logFile, 'a')\n const child = spawn(\n 'pnpm',\n ['exec', 'turbo', 'watch', 'build', ...filters, '--continue=dependencies-successful', '--env-mode=loose'],\n { cwd, detached: true, stdio: ['ignore', out, out] },\n )\n\n return superviseChild(child)\n}\n", "/**\n * Shared supervision for the dev-server's long-lived, detached child processes\n * (`turbo watch build`, `turbo run dev`). Both are deep trees\n * (`sh \u2192 pnpm \u2192 node \u2192 turbo \u2192 \u2026`) spawned `detached` so they form their own process\n * group; teardown signals the whole GROUP (`process.kill(-pid, \u2026)`), not just the wrapper.\n *\n * Escalation: SIGTERM first, then \u2014 if the group is still alive after a grace window \u2014\n * SIGKILL. FE dev servers (vite/vike/astro) run async teardown and can straggle on a\n * lone SIGTERM (orphaned port \u2192 next run's `EADDRINUSE`), so the SIGKILL fallback matters.\n */\nimport type { ChildProcess } from 'node:child_process'\nimport process from 'node:process'\n\n/** Handle to a supervised child; `kill()` reaps its whole process group and resolves when gone. */\nexport interface ManagedChild {\n kill: () => Promise<void>\n}\n\n/** Default grace before escalating SIGTERM \u2192 SIGKILL on a stubborn process group. */\nconst DEFAULT_GRACE_MS = 2000\n\n/** Is the process group led by `pid` still alive? (`kill(-pid, 0)` throws ESRCH when gone.) */\nfunction groupAlive(pid: number): boolean {\n try {\n process.kill(-pid, 0)\n\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Wrap a detached child: `unref()` it (so it never keeps the loop alive) and return a\n * handle whose `kill()` sends a group SIGTERM, polls up to `graceMs` for the group to\n * exit, and SIGKILLs any survivor. Resolves once the group is gone (or was never spawned).\n */\nexport function superviseChild(child: ChildProcess, graceMs: number = DEFAULT_GRACE_MS): ManagedChild {\n // Don't keep the parent event loop alive on the child; the runner owns lifecycle via kill().\n child.unref()\n\n return {\n kill: async (): Promise<void> => {\n const pid = child.pid\n\n if (pid == null) return\n\n try {\n // Negative pid \u2192 the whole group (detached made the child a group leader).\n process.kill(-pid, 'SIGTERM')\n } catch {\n // Already exited (ESRCH) \u2014 nothing to reap.\n return\n }\n\n const deadline = Date.now() + graceMs\n\n while (Date.now() < deadline) {\n await new Promise((r) => {\n return setTimeout(r, 100)\n })\n if (!groupAlive(pid)) return\n }\n\n // Still alive after the grace window \u2014 force it.\n try {\n process.kill(-pid, 'SIGKILL')\n } catch {\n // Raced to exit between the last poll and now \u2014 fine.\n }\n },\n }\n}\n", "/*\n * `pnpm` is resolved from PATH \u2014 same trust posture as the rest of the dev-server (which already\n * shells out to `pnpm exec turbo \u2026`); args are fixed literals plus discovered package names, never\n * shell-interpolated. Matches the file-level disable in `scripts/build.js`.\n */\n/* eslint-disable sonarjs/no-os-command-from-path */\n/**\n * Frontend dev engine for `infra-kit dev --ui`.\n *\n * Delegates FE to ONE `turbo run dev` child (turbo owns the `dev` fan-out, `^build` ordering\n * and concurrency) rather than infra-kit spawning each framework itself \u2014 the same delegation\n * choice already made for builds via `turbo watch`. infra-kit treats UIs opaquely: it runs their\n * `dev` script (vite/vike/astro/\u2026) and never encodes per-framework knowledge.\n *\n * Unlike the `turbo watch` child, this one's stdio is INHERITED \u2014 the framework dev servers own\n * their own TTY output (HMR overlays, URLs, spinners), so it streams raw to the terminal below the\n * BE server table rather than being teed into the runner log (which would corrupt it with ANSI).\n *\n * Detached \u2192 its own process group; reaped as a group (SIGTERM\u2192SIGKILL) via {@link superviseChild}.\n */\nimport { spawn } from 'node:child_process'\n\nimport { superviseChild } from './managed-child.js'\nimport type { ManagedChild } from './managed-child.js'\n\n/** Handle to the running `turbo run dev` child; `kill()` reaps the whole process group. */\nexport type UiDevHandle = ManagedChild\n\n/** Injectable spawn seam so tests run the orchestrator without a real turbo child. */\nexport type UiDevFactory = (opts: UiDevOptions) => UiDevHandle\n\nexport interface UiDevOptions {\n /** UI app package names; each becomes an exact `--filter=<pkg>` (turbo runs its `dev` task). */\n packageNames: string[]\n /** Consumer repo cwd the child runs in. */\n cwd: string\n /**\n * Concurrency cap. Must be \u2265 the number of selected UI `dev` tasks (they're persistent) \u2014\n * turbo hard-errors when persistent tasks exceed concurrency (default 10).\n */\n concurrency: number\n}\n\n/**\n * Default factory: spawn `pnpm exec turbo run dev --filter=<pkg> \u2026 --concurrency=N --env-mode=loose`\n * detached, streaming to the parent terminal, and reap the process group on `kill()`.\n *\n * Exact `--filter=<pkg>` (no `...`) selects only the UI packages, so an API app that also defines a\n * `dev` task is never picked up.\n */\nexport const defaultUiDevFactory: UiDevFactory = ({ packageNames, cwd, concurrency }) => {\n const filters = packageNames.map((name) => {\n return `--filter=${name}`\n })\n const child = spawn(\n 'pnpm',\n ['exec', 'turbo', 'run', 'dev', ...filters, `--concurrency=${concurrency}`, '--env-mode=loose'],\n { cwd, detached: true, stdio: ['ignore', 'inherit', 'inherit'] },\n )\n\n return superviseChild(child)\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["Command", "process", "pathToFileURL", "path", "process", "makeLeaf", "command", "buildNode", "commands", "depth", "leftCount", "left", "right", "buildCmuxLayout", "buildPaneCommands", "appNames", "watch", "name", "selectApiApps", "root", "include", "apps", "discoverApiApps", "app", "logDevWorkspace", "ref", "logger", "registerShutdown", "shuttingDown", "shutdown", "signal", "closeCmuxDevWorkspace", "process", "runCmuxDevServer", "options", "findMonorepoRoot", "normalizeAppInclude", "commands", "layout", "buildCmuxLayout", "title", "openCmuxDevWorkspace", "heartbeat", "chokidar", "exec", "execFileSync", "fs", "path", "process", "util", "execFile", "fs", "path", "promisify", "execFileAsync", "promisify", "execFile", "readPackageName", "dir", "parsed", "defaultDryRunner", "root", "packageName", "stdout", "names", "t", "p", "readPackageDirs", "packageNameByDir", "dirByName", "distDir", "getPackageDistDirs", "name", "buildClosureMap", "apps", "dryRunner", "dependentsByPackageDir", "closures", "app", "closure", "pkgName", "dependents", "packageDebounceKey", "packageDir", "selectPackageRestartTargets", "closureMap", "a", "DEFAULT_PREFIX_URL", "parsePortString", "raw", "n", "resolvePreferredPort", "appName", "env", "devConfig", "prefixedKey", "fromPrefixed", "parsePortString", "fromPort", "resolvePrefixUrl", "DEFAULT_PREFIX_URL", "findPortConflicts", "apps", "ports", "a", "duplicatePorts", "port", "index", "conflictingApps", "Logger", "fastify", "fs", "path", "process", "pathToFileURL", "parseYaml", "isAddressInUse", "error", "DEFAULT_LAMBDA_TIMEOUT_MS", "resolveLambdaTimeoutMs", "raw", "isRequestLogEnabled", "ServerlessLocalRun", "serverConfig", "request", "reply", "ms", "boundPort", "preferred", "address", "_request", "serverlessYmlPath", "fileContents", "data", "p", "funcName", "funcDef", "element", "http", "url", "urlAction", "validMethods", "method", "routeKey", "parts", "filepath", "handler", "controllerPath", "fileUrl", "action", "traceLogger", "controller", "handlerFn", "retVal", "responseBody", "requestBody", "queryParams", "pathParameters", "headers", "httpMethod", "startTime", "timeoutMs", "datePart", "_error", "_result", "_messageOrObject", "spawn", "fs", "process", "DEFAULT_GRACE_MS", "groupAlive", "pid", "superviseChild", "child", "graceMs", "deadline", "r", "buildTurboWatchFilters", "depInclusive", "depClosure", "name", "defaultTurboWatchFactory", "cwd", "logFile", "filters", "out", "child", "spawn", "superviseChild", "spawn", "defaultUiDevFactory", "packageNames", "cwd", "concurrency", "filters", "name", "child", "spawn", "superviseChild", "LOG_FILE_PATH", "process", "VERBOSE", "initLogFile", "execFn", "util", "exec", "launchScript", "script", "logFn", "stderr", "error", "err", "appendLogFile", "text", "log", "message", "level", "logStep", "logTable", "lines", "output", "center", "s", "width", "pad", "left", "renderTable", "title", "headers", "rows", "widths", "header", "i", "row", "columnsInner", "sum", "w", "lastIdx", "inner", "blocks", "rowLine", "cells", "c", "readAppRelease", "cwd", "branch", "execFileSync", "slug", "slugifyRelease", "DevServerRunner", "_DevServerRunner", "options", "runBuild", "turboWatchFactory", "defaultTurboWatchFactory", "uiDevFactory", "defaultUiDevFactory", "dryRunner", "findMonorepoRoot", "devConfig", "discoverApiApps", "app", "getInfraKitConfig", "normalizeAppInclude", "appName", "resolvePreferredPort", "resolvePrefixUrl", "devPresets", "name", "def", "available", "include", "watch", "apiAppsAll", "uiAppsAll", "discoverUiApps", "resolved", "resolvePreset", "apiNames", "t", "uiNames", "passesInclude", "watchDepsByApp", "apps", "uiApps", "closureMap", "filters", "a", "names", "explicitApps", "duplicatePorts", "conflictingApps", "findPortConflicts", "buildCmd", "buildError", "started", "server", "ServerlessLocalRun", "boundPort", "release", "fragment", "target", "tmp", "work", "run", "r", "e", "targets", "label", "idx", "restarted", "restartedSummary", "entry", "buildClosureMap", "appDistDirs", "getAppDistDirs", "packageDistDirs", "getPackageDistDirs", "allDistDirs", "usePoll", "watcher", "chokidar", "p", "filePath", "change", "classifyDistChange", "selectPackageRestartTargets", "packageDebounceKey", "key", "existing", "timer", "routes", "runner", "splitList", "value", "parts", "s", "toDevServerOptions", "raw", "resolveSelfOptions", "options", "resolveSelfAppName", "process", "runDevServer", "rawOptions", "isCmuxAvailable", "runCmuxDevServer", "runner", "run", "shuttingDown", "shutdown", "signal", "parseAndRun", "argv", "program", "Command", "pathToFileURL", "error"]
7
7
  }
@@ -1,4 +1,4 @@
1
1
  export { defineConfig } from '../lib/package-config/package-config';
2
- export type { InfraKitPackageConfig, InfraKitPackageConfigInput } from '../lib/package-config/package-config';
2
+ export type { InfraKitDev, InfraKitDevProxy, InfraKitDevProxyRoute, InfraKitDevProxySource, InfraKitPackageConfig, InfraKitPackageConfigInput, } from '../lib/package-config/package-config';
3
3
  export { defineVendorConfig } from '../lib/vendor/config-schema';
4
4
  export type { VendorConfig, VendorCopyItem } from '../lib/vendor/config-schema';
@@ -0,0 +1,2 @@
1
+ export { infraKitDev, infraKitProxy, resolveProxyConfig, slugifyRelease } from '../lib/vite/vite';
2
+ export type { InfraKitBasicAuth, InfraKitDevOptions, InfraKitViteProxy, InfraKitViteProxyEntry } from '../lib/vite/vite';
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{a as o,g as e}from"./chunk-YSBF5C7C.js";export{o as defineConfig,e as defineVendorConfig};
1
+ import{a as e,g as o}from"./chunk-Z6KTUVIC.js";export{e as defineConfig,o as defineVendorConfig};
2
2
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Schema for the resolved (post-factory) package config object. `strictObject`
4
+ * rejects unknown keys so typos in `infra-kit.config.ts` surface as validation
5
+ * errors instead of being silently ignored.
6
+ *
7
+ * Kept in its own module — separate from the public `defineConfig`/types entry —
8
+ * so the published `infra-kit` type surface stays free of a `zod` import.
9
+ */
10
+ export declare const packageConfigSchema: z.ZodObject<{
11
+ requiredScripts: z.ZodOptional<z.ZodArray<z.ZodString>>;
12
+ requiredFiles: z.ZodOptional<z.ZodArray<z.ZodString>>;
13
+ turbo: z.ZodOptional<z.ZodObject<{
14
+ requiredTasks: z.ZodOptional<z.ZodArray<z.ZodString>>;
15
+ }, z.core.$strict>>;
16
+ dev: z.ZodOptional<z.ZodObject<{
17
+ proxy: z.ZodOptional<z.ZodObject<{
18
+ templates: z.ZodObject<{
19
+ local: z.ZodString;
20
+ cloud: z.ZodString;
21
+ }, z.core.$strict>;
22
+ routes: z.ZodRecord<z.ZodString, z.ZodObject<{
23
+ packageName: z.ZodString;
24
+ from: z.ZodArray<z.ZodEnum<{
25
+ local: "local";
26
+ cloud: "cloud";
27
+ }>>;
28
+ default: z.ZodOptional<z.ZodEnum<{
29
+ local: "local";
30
+ cloud: "cloud";
31
+ }>>;
32
+ }, z.core.$strict>>;
33
+ }, z.core.$strict>>;
34
+ }, z.core.$strict>>;
35
+ }, z.core.$strict>;