infra-kit 0.1.125 → 0.1.127

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 (318) hide show
  1. package/.eslintcache +1 -1
  2. package/.omc/state/agent-replay-036daa78-5fee-4c7d-9b44-53584acb0d87.jsonl +26 -0
  3. package/.omc/state/agent-replay-0a65ec83-9de7-458d-9d0f-e56e1a26c68e.jsonl +2 -0
  4. package/.omc/state/agent-replay-1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a.jsonl +17 -0
  5. package/.omc/state/agent-replay-2ac0dcd0-01f7-41a8-a8c9-f2195599817b.jsonl +5 -0
  6. package/.omc/state/agent-replay-d02e6565-5168-40c8-8629-de219a29fa43.jsonl +2 -0
  7. package/.omc/state/idle-notif-cooldown.json +1 -1
  8. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/last-tool-error-state.json +7 -0
  9. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/mission-state.json +129 -0
  10. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/pre-tool-advisory-throttle.json +34 -0
  11. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/ralph-state.json +13 -0
  12. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/ralplan-state.json +11 -0
  13. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/subagent-tracking-state.json +80 -0
  14. package/.omc/state/sessions/036daa78-5fee-4c7d-9b44-53584acb0d87/ultrawork-state.json +11 -0
  15. package/.omc/state/sessions/0a65ec83-9de7-458d-9d0f-e56e1a26c68e/pre-tool-advisory-throttle.json +18 -0
  16. package/.omc/state/sessions/0a65ec83-9de7-458d-9d0f-e56e1a26c68e/skill-active-state.json +15 -0
  17. package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/last-tool-error-state.json +7 -0
  18. package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/mission-state.json +139 -0
  19. package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/pre-tool-advisory-throttle.json +50 -0
  20. package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/ralplan-state.json +11 -0
  21. package/.omc/state/sessions/1b6ffc57-2d9b-4af4-b603-f1cef7e01b0a/subagent-tracking-state.json +90 -0
  22. package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/last-tool-error-state.json +7 -0
  23. package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/mission-state.json +79 -0
  24. package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/pre-tool-advisory-throttle.json +10 -0
  25. package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/skill-active-state.json +15 -0
  26. package/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/subagent-tracking-state.json +26 -0
  27. package/.omc/state/sessions/7772f972-4ec1-4287-bf42-a92c14cf3ffc/pre-tool-advisory-throttle.json +10 -0
  28. package/.omc/state/sessions/d02e6565-5168-40c8-8629-de219a29fa43/last-tool-error-state.json +7 -0
  29. package/.omc/state/sessions/d02e6565-5168-40c8-8629-de219a29fa43/mission-state.json +53 -0
  30. package/.omc/state/sessions/d02e6565-5168-40c8-8629-de219a29fa43/pre-tool-advisory-throttle.json +18 -0
  31. package/.omc/state/sessions/d02e6565-5168-40c8-8629-de219a29fa43/subagent-tracking-state.json +17 -0
  32. package/.turbo/turbo-build.log +7 -6
  33. package/.turbo/turbo-eslint-check.log +2 -1
  34. package/.turbo/turbo-prettier-check.log +1 -1
  35. package/.turbo/turbo-test.log +406 -128
  36. package/.turbo/turbo-ts-check.log +1 -1
  37. package/coverage/base.css +224 -0
  38. package/coverage/block-navigation.js +87 -0
  39. package/coverage/cli/index.html +116 -0
  40. package/coverage/cli/package.json.html +283 -0
  41. package/coverage/cli/src/commands/audit/audit.ts.html +616 -0
  42. package/coverage/cli/src/commands/audit/index.html +131 -0
  43. package/coverage/cli/src/commands/audit/index.ts.html +88 -0
  44. package/coverage/cli/src/commands/doctor/doctor.ts.html +1654 -0
  45. package/coverage/cli/src/commands/doctor/index.html +131 -0
  46. package/coverage/cli/src/commands/doctor/index.ts.html +88 -0
  47. package/coverage/cli/src/commands/env-clear/env-clear.ts.html +370 -0
  48. package/coverage/cli/src/commands/env-clear/index.html +131 -0
  49. package/coverage/cli/src/commands/env-clear/index.ts.html +88 -0
  50. package/coverage/cli/src/commands/env-list/env-list.ts.html +229 -0
  51. package/coverage/cli/src/commands/env-list/index.html +131 -0
  52. package/coverage/cli/src/commands/env-list/index.ts.html +88 -0
  53. package/coverage/cli/src/commands/env-load/env-load.ts.html +1201 -0
  54. package/coverage/cli/src/commands/env-load/index.html +131 -0
  55. package/coverage/cli/src/commands/env-load/index.ts.html +91 -0
  56. package/coverage/cli/src/commands/env-status/env-status.ts.html +409 -0
  57. package/coverage/cli/src/commands/env-status/index.html +131 -0
  58. package/coverage/cli/src/commands/env-status/index.ts.html +88 -0
  59. package/coverage/cli/src/commands/gh-merge-dev/gh-merge-dev.ts.html +694 -0
  60. package/coverage/cli/src/commands/gh-merge-dev/index.html +131 -0
  61. package/coverage/cli/src/commands/gh-merge-dev/index.ts.html +88 -0
  62. package/coverage/cli/src/commands/gh-release-deliver/gh-release-deliver.ts.html +1495 -0
  63. package/coverage/cli/src/commands/gh-release-deliver/index.html +131 -0
  64. package/coverage/cli/src/commands/gh-release-deliver/index.ts.html +88 -0
  65. package/coverage/cli/src/commands/gh-release-deploy-all/gh-release-deploy-all.ts.html +706 -0
  66. package/coverage/cli/src/commands/gh-release-deploy-all/index.html +131 -0
  67. package/coverage/cli/src/commands/gh-release-deploy-all/index.ts.html +88 -0
  68. package/coverage/cli/src/commands/gh-release-deploy-selected/gh-release-deploy-selected.ts.html +994 -0
  69. package/coverage/cli/src/commands/gh-release-deploy-selected/index.html +131 -0
  70. package/coverage/cli/src/commands/gh-release-deploy-selected/index.ts.html +88 -0
  71. package/coverage/cli/src/commands/gh-release-list/gh-release-list.ts.html +355 -0
  72. package/coverage/cli/src/commands/gh-release-list/index.html +131 -0
  73. package/coverage/cli/src/commands/gh-release-list/index.ts.html +88 -0
  74. package/coverage/cli/src/commands/init/agent-files.ts.html +742 -0
  75. package/coverage/cli/src/commands/init/index.html +146 -0
  76. package/coverage/cli/src/commands/init/init.ts.html +1159 -0
  77. package/coverage/cli/src/commands/init/migrate-config.ts.html +1219 -0
  78. package/coverage/cli/src/commands/release-create/index.html +131 -0
  79. package/coverage/cli/src/commands/release-create/index.ts.html +88 -0
  80. package/coverage/cli/src/commands/release-create/release-create.ts.html +1426 -0
  81. package/coverage/cli/src/commands/release-desc-edit/index.html +131 -0
  82. package/coverage/cli/src/commands/release-desc-edit/index.ts.html +88 -0
  83. package/coverage/cli/src/commands/release-desc-edit/release-desc-edit.ts.html +766 -0
  84. package/coverage/cli/src/commands/vendor-check/index.html +131 -0
  85. package/coverage/cli/src/commands/vendor-check/index.ts.html +88 -0
  86. package/coverage/cli/src/commands/vendor-check/vendor-check.ts.html +466 -0
  87. package/coverage/cli/src/commands/vendor-config/index.html +116 -0
  88. package/coverage/cli/src/commands/vendor-config/vendor-config.ts.html +571 -0
  89. package/coverage/cli/src/commands/vendor-diff/index.html +131 -0
  90. package/coverage/cli/src/commands/vendor-diff/index.ts.html +88 -0
  91. package/coverage/cli/src/commands/vendor-diff/vendor-diff.ts.html +316 -0
  92. package/coverage/cli/src/commands/vendor-manifest/index.html +131 -0
  93. package/coverage/cli/src/commands/vendor-manifest/index.ts.html +88 -0
  94. package/coverage/cli/src/commands/vendor-manifest/vendor-manifest.ts.html +265 -0
  95. package/coverage/cli/src/commands/vendor-sync/index.html +131 -0
  96. package/coverage/cli/src/commands/vendor-sync/index.ts.html +88 -0
  97. package/coverage/cli/src/commands/vendor-sync/vendor-sync.ts.html +355 -0
  98. package/coverage/cli/src/commands/version/index.html +131 -0
  99. package/coverage/cli/src/commands/version/index.ts.html +88 -0
  100. package/coverage/cli/src/commands/version/version.ts.html +184 -0
  101. package/coverage/cli/src/commands/worktrees-add/index.html +131 -0
  102. package/coverage/cli/src/commands/worktrees-add/index.ts.html +88 -0
  103. package/coverage/cli/src/commands/worktrees-add/worktrees-add.ts.html +1183 -0
  104. package/coverage/cli/src/commands/worktrees-list/index.html +131 -0
  105. package/coverage/cli/src/commands/worktrees-list/index.ts.html +88 -0
  106. package/coverage/cli/src/commands/worktrees-list/worktrees-list.ts.html +400 -0
  107. package/coverage/cli/src/commands/worktrees-reload/index.html +131 -0
  108. package/coverage/cli/src/commands/worktrees-reload/index.ts.html +88 -0
  109. package/coverage/cli/src/commands/worktrees-reload/worktrees-reload.ts.html +775 -0
  110. package/coverage/cli/src/commands/worktrees-remove/index.html +131 -0
  111. package/coverage/cli/src/commands/worktrees-remove/index.ts.html +88 -0
  112. package/coverage/cli/src/commands/worktrees-remove/worktrees-remove.ts.html +682 -0
  113. package/coverage/cli/src/commands/worktrees-sync/index.html +131 -0
  114. package/coverage/cli/src/commands/worktrees-sync/index.ts.html +88 -0
  115. package/coverage/cli/src/commands/worktrees-sync/worktrees-sync.ts.html +679 -0
  116. package/coverage/cli/src/dev/__tests__/fixtures.ts.html +787 -0
  117. package/coverage/cli/src/dev/__tests__/index.html +116 -0
  118. package/coverage/cli/src/dev/dev-server.ts.html +1855 -0
  119. package/coverage/cli/src/dev/discovery.ts.html +598 -0
  120. package/coverage/cli/src/dev/index.html +191 -0
  121. package/coverage/cli/src/dev/interfaces.ts.html +223 -0
  122. package/coverage/cli/src/dev/logger.ts.html +1102 -0
  123. package/coverage/cli/src/dev/ports.ts.html +430 -0
  124. package/coverage/cli/src/dev/serverless-local-run.ts.html +916 -0
  125. package/coverage/cli/src/entry/dev-server.ts.html +409 -0
  126. package/coverage/cli/src/entry/index.html +116 -0
  127. package/coverage/cli/src/index.html +116 -0
  128. package/coverage/cli/src/integrations/cmux/canonicalize-cmux-title.ts.html +178 -0
  129. package/coverage/cli/src/integrations/cmux/close-workspace-by-title.ts.html +262 -0
  130. package/coverage/cli/src/integrations/cmux/index.html +191 -0
  131. package/coverage/cli/src/integrations/cmux/index.ts.html +100 -0
  132. package/coverage/cli/src/integrations/cmux/list-workspace-titles.ts.html +226 -0
  133. package/coverage/cli/src/integrations/cmux/open-workspace-with-layout.ts.html +325 -0
  134. package/coverage/cli/src/integrations/cmux/workspace-title.ts.html +154 -0
  135. package/coverage/cli/src/integrations/cursor/add-folders-to-workspace.ts.html +337 -0
  136. package/coverage/cli/src/integrations/cursor/index.html +206 -0
  137. package/coverage/cli/src/integrations/cursor/index.ts.html +103 -0
  138. package/coverage/cli/src/integrations/cursor/launch-cursor.ts.html +121 -0
  139. package/coverage/cli/src/integrations/cursor/open-cursor-workspace.ts.html +277 -0
  140. package/coverage/cli/src/integrations/cursor/reconcile-workspace-folders.ts.html +355 -0
  141. package/coverage/cli/src/integrations/cursor/remove-folders-from-workspace.ts.html +364 -0
  142. package/coverage/cli/src/integrations/cursor/resolve-workspace-path.ts.html +124 -0
  143. package/coverage/cli/src/integrations/doppler/doppler-cli-auth.ts.html +178 -0
  144. package/coverage/cli/src/integrations/doppler/doppler-errors.ts.html +349 -0
  145. package/coverage/cli/src/integrations/doppler/doppler-project.ts.html +355 -0
  146. package/coverage/cli/src/integrations/doppler/index.html +161 -0
  147. package/coverage/cli/src/integrations/doppler/index.ts.html +97 -0
  148. package/coverage/cli/src/integrations/gh/gh-cli-auth/gh-cli-auth.ts.html +172 -0
  149. package/coverage/cli/src/integrations/gh/gh-cli-auth/index.html +131 -0
  150. package/coverage/cli/src/integrations/gh/gh-cli-auth/index.ts.html +88 -0
  151. package/coverage/cli/src/integrations/gh/gh-release-prs/gh-release-prs.ts.html +703 -0
  152. package/coverage/cli/src/integrations/gh/gh-release-prs/index.html +131 -0
  153. package/coverage/cli/src/integrations/gh/gh-release-prs/index.ts.html +91 -0
  154. package/coverage/cli/src/integrations/gh/index.html +116 -0
  155. package/coverage/cli/src/integrations/gh/index.ts.html +94 -0
  156. package/coverage/cli/src/integrations/ide/add-ide-worktree-folders.ts.html +316 -0
  157. package/coverage/cli/src/integrations/ide/index.html +191 -0
  158. package/coverage/cli/src/integrations/ide/index.ts.html +103 -0
  159. package/coverage/cli/src/integrations/ide/open-ide-workspace.ts.html +238 -0
  160. package/coverage/cli/src/integrations/ide/provider-label.ts.html +157 -0
  161. package/coverage/cli/src/integrations/ide/remove-ide-worktree-folders.ts.html +520 -0
  162. package/coverage/cli/src/integrations/ide/types.ts.html +208 -0
  163. package/coverage/cli/src/integrations/jira/api.ts.html +1060 -0
  164. package/coverage/cli/src/integrations/jira/index.html +131 -0
  165. package/coverage/cli/src/integrations/jira/index.ts.html +142 -0
  166. package/coverage/cli/src/integrations/zed/add-folders-to-zed-workspace.ts.html +175 -0
  167. package/coverage/cli/src/integrations/zed/index.html +161 -0
  168. package/coverage/cli/src/integrations/zed/index.ts.html +94 -0
  169. package/coverage/cli/src/integrations/zed/open-zed-workspace.ts.html +238 -0
  170. package/coverage/cli/src/integrations/zed/reuse-zed-workspace.ts.html +256 -0
  171. package/coverage/cli/src/lib/assert-never/assert-never.ts.html +130 -0
  172. package/coverage/cli/src/lib/assert-never/index.html +131 -0
  173. package/coverage/cli/src/lib/assert-never/index.ts.html +88 -0
  174. package/coverage/cli/src/lib/command-catalog/command-catalog.ts.html +523 -0
  175. package/coverage/cli/src/lib/command-catalog/index.html +116 -0
  176. package/coverage/cli/src/lib/command-echo/command-echo.ts.html +319 -0
  177. package/coverage/cli/src/lib/command-echo/index.html +131 -0
  178. package/coverage/cli/src/lib/command-echo/index.ts.html +88 -0
  179. package/coverage/cli/src/lib/constants/constants.ts.html +472 -0
  180. package/coverage/cli/src/lib/constants/index.html +131 -0
  181. package/coverage/cli/src/lib/constants/index.ts.html +139 -0
  182. package/coverage/cli/src/lib/env-autoload/env-autoload.ts.html +1111 -0
  183. package/coverage/cli/src/lib/env-autoload/index.html +116 -0
  184. package/coverage/cli/src/lib/errors/format-zx-error.ts.html +247 -0
  185. package/coverage/cli/src/lib/errors/index.html +146 -0
  186. package/coverage/cli/src/lib/errors/is-prompt-cancellation.ts.html +199 -0
  187. package/coverage/cli/src/lib/errors/operation-error.ts.html +325 -0
  188. package/coverage/cli/src/lib/git-guard/git-guard.ts.html +250 -0
  189. package/coverage/cli/src/lib/git-guard/index.html +131 -0
  190. package/coverage/cli/src/lib/git-guard/index.ts.html +91 -0
  191. package/coverage/cli/src/lib/git-utils/git-utils.ts.html +622 -0
  192. package/coverage/cli/src/lib/git-utils/index.html +131 -0
  193. package/coverage/cli/src/lib/git-utils/index.ts.html +115 -0
  194. package/coverage/cli/src/lib/infra-kit-config/index.html +131 -0
  195. package/coverage/cli/src/lib/infra-kit-config/index.ts.html +142 -0
  196. package/coverage/cli/src/lib/infra-kit-config/infra-kit-config.ts.html +1447 -0
  197. package/coverage/cli/src/lib/json-output/index.html +116 -0
  198. package/coverage/cli/src/lib/json-output/json-output.ts.html +226 -0
  199. package/coverage/cli/src/lib/logger/index.html +116 -0
  200. package/coverage/cli/src/lib/logger/index.ts.html +205 -0
  201. package/coverage/cli/src/lib/managed-block/index.html +131 -0
  202. package/coverage/cli/src/lib/managed-block/index.ts.html +109 -0
  203. package/coverage/cli/src/lib/managed-block/managed-block.ts.html +520 -0
  204. package/coverage/cli/src/lib/package-config/index.html +146 -0
  205. package/coverage/cli/src/lib/package-config/index.ts.html +94 -0
  206. package/coverage/cli/src/lib/package-config/package-config-schema.ts.html +142 -0
  207. package/coverage/cli/src/lib/package-config/package-config.ts.html +376 -0
  208. package/coverage/cli/src/lib/package-validator/checks/config-check.ts.html +175 -0
  209. package/coverage/cli/src/lib/package-validator/checks/files-check.ts.html +172 -0
  210. package/coverage/cli/src/lib/package-validator/checks/index.html +176 -0
  211. package/coverage/cli/src/lib/package-validator/checks/index.ts.html +97 -0
  212. package/coverage/cli/src/lib/package-validator/checks/scripts-check.ts.html +154 -0
  213. package/coverage/cli/src/lib/package-validator/checks/turbo-check.ts.html +226 -0
  214. package/coverage/cli/src/lib/package-validator/fs-utils.ts.html +139 -0
  215. package/coverage/cli/src/lib/package-validator/index.html +146 -0
  216. package/coverage/cli/src/lib/package-validator/index.ts.html +94 -0
  217. package/coverage/cli/src/lib/package-validator/loader/config-loader.ts.html +316 -0
  218. package/coverage/cli/src/lib/package-validator/loader/index.html +146 -0
  219. package/coverage/cli/src/lib/package-validator/loader/index.ts.html +91 -0
  220. package/coverage/cli/src/lib/package-validator/loader/package-discovery.ts.html +379 -0
  221. package/coverage/cli/src/lib/package-validator/package-validator.ts.html +229 -0
  222. package/coverage/cli/src/lib/path-display/index.html +131 -0
  223. package/coverage/cli/src/lib/path-display/index.ts.html +88 -0
  224. package/coverage/cli/src/lib/path-display/path-display.ts.html +211 -0
  225. package/coverage/cli/src/lib/release-id/index.html +131 -0
  226. package/coverage/cli/src/lib/release-id/index.ts.html +130 -0
  227. package/coverage/cli/src/lib/release-id/release-id.ts.html +859 -0
  228. package/coverage/cli/src/lib/release-utils/index.html +131 -0
  229. package/coverage/cli/src/lib/release-utils/index.ts.html +130 -0
  230. package/coverage/cli/src/lib/release-utils/release-utils.ts.html +778 -0
  231. package/coverage/cli/src/lib/render/index.html +116 -0
  232. package/coverage/cli/src/lib/render/render.ts.html +157 -0
  233. package/coverage/cli/src/lib/vendor/__tests__/index.html +116 -0
  234. package/coverage/cli/src/lib/vendor/__tests__/zx-mock.ts.html +181 -0
  235. package/coverage/cli/src/lib/vendor/config-schema.ts.html +319 -0
  236. package/coverage/cli/src/lib/vendor/config.ts.html +259 -0
  237. package/coverage/cli/src/lib/vendor/factory-config-schema.ts.html +190 -0
  238. package/coverage/cli/src/lib/vendor/factory-config.ts.html +358 -0
  239. package/coverage/cli/src/lib/vendor/hash.ts.html +133 -0
  240. package/coverage/cli/src/lib/vendor/index.html +251 -0
  241. package/coverage/cli/src/lib/vendor/index.ts.html +154 -0
  242. package/coverage/cli/src/lib/vendor/manifest.ts.html +538 -0
  243. package/coverage/cli/src/lib/vendor/skip-sets.ts.html +229 -0
  244. package/coverage/cli/src/lib/vendor/sync-ops.ts.html +955 -0
  245. package/coverage/cli/src/lib/vendor/walk.ts.html +253 -0
  246. package/coverage/cli/src/lib/version-utils/index.html +161 -0
  247. package/coverage/cli/src/lib/version-utils/index.ts.html +139 -0
  248. package/coverage/cli/src/lib/version-utils/load-existing-versions.ts.html +343 -0
  249. package/coverage/cli/src/lib/version-utils/next-version.ts.html +934 -0
  250. package/coverage/cli/src/lib/version-utils/version-utils.ts.html +178 -0
  251. package/coverage/cli/src/lib/worktrees/index.html +131 -0
  252. package/coverage/cli/src/lib/worktrees/index.ts.html +88 -0
  253. package/coverage/cli/src/lib/worktrees/remove-worktrees.ts.html +283 -0
  254. package/coverage/cli/src/tui/boot.tsx.html +265 -0
  255. package/coverage/cli/src/tui/index.html +116 -0
  256. package/coverage/cli/src/tui/screens/command-palette.tsx.html +562 -0
  257. package/coverage/cli/src/tui/screens/index.html +116 -0
  258. package/coverage/cli/src/types.ts.html +283 -0
  259. package/coverage/clover.xml +4488 -0
  260. package/coverage/coverage-final.json +156 -0
  261. package/coverage/favicon.png +0 -0
  262. package/coverage/index.html +1076 -0
  263. package/coverage/prettify.css +1 -0
  264. package/coverage/prettify.js +2 -0
  265. package/coverage/sort-arrow-sprite.png +0 -0
  266. package/coverage/sorter.js +210 -0
  267. package/dist/chunk-DB6CTNBS.js +3 -0
  268. package/dist/chunk-DB6CTNBS.js.map +7 -0
  269. package/dist/chunk-SGR2XAVR.js +164 -0
  270. package/dist/chunk-SGR2XAVR.js.map +7 -0
  271. package/dist/cli.js +5 -5
  272. package/dist/cli.js.map +3 -3
  273. package/dist/dev-server.js +13 -0
  274. package/dist/dev-server.js.map +7 -0
  275. package/dist/mcp.js +1 -1
  276. package/dist/mcp.js.map +1 -1
  277. package/package.json +6 -1
  278. package/scripts/build.js +4 -4
  279. package/src/.omc/state/agent-replay-2ac0dcd0-01f7-41a8-a8c9-f2195599817b.jsonl +5 -0
  280. package/src/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/mission-state.json +79 -0
  281. package/src/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/pre-tool-advisory-throttle.json +26 -0
  282. package/src/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/subagent-tracking-state.json +26 -0
  283. package/src/commands/doctor/doctor.ts +53 -0
  284. package/src/commands/env-autoload/env-autoload.ts +14 -2
  285. package/src/commands/env-clear/env-clear.ts +48 -7
  286. package/src/commands/env-load/env-load.ts +23 -1
  287. package/src/commands/init/__tests__/shell-body.test.ts +73 -3
  288. package/src/commands/init/init.ts +74 -7
  289. package/src/dev/__tests__/dev-server-options.test.ts +57 -0
  290. package/src/dev/__tests__/dev-server.test.ts +420 -0
  291. package/src/dev/__tests__/discovery.test.ts +181 -0
  292. package/src/dev/__tests__/fixtures.ts +257 -0
  293. package/src/dev/__tests__/ports.test.ts +98 -0
  294. package/src/dev/__tests__/serverless-local-run.test.ts +533 -0
  295. package/src/dev/dev-server.ts +796 -0
  296. package/src/dev/discovery.ts +229 -0
  297. package/src/dev/interfaces.ts +11 -0
  298. package/src/dev/managed-child.ts +73 -0
  299. package/src/dev/ports.ts +100 -0
  300. package/src/dev/serverless-local-run.ts +329 -0
  301. package/src/dev/turbo-watch.ts +62 -0
  302. package/src/dev/ui-dev.ts +62 -0
  303. package/src/entry/cli.ts +25 -6
  304. package/src/entry/dev-server.ts +103 -0
  305. package/src/lib/command-catalog/__tests__/__snapshots__/command-catalog.test.ts.snap +1 -0
  306. package/src/lib/command-catalog/command-catalog.ts +4 -0
  307. package/src/lib/constants/constants.ts +38 -0
  308. package/src/lib/constants/index.ts +4 -0
  309. package/src/lib/env-autoload/__tests__/env-autoload.test.ts +25 -0
  310. package/src/lib/env-autoload/env-autoload.ts +35 -4
  311. package/src/lib/infra-kit-config/index.ts +2 -0
  312. package/src/lib/infra-kit-config/infra-kit-config.ts +22 -0
  313. package/src/lib/warm-cache/__tests__/warm-cache.test.ts +164 -0
  314. package/src/lib/warm-cache/index.ts +7 -0
  315. package/src/lib/warm-cache/warm-cache.ts +136 -0
  316. package/tsconfig.tsbuildinfo +1 -1
  317. package/dist/chunk-VI7TEWVJ.js +0 -164
  318. package/dist/chunk-VI7TEWVJ.js.map +0 -7
@@ -0,0 +1,7 @@
1
+ {
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"]
7
+ }
package/dist/mcp.js CHANGED
@@ -1,2 +1,2 @@
1
- import{W as m,b as s,c as p,d as c}from"./chunk-VI7TEWVJ.js";import"./chunk-WA4BQRDC.js";import{StdioServerTransport as g}from"@modelcontextprotocol/sdk/server/stdio.js";import h from"node:process";import o from"node:process";var l=r=>{o.on("SIGINT",()=>{r.info({msg:"Received SIGINT. Shutting down..."}),o.exit(0)}),o.on("SIGTERM",()=>{r.info({msg:"Received SIGTERM. Shutting down..."}),o.exit(0)}),o.on("uncaughtException",e=>{r.fatal({err:e,msg:"Uncaught Exception"}),r.error(`Uncaught Exception! Check ${s}. Shutting down...`),r.flush(),o.exit(1)}),o.on("unhandledRejection",(e,n)=>{r.fatal({reason:e,promise:n,msg:"Unhandled Rejection"}),r.error(`Unhandled Rejection! Check ${s}. Shutting down...`),r.flush(),o.exit(1)})};import{McpServer as x}from"@modelcontextprotocol/sdk/server/mcp.js";var d=async r=>{};var u=async r=>{};var a=r=>async e=>{let{toolName:n,handler:S}=r;c.info({msg:`Tool execution started: ${n}`,params:e});try{let i=await S({...e,confirmedCommand:!0});return c.info({msg:`Tool execution successful: ${n}`}),i}catch(i){throw c.error({err:i,params:e,msg:`Tool execution failed: ${n}`}),i}};var f=async r=>{for(let e of m())r.registerTool(e.name,{description:e.description,inputSchema:e.inputSchema,outputSchema:e.outputSchema},a({toolName:e.name,handler:e.handler}))};async function v(){let r=new x({name:"infra-kit",version:"1.0.0"},{capabilities:{resources:{},tools:{},prompts:{}}});return await d(r),await u(r),await f(r),r}var t=p(),T=async()=>{let r;try{r=await v(),t.info("MCP Server instance created")}catch(e){t.error({err:e,msg:"Failed to create MCP server"}),t.error("Fatal error during server creation."),h.exit(1)}try{let e=new g;await r.connect(e),t.info({msg:"Server connected to transport. Ready."})}catch(e){t.error({err:e,msg:"Failed to initialize server"}),t.error("Fatal error during server transport init."),h.exit(1)}};l(t);T();
1
+ import{S as m,a as s,b as p,c}from"./chunk-SGR2XAVR.js";import"./chunk-DB6CTNBS.js";import"./chunk-WA4BQRDC.js";import{StdioServerTransport as g}from"@modelcontextprotocol/sdk/server/stdio.js";import h from"node:process";import o from"node:process";var l=r=>{o.on("SIGINT",()=>{r.info({msg:"Received SIGINT. Shutting down..."}),o.exit(0)}),o.on("SIGTERM",()=>{r.info({msg:"Received SIGTERM. Shutting down..."}),o.exit(0)}),o.on("uncaughtException",e=>{r.fatal({err:e,msg:"Uncaught Exception"}),r.error(`Uncaught Exception! Check ${s}. Shutting down...`),r.flush(),o.exit(1)}),o.on("unhandledRejection",(e,n)=>{r.fatal({reason:e,promise:n,msg:"Unhandled Rejection"}),r.error(`Unhandled Rejection! Check ${s}. Shutting down...`),r.flush(),o.exit(1)})};import{McpServer as x}from"@modelcontextprotocol/sdk/server/mcp.js";var d=async r=>{};var u=async r=>{};var a=r=>async e=>{let{toolName:n,handler:S}=r;c.info({msg:`Tool execution started: ${n}`,params:e});try{let i=await S({...e,confirmedCommand:!0});return c.info({msg:`Tool execution successful: ${n}`}),i}catch(i){throw c.error({err:i,params:e,msg:`Tool execution failed: ${n}`}),i}};var f=async r=>{for(let e of m())r.registerTool(e.name,{description:e.description,inputSchema:e.inputSchema,outputSchema:e.outputSchema},a({toolName:e.name,handler:e.handler}))};async function v(){let r=new x({name:"infra-kit",version:"1.0.0"},{capabilities:{resources:{},tools:{},prompts:{}}});return await d(r),await u(r),await f(r),r}var t=p(),T=async()=>{let r;try{r=await v(),t.info("MCP Server instance created")}catch(e){t.error({err:e,msg:"Failed to create MCP server"}),t.error("Fatal error during server creation."),h.exit(1)}try{let e=new g;await r.connect(e),t.info({msg:"Server connected to transport. Ready."})}catch(e){t.error({err:e,msg:"Failed to initialize server"}),t.error("Fatal error during server transport init."),h.exit(1)}};l(t);T();
2
2
  //# sourceMappingURL=mcp.js.map
package/dist/mcp.js.map CHANGED
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/entry/mcp.ts", "../src/lib/error-handlers/index.ts", "../src/mcp/server.ts", "../src/mcp/prompts/index.ts", "../src/mcp/resources/index.ts", "../src/lib/tool-handler/tool-handler.ts", "../src/mcp/tools/index.ts"],
4
4
  "sourcesContent": ["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport process from 'node:process'\n\nimport { setupErrorHandlers } from 'src/lib/error-handlers'\nimport { initLoggerMcp } from 'src/lib/logger'\n\nimport { createMcpServer } from '../mcp/server'\n\nconst logger = initLoggerMcp()\n\nconst startServer = async () => {\n let server\n\n try {\n server = await createMcpServer()\n\n logger.info('MCP Server instance created')\n } catch (error) {\n logger.error({ err: error, msg: 'Failed to create MCP server' })\n logger.error(`Fatal error during server creation.`)\n\n process.exit(1)\n }\n\n try {\n const transport = new StdioServerTransport()\n\n await server.connect(transport)\n\n logger.info({ msg: 'Server connected to transport. Ready.' })\n } catch (error) {\n logger.error({ err: error, msg: 'Failed to initialize server' })\n logger.error(`Fatal error during server transport init.`)\n\n process.exit(1)\n }\n}\n\n// Setup error handlers\nsetupErrorHandlers(logger)\n\n// Start the server\nstartServer()\n", "import process from 'node:process'\nimport type { Logger } from 'pino'\n\nimport { LOG_FILE_PATH } from '../logger/index'\n\n/**\n * Setup error handlers for the application\n * @param logger - The logger instance\n *\n * ONLY FOR SERVER!\n */\nexport const setupErrorHandlers = (logger: Logger) => {\n process.on('SIGINT', () => {\n logger.info({ msg: 'Received SIGINT. Shutting down...' })\n process.exit(0)\n })\n\n process.on('SIGTERM', () => {\n logger.info({ msg: 'Received SIGTERM. Shutting down...' })\n process.exit(0)\n })\n\n process.on('uncaughtException', (error) => {\n logger.fatal({ err: error, msg: 'Uncaught Exception' })\n logger.error(`Uncaught Exception! Check ${LOG_FILE_PATH}. Shutting down...`)\n logger.flush()\n process.exit(1)\n })\n\n process.on('unhandledRejection', (reason, promise) => {\n logger.fatal({ reason, promise, msg: 'Unhandled Rejection' })\n logger.error(`Unhandled Rejection! Check ${LOG_FILE_PATH}. Shutting down...`)\n logger.flush()\n process.exit(1)\n })\n}\n", "import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\n\nimport { initializePrompts } from './prompts'\nimport { initializeResources } from './resources'\nimport { initializeTools } from './tools'\n\nexport async function createMcpServer() {\n const server = new McpServer(\n {\n name: 'infra-kit',\n version: '1.0.0',\n },\n {\n capabilities: {\n resources: {},\n tools: {},\n prompts: {},\n },\n },\n )\n\n await initializePrompts(server)\n await initializeResources(server)\n await initializeTools(server)\n\n return server\n}\n", "import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\n\nexport const initializePrompts = async (_server: McpServer) => {}\n", "import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\n\nexport const initializeResources = async (_server: McpServer) => {}\n", "import { logger } from 'src/lib/logger'\nimport type { ToolsExecutionResult } from 'src/types'\n\ninterface ToolHandlerArgs {\n toolName: string\n handler: (params: any) => Promise<ToolsExecutionResult>\n}\n\nexport const createToolHandler = (args: ToolHandlerArgs) => {\n return async (params: unknown) => {\n const { toolName, handler } = args\n\n logger.info({ msg: `Tool execution started: ${toolName}`, params })\n try {\n const payload = await handler({ ...(params as object), confirmedCommand: true })\n\n logger.info({ msg: `Tool execution successful: ${toolName}` })\n\n return payload\n } catch (error) {\n logger.error({\n err: error,\n params,\n msg: `Tool execution failed: ${toolName}`,\n })\n\n throw error\n }\n }\n}\n", "import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\n\nimport { getExposedMcpTools } from 'src/lib/command-catalog'\nimport { createToolHandler } from 'src/lib/tool-handler'\n\nexport const initializeTools = async (server: McpServer) => {\n // The registered tool set is derived from the single command catalog, filtered\n // by its explicit `mcpExposed` allowlist. doctor / vendor-sync / vendor-manifest\n // are intentionally excluded there and must never be registered here.\n for (const tool of getExposedMcpTools()) {\n server.registerTool(\n tool.name,\n {\n description: tool.description,\n inputSchema: tool.inputSchema,\n outputSchema: tool.outputSchema,\n },\n createToolHandler({ toolName: tool.name, handler: tool.handler }),\n )\n }\n}\n"],
5
- "mappings": "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",
5
+ "mappings": "gHAAA,OAAS,wBAAAA,MAA4B,4CACrC,OAAOC,MAAa,eCDpB,OAAOC,MAAa,eAWb,IAAMC,EAAsBC,GAAmB,CACpDC,EAAQ,GAAG,SAAU,IAAM,CACzBD,EAAO,KAAK,CAAE,IAAK,mCAAoC,CAAC,EACxDC,EAAQ,KAAK,CAAC,CAChB,CAAC,EAEDA,EAAQ,GAAG,UAAW,IAAM,CAC1BD,EAAO,KAAK,CAAE,IAAK,oCAAqC,CAAC,EACzDC,EAAQ,KAAK,CAAC,CAChB,CAAC,EAEDA,EAAQ,GAAG,oBAAsBC,GAAU,CACzCF,EAAO,MAAM,CAAE,IAAKE,EAAO,IAAK,oBAAqB,CAAC,EACtDF,EAAO,MAAM,6BAA6BG,CAAa,oBAAoB,EAC3EH,EAAO,MAAM,EACbC,EAAQ,KAAK,CAAC,CAChB,CAAC,EAEDA,EAAQ,GAAG,qBAAsB,CAACG,EAAQC,IAAY,CACpDL,EAAO,MAAM,CAAE,OAAAI,EAAQ,QAAAC,EAAS,IAAK,qBAAsB,CAAC,EAC5DL,EAAO,MAAM,8BAA8BG,CAAa,oBAAoB,EAC5EH,EAAO,MAAM,EACbC,EAAQ,KAAK,CAAC,CAChB,CAAC,CACH,ECnCA,OAAS,aAAAK,MAAiB,0CCEnB,IAAMC,EAAoB,MAAOC,GAAuB,CAAC,ECAzD,IAAMC,EAAsB,MAAOC,GAAuB,CAAC,ECM3D,IAAMC,EAAqBC,GACzB,MAAOC,GAAoB,CAChC,GAAM,CAAE,SAAAC,EAAU,QAAAC,CAAQ,EAAIH,EAE9BI,EAAO,KAAK,CAAE,IAAK,2BAA2BF,CAAQ,GAAI,OAAAD,CAAO,CAAC,EAClE,GAAI,CACF,IAAMI,EAAU,MAAMF,EAAQ,CAAE,GAAIF,EAAmB,iBAAkB,EAAK,CAAC,EAE/E,OAAAG,EAAO,KAAK,CAAE,IAAK,8BAA8BF,CAAQ,EAAG,CAAC,EAEtDG,CACT,OAASC,EAAO,CACd,MAAAF,EAAO,MAAM,CACX,IAAKE,EACL,OAAAL,EACA,IAAK,0BAA0BC,CAAQ,EACzC,CAAC,EAEKI,CACR,CACF,ECvBK,IAAMC,EAAkB,MAAOC,GAAsB,CAI1D,QAAWC,KAAQC,EAAmB,EACpCF,EAAO,aACLC,EAAK,KACL,CACE,YAAaA,EAAK,YAClB,YAAaA,EAAK,YAClB,aAAcA,EAAK,YACrB,EACAE,EAAkB,CAAE,SAAUF,EAAK,KAAM,QAASA,EAAK,OAAQ,CAAC,CAClE,CAEJ,EJdA,eAAsBG,GAAkB,CACtC,IAAMC,EAAS,IAAIC,EACjB,CACE,KAAM,YACN,QAAS,OACX,EACA,CACE,aAAc,CACZ,UAAW,CAAC,EACZ,MAAO,CAAC,EACR,QAAS,CAAC,CACZ,CACF,CACF,EAEA,aAAMC,EAAkBF,CAAM,EAC9B,MAAMG,EAAoBH,CAAM,EAChC,MAAMI,EAAgBJ,CAAM,EAErBA,CACT,CFlBA,IAAMK,EAASC,EAAc,EAEvBC,EAAc,SAAY,CAC9B,IAAIC,EAEJ,GAAI,CACFA,EAAS,MAAMC,EAAgB,EAE/BJ,EAAO,KAAK,6BAA6B,CAC3C,OAASK,EAAO,CACdL,EAAO,MAAM,CAAE,IAAKK,EAAO,IAAK,6BAA8B,CAAC,EAC/DL,EAAO,MAAM,qCAAqC,EAElDM,EAAQ,KAAK,CAAC,CAChB,CAEA,GAAI,CACF,IAAMC,EAAY,IAAIC,EAEtB,MAAML,EAAO,QAAQI,CAAS,EAE9BP,EAAO,KAAK,CAAE,IAAK,uCAAwC,CAAC,CAC9D,OAASK,EAAO,CACdL,EAAO,MAAM,CAAE,IAAKK,EAAO,IAAK,6BAA8B,CAAC,EAC/DL,EAAO,MAAM,2CAA2C,EAExDM,EAAQ,KAAK,CAAC,CAChB,CACF,EAGAG,EAAmBT,CAAM,EAGzBE,EAAY",
6
6
  "names": ["StdioServerTransport", "process", "process", "setupErrorHandlers", "logger", "process", "error", "LOG_FILE_PATH", "reason", "promise", "McpServer", "initializePrompts", "_server", "initializeResources", "_server", "createToolHandler", "args", "params", "toolName", "handler", "logger", "payload", "error", "initializeTools", "server", "tool", "getExposedMcpTools", "createToolHandler", "createMcpServer", "server", "McpServer", "initializePrompts", "initializeResources", "initializeTools", "logger", "initLoggerMcp", "startServer", "server", "createMcpServer", "error", "process", "transport", "StdioServerTransport", "setupErrorHandlers"]
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "infra-kit",
3
3
  "type": "module",
4
- "version": "0.1.125",
4
+ "version": "0.1.127",
5
5
  "description": "infra-kit",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -37,11 +37,15 @@
37
37
  "fix": "pnpm run prettier-fix && pnpm run eslint-fix && pnpm run qa"
38
38
  },
39
39
  "dependencies": {
40
+ "@aws-lambda-powertools/logger": "^2.33.1",
40
41
  "@inquirer/checkbox": "^5.2.1",
41
42
  "@inquirer/confirm": "^6.1.1",
42
43
  "@inquirer/select": "^5.2.1",
43
44
  "@modelcontextprotocol/sdk": "^1.29.0",
45
+ "chalk": "^5.6.2",
46
+ "chokidar": "^5.0.0",
44
47
  "commander": "^15.0.0",
48
+ "fastify": "5.10.0",
45
49
  "ink": "^7.1.0",
46
50
  "pino": "^10.3.1",
47
51
  "pino-pretty": "^13.1.3",
@@ -51,6 +55,7 @@
51
55
  "zx": "^8.8.5"
52
56
  },
53
57
  "devDependencies": {
58
+ "@types/aws-lambda": "^8.10.162",
54
59
  "@types/react": "catalog:",
55
60
  "@wl/eslint-config": "workspace:*",
56
61
  "@wl/vitest-config": "workspace:*",
package/scripts/build.js CHANGED
@@ -52,10 +52,10 @@ for (const entryPoint of entryPoints) {
52
52
  }
53
53
 
54
54
  // 2. Emit the public type declarations with tsc (esbuild does not generate them).
55
- // The library entry (src/entry/index.ts) only re-exports the package-config
56
- // API via relative imports, so tsc needs no project config — a direct CLI
57
- // call replaces the separate tsconfig.build.json. `--ignoreConfig` is
58
- // required because tsconfig.json is present alongside the input file.
55
+ // The library entry (src/entry/index.ts) only re-exports public API via relative
56
+ // imports, so tsc needs no project config — a direct CLI call replaces the separate
57
+ // tsconfig.build.json. `--ignoreConfig` is required because tsconfig.json is present
58
+ // alongside the input file.
59
59
  execFileSync(
60
60
  'tsc',
61
61
  [
@@ -0,0 +1,5 @@
1
+ {"t":0,"agent":"aa7e5ef","agent_type":"architect","event":"agent_start","parent_mode":"none"}
2
+ {"t":0,"agent":"aa7e5ef","agent_type":"architect","event":"agent_stop","success":true,"duration_ms":256452}
3
+ {"t":0,"agent":"aceccf3","agent_type":"critic","event":"agent_start","parent_mode":"none"}
4
+ {"t":0,"agent":"aceccf3","agent_type":"critic","event":"agent_stop","success":true,"duration_ms":242260}
5
+ {"t":0,"agent":"system","event":"skill_invoked","skill_name":"oh-my-claudecode:ralph"}
@@ -0,0 +1,79 @@
1
+ {
2
+ "updatedAt": "2026-07-06T07:54:59.229Z",
3
+ "missions": [
4
+ {
5
+ "id": "session:2ac0dcd0-01f7-41a8-a8c9-f2195599817b:none",
6
+ "source": "session",
7
+ "name": "none",
8
+ "objective": "Session mission",
9
+ "createdAt": "2026-07-06T07:45:03.319Z",
10
+ "updatedAt": "2026-07-06T07:54:59.229Z",
11
+ "status": "done",
12
+ "workerCount": 2,
13
+ "taskCounts": {
14
+ "total": 2,
15
+ "pending": 0,
16
+ "blocked": 0,
17
+ "inProgress": 0,
18
+ "completed": 2,
19
+ "failed": 0
20
+ },
21
+ "agents": [
22
+ {
23
+ "name": "architect:aa7e5ef",
24
+ "role": "architect",
25
+ "ownership": "aa7e5efba2542b4ed",
26
+ "status": "done",
27
+ "currentStep": null,
28
+ "latestUpdate": "completed",
29
+ "completedSummary": null,
30
+ "updatedAt": "2026-07-06T07:49:19.771Z"
31
+ },
32
+ {
33
+ "name": "critic:aceccf3",
34
+ "role": "critic",
35
+ "ownership": "aceccf3c05603a5c6",
36
+ "status": "done",
37
+ "currentStep": null,
38
+ "latestUpdate": "completed",
39
+ "completedSummary": null,
40
+ "updatedAt": "2026-07-06T07:54:59.229Z"
41
+ }
42
+ ],
43
+ "timeline": [
44
+ {
45
+ "id": "session-start:aa7e5efba2542b4ed:2026-07-06T07:45:03.319Z",
46
+ "at": "2026-07-06T07:45:03.319Z",
47
+ "kind": "update",
48
+ "agent": "architect:aa7e5ef",
49
+ "detail": "started architect:aa7e5ef",
50
+ "sourceKey": "session-start:aa7e5efba2542b4ed"
51
+ },
52
+ {
53
+ "id": "session-stop:aa7e5efba2542b4ed:2026-07-06T07:49:19.771Z",
54
+ "at": "2026-07-06T07:49:19.771Z",
55
+ "kind": "completion",
56
+ "agent": "architect:aa7e5ef",
57
+ "detail": "completed",
58
+ "sourceKey": "session-stop:aa7e5efba2542b4ed"
59
+ },
60
+ {
61
+ "id": "session-start:aceccf3c05603a5c6:2026-07-06T07:50:56.969Z",
62
+ "at": "2026-07-06T07:50:56.969Z",
63
+ "kind": "update",
64
+ "agent": "critic:aceccf3",
65
+ "detail": "started critic:aceccf3",
66
+ "sourceKey": "session-start:aceccf3c05603a5c6"
67
+ },
68
+ {
69
+ "id": "session-stop:aceccf3c05603a5c6:2026-07-06T07:54:59.229Z",
70
+ "at": "2026-07-06T07:54:59.229Z",
71
+ "kind": "completion",
72
+ "agent": "critic:aceccf3",
73
+ "detail": "completed",
74
+ "sourceKey": "session-stop:aceccf3c05603a5c6"
75
+ }
76
+ ]
77
+ }
78
+ ]
79
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "version": 1,
3
+ "entries": {
4
+ "79a93d4a2f8f50b95f852280616242fee1855dc99a3c75211917f55e72e95fae": {
5
+ "last_emitted_at_ms": 1783324920412,
6
+ "message": "Use parallel execution for independent tasks. Use run_in_background for long operations (npm install, builds, tests)."
7
+ },
8
+ "445ed27a3872b681d98190bae61ccb84954e1bc4e140df5370be958dee776b3a": {
9
+ "last_emitted_at_ms": 1783324912441,
10
+ "message": "Verify changes work after editing. Test functionality before marking complete."
11
+ },
12
+ "466399dafa2d20f60587180bad0a07358eb7f2bce724df0ff682f038ad33f5ad": {
13
+ "last_emitted_at_ms": 1783324804396,
14
+ "message": "Read multiple files in parallel when possible for faster analysis."
15
+ },
16
+ "e6902b7833dc263b1fbe501dce7643a9b8d94e7c88241163217ce252050f847f": {
17
+ "last_emitted_at_ms": 1783324256759,
18
+ "message": "Spawning agent: oh-my-claudecode:critic (inherit) | Task: Critic review warm-cache plan v2"
19
+ },
20
+ "4ac1e495e73da114017671b508923da62c3afc681662bfbd1e62586693a6b5d5": {
21
+ "last_emitted_at_ms": 1783323903128,
22
+ "message": "Spawning agent: oh-my-claudecode:architect (inherit) | Task: Architect review warm-cache plan"
23
+ }
24
+ },
25
+ "updated_at": "2026-07-06T08:02:00.412Z"
26
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "agents": [
3
+ {
4
+ "agent_id": "aa7e5efba2542b4ed",
5
+ "agent_type": "oh-my-claudecode:architect",
6
+ "started_at": "2026-07-06T07:45:03.319Z",
7
+ "parent_mode": "none",
8
+ "status": "completed",
9
+ "completed_at": "2026-07-06T07:49:19.771Z",
10
+ "duration_ms": 256452
11
+ },
12
+ {
13
+ "agent_id": "aceccf3c05603a5c6",
14
+ "agent_type": "oh-my-claudecode:critic",
15
+ "started_at": "2026-07-06T07:50:56.969Z",
16
+ "parent_mode": "none",
17
+ "status": "completed",
18
+ "completed_at": "2026-07-06T07:54:59.229Z",
19
+ "duration_ms": 242260
20
+ }
21
+ ],
22
+ "total_spawned": 2,
23
+ "total_completed": 2,
24
+ "total_failed": 0,
25
+ "last_updated": "2026-07-06T07:54:59.405Z"
26
+ }
@@ -7,6 +7,7 @@ import { $ } from 'zx'
7
7
  import { AGENTS_MARKER_END, AGENTS_MARKER_START } from 'src/commands/init/agent-files'
8
8
  import { MARKER_END, MARKER_START, buildShellBlock } from 'src/commands/init/init'
9
9
  import { getDopplerProject, listDopplerProjects } from 'src/integrations/doppler'
10
+ import { DEFAULT_WARM_TTL_SECONDS, ENV_LOAD_FILE, getProjectWarmCacheDir } from 'src/lib/constants'
10
11
  import { getProjectRoot } from 'src/lib/git-utils/git-utils'
11
12
  import {
12
13
  getInfraKitConfig,
@@ -17,6 +18,7 @@ import {
17
18
  import { logger } from 'src/lib/logger'
18
19
  import { hasManagedBlock } from 'src/lib/managed-block'
19
20
  import { tildify } from 'src/lib/path-display'
21
+ import { canonicalizeProjectRoot } from 'src/lib/warm-cache'
20
22
  import { defineMcpTool, textContent } from 'src/types'
21
23
 
22
24
  interface CheckResult {
@@ -74,6 +76,50 @@ const checkZshrcInitialized = (): CheckResult => {
74
76
  return { name, status: 'pass', message: 'infra-kit shell block in ~/.zshrc is up to date' }
75
77
  }
76
78
 
79
+ /**
80
+ * Surface the state of the project-scoped warm env cache (populated by an
81
+ * auto-loaded shell startup). Informational only — always passes — since a
82
+ * missing or stale warm file just means the next auto-load will (re)populate
83
+ * it rather than indicating a problem.
84
+ */
85
+ const checkWarmCache = async (): Promise<CheckResult> => {
86
+ const name = 'warm cache'
87
+
88
+ let root: string
89
+
90
+ try {
91
+ root = await getProjectRoot()
92
+ } catch {
93
+ return { name, status: 'pass', message: 'warm cache: not a git project' }
94
+ }
95
+
96
+ const canon = canonicalizeProjectRoot(root)
97
+
98
+ if (!canon) {
99
+ return { name, status: 'pass', message: 'warm cache: unavailable' }
100
+ }
101
+
102
+ const warmFile = path.join(getProjectWarmCacheDir(canon), ENV_LOAD_FILE)
103
+
104
+ if (!fs.existsSync(warmFile)) {
105
+ return { name, status: 'pass', message: 'warm cache: none yet (populated on next auto-load)' }
106
+ }
107
+
108
+ const ageSeconds = Math.floor((Date.now() - fs.statSync(warmFile).mtimeMs) / 1000)
109
+ const ageMinutes = Math.floor(ageSeconds / 60)
110
+ const ttlMinutes = Math.floor(DEFAULT_WARM_TTL_SECONDS / 60)
111
+
112
+ if (ageSeconds >= DEFAULT_WARM_TTL_SECONDS) {
113
+ return {
114
+ name,
115
+ status: 'pass',
116
+ message: `warm cache: present but stale (${ageMinutes}m old, TTL ${ttlMinutes}m) — will refresh`,
117
+ }
118
+ }
119
+
120
+ return { name, status: 'pass', message: `warm cache: present, ${ageMinutes}m old` }
121
+ }
122
+
77
123
  const checkPnpmWorkspaceVirtualStore = async (): Promise<CheckResult> => {
78
124
  const name = 'pnpm enableGlobalVirtualStore'
79
125
 
@@ -467,8 +513,15 @@ export const doctor = async () => {
467
513
  'typescript-language-server is installed',
468
514
  'typescript-language-server is not installed. Install from: https://github.com/typescript-language-server/typescript-language-server#installing',
469
515
  ),
516
+ checkCommand(
517
+ 'cmux installed',
518
+ ['cmux', '--version'],
519
+ 'cmux is installed',
520
+ 'cmux is not installed. Install from: https://cmux.com/',
521
+ ),
470
522
  checkRtkConfigured(),
471
523
  Promise.resolve(checkZshrcInitialized()),
524
+ checkWarmCache(),
472
525
  checkPnpmWorkspaceVirtualStore(),
473
526
  checkInfraKitConfigValid(),
474
527
  checkDopplerProjectExists(),
@@ -1,5 +1,14 @@
1
1
  import { runEnvAutoLoad } from 'src/lib/env-autoload'
2
2
 
3
+ export interface EnvAutoloadArgs {
4
+ /**
5
+ * Canonical (realpath'd) project dir the shell computed (`${dir:A}`) and passed
6
+ * via `--project-dir`. Forwarded to enable the project-scoped warm cache; absent
7
+ * when invoked without the flag (then no warm copy is written).
8
+ */
9
+ projectDir?: string
10
+ }
11
+
3
12
  /**
4
13
  * Internal command invoked (backgrounded) by the `infra-kit init` shell-startup
5
14
  * integration. Runs the 'shell-startup' trigger, writing env-load.sh when
@@ -7,6 +16,9 @@ import { runEnvAutoLoad } from 'src/lib/env-autoload'
7
16
  * a subsequent prompt. Intentionally writes NOTHING to stdout and never throws —
8
17
  * auto-load must never disrupt shell startup.
9
18
  */
10
- export const envAutoload = async (): Promise<void> => {
11
- await runEnvAutoLoad({ expectedTrigger: 'shell-startup' })
19
+ export const envAutoload = async ({ projectDir }: EnvAutoloadArgs = {}): Promise<void> => {
20
+ // `force`: the shell may have just WARM-sourced the same config (exporting the
21
+ // auto-load marker this process inherits); without it the refresh would self-skip
22
+ // and stale warm secrets would never be replaced this session.
23
+ await runEnvAutoLoad({ expectedTrigger: 'shell-startup', projectDir, force: true })
12
24
  }