infra-kit 0.1.126 → 0.1.128

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 (335) 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/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/pre-tool-advisory-throttle.json +10 -0
  33. package/.turbo/turbo-build.log +7 -6
  34. package/.turbo/turbo-check.log +1 -1
  35. package/.turbo/turbo-eslint-check.log +2 -1
  36. package/.turbo/turbo-infra-kit-check.log +14 -0
  37. package/.turbo/turbo-prettier-check.log +1 -1
  38. package/.turbo/turbo-test.log +406 -128
  39. package/.turbo/turbo-ts-check.log +1 -1
  40. package/coverage/base.css +224 -0
  41. package/coverage/block-navigation.js +87 -0
  42. package/coverage/cli/index.html +116 -0
  43. package/coverage/cli/package.json.html +283 -0
  44. package/coverage/cli/src/commands/audit/audit.ts.html +616 -0
  45. package/coverage/cli/src/commands/audit/index.html +131 -0
  46. package/coverage/cli/src/commands/audit/index.ts.html +88 -0
  47. package/coverage/cli/src/commands/doctor/doctor.ts.html +1654 -0
  48. package/coverage/cli/src/commands/doctor/index.html +131 -0
  49. package/coverage/cli/src/commands/doctor/index.ts.html +88 -0
  50. package/coverage/cli/src/commands/env-clear/env-clear.ts.html +370 -0
  51. package/coverage/cli/src/commands/env-clear/index.html +131 -0
  52. package/coverage/cli/src/commands/env-clear/index.ts.html +88 -0
  53. package/coverage/cli/src/commands/env-list/env-list.ts.html +229 -0
  54. package/coverage/cli/src/commands/env-list/index.html +131 -0
  55. package/coverage/cli/src/commands/env-list/index.ts.html +88 -0
  56. package/coverage/cli/src/commands/env-load/env-load.ts.html +1201 -0
  57. package/coverage/cli/src/commands/env-load/index.html +131 -0
  58. package/coverage/cli/src/commands/env-load/index.ts.html +91 -0
  59. package/coverage/cli/src/commands/env-status/env-status.ts.html +409 -0
  60. package/coverage/cli/src/commands/env-status/index.html +131 -0
  61. package/coverage/cli/src/commands/env-status/index.ts.html +88 -0
  62. package/coverage/cli/src/commands/gh-merge-dev/gh-merge-dev.ts.html +694 -0
  63. package/coverage/cli/src/commands/gh-merge-dev/index.html +131 -0
  64. package/coverage/cli/src/commands/gh-merge-dev/index.ts.html +88 -0
  65. package/coverage/cli/src/commands/gh-release-deliver/gh-release-deliver.ts.html +1495 -0
  66. package/coverage/cli/src/commands/gh-release-deliver/index.html +131 -0
  67. package/coverage/cli/src/commands/gh-release-deliver/index.ts.html +88 -0
  68. package/coverage/cli/src/commands/gh-release-deploy-all/gh-release-deploy-all.ts.html +706 -0
  69. package/coverage/cli/src/commands/gh-release-deploy-all/index.html +131 -0
  70. package/coverage/cli/src/commands/gh-release-deploy-all/index.ts.html +88 -0
  71. package/coverage/cli/src/commands/gh-release-deploy-selected/gh-release-deploy-selected.ts.html +994 -0
  72. package/coverage/cli/src/commands/gh-release-deploy-selected/index.html +131 -0
  73. package/coverage/cli/src/commands/gh-release-deploy-selected/index.ts.html +88 -0
  74. package/coverage/cli/src/commands/gh-release-list/gh-release-list.ts.html +355 -0
  75. package/coverage/cli/src/commands/gh-release-list/index.html +131 -0
  76. package/coverage/cli/src/commands/gh-release-list/index.ts.html +88 -0
  77. package/coverage/cli/src/commands/init/agent-files.ts.html +742 -0
  78. package/coverage/cli/src/commands/init/index.html +146 -0
  79. package/coverage/cli/src/commands/init/init.ts.html +1159 -0
  80. package/coverage/cli/src/commands/init/migrate-config.ts.html +1219 -0
  81. package/coverage/cli/src/commands/release-create/index.html +131 -0
  82. package/coverage/cli/src/commands/release-create/index.ts.html +88 -0
  83. package/coverage/cli/src/commands/release-create/release-create.ts.html +1426 -0
  84. package/coverage/cli/src/commands/release-desc-edit/index.html +131 -0
  85. package/coverage/cli/src/commands/release-desc-edit/index.ts.html +88 -0
  86. package/coverage/cli/src/commands/release-desc-edit/release-desc-edit.ts.html +766 -0
  87. package/coverage/cli/src/commands/vendor-check/index.html +131 -0
  88. package/coverage/cli/src/commands/vendor-check/index.ts.html +88 -0
  89. package/coverage/cli/src/commands/vendor-check/vendor-check.ts.html +466 -0
  90. package/coverage/cli/src/commands/vendor-config/index.html +116 -0
  91. package/coverage/cli/src/commands/vendor-config/vendor-config.ts.html +571 -0
  92. package/coverage/cli/src/commands/vendor-diff/index.html +131 -0
  93. package/coverage/cli/src/commands/vendor-diff/index.ts.html +88 -0
  94. package/coverage/cli/src/commands/vendor-diff/vendor-diff.ts.html +316 -0
  95. package/coverage/cli/src/commands/vendor-manifest/index.html +131 -0
  96. package/coverage/cli/src/commands/vendor-manifest/index.ts.html +88 -0
  97. package/coverage/cli/src/commands/vendor-manifest/vendor-manifest.ts.html +265 -0
  98. package/coverage/cli/src/commands/vendor-sync/index.html +131 -0
  99. package/coverage/cli/src/commands/vendor-sync/index.ts.html +88 -0
  100. package/coverage/cli/src/commands/vendor-sync/vendor-sync.ts.html +355 -0
  101. package/coverage/cli/src/commands/version/index.html +131 -0
  102. package/coverage/cli/src/commands/version/index.ts.html +88 -0
  103. package/coverage/cli/src/commands/version/version.ts.html +184 -0
  104. package/coverage/cli/src/commands/worktrees-add/index.html +131 -0
  105. package/coverage/cli/src/commands/worktrees-add/index.ts.html +88 -0
  106. package/coverage/cli/src/commands/worktrees-add/worktrees-add.ts.html +1183 -0
  107. package/coverage/cli/src/commands/worktrees-list/index.html +131 -0
  108. package/coverage/cli/src/commands/worktrees-list/index.ts.html +88 -0
  109. package/coverage/cli/src/commands/worktrees-list/worktrees-list.ts.html +400 -0
  110. package/coverage/cli/src/commands/worktrees-reload/index.html +131 -0
  111. package/coverage/cli/src/commands/worktrees-reload/index.ts.html +88 -0
  112. package/coverage/cli/src/commands/worktrees-reload/worktrees-reload.ts.html +775 -0
  113. package/coverage/cli/src/commands/worktrees-remove/index.html +131 -0
  114. package/coverage/cli/src/commands/worktrees-remove/index.ts.html +88 -0
  115. package/coverage/cli/src/commands/worktrees-remove/worktrees-remove.ts.html +682 -0
  116. package/coverage/cli/src/commands/worktrees-sync/index.html +131 -0
  117. package/coverage/cli/src/commands/worktrees-sync/index.ts.html +88 -0
  118. package/coverage/cli/src/commands/worktrees-sync/worktrees-sync.ts.html +679 -0
  119. package/coverage/cli/src/dev/__tests__/fixtures.ts.html +787 -0
  120. package/coverage/cli/src/dev/__tests__/index.html +116 -0
  121. package/coverage/cli/src/dev/dev-server.ts.html +1855 -0
  122. package/coverage/cli/src/dev/discovery.ts.html +598 -0
  123. package/coverage/cli/src/dev/index.html +191 -0
  124. package/coverage/cli/src/dev/interfaces.ts.html +223 -0
  125. package/coverage/cli/src/dev/logger.ts.html +1102 -0
  126. package/coverage/cli/src/dev/ports.ts.html +430 -0
  127. package/coverage/cli/src/dev/serverless-local-run.ts.html +916 -0
  128. package/coverage/cli/src/entry/dev-server.ts.html +409 -0
  129. package/coverage/cli/src/entry/index.html +116 -0
  130. package/coverage/cli/src/index.html +116 -0
  131. package/coverage/cli/src/integrations/cmux/canonicalize-cmux-title.ts.html +178 -0
  132. package/coverage/cli/src/integrations/cmux/close-workspace-by-title.ts.html +262 -0
  133. package/coverage/cli/src/integrations/cmux/index.html +191 -0
  134. package/coverage/cli/src/integrations/cmux/index.ts.html +100 -0
  135. package/coverage/cli/src/integrations/cmux/list-workspace-titles.ts.html +226 -0
  136. package/coverage/cli/src/integrations/cmux/open-workspace-with-layout.ts.html +325 -0
  137. package/coverage/cli/src/integrations/cmux/workspace-title.ts.html +154 -0
  138. package/coverage/cli/src/integrations/cursor/add-folders-to-workspace.ts.html +337 -0
  139. package/coverage/cli/src/integrations/cursor/index.html +206 -0
  140. package/coverage/cli/src/integrations/cursor/index.ts.html +103 -0
  141. package/coverage/cli/src/integrations/cursor/launch-cursor.ts.html +121 -0
  142. package/coverage/cli/src/integrations/cursor/open-cursor-workspace.ts.html +277 -0
  143. package/coverage/cli/src/integrations/cursor/reconcile-workspace-folders.ts.html +355 -0
  144. package/coverage/cli/src/integrations/cursor/remove-folders-from-workspace.ts.html +364 -0
  145. package/coverage/cli/src/integrations/cursor/resolve-workspace-path.ts.html +124 -0
  146. package/coverage/cli/src/integrations/doppler/doppler-cli-auth.ts.html +178 -0
  147. package/coverage/cli/src/integrations/doppler/doppler-errors.ts.html +349 -0
  148. package/coverage/cli/src/integrations/doppler/doppler-project.ts.html +355 -0
  149. package/coverage/cli/src/integrations/doppler/index.html +161 -0
  150. package/coverage/cli/src/integrations/doppler/index.ts.html +97 -0
  151. package/coverage/cli/src/integrations/gh/gh-cli-auth/gh-cli-auth.ts.html +172 -0
  152. package/coverage/cli/src/integrations/gh/gh-cli-auth/index.html +131 -0
  153. package/coverage/cli/src/integrations/gh/gh-cli-auth/index.ts.html +88 -0
  154. package/coverage/cli/src/integrations/gh/gh-release-prs/gh-release-prs.ts.html +703 -0
  155. package/coverage/cli/src/integrations/gh/gh-release-prs/index.html +131 -0
  156. package/coverage/cli/src/integrations/gh/gh-release-prs/index.ts.html +91 -0
  157. package/coverage/cli/src/integrations/gh/index.html +116 -0
  158. package/coverage/cli/src/integrations/gh/index.ts.html +94 -0
  159. package/coverage/cli/src/integrations/ide/add-ide-worktree-folders.ts.html +316 -0
  160. package/coverage/cli/src/integrations/ide/index.html +191 -0
  161. package/coverage/cli/src/integrations/ide/index.ts.html +103 -0
  162. package/coverage/cli/src/integrations/ide/open-ide-workspace.ts.html +238 -0
  163. package/coverage/cli/src/integrations/ide/provider-label.ts.html +157 -0
  164. package/coverage/cli/src/integrations/ide/remove-ide-worktree-folders.ts.html +520 -0
  165. package/coverage/cli/src/integrations/ide/types.ts.html +208 -0
  166. package/coverage/cli/src/integrations/jira/api.ts.html +1060 -0
  167. package/coverage/cli/src/integrations/jira/index.html +131 -0
  168. package/coverage/cli/src/integrations/jira/index.ts.html +142 -0
  169. package/coverage/cli/src/integrations/zed/add-folders-to-zed-workspace.ts.html +175 -0
  170. package/coverage/cli/src/integrations/zed/index.html +161 -0
  171. package/coverage/cli/src/integrations/zed/index.ts.html +94 -0
  172. package/coverage/cli/src/integrations/zed/open-zed-workspace.ts.html +238 -0
  173. package/coverage/cli/src/integrations/zed/reuse-zed-workspace.ts.html +256 -0
  174. package/coverage/cli/src/lib/assert-never/assert-never.ts.html +130 -0
  175. package/coverage/cli/src/lib/assert-never/index.html +131 -0
  176. package/coverage/cli/src/lib/assert-never/index.ts.html +88 -0
  177. package/coverage/cli/src/lib/command-catalog/command-catalog.ts.html +523 -0
  178. package/coverage/cli/src/lib/command-catalog/index.html +116 -0
  179. package/coverage/cli/src/lib/command-echo/command-echo.ts.html +319 -0
  180. package/coverage/cli/src/lib/command-echo/index.html +131 -0
  181. package/coverage/cli/src/lib/command-echo/index.ts.html +88 -0
  182. package/coverage/cli/src/lib/constants/constants.ts.html +472 -0
  183. package/coverage/cli/src/lib/constants/index.html +131 -0
  184. package/coverage/cli/src/lib/constants/index.ts.html +139 -0
  185. package/coverage/cli/src/lib/env-autoload/env-autoload.ts.html +1111 -0
  186. package/coverage/cli/src/lib/env-autoload/index.html +116 -0
  187. package/coverage/cli/src/lib/errors/format-zx-error.ts.html +247 -0
  188. package/coverage/cli/src/lib/errors/index.html +146 -0
  189. package/coverage/cli/src/lib/errors/is-prompt-cancellation.ts.html +199 -0
  190. package/coverage/cli/src/lib/errors/operation-error.ts.html +325 -0
  191. package/coverage/cli/src/lib/git-guard/git-guard.ts.html +250 -0
  192. package/coverage/cli/src/lib/git-guard/index.html +131 -0
  193. package/coverage/cli/src/lib/git-guard/index.ts.html +91 -0
  194. package/coverage/cli/src/lib/git-utils/git-utils.ts.html +622 -0
  195. package/coverage/cli/src/lib/git-utils/index.html +131 -0
  196. package/coverage/cli/src/lib/git-utils/index.ts.html +115 -0
  197. package/coverage/cli/src/lib/infra-kit-config/index.html +131 -0
  198. package/coverage/cli/src/lib/infra-kit-config/index.ts.html +142 -0
  199. package/coverage/cli/src/lib/infra-kit-config/infra-kit-config.ts.html +1447 -0
  200. package/coverage/cli/src/lib/json-output/index.html +116 -0
  201. package/coverage/cli/src/lib/json-output/json-output.ts.html +226 -0
  202. package/coverage/cli/src/lib/logger/index.html +116 -0
  203. package/coverage/cli/src/lib/logger/index.ts.html +205 -0
  204. package/coverage/cli/src/lib/managed-block/index.html +131 -0
  205. package/coverage/cli/src/lib/managed-block/index.ts.html +109 -0
  206. package/coverage/cli/src/lib/managed-block/managed-block.ts.html +520 -0
  207. package/coverage/cli/src/lib/package-config/index.html +146 -0
  208. package/coverage/cli/src/lib/package-config/index.ts.html +94 -0
  209. package/coverage/cli/src/lib/package-config/package-config-schema.ts.html +142 -0
  210. package/coverage/cli/src/lib/package-config/package-config.ts.html +376 -0
  211. package/coverage/cli/src/lib/package-validator/checks/config-check.ts.html +175 -0
  212. package/coverage/cli/src/lib/package-validator/checks/files-check.ts.html +172 -0
  213. package/coverage/cli/src/lib/package-validator/checks/index.html +176 -0
  214. package/coverage/cli/src/lib/package-validator/checks/index.ts.html +97 -0
  215. package/coverage/cli/src/lib/package-validator/checks/scripts-check.ts.html +154 -0
  216. package/coverage/cli/src/lib/package-validator/checks/turbo-check.ts.html +226 -0
  217. package/coverage/cli/src/lib/package-validator/fs-utils.ts.html +139 -0
  218. package/coverage/cli/src/lib/package-validator/index.html +146 -0
  219. package/coverage/cli/src/lib/package-validator/index.ts.html +94 -0
  220. package/coverage/cli/src/lib/package-validator/loader/config-loader.ts.html +316 -0
  221. package/coverage/cli/src/lib/package-validator/loader/index.html +146 -0
  222. package/coverage/cli/src/lib/package-validator/loader/index.ts.html +91 -0
  223. package/coverage/cli/src/lib/package-validator/loader/package-discovery.ts.html +379 -0
  224. package/coverage/cli/src/lib/package-validator/package-validator.ts.html +229 -0
  225. package/coverage/cli/src/lib/path-display/index.html +131 -0
  226. package/coverage/cli/src/lib/path-display/index.ts.html +88 -0
  227. package/coverage/cli/src/lib/path-display/path-display.ts.html +211 -0
  228. package/coverage/cli/src/lib/release-id/index.html +131 -0
  229. package/coverage/cli/src/lib/release-id/index.ts.html +130 -0
  230. package/coverage/cli/src/lib/release-id/release-id.ts.html +859 -0
  231. package/coverage/cli/src/lib/release-utils/index.html +131 -0
  232. package/coverage/cli/src/lib/release-utils/index.ts.html +130 -0
  233. package/coverage/cli/src/lib/release-utils/release-utils.ts.html +778 -0
  234. package/coverage/cli/src/lib/render/index.html +116 -0
  235. package/coverage/cli/src/lib/render/render.ts.html +157 -0
  236. package/coverage/cli/src/lib/vendor/__tests__/index.html +116 -0
  237. package/coverage/cli/src/lib/vendor/__tests__/zx-mock.ts.html +181 -0
  238. package/coverage/cli/src/lib/vendor/config-schema.ts.html +319 -0
  239. package/coverage/cli/src/lib/vendor/config.ts.html +259 -0
  240. package/coverage/cli/src/lib/vendor/factory-config-schema.ts.html +190 -0
  241. package/coverage/cli/src/lib/vendor/factory-config.ts.html +358 -0
  242. package/coverage/cli/src/lib/vendor/hash.ts.html +133 -0
  243. package/coverage/cli/src/lib/vendor/index.html +251 -0
  244. package/coverage/cli/src/lib/vendor/index.ts.html +154 -0
  245. package/coverage/cli/src/lib/vendor/manifest.ts.html +538 -0
  246. package/coverage/cli/src/lib/vendor/skip-sets.ts.html +229 -0
  247. package/coverage/cli/src/lib/vendor/sync-ops.ts.html +955 -0
  248. package/coverage/cli/src/lib/vendor/walk.ts.html +253 -0
  249. package/coverage/cli/src/lib/version-utils/index.html +161 -0
  250. package/coverage/cli/src/lib/version-utils/index.ts.html +139 -0
  251. package/coverage/cli/src/lib/version-utils/load-existing-versions.ts.html +343 -0
  252. package/coverage/cli/src/lib/version-utils/next-version.ts.html +934 -0
  253. package/coverage/cli/src/lib/version-utils/version-utils.ts.html +178 -0
  254. package/coverage/cli/src/lib/worktrees/index.html +131 -0
  255. package/coverage/cli/src/lib/worktrees/index.ts.html +88 -0
  256. package/coverage/cli/src/lib/worktrees/remove-worktrees.ts.html +283 -0
  257. package/coverage/cli/src/tui/boot.tsx.html +265 -0
  258. package/coverage/cli/src/tui/index.html +116 -0
  259. package/coverage/cli/src/tui/screens/command-palette.tsx.html +562 -0
  260. package/coverage/cli/src/tui/screens/index.html +116 -0
  261. package/coverage/cli/src/types.ts.html +283 -0
  262. package/coverage/clover.xml +4488 -0
  263. package/coverage/coverage-final.json +156 -0
  264. package/coverage/favicon.png +0 -0
  265. package/coverage/index.html +1076 -0
  266. package/coverage/prettify.css +1 -0
  267. package/coverage/prettify.js +2 -0
  268. package/coverage/sort-arrow-sprite.png +0 -0
  269. package/coverage/sorter.js +210 -0
  270. package/dist/chunk-DB6CTNBS.js +3 -0
  271. package/dist/chunk-DB6CTNBS.js.map +7 -0
  272. package/dist/chunk-QBHCWAAG.js +164 -0
  273. package/dist/chunk-QBHCWAAG.js.map +7 -0
  274. package/dist/chunk-YSBF5C7C.js +2 -0
  275. package/dist/chunk-YSBF5C7C.js.map +7 -0
  276. package/dist/cli.js +5 -5
  277. package/dist/cli.js.map +3 -3
  278. package/dist/dev-server.js +13 -0
  279. package/dist/dev-server.js.map +7 -0
  280. package/dist/index.js +1 -1
  281. package/dist/mcp.js +1 -1
  282. package/dist/mcp.js.map +1 -1
  283. package/package.json +7 -2
  284. package/scripts/build.js +4 -4
  285. package/src/.omc/state/agent-replay-2ac0dcd0-01f7-41a8-a8c9-f2195599817b.jsonl +5 -0
  286. package/src/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/mission-state.json +79 -0
  287. package/src/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/pre-tool-advisory-throttle.json +26 -0
  288. package/src/.omc/state/sessions/2ac0dcd0-01f7-41a8-a8c9-f2195599817b/subagent-tracking-state.json +26 -0
  289. package/src/commands/audit/.omc/state/agent-replay-f9c17a0e-2dd8-4f7d-badf-631f266c5d4c.jsonl +4 -0
  290. package/src/commands/audit/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/mission-state.json +79 -0
  291. package/src/commands/audit/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/pre-tool-advisory-throttle.json +22 -0
  292. package/src/commands/audit/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/subagent-tracking-state.json +26 -0
  293. package/src/commands/audit/audit.ts +1 -1
  294. package/src/commands/doctor/doctor.ts +53 -0
  295. package/src/commands/env-autoload/env-autoload.ts +14 -2
  296. package/src/commands/env-clear/env-clear.ts +48 -7
  297. package/src/commands/env-load/env-load.ts +23 -1
  298. package/src/commands/init/__tests__/shell-body.test.ts +104 -3
  299. package/src/commands/init/init.ts +91 -9
  300. package/src/dev/__tests__/dev-server-options.test.ts +57 -0
  301. package/src/dev/__tests__/dev-server.test.ts +420 -0
  302. package/src/dev/__tests__/discovery.test.ts +181 -0
  303. package/src/dev/__tests__/fixtures.ts +257 -0
  304. package/src/dev/__tests__/ports.test.ts +98 -0
  305. package/src/dev/__tests__/serverless-local-run.test.ts +533 -0
  306. package/src/dev/dev-server.ts +796 -0
  307. package/src/dev/discovery.ts +229 -0
  308. package/src/dev/interfaces.ts +11 -0
  309. package/src/dev/managed-child.ts +73 -0
  310. package/src/dev/ports.ts +100 -0
  311. package/src/dev/serverless-local-run.ts +329 -0
  312. package/src/dev/turbo-watch.ts +62 -0
  313. package/src/dev/ui-dev.ts +62 -0
  314. package/src/entry/cli.ts +25 -6
  315. package/src/entry/dev-server.ts +103 -0
  316. package/src/lib/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/pre-tool-advisory-throttle.json +18 -0
  317. package/src/lib/command-catalog/__tests__/__snapshots__/command-catalog.test.ts.snap +1 -0
  318. package/src/lib/command-catalog/command-catalog.ts +4 -0
  319. package/src/lib/constants/constants.ts +38 -0
  320. package/src/lib/constants/index.ts +4 -0
  321. package/src/lib/env-autoload/__tests__/env-autoload.test.ts +25 -0
  322. package/src/lib/env-autoload/env-autoload.ts +35 -4
  323. package/src/lib/infra-kit-config/index.ts +2 -0
  324. package/src/lib/infra-kit-config/infra-kit-config.ts +22 -0
  325. package/src/lib/package-config/package-config.ts +2 -2
  326. package/src/lib/package-validator/.omc/state/sessions/f9c17a0e-2dd8-4f7d-badf-631f266c5d4c/pre-tool-advisory-throttle.json +10 -0
  327. package/src/lib/package-validator/__tests__/package-validator.test.ts +9 -2
  328. package/src/lib/warm-cache/__tests__/warm-cache.test.ts +164 -0
  329. package/src/lib/warm-cache/index.ts +7 -0
  330. package/src/lib/warm-cache/warm-cache.ts +136 -0
  331. package/tsconfig.tsbuildinfo +1 -1
  332. package/dist/chunk-EY5LDHXC.js +0 -164
  333. package/dist/chunk-EY5LDHXC.js.map +0 -7
  334. package/dist/chunk-WA4BQRDC.js +0 -2
  335. package/dist/chunk-WA4BQRDC.js.map +0 -7
@@ -0,0 +1,1447 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for cli/src/lib/infra-kit-config/infra-kit-config.ts</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../../../prettify.css" />
9
+ <link rel="stylesheet" href="../../../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../../../index.html">All files</a> / <a href="index.html">cli/src/lib/infra-kit-config</a> infra-kit-config.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">97.97% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>97/99</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">91.17% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>31/34</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">100% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>11/11</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">98.94% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>94/95</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a>
310
+ <a name='L245'></a><a href='#L245'>245</a>
311
+ <a name='L246'></a><a href='#L246'>246</a>
312
+ <a name='L247'></a><a href='#L247'>247</a>
313
+ <a name='L248'></a><a href='#L248'>248</a>
314
+ <a name='L249'></a><a href='#L249'>249</a>
315
+ <a name='L250'></a><a href='#L250'>250</a>
316
+ <a name='L251'></a><a href='#L251'>251</a>
317
+ <a name='L252'></a><a href='#L252'>252</a>
318
+ <a name='L253'></a><a href='#L253'>253</a>
319
+ <a name='L254'></a><a href='#L254'>254</a>
320
+ <a name='L255'></a><a href='#L255'>255</a>
321
+ <a name='L256'></a><a href='#L256'>256</a>
322
+ <a name='L257'></a><a href='#L257'>257</a>
323
+ <a name='L258'></a><a href='#L258'>258</a>
324
+ <a name='L259'></a><a href='#L259'>259</a>
325
+ <a name='L260'></a><a href='#L260'>260</a>
326
+ <a name='L261'></a><a href='#L261'>261</a>
327
+ <a name='L262'></a><a href='#L262'>262</a>
328
+ <a name='L263'></a><a href='#L263'>263</a>
329
+ <a name='L264'></a><a href='#L264'>264</a>
330
+ <a name='L265'></a><a href='#L265'>265</a>
331
+ <a name='L266'></a><a href='#L266'>266</a>
332
+ <a name='L267'></a><a href='#L267'>267</a>
333
+ <a name='L268'></a><a href='#L268'>268</a>
334
+ <a name='L269'></a><a href='#L269'>269</a>
335
+ <a name='L270'></a><a href='#L270'>270</a>
336
+ <a name='L271'></a><a href='#L271'>271</a>
337
+ <a name='L272'></a><a href='#L272'>272</a>
338
+ <a name='L273'></a><a href='#L273'>273</a>
339
+ <a name='L274'></a><a href='#L274'>274</a>
340
+ <a name='L275'></a><a href='#L275'>275</a>
341
+ <a name='L276'></a><a href='#L276'>276</a>
342
+ <a name='L277'></a><a href='#L277'>277</a>
343
+ <a name='L278'></a><a href='#L278'>278</a>
344
+ <a name='L279'></a><a href='#L279'>279</a>
345
+ <a name='L280'></a><a href='#L280'>280</a>
346
+ <a name='L281'></a><a href='#L281'>281</a>
347
+ <a name='L282'></a><a href='#L282'>282</a>
348
+ <a name='L283'></a><a href='#L283'>283</a>
349
+ <a name='L284'></a><a href='#L284'>284</a>
350
+ <a name='L285'></a><a href='#L285'>285</a>
351
+ <a name='L286'></a><a href='#L286'>286</a>
352
+ <a name='L287'></a><a href='#L287'>287</a>
353
+ <a name='L288'></a><a href='#L288'>288</a>
354
+ <a name='L289'></a><a href='#L289'>289</a>
355
+ <a name='L290'></a><a href='#L290'>290</a>
356
+ <a name='L291'></a><a href='#L291'>291</a>
357
+ <a name='L292'></a><a href='#L292'>292</a>
358
+ <a name='L293'></a><a href='#L293'>293</a>
359
+ <a name='L294'></a><a href='#L294'>294</a>
360
+ <a name='L295'></a><a href='#L295'>295</a>
361
+ <a name='L296'></a><a href='#L296'>296</a>
362
+ <a name='L297'></a><a href='#L297'>297</a>
363
+ <a name='L298'></a><a href='#L298'>298</a>
364
+ <a name='L299'></a><a href='#L299'>299</a>
365
+ <a name='L300'></a><a href='#L300'>300</a>
366
+ <a name='L301'></a><a href='#L301'>301</a>
367
+ <a name='L302'></a><a href='#L302'>302</a>
368
+ <a name='L303'></a><a href='#L303'>303</a>
369
+ <a name='L304'></a><a href='#L304'>304</a>
370
+ <a name='L305'></a><a href='#L305'>305</a>
371
+ <a name='L306'></a><a href='#L306'>306</a>
372
+ <a name='L307'></a><a href='#L307'>307</a>
373
+ <a name='L308'></a><a href='#L308'>308</a>
374
+ <a name='L309'></a><a href='#L309'>309</a>
375
+ <a name='L310'></a><a href='#L310'>310</a>
376
+ <a name='L311'></a><a href='#L311'>311</a>
377
+ <a name='L312'></a><a href='#L312'>312</a>
378
+ <a name='L313'></a><a href='#L313'>313</a>
379
+ <a name='L314'></a><a href='#L314'>314</a>
380
+ <a name='L315'></a><a href='#L315'>315</a>
381
+ <a name='L316'></a><a href='#L316'>316</a>
382
+ <a name='L317'></a><a href='#L317'>317</a>
383
+ <a name='L318'></a><a href='#L318'>318</a>
384
+ <a name='L319'></a><a href='#L319'>319</a>
385
+ <a name='L320'></a><a href='#L320'>320</a>
386
+ <a name='L321'></a><a href='#L321'>321</a>
387
+ <a name='L322'></a><a href='#L322'>322</a>
388
+ <a name='L323'></a><a href='#L323'>323</a>
389
+ <a name='L324'></a><a href='#L324'>324</a>
390
+ <a name='L325'></a><a href='#L325'>325</a>
391
+ <a name='L326'></a><a href='#L326'>326</a>
392
+ <a name='L327'></a><a href='#L327'>327</a>
393
+ <a name='L328'></a><a href='#L328'>328</a>
394
+ <a name='L329'></a><a href='#L329'>329</a>
395
+ <a name='L330'></a><a href='#L330'>330</a>
396
+ <a name='L331'></a><a href='#L331'>331</a>
397
+ <a name='L332'></a><a href='#L332'>332</a>
398
+ <a name='L333'></a><a href='#L333'>333</a>
399
+ <a name='L334'></a><a href='#L334'>334</a>
400
+ <a name='L335'></a><a href='#L335'>335</a>
401
+ <a name='L336'></a><a href='#L336'>336</a>
402
+ <a name='L337'></a><a href='#L337'>337</a>
403
+ <a name='L338'></a><a href='#L338'>338</a>
404
+ <a name='L339'></a><a href='#L339'>339</a>
405
+ <a name='L340'></a><a href='#L340'>340</a>
406
+ <a name='L341'></a><a href='#L341'>341</a>
407
+ <a name='L342'></a><a href='#L342'>342</a>
408
+ <a name='L343'></a><a href='#L343'>343</a>
409
+ <a name='L344'></a><a href='#L344'>344</a>
410
+ <a name='L345'></a><a href='#L345'>345</a>
411
+ <a name='L346'></a><a href='#L346'>346</a>
412
+ <a name='L347'></a><a href='#L347'>347</a>
413
+ <a name='L348'></a><a href='#L348'>348</a>
414
+ <a name='L349'></a><a href='#L349'>349</a>
415
+ <a name='L350'></a><a href='#L350'>350</a>
416
+ <a name='L351'></a><a href='#L351'>351</a>
417
+ <a name='L352'></a><a href='#L352'>352</a>
418
+ <a name='L353'></a><a href='#L353'>353</a>
419
+ <a name='L354'></a><a href='#L354'>354</a>
420
+ <a name='L355'></a><a href='#L355'>355</a>
421
+ <a name='L356'></a><a href='#L356'>356</a>
422
+ <a name='L357'></a><a href='#L357'>357</a>
423
+ <a name='L358'></a><a href='#L358'>358</a>
424
+ <a name='L359'></a><a href='#L359'>359</a>
425
+ <a name='L360'></a><a href='#L360'>360</a>
426
+ <a name='L361'></a><a href='#L361'>361</a>
427
+ <a name='L362'></a><a href='#L362'>362</a>
428
+ <a name='L363'></a><a href='#L363'>363</a>
429
+ <a name='L364'></a><a href='#L364'>364</a>
430
+ <a name='L365'></a><a href='#L365'>365</a>
431
+ <a name='L366'></a><a href='#L366'>366</a>
432
+ <a name='L367'></a><a href='#L367'>367</a>
433
+ <a name='L368'></a><a href='#L368'>368</a>
434
+ <a name='L369'></a><a href='#L369'>369</a>
435
+ <a name='L370'></a><a href='#L370'>370</a>
436
+ <a name='L371'></a><a href='#L371'>371</a>
437
+ <a name='L372'></a><a href='#L372'>372</a>
438
+ <a name='L373'></a><a href='#L373'>373</a>
439
+ <a name='L374'></a><a href='#L374'>374</a>
440
+ <a name='L375'></a><a href='#L375'>375</a>
441
+ <a name='L376'></a><a href='#L376'>376</a>
442
+ <a name='L377'></a><a href='#L377'>377</a>
443
+ <a name='L378'></a><a href='#L378'>378</a>
444
+ <a name='L379'></a><a href='#L379'>379</a>
445
+ <a name='L380'></a><a href='#L380'>380</a>
446
+ <a name='L381'></a><a href='#L381'>381</a>
447
+ <a name='L382'></a><a href='#L382'>382</a>
448
+ <a name='L383'></a><a href='#L383'>383</a>
449
+ <a name='L384'></a><a href='#L384'>384</a>
450
+ <a name='L385'></a><a href='#L385'>385</a>
451
+ <a name='L386'></a><a href='#L386'>386</a>
452
+ <a name='L387'></a><a href='#L387'>387</a>
453
+ <a name='L388'></a><a href='#L388'>388</a>
454
+ <a name='L389'></a><a href='#L389'>389</a>
455
+ <a name='L390'></a><a href='#L390'>390</a>
456
+ <a name='L391'></a><a href='#L391'>391</a>
457
+ <a name='L392'></a><a href='#L392'>392</a>
458
+ <a name='L393'></a><a href='#L393'>393</a>
459
+ <a name='L394'></a><a href='#L394'>394</a>
460
+ <a name='L395'></a><a href='#L395'>395</a>
461
+ <a name='L396'></a><a href='#L396'>396</a>
462
+ <a name='L397'></a><a href='#L397'>397</a>
463
+ <a name='L398'></a><a href='#L398'>398</a>
464
+ <a name='L399'></a><a href='#L399'>399</a>
465
+ <a name='L400'></a><a href='#L400'>400</a>
466
+ <a name='L401'></a><a href='#L401'>401</a>
467
+ <a name='L402'></a><a href='#L402'>402</a>
468
+ <a name='L403'></a><a href='#L403'>403</a>
469
+ <a name='L404'></a><a href='#L404'>404</a>
470
+ <a name='L405'></a><a href='#L405'>405</a>
471
+ <a name='L406'></a><a href='#L406'>406</a>
472
+ <a name='L407'></a><a href='#L407'>407</a>
473
+ <a name='L408'></a><a href='#L408'>408</a>
474
+ <a name='L409'></a><a href='#L409'>409</a>
475
+ <a name='L410'></a><a href='#L410'>410</a>
476
+ <a name='L411'></a><a href='#L411'>411</a>
477
+ <a name='L412'></a><a href='#L412'>412</a>
478
+ <a name='L413'></a><a href='#L413'>413</a>
479
+ <a name='L414'></a><a href='#L414'>414</a>
480
+ <a name='L415'></a><a href='#L415'>415</a>
481
+ <a name='L416'></a><a href='#L416'>416</a>
482
+ <a name='L417'></a><a href='#L417'>417</a>
483
+ <a name='L418'></a><a href='#L418'>418</a>
484
+ <a name='L419'></a><a href='#L419'>419</a>
485
+ <a name='L420'></a><a href='#L420'>420</a>
486
+ <a name='L421'></a><a href='#L421'>421</a>
487
+ <a name='L422'></a><a href='#L422'>422</a>
488
+ <a name='L423'></a><a href='#L423'>423</a>
489
+ <a name='L424'></a><a href='#L424'>424</a>
490
+ <a name='L425'></a><a href='#L425'>425</a>
491
+ <a name='L426'></a><a href='#L426'>426</a>
492
+ <a name='L427'></a><a href='#L427'>427</a>
493
+ <a name='L428'></a><a href='#L428'>428</a>
494
+ <a name='L429'></a><a href='#L429'>429</a>
495
+ <a name='L430'></a><a href='#L430'>430</a>
496
+ <a name='L431'></a><a href='#L431'>431</a>
497
+ <a name='L432'></a><a href='#L432'>432</a>
498
+ <a name='L433'></a><a href='#L433'>433</a>
499
+ <a name='L434'></a><a href='#L434'>434</a>
500
+ <a name='L435'></a><a href='#L435'>435</a>
501
+ <a name='L436'></a><a href='#L436'>436</a>
502
+ <a name='L437'></a><a href='#L437'>437</a>
503
+ <a name='L438'></a><a href='#L438'>438</a>
504
+ <a name='L439'></a><a href='#L439'>439</a>
505
+ <a name='L440'></a><a href='#L440'>440</a>
506
+ <a name='L441'></a><a href='#L441'>441</a>
507
+ <a name='L442'></a><a href='#L442'>442</a>
508
+ <a name='L443'></a><a href='#L443'>443</a>
509
+ <a name='L444'></a><a href='#L444'>444</a>
510
+ <a name='L445'></a><a href='#L445'>445</a>
511
+ <a name='L446'></a><a href='#L446'>446</a>
512
+ <a name='L447'></a><a href='#L447'>447</a>
513
+ <a name='L448'></a><a href='#L448'>448</a>
514
+ <a name='L449'></a><a href='#L449'>449</a>
515
+ <a name='L450'></a><a href='#L450'>450</a>
516
+ <a name='L451'></a><a href='#L451'>451</a>
517
+ <a name='L452'></a><a href='#L452'>452</a>
518
+ <a name='L453'></a><a href='#L453'>453</a>
519
+ <a name='L454'></a><a href='#L454'>454</a>
520
+ <a name='L455'></a><a href='#L455'>455</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
521
+ <span class="cline-any cline-neutral">&nbsp;</span>
522
+ <span class="cline-any cline-neutral">&nbsp;</span>
523
+ <span class="cline-any cline-neutral">&nbsp;</span>
524
+ <span class="cline-any cline-neutral">&nbsp;</span>
525
+ <span class="cline-any cline-neutral">&nbsp;</span>
526
+ <span class="cline-any cline-neutral">&nbsp;</span>
527
+ <span class="cline-any cline-yes">19x</span>
528
+ <span class="cline-any cline-neutral">&nbsp;</span>
529
+ <span class="cline-any cline-neutral">&nbsp;</span>
530
+ <span class="cline-any cline-neutral">&nbsp;</span>
531
+ <span class="cline-any cline-neutral">&nbsp;</span>
532
+ <span class="cline-any cline-neutral">&nbsp;</span>
533
+ <span class="cline-any cline-neutral">&nbsp;</span>
534
+ <span class="cline-any cline-neutral">&nbsp;</span>
535
+ <span class="cline-any cline-neutral">&nbsp;</span>
536
+ <span class="cline-any cline-yes">19x</span>
537
+ <span class="cline-any cline-yes">19x</span>
538
+ <span class="cline-any cline-yes">19x</span>
539
+ <span class="cline-any cline-neutral">&nbsp;</span>
540
+ <span class="cline-any cline-neutral">&nbsp;</span>
541
+ <span class="cline-any cline-yes">19x</span>
542
+ <span class="cline-any cline-neutral">&nbsp;</span>
543
+ <span class="cline-any cline-neutral">&nbsp;</span>
544
+ <span class="cline-any cline-neutral">&nbsp;</span>
545
+ <span class="cline-any cline-neutral">&nbsp;</span>
546
+ <span class="cline-any cline-neutral">&nbsp;</span>
547
+ <span class="cline-any cline-neutral">&nbsp;</span>
548
+ <span class="cline-any cline-yes">19x</span>
549
+ <span class="cline-any cline-neutral">&nbsp;</span>
550
+ <span class="cline-any cline-neutral">&nbsp;</span>
551
+ <span class="cline-any cline-neutral">&nbsp;</span>
552
+ <span class="cline-any cline-neutral">&nbsp;</span>
553
+ <span class="cline-any cline-neutral">&nbsp;</span>
554
+ <span class="cline-any cline-yes">19x</span>
555
+ <span class="cline-any cline-neutral">&nbsp;</span>
556
+ <span class="cline-any cline-neutral">&nbsp;</span>
557
+ <span class="cline-any cline-neutral">&nbsp;</span>
558
+ <span class="cline-any cline-yes">19x</span>
559
+ <span class="cline-any cline-neutral">&nbsp;</span>
560
+ <span class="cline-any cline-neutral">&nbsp;</span>
561
+ <span class="cline-any cline-neutral">&nbsp;</span>
562
+ <span class="cline-any cline-neutral">&nbsp;</span>
563
+ <span class="cline-any cline-neutral">&nbsp;</span>
564
+ <span class="cline-any cline-neutral">&nbsp;</span>
565
+ <span class="cline-any cline-neutral">&nbsp;</span>
566
+ <span class="cline-any cline-yes">19x</span>
567
+ <span class="cline-any cline-neutral">&nbsp;</span>
568
+ <span class="cline-any cline-yes">19x</span>
569
+ <span class="cline-any cline-neutral">&nbsp;</span>
570
+ <span class="cline-any cline-neutral">&nbsp;</span>
571
+ <span class="cline-any cline-neutral">&nbsp;</span>
572
+ <span class="cline-any cline-neutral">&nbsp;</span>
573
+ <span class="cline-any cline-yes">19x</span>
574
+ <span class="cline-any cline-neutral">&nbsp;</span>
575
+ <span class="cline-any cline-neutral">&nbsp;</span>
576
+ <span class="cline-any cline-neutral">&nbsp;</span>
577
+ <span class="cline-any cline-neutral">&nbsp;</span>
578
+ <span class="cline-any cline-neutral">&nbsp;</span>
579
+ <span class="cline-any cline-neutral">&nbsp;</span>
580
+ <span class="cline-any cline-yes">19x</span>
581
+ <span class="cline-any cline-neutral">&nbsp;</span>
582
+ <span class="cline-any cline-neutral">&nbsp;</span>
583
+ <span class="cline-any cline-yes">19x</span>
584
+ <span class="cline-any cline-neutral">&nbsp;</span>
585
+ <span class="cline-any cline-neutral">&nbsp;</span>
586
+ <span class="cline-any cline-neutral">&nbsp;</span>
587
+ <span class="cline-any cline-neutral">&nbsp;</span>
588
+ <span class="cline-any cline-neutral">&nbsp;</span>
589
+ <span class="cline-any cline-neutral">&nbsp;</span>
590
+ <span class="cline-any cline-neutral">&nbsp;</span>
591
+ <span class="cline-any cline-yes">19x</span>
592
+ <span class="cline-any cline-neutral">&nbsp;</span>
593
+ <span class="cline-any cline-neutral">&nbsp;</span>
594
+ <span class="cline-any cline-neutral">&nbsp;</span>
595
+ <span class="cline-any cline-neutral">&nbsp;</span>
596
+ <span class="cline-any cline-neutral">&nbsp;</span>
597
+ <span class="cline-any cline-neutral">&nbsp;</span>
598
+ <span class="cline-any cline-yes">19x</span>
599
+ <span class="cline-any cline-neutral">&nbsp;</span>
600
+ <span class="cline-any cline-yes">19x</span>
601
+ <span class="cline-any cline-neutral">&nbsp;</span>
602
+ <span class="cline-any cline-neutral">&nbsp;</span>
603
+ <span class="cline-any cline-neutral">&nbsp;</span>
604
+ <span class="cline-any cline-neutral">&nbsp;</span>
605
+ <span class="cline-any cline-yes">19x</span>
606
+ <span class="cline-any cline-neutral">&nbsp;</span>
607
+ <span class="cline-any cline-neutral">&nbsp;</span>
608
+ <span class="cline-any cline-neutral">&nbsp;</span>
609
+ <span class="cline-any cline-neutral">&nbsp;</span>
610
+ <span class="cline-any cline-neutral">&nbsp;</span>
611
+ <span class="cline-any cline-neutral">&nbsp;</span>
612
+ <span class="cline-any cline-neutral">&nbsp;</span>
613
+ <span class="cline-any cline-neutral">&nbsp;</span>
614
+ <span class="cline-any cline-neutral">&nbsp;</span>
615
+ <span class="cline-any cline-neutral">&nbsp;</span>
616
+ <span class="cline-any cline-neutral">&nbsp;</span>
617
+ <span class="cline-any cline-yes">19x</span>
618
+ <span class="cline-any cline-neutral">&nbsp;</span>
619
+ <span class="cline-any cline-neutral">&nbsp;</span>
620
+ <span class="cline-any cline-neutral">&nbsp;</span>
621
+ <span class="cline-any cline-neutral">&nbsp;</span>
622
+ <span class="cline-any cline-neutral">&nbsp;</span>
623
+ <span class="cline-any cline-neutral">&nbsp;</span>
624
+ <span class="cline-any cline-yes">19x</span>
625
+ <span class="cline-any cline-neutral">&nbsp;</span>
626
+ <span class="cline-any cline-neutral">&nbsp;</span>
627
+ <span class="cline-any cline-neutral">&nbsp;</span>
628
+ <span class="cline-any cline-neutral">&nbsp;</span>
629
+ <span class="cline-any cline-neutral">&nbsp;</span>
630
+ <span class="cline-any cline-neutral">&nbsp;</span>
631
+ <span class="cline-any cline-neutral">&nbsp;</span>
632
+ <span class="cline-any cline-neutral">&nbsp;</span>
633
+ <span class="cline-any cline-neutral">&nbsp;</span>
634
+ <span class="cline-any cline-neutral">&nbsp;</span>
635
+ <span class="cline-any cline-yes">19x</span>
636
+ <span class="cline-any cline-neutral">&nbsp;</span>
637
+ <span class="cline-any cline-neutral">&nbsp;</span>
638
+ <span class="cline-any cline-neutral">&nbsp;</span>
639
+ <span class="cline-any cline-neutral">&nbsp;</span>
640
+ <span class="cline-any cline-neutral">&nbsp;</span>
641
+ <span class="cline-any cline-neutral">&nbsp;</span>
642
+ <span class="cline-any cline-neutral">&nbsp;</span>
643
+ <span class="cline-any cline-neutral">&nbsp;</span>
644
+ <span class="cline-any cline-neutral">&nbsp;</span>
645
+ <span class="cline-any cline-yes">19x</span>
646
+ <span class="cline-any cline-neutral">&nbsp;</span>
647
+ <span class="cline-any cline-neutral">&nbsp;</span>
648
+ <span class="cline-any cline-neutral">&nbsp;</span>
649
+ <span class="cline-any cline-neutral">&nbsp;</span>
650
+ <span class="cline-any cline-neutral">&nbsp;</span>
651
+ <span class="cline-any cline-neutral">&nbsp;</span>
652
+ <span class="cline-any cline-neutral">&nbsp;</span>
653
+ <span class="cline-any cline-neutral">&nbsp;</span>
654
+ <span class="cline-any cline-neutral">&nbsp;</span>
655
+ <span class="cline-any cline-neutral">&nbsp;</span>
656
+ <span class="cline-any cline-neutral">&nbsp;</span>
657
+ <span class="cline-any cline-neutral">&nbsp;</span>
658
+ <span class="cline-any cline-neutral">&nbsp;</span>
659
+ <span class="cline-any cline-neutral">&nbsp;</span>
660
+ <span class="cline-any cline-yes">19x</span>
661
+ <span class="cline-any cline-yes">24x</span>
662
+ <span class="cline-any cline-neutral">&nbsp;</span>
663
+ <span class="cline-any cline-yes">2x</span>
664
+ <span class="cline-any cline-neutral">&nbsp;</span>
665
+ <span class="cline-any cline-yes">2x</span>
666
+ <span class="cline-any cline-yes">4x</span>
667
+ <span class="cline-any cline-yes">1x</span>
668
+ <span class="cline-any cline-neutral">&nbsp;</span>
669
+ <span class="cline-any cline-neutral">&nbsp;</span>
670
+ <span class="cline-any cline-neutral">&nbsp;</span>
671
+ <span class="cline-any cline-neutral">&nbsp;</span>
672
+ <span class="cline-any cline-neutral">&nbsp;</span>
673
+ <span class="cline-any cline-yes">1x</span>
674
+ <span class="cline-any cline-neutral">&nbsp;</span>
675
+ <span class="cline-any cline-neutral">&nbsp;</span>
676
+ <span class="cline-any cline-yes">3x</span>
677
+ <span class="cline-any cline-neutral">&nbsp;</span>
678
+ <span class="cline-any cline-neutral">&nbsp;</span>
679
+ <span class="cline-any cline-neutral">&nbsp;</span>
680
+ <span class="cline-any cline-yes">19x</span>
681
+ <span class="cline-any cline-neutral">&nbsp;</span>
682
+ <span class="cline-any cline-neutral">&nbsp;</span>
683
+ <span class="cline-any cline-neutral">&nbsp;</span>
684
+ <span class="cline-any cline-neutral">&nbsp;</span>
685
+ <span class="cline-any cline-neutral">&nbsp;</span>
686
+ <span class="cline-any cline-neutral">&nbsp;</span>
687
+ <span class="cline-any cline-neutral">&nbsp;</span>
688
+ <span class="cline-any cline-neutral">&nbsp;</span>
689
+ <span class="cline-any cline-neutral">&nbsp;</span>
690
+ <span class="cline-any cline-neutral">&nbsp;</span>
691
+ <span class="cline-any cline-neutral">&nbsp;</span>
692
+ <span class="cline-any cline-neutral">&nbsp;</span>
693
+ <span class="cline-any cline-neutral">&nbsp;</span>
694
+ <span class="cline-any cline-neutral">&nbsp;</span>
695
+ <span class="cline-any cline-neutral">&nbsp;</span>
696
+ <span class="cline-any cline-neutral">&nbsp;</span>
697
+ <span class="cline-any cline-neutral">&nbsp;</span>
698
+ <span class="cline-any cline-neutral">&nbsp;</span>
699
+ <span class="cline-any cline-neutral">&nbsp;</span>
700
+ <span class="cline-any cline-neutral">&nbsp;</span>
701
+ <span class="cline-any cline-neutral">&nbsp;</span>
702
+ <span class="cline-any cline-neutral">&nbsp;</span>
703
+ <span class="cline-any cline-neutral">&nbsp;</span>
704
+ <span class="cline-any cline-neutral">&nbsp;</span>
705
+ <span class="cline-any cline-neutral">&nbsp;</span>
706
+ <span class="cline-any cline-yes">19x</span>
707
+ <span class="cline-any cline-yes">7x</span>
708
+ <span class="cline-any cline-neutral">&nbsp;</span>
709
+ <span class="cline-any cline-yes">7x</span>
710
+ <span class="cline-any cline-neutral">&nbsp;</span>
711
+ <span class="cline-any cline-yes">6x</span>
712
+ <span class="cline-any cline-neutral">&nbsp;</span>
713
+ <span class="cline-any cline-neutral">&nbsp;</span>
714
+ <span class="cline-any cline-neutral">&nbsp;</span>
715
+ <span class="cline-any cline-neutral">&nbsp;</span>
716
+ <span class="cline-any cline-neutral">&nbsp;</span>
717
+ <span class="cline-any cline-neutral">&nbsp;</span>
718
+ <span class="cline-any cline-yes">19x</span>
719
+ <span class="cline-any cline-neutral">&nbsp;</span>
720
+ <span class="cline-any cline-neutral">&nbsp;</span>
721
+ <span class="cline-any cline-neutral">&nbsp;</span>
722
+ <span class="cline-any cline-neutral">&nbsp;</span>
723
+ <span class="cline-any cline-neutral">&nbsp;</span>
724
+ <span class="cline-any cline-neutral">&nbsp;</span>
725
+ <span class="cline-any cline-neutral">&nbsp;</span>
726
+ <span class="cline-any cline-neutral">&nbsp;</span>
727
+ <span class="cline-any cline-neutral">&nbsp;</span>
728
+ <span class="cline-any cline-neutral">&nbsp;</span>
729
+ <span class="cline-any cline-yes">19x</span>
730
+ <span class="cline-any cline-yes">8x</span>
731
+ <span class="cline-any cline-neutral">&nbsp;</span>
732
+ <span class="cline-any cline-neutral">&nbsp;</span>
733
+ <span class="cline-any cline-neutral">&nbsp;</span>
734
+ <span class="cline-any cline-neutral">&nbsp;</span>
735
+ <span class="cline-any cline-neutral">&nbsp;</span>
736
+ <span class="cline-any cline-neutral">&nbsp;</span>
737
+ <span class="cline-any cline-neutral">&nbsp;</span>
738
+ <span class="cline-any cline-neutral">&nbsp;</span>
739
+ <span class="cline-any cline-neutral">&nbsp;</span>
740
+ <span class="cline-any cline-neutral">&nbsp;</span>
741
+ <span class="cline-any cline-neutral">&nbsp;</span>
742
+ <span class="cline-any cline-neutral">&nbsp;</span>
743
+ <span class="cline-any cline-neutral">&nbsp;</span>
744
+ <span class="cline-any cline-neutral">&nbsp;</span>
745
+ <span class="cline-any cline-neutral">&nbsp;</span>
746
+ <span class="cline-any cline-neutral">&nbsp;</span>
747
+ <span class="cline-any cline-neutral">&nbsp;</span>
748
+ <span class="cline-any cline-neutral">&nbsp;</span>
749
+ <span class="cline-any cline-yes">19x</span>
750
+ <span class="cline-any cline-neutral">&nbsp;</span>
751
+ <span class="cline-any cline-neutral">&nbsp;</span>
752
+ <span class="cline-any cline-neutral">&nbsp;</span>
753
+ <span class="cline-any cline-neutral">&nbsp;</span>
754
+ <span class="cline-any cline-neutral">&nbsp;</span>
755
+ <span class="cline-any cline-neutral">&nbsp;</span>
756
+ <span class="cline-any cline-neutral">&nbsp;</span>
757
+ <span class="cline-any cline-neutral">&nbsp;</span>
758
+ <span class="cline-any cline-neutral">&nbsp;</span>
759
+ <span class="cline-any cline-neutral">&nbsp;</span>
760
+ <span class="cline-any cline-neutral">&nbsp;</span>
761
+ <span class="cline-any cline-neutral">&nbsp;</span>
762
+ <span class="cline-any cline-neutral">&nbsp;</span>
763
+ <span class="cline-any cline-neutral">&nbsp;</span>
764
+ <span class="cline-any cline-neutral">&nbsp;</span>
765
+ <span class="cline-any cline-yes">19x</span>
766
+ <span class="cline-any cline-yes">68x</span>
767
+ <span class="cline-any cline-neutral">&nbsp;</span>
768
+ <span class="cline-any cline-neutral">&nbsp;</span>
769
+ <span class="cline-any cline-yes">68x</span>
770
+ <span class="cline-any cline-yes">68x</span>
771
+ <span class="cline-any cline-neutral">&nbsp;</span>
772
+ <span class="cline-any cline-yes">68x</span>
773
+ <span class="cline-any cline-neutral">&nbsp;</span>
774
+ <span class="cline-any cline-neutral">&nbsp;</span>
775
+ <span class="cline-any cline-neutral">&nbsp;</span>
776
+ <span class="cline-any cline-neutral">&nbsp;</span>
777
+ <span class="cline-any cline-neutral">&nbsp;</span>
778
+ <span class="cline-any cline-neutral">&nbsp;</span>
779
+ <span class="cline-any cline-neutral">&nbsp;</span>
780
+ <span class="cline-any cline-neutral">&nbsp;</span>
781
+ <span class="cline-any cline-neutral">&nbsp;</span>
782
+ <span class="cline-any cline-neutral">&nbsp;</span>
783
+ <span class="cline-any cline-neutral">&nbsp;</span>
784
+ <span class="cline-any cline-neutral">&nbsp;</span>
785
+ <span class="cline-any cline-neutral">&nbsp;</span>
786
+ <span class="cline-any cline-neutral">&nbsp;</span>
787
+ <span class="cline-any cline-neutral">&nbsp;</span>
788
+ <span class="cline-any cline-neutral">&nbsp;</span>
789
+ <span class="cline-any cline-neutral">&nbsp;</span>
790
+ <span class="cline-any cline-neutral">&nbsp;</span>
791
+ <span class="cline-any cline-neutral">&nbsp;</span>
792
+ <span class="cline-any cline-neutral">&nbsp;</span>
793
+ <span class="cline-any cline-neutral">&nbsp;</span>
794
+ <span class="cline-any cline-neutral">&nbsp;</span>
795
+ <span class="cline-any cline-neutral">&nbsp;</span>
796
+ <span class="cline-any cline-neutral">&nbsp;</span>
797
+ <span class="cline-any cline-yes">19x</span>
798
+ <span class="cline-any cline-yes">29x</span>
799
+ <span class="cline-any cline-neutral">&nbsp;</span>
800
+ <span class="cline-any cline-neutral">&nbsp;</span>
801
+ <span class="cline-any cline-neutral">&nbsp;</span>
802
+ <span class="cline-any cline-yes">29x</span>
803
+ <span class="cline-any cline-yes">29x</span>
804
+ <span class="cline-any cline-neutral">&nbsp;</span>
805
+ <span class="cline-any cline-yes">4x</span>
806
+ <span class="cline-any cline-neutral">&nbsp;</span>
807
+ <span class="cline-any cline-neutral">&nbsp;</span>
808
+ <span class="cline-any cline-neutral">&nbsp;</span>
809
+ <span class="cline-any cline-yes">4x</span>
810
+ <span class="cline-any cline-neutral">&nbsp;</span>
811
+ <span class="cline-any cline-yes">4x</span>
812
+ <span class="cline-any cline-yes">1x</span>
813
+ <span class="cline-any cline-neutral">&nbsp;</span>
814
+ <span class="cline-any cline-neutral">&nbsp;</span>
815
+ <span class="cline-any cline-neutral">&nbsp;</span>
816
+ <span class="cline-any cline-neutral">&nbsp;</span>
817
+ <span class="cline-any cline-yes">3x</span>
818
+ <span class="cline-any cline-neutral">&nbsp;</span>
819
+ <span class="cline-any cline-neutral">&nbsp;</span>
820
+ <span class="cline-any cline-yes">25x</span>
821
+ <span class="cline-any cline-neutral">&nbsp;</span>
822
+ <span class="cline-any cline-neutral">&nbsp;</span>
823
+ <span class="cline-any cline-neutral">&nbsp;</span>
824
+ <span class="cline-any cline-neutral">&nbsp;</span>
825
+ <span class="cline-any cline-yes">25x</span>
826
+ <span class="cline-any cline-neutral">&nbsp;</span>
827
+ <span class="cline-any cline-neutral">&nbsp;</span>
828
+ <span class="cline-any cline-neutral">&nbsp;</span>
829
+ <span class="cline-any cline-neutral">&nbsp;</span>
830
+ <span class="cline-any cline-neutral">&nbsp;</span>
831
+ <span class="cline-any cline-yes">29x</span>
832
+ <span class="cline-any cline-yes">3x</span>
833
+ <span class="cline-any cline-neutral">&nbsp;</span>
834
+ <span class="cline-any cline-neutral">&nbsp;</span>
835
+ <span class="cline-any cline-yes">22x</span>
836
+ <span class="cline-any cline-neutral">&nbsp;</span>
837
+ <span class="cline-any cline-neutral">&nbsp;</span>
838
+ <span class="cline-any cline-neutral">&nbsp;</span>
839
+ <span class="cline-any cline-neutral">&nbsp;</span>
840
+ <span class="cline-any cline-neutral">&nbsp;</span>
841
+ <span class="cline-any cline-neutral">&nbsp;</span>
842
+ <span class="cline-any cline-neutral">&nbsp;</span>
843
+ <span class="cline-any cline-neutral">&nbsp;</span>
844
+ <span class="cline-any cline-neutral">&nbsp;</span>
845
+ <span class="cline-any cline-yes">22x</span>
846
+ <span class="cline-any cline-neutral">&nbsp;</span>
847
+ <span class="cline-any cline-yes">22x</span>
848
+ <span class="cline-any cline-yes">54x</span>
849
+ <span class="cline-any cline-neutral">&nbsp;</span>
850
+ <span class="cline-any cline-yes">48x</span>
851
+ <span class="cline-any cline-neutral">&nbsp;</span>
852
+ <span class="cline-any cline-yes">19x</span>
853
+ <span class="cline-any cline-neutral">&nbsp;</span>
854
+ <span class="cline-any cline-neutral">&nbsp;</span>
855
+ <span class="cline-any cline-yes">16x</span>
856
+ <span class="cline-any cline-neutral">&nbsp;</span>
857
+ <span class="cline-any cline-yes">16x</span>
858
+ <span class="cline-any cline-yes">1x</span>
859
+ <span class="cline-any cline-neutral">&nbsp;</span>
860
+ <span class="cline-any cline-neutral">&nbsp;</span>
861
+ <span class="cline-any cline-yes">15x</span>
862
+ <span class="cline-any cline-neutral">&nbsp;</span>
863
+ <span class="cline-any cline-yes">15x</span>
864
+ <span class="cline-any cline-neutral">&nbsp;</span>
865
+ <span class="cline-any cline-neutral">&nbsp;</span>
866
+ <span class="cline-any cline-neutral">&nbsp;</span>
867
+ <span class="cline-any cline-neutral">&nbsp;</span>
868
+ <span class="cline-any cline-neutral">&nbsp;</span>
869
+ <span class="cline-any cline-neutral">&nbsp;</span>
870
+ <span class="cline-any cline-neutral">&nbsp;</span>
871
+ <span class="cline-any cline-neutral">&nbsp;</span>
872
+ <span class="cline-any cline-neutral">&nbsp;</span>
873
+ <span class="cline-any cline-yes">19x</span>
874
+ <span class="cline-any cline-yes">99x</span>
875
+ <span class="cline-any cline-neutral">&nbsp;</span>
876
+ <span class="cline-any cline-neutral">&nbsp;</span>
877
+ <span class="cline-any cline-neutral">&nbsp;</span>
878
+ <span class="cline-any cline-neutral">&nbsp;</span>
879
+ <span class="cline-any cline-neutral">&nbsp;</span>
880
+ <span class="cline-any cline-neutral">&nbsp;</span>
881
+ <span class="cline-any cline-neutral">&nbsp;</span>
882
+ <span class="cline-any cline-neutral">&nbsp;</span>
883
+ <span class="cline-any cline-neutral">&nbsp;</span>
884
+ <span class="cline-any cline-yes">19x</span>
885
+ <span class="cline-any cline-yes">54x</span>
886
+ <span class="cline-any cline-yes">54x</span>
887
+ <span class="cline-any cline-neutral">&nbsp;</span>
888
+ <span class="cline-any cline-yes">48x</span>
889
+ <span class="cline-any cline-neutral">&nbsp;</span>
890
+ <span class="cline-any cline-neutral">&nbsp;</span>
891
+ <span class="cline-any cline-neutral">&nbsp;</span>
892
+ <span class="cline-any cline-neutral">&nbsp;</span>
893
+ <span class="cline-any cline-neutral">&nbsp;</span>
894
+ <span class="cline-any cline-neutral">&nbsp;</span>
895
+ <span class="cline-any cline-neutral">&nbsp;</span>
896
+ <span class="cline-any cline-neutral">&nbsp;</span>
897
+ <span class="cline-any cline-neutral">&nbsp;</span>
898
+ <span class="cline-any cline-neutral">&nbsp;</span>
899
+ <span class="cline-any cline-yes">19x</span>
900
+ <span class="cline-any cline-yes">54x</span>
901
+ <span class="cline-any cline-yes">54x</span>
902
+ <span class="cline-any cline-neutral">&nbsp;</span>
903
+ <span class="cline-any cline-yes">29x</span>
904
+ <span class="cline-any cline-neutral">&nbsp;</span>
905
+ <span class="cline-any cline-neutral">&nbsp;</span>
906
+ <span class="cline-any cline-neutral">&nbsp;</span>
907
+ <span class="cline-any cline-neutral">&nbsp;</span>
908
+ <span class="cline-any cline-neutral">&nbsp;</span>
909
+ <span class="cline-any cline-neutral">&nbsp;</span>
910
+ <span class="cline-any cline-neutral">&nbsp;</span>
911
+ <span class="cline-any cline-neutral">&nbsp;</span>
912
+ <span class="cline-any cline-neutral">&nbsp;</span>
913
+ <span class="cline-any cline-neutral">&nbsp;</span>
914
+ <span class="cline-any cline-neutral">&nbsp;</span>
915
+ <span class="cline-any cline-neutral">&nbsp;</span>
916
+ <span class="cline-any cline-yes">19x</span>
917
+ <span class="cline-any cline-yes">4x</span>
918
+ <span class="cline-any cline-neutral">&nbsp;</span>
919
+ <span class="cline-any cline-yes">4x</span>
920
+ <span class="cline-any cline-neutral">&nbsp;</span>
921
+ <span class="cline-any cline-yes">4x</span>
922
+ <span class="cline-any cline-yes">10x</span>
923
+ <span class="cline-any cline-neutral">&nbsp;</span>
924
+ <span class="cline-any cline-neutral">&nbsp;</span>
925
+ <span class="cline-any cline-neutral">&nbsp;</span>
926
+ <span class="cline-any cline-neutral">&nbsp;</span>
927
+ <span class="cline-any cline-neutral">&nbsp;</span>
928
+ <span class="cline-any cline-neutral">&nbsp;</span>
929
+ <span class="cline-any cline-neutral">&nbsp;</span>
930
+ <span class="cline-any cline-neutral">&nbsp;</span>
931
+ <span class="cline-any cline-neutral">&nbsp;</span>
932
+ <span class="cline-any cline-neutral">&nbsp;</span>
933
+ <span class="cline-any cline-neutral">&nbsp;</span>
934
+ <span class="cline-any cline-neutral">&nbsp;</span>
935
+ <span class="cline-any cline-neutral">&nbsp;</span>
936
+ <span class="cline-any cline-neutral">&nbsp;</span>
937
+ <span class="cline-any cline-neutral">&nbsp;</span>
938
+ <span class="cline-any cline-neutral">&nbsp;</span>
939
+ <span class="cline-any cline-neutral">&nbsp;</span>
940
+ <span class="cline-any cline-neutral">&nbsp;</span>
941
+ <span class="cline-any cline-neutral">&nbsp;</span>
942
+ <span class="cline-any cline-neutral">&nbsp;</span>
943
+ <span class="cline-any cline-neutral">&nbsp;</span>
944
+ <span class="cline-any cline-neutral">&nbsp;</span>
945
+ <span class="cline-any cline-neutral">&nbsp;</span>
946
+ <span class="cline-any cline-neutral">&nbsp;</span>
947
+ <span class="cline-any cline-yes">19x</span>
948
+ <span class="cline-any cline-yes">54x</span>
949
+ <span class="cline-any cline-neutral">&nbsp;</span>
950
+ <span class="cline-any cline-yes">54x</span>
951
+ <span class="cline-any cline-yes">29x</span>
952
+ <span class="cline-any cline-no">&nbsp;</span>
953
+ <span class="cline-any cline-neutral">&nbsp;</span>
954
+ <span class="cline-any cline-neutral">&nbsp;</span>
955
+ <span class="cline-any cline-yes">29x</span>
956
+ <span class="cline-any cline-neutral">&nbsp;</span>
957
+ <span class="cline-any cline-neutral">&nbsp;</span>
958
+ <span class="cline-any cline-neutral">&nbsp;</span>
959
+ <span class="cline-any cline-neutral">&nbsp;</span>
960
+ <span class="cline-any cline-yes">25x</span>
961
+ <span class="cline-any cline-yes">25x</span>
962
+ <span class="cline-any cline-neutral">&nbsp;</span>
963
+ <span class="cline-any cline-yes">1x</span>
964
+ <span class="cline-any cline-neutral">&nbsp;</span>
965
+ <span class="cline-any cline-neutral">&nbsp;</span>
966
+ <span class="cline-any cline-yes">24x</span>
967
+ <span class="cline-any cline-neutral">&nbsp;</span>
968
+ <span class="cline-any cline-yes">24x</span>
969
+ <span class="cline-any cline-yes">5x</span>
970
+ <span class="cline-any cline-neutral">&nbsp;</span>
971
+ <span class="cline-any cline-neutral">&nbsp;</span>
972
+ <span class="cline-any cline-yes">19x</span>
973
+ <span class="cline-any cline-neutral">&nbsp;</span>
974
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import fs from 'node:fs/promises'
975
+ import os from 'node:os'
976
+ import path from 'node:path'
977
+ import { z } from 'zod'
978
+ &nbsp;
979
+ import { getProjectRoot } from 'src/lib/git-utils'
980
+ &nbsp;
981
+ const INFRA_KIT_CONFIG_FILE = 'infra-kit.json'
982
+ &nbsp;
983
+ /**
984
+ * Directory under the user's home that holds all machine-local infra-kit config:
985
+ * the runtime `infra-kit.json` merge layer, per-project overrides, and the factory
986
+ * registry (`vendor.json`). Single source of truth for `.infra-kit`, reused
987
+ * by the vendor factory-config loader (no import cycle — this module imports no
988
+ * `lib/vendor` code).
989
+ */
990
+ export const USER_CONFIG_DIR_NAME = '.infra-kit'
991
+ const USER_GLOBAL_CONFIG_FILE = 'infra-kit.json'
992
+ const USER_PROJECTS_DIR = 'projects'
993
+ &nbsp;
994
+ // envManagement
995
+ const dopplerEnvManagementSchema = z.object({
996
+ provider: z.literal('doppler'),
997
+ config: z.object({
998
+ name: z.string().min(1),
999
+ }),
1000
+ })
1001
+ &nbsp;
1002
+ const envManagementSchema = z.discriminatedUnion('provider', [dopplerEnvManagementSchema])
1003
+ &nbsp;
1004
+ // ide
1005
+ // There is one attach style: each worktree is added to the configured editor's
1006
+ // workspace and opened (no per-window mode). Cursor needs a `.code-workspace`
1007
+ // path to reconcile its `folders` array against.
1008
+ const cursorIdeConfigSchema = z.object({
1009
+ workspaceConfigPath: z.string().min(1),
1010
+ })
1011
+ &nbsp;
1012
+ const cursorIdeSchema = z.object({
1013
+ provider: z.literal('cursor'),
1014
+ config: cursorIdeConfigSchema,
1015
+ })
1016
+ &nbsp;
1017
+ // Zed has no portable workspace file (no `.code-workspace`) and no folder-remove
1018
+ // CLI: a multi-worktree workspace is realized by a single `zed &lt;root&gt; &lt;wt...&gt;`
1019
+ // invocation. So `config` carries no settings — there's no path to point at.
1020
+ const zedIdeConfigSchema = z.object({})
1021
+ &nbsp;
1022
+ const zedIdeSchema = z.object({
1023
+ provider: z.literal('zed'),
1024
+ config: zedIdeConfigSchema,
1025
+ })
1026
+ &nbsp;
1027
+ const ideSchema = z.discriminatedUnion('provider', [cursorIdeSchema, zedIdeSchema])
1028
+ &nbsp;
1029
+ // `ide` accepts a single provider (back-compat) OR an array to drive multiple
1030
+ // editors at once (e.g. Cursor + Zed). Normalized to an array everywhere via
1031
+ // `resolveConfiguredIdes`. Uniqueness-by-provider is enforced at parse time by a
1032
+ // `.superRefine` on the full config schema (see below) — not here, so the message
1033
+ // survives `z.union` error aggregation.
1034
+ const idesSchema = z.union([ideSchema, z.array(ideSchema).min(1)])
1035
+ &nbsp;
1036
+ // taskManager
1037
+ const jiraTaskManagerSchema = z.object({
1038
+ provider: z.literal('jira'),
1039
+ config: z.object({
1040
+ baseUrl: z.string().url(),
1041
+ projectId: z.number().int().positive(),
1042
+ }),
1043
+ })
1044
+ &nbsp;
1045
+ const taskManagerSchema = z.discriminatedUnion('provider', [jiraTaskManagerSchema])
1046
+ &nbsp;
1047
+ // cmux pane layout for opened worktree workspaces. Named presets keep the config
1048
+ // typo-proof (an enum, not a free string) and let the opener switch on a single
1049
+ // value; extend the enum + the opener's switch to add a layout.
1050
+ // two-columns — left | right, both full-height (default)
1051
+ // three-pane — left split top/bottom + full-height right (legacy layout)
1052
+ const cmuxLayouts = ['two-columns', 'three-pane'] as const
1053
+ &nbsp;
1054
+ const cmuxConfigSchema = z.object({
1055
+ layout: z.enum(cmuxLayouts).optional(),
1056
+ })
1057
+ &nbsp;
1058
+ // worktrees prompt defaults
1059
+ const worktreesConfigSchema = z.object({
1060
+ openInGithubDesktop: z.boolean().optional(),
1061
+ openInCmux: z.boolean().optional(),
1062
+ cmux: cmuxConfigSchema.optional(),
1063
+ })
1064
+ &nbsp;
1065
+ // dev-server per-app overrides. Maps an app folder name (e.g. `client`) to its
1066
+ // local dev port and/or URL prefix. Both keys optional. An app absent from the
1067
+ // map falls back to env (`{APP}_PORT` / `PORT`) then the built-in defaults, so
1068
+ // the map is intentionally NOT validated against the discovered apps here — an
1069
+ // unknown app name is simply ignored at resolve time (lib/dev), never a parse
1070
+ // error that would brick every command.
1071
+ const devAppConfigSchema = z
1072
+ .object({
1073
+ port: z.number().int().positive().optional(),
1074
+ prefixUrl: z.string().min(1).optional(),
1075
+ })
1076
+ .strict()
1077
+ &nbsp;
1078
+ const devConfigSchema = z.record(z.string().min(1), devAppConfigSchema)
1079
+ &nbsp;
1080
+ // env auto-load: opt-in convenience that primes Doppler env when you work inside
1081
+ // this project / a worktree. Absent =&gt; disabled. `trigger` selects the moment
1082
+ // (pick one):
1083
+ // shell-startup — when a new shell opens inside the project
1084
+ // cli-invocation — before each `infra-kit` command (primes SUBSEQUENT commands)
1085
+ // `config` names which environment to load. It is intentionally NOT validated
1086
+ // against `environments` here: an invalid name must DISABLE the feature at
1087
+ // resolve time (lib/env-autoload), never throw inside the merged-config parse and
1088
+ // brick every command.
1089
+ const envAutoLoadSchema = z
1090
+ .object({
1091
+ trigger: z.enum(['shell-startup', 'cli-invocation']),
1092
+ config: z.string().min(1),
1093
+ })
1094
+ .strict()
1095
+ &nbsp;
1096
+ // Base object shape, kept separate so `.partial()` (which only works on a plain
1097
+ // ZodObject, not the `.superRefine`-wrapped full schema) can derive the override
1098
+ // schema from it.
1099
+ const infraKitConfigObject = z.object({
1100
+ environments: z.array(z.string().min(1)).min(1),
1101
+ envManagement: envManagementSchema,
1102
+ ide: idesSchema.optional(),
1103
+ taskManager: taskManagerSchema.optional(),
1104
+ worktrees: worktreesConfigSchema.optional(),
1105
+ envAutoLoad: envAutoLoadSchema.optional(),
1106
+ dev: devConfigSchema.optional(),
1107
+ })
1108
+ &nbsp;
1109
+ // Full schema = base object + a parse-time uniqueness check on the `ide` array.
1110
+ // This runs inside the *merged* `safeParse` in getInfraKitConfig, so it's the
1111
+ // gate for the final config. (The override layers use the `.partial()` form
1112
+ // below, which drops this object-level refinement — acceptable, the merged
1113
+ // parse is authoritative.)
1114
+ export const infraKitConfigSchema = infraKitConfigObject.superRefine((cfg, ctx) =&gt; {
1115
+ if (!Array.isArray(cfg.ide)) return
1116
+ &nbsp;
1117
+ const seen = new Set&lt;string&gt;()
1118
+ &nbsp;
1119
+ for (const entry of cfg.ide) {
1120
+ if (seen.has(entry.provider)) {
1121
+ ctx.addIssue({
1122
+ code: 'custom',
1123
+ message: 'each IDE provider may appear at most once',
1124
+ path: ['ide'],
1125
+ })
1126
+ &nbsp;
1127
+ return
1128
+ }
1129
+ &nbsp;
1130
+ seen.add(entry.provider)
1131
+ }
1132
+ })
1133
+ &nbsp;
1134
+ export const infraKitOverrideConfigSchema = infraKitConfigObject.partial()
1135
+ &nbsp;
1136
+ export type InfraKitConfig = z.infer&lt;typeof infraKitConfigSchema&gt;
1137
+ &nbsp;
1138
+ /** Resolved env auto-load config (`{ trigger, config }`), or `undefined` when off. */
1139
+ export type EnvAutoLoadConfig = z.infer&lt;typeof envAutoLoadSchema&gt;
1140
+ &nbsp;
1141
+ /** Per-app dev-server overrides (`{ port?, prefixUrl? }`). */
1142
+ export type DevAppConfig = z.infer&lt;typeof devAppConfigSchema&gt;
1143
+ &nbsp;
1144
+ /** The full `dev` section: a map of app folder name to its {@link DevAppConfig}. */
1145
+ export type DevConfig = z.infer&lt;typeof devConfigSchema&gt;
1146
+ &nbsp;
1147
+ /** A single resolved IDE entry (`{ provider, config }`). */
1148
+ export type ConfiguredIde = z.infer&lt;typeof ideSchema&gt;
1149
+ &nbsp;
1150
+ /**
1151
+ * Normalize the `ide` config (single object, array, or unset) into a flat list.
1152
+ * Validation-free: assumes already-parsed input (uniqueness is enforced by the
1153
+ * schema). The one source of truth for "which editors are configured."
1154
+ *
1155
+ * @example
1156
+ * resolveConfiguredIdes({ ide: { provider: 'cursor', config: {...} } }) // =&gt; [cursor]
1157
+ * resolveConfiguredIdes({ ide: [cursor, zed] }) // =&gt; [cursor, zed]
1158
+ * resolveConfiguredIdes({}) // =&gt; []
1159
+ */
1160
+ export const resolveConfiguredIdes = (config: InfraKitConfig): ConfiguredIde[] =&gt; {
1161
+ const ide = config.ide
1162
+ &nbsp;
1163
+ if (!ide) return []
1164
+ &nbsp;
1165
+ return Array.isArray(ide) ? ide : [ide]
1166
+ }
1167
+ &nbsp;
1168
+ /** A cmux pane layout preset (see {@link cmuxLayouts}). */
1169
+ export type CmuxLayout = (typeof cmuxLayouts)[number]
1170
+ &nbsp;
1171
+ /** The layout applied when `worktrees.cmux.layout` is left unset. */
1172
+ export const DEFAULT_CMUX_LAYOUT: CmuxLayout = 'two-columns'
1173
+ &nbsp;
1174
+ /**
1175
+ * Resolve the cmux pane layout for opened worktree workspaces, falling back to
1176
+ * {@link DEFAULT_CMUX_LAYOUT} when unconfigured. The one source of truth for
1177
+ * "which layout should the cmux opener build."
1178
+ *
1179
+ * @example
1180
+ * resolveCmuxLayout({ worktrees: { cmux: { layout: 'three-pane' } } }) // =&gt; 'three-pane'
1181
+ * resolveCmuxLayout({}) // =&gt; 'two-columns'
1182
+ */
1183
+ export const resolveCmuxLayout = (config: InfraKitConfig): CmuxLayout =&gt; {
1184
+ return config.worktrees?.cmux?.layout ?? DEFAULT_CMUX_LAYOUT
1185
+ }
1186
+ &nbsp;
1187
+ export interface InfraKitConfigPaths {
1188
+ /** Committed project config (required). */
1189
+ main: string
1190
+ /** User-scope global overrides applied to every project. */
1191
+ userGlobal: string
1192
+ /** User-scope per-project overrides — `&lt;userProjectsDir&gt;/&lt;projectName&gt;/infra-kit.json`. */
1193
+ userProject: string
1194
+ /** Repo basename (`path.basename(projectRoot)`) used to namespace the user-project file. */
1195
+ projectName: string
1196
+ }
1197
+ &nbsp;
1198
+ interface CacheEntry {
1199
+ mtimes: Record&lt;keyof Omit&lt;InfraKitConfigPaths, 'projectName'&gt;, number | null&gt;
1200
+ value: InfraKitConfig
1201
+ }
1202
+ &nbsp;
1203
+ let cached: CacheEntry | null = null
1204
+ &nbsp;
1205
+ /**
1206
+ * Resolve every file path that participates in the config merge chain. Always
1207
+ * returns paths even for files that don't yet exist, so callers can use them
1208
+ * for "where would my override go?" prompts.
1209
+ *
1210
+ * @example
1211
+ * const paths = await getInfraKitConfigPaths()
1212
+ * // {
1213
+ * // main: '/Users/arthur/projects/api/infra-kit.json',
1214
+ * // userGlobal: '/Users/arthur/.infra-kit/infra-kit.json',
1215
+ * // userProject: '/Users/arthur/.infra-kit/projects/api/infra-kit.json',
1216
+ * // projectName: 'api',
1217
+ * // }
1218
+ */
1219
+ export const getInfraKitConfigPaths = async (): Promise&lt;InfraKitConfigPaths&gt; =&gt; {
1220
+ const projectRoot = await getProjectRoot()
1221
+ // Repo name is the project-root basename (same as getRepoName), derived here to
1222
+ // avoid a second `git rev-parse` — getRepoName would re-resolve the root.
1223
+ const projectName = path.basename(projectRoot)
1224
+ const userConfigDir = path.join(os.homedir(), USER_CONFIG_DIR_NAME)
1225
+ &nbsp;
1226
+ return {
1227
+ main: path.join(projectRoot, INFRA_KIT_CONFIG_FILE),
1228
+ userGlobal: path.join(userConfigDir, USER_GLOBAL_CONFIG_FILE),
1229
+ userProject: path.join(userConfigDir, USER_PROJECTS_DIR, projectName, INFRA_KIT_CONFIG_FILE),
1230
+ projectName,
1231
+ }
1232
+ }
1233
+ &nbsp;
1234
+ /**
1235
+ * Read and validate `infra-kit.json`, with optional override layers shallow-merged
1236
+ * on top in this order (later wins):
1237
+ * 1. project `infra-kit.json` — committed source of truth
1238
+ * 2. `~/.infra-kit/infra-kit.json` — user-global defaults
1239
+ * 3. `~/.infra-kit/projects/&lt;repo-name&gt;/infra-kit.json` — user-scope per-project overrides
1240
+ *
1241
+ * Top-level keys (entire capability sections like `ide`, `envManagement`)
1242
+ * replace wholesale. Results are cached per file mtimes so the long-running
1243
+ * MCP server picks up edits without a restart.
1244
+ *
1245
+ * @example
1246
+ * // infra-kit.json: { "environments": ["dev"], "envManagement": { "provider": "doppler", "config": { "name": "p" } } }
1247
+ * // ~/.infra-kit/infra-kit.json: { "ide": { "provider": "cursor", "config": { "workspaceConfigPath": "./ws.code-workspace" } } }
1248
+ * const cfg = await getInfraKitConfig()
1249
+ * // =&gt; { environments: ['dev'], envManagement: {...}, ide: { provider: 'cursor', config: { workspaceConfigPath: './ws.code-workspace' } } }
1250
+ */
1251
+ export const getInfraKitConfig = async (): Promise&lt;InfraKitConfig&gt; =&gt; {
1252
+ const paths = await getInfraKitConfigPaths()
1253
+ &nbsp;
1254
+ let mainStat: Awaited&lt;ReturnType&lt;typeof fs.stat&gt;&gt;
1255
+ &nbsp;
1256
+ try {
1257
+ mainStat = await fs.stat(paths.main)
1258
+ } catch {
1259
+ cached = null
1260
+ &nbsp;
1261
+ // Bridge the YAML→JSON cutover: if a legacy infra-kit.yml is sitting where
1262
+ // the JSON config should be, point the user at the one-shot migration.
1263
+ const legacyYmlPath = paths.main.replace(/\.json$/, '.yml')
1264
+ &nbsp;
1265
+ if (await statIfExists(legacyYmlPath)) {
1266
+ throw new Error(
1267
+ `infra-kit.json not found at ${paths.main}. A legacy infra-kit.yml exists — run \`infra-kit init\` to convert it.`,
1268
+ )
1269
+ }
1270
+ &nbsp;
1271
+ throw new Error(`infra-kit.json not found at ${paths.main}`)
1272
+ }
1273
+ &nbsp;
1274
+ const [userGlobalStat, userProjectStat] = await Promise.all([
1275
+ statIfExists(paths.userGlobal),
1276
+ statIfExists(paths.userProject),
1277
+ ])
1278
+ &nbsp;
1279
+ const mtimes = {
1280
+ main: Number(mainStat.mtimeMs),
1281
+ userGlobal: userGlobalStat ? Number(userGlobalStat.mtimeMs) : null,
1282
+ userProject: userProjectStat ? <span class="branch-0 cbranch-no" title="branch not covered" >Number(userProjectStat.mtimeMs) : n</span>ull,
1283
+ }
1284
+ &nbsp;
1285
+ if (cached &amp;&amp; shallowEqual(cached.mtimes, mtimes)) {
1286
+ return cached.value
1287
+ }
1288
+ &nbsp;
1289
+ const layers: ConfigLayer[] = [
1290
+ { label: 'infra-kit.json', path: paths.main, required: true },
1291
+ { label: '~/.infra-kit/infra-kit.json', path: paths.userGlobal, required: false },
1292
+ {
1293
+ label: `~/.infra-kit/projects/${paths.projectName}/infra-kit.json`,
1294
+ path: paths.userProject,
1295
+ required: false,
1296
+ },
1297
+ ]
1298
+ &nbsp;
1299
+ let merged: Record&lt;string, unknown&gt; = {}
1300
+ &nbsp;
1301
+ for (const layer of layers) {
1302
+ const data = await loadLayer(layer)
1303
+ &nbsp;
1304
+ if (data === null) continue
1305
+ &nbsp;
1306
+ merged = { ...merged, ...data }
1307
+ }
1308
+ &nbsp;
1309
+ const finalResult = infraKitConfigSchema.safeParse(merged)
1310
+ &nbsp;
1311
+ if (!finalResult.success) {
1312
+ throw new Error(`Invalid merged infra-kit config: ${z.prettifyError(finalResult.error)}`)
1313
+ }
1314
+ &nbsp;
1315
+ cached = { mtimes, value: finalResult.data }
1316
+ &nbsp;
1317
+ return finalResult.data
1318
+ }
1319
+ &nbsp;
1320
+ /**
1321
+ * For tests — drops the in-memory cache so the next read hits disk.
1322
+ *
1323
+ * @example
1324
+ * resetInfraKitConfigCache()
1325
+ * await getInfraKitConfig() // re-reads files even if mtimes look unchanged
1326
+ */
1327
+ export const resetInfraKitConfigCache = (): void =&gt; {
1328
+ cached = null
1329
+ }
1330
+ &nbsp;
1331
+ /**
1332
+ * `fs.stat` that returns `null` instead of throwing on ENOENT. Used so the
1333
+ * resolver can probe optional files in the merge chain without try/catch noise.
1334
+ *
1335
+ * @example
1336
+ * const stat = await statIfExists('/does/not/exist') // =&gt; null
1337
+ */
1338
+ const statIfExists = async (filePath: string): Promise&lt;Awaited&lt;ReturnType&lt;typeof fs.stat&gt;&gt; | null&gt; =&gt; {
1339
+ try {
1340
+ return await fs.stat(filePath)
1341
+ } catch {
1342
+ return null
1343
+ }
1344
+ }
1345
+ &nbsp;
1346
+ /**
1347
+ * `fs.readFile` that returns `null` instead of throwing on ENOENT.
1348
+ *
1349
+ * @example
1350
+ * const raw = await readIfExists('/missing.json') // =&gt; null
1351
+ * const raw = await readIfExists('/exists.json') // =&gt; '{ "environments": ["dev"] }\n'
1352
+ */
1353
+ const readIfExists = async (filePath: string): Promise&lt;string | null&gt; =&gt; {
1354
+ try {
1355
+ return await fs.readFile(filePath, 'utf-8')
1356
+ } catch {
1357
+ return null
1358
+ }
1359
+ }
1360
+ &nbsp;
1361
+ /**
1362
+ * Reference-equality comparison of every key in two flat records. Used to
1363
+ * cheaply detect whether the cached mtime fingerprint still matches.
1364
+ *
1365
+ * @example
1366
+ * shallowEqual({ a: 1, b: 2 }, { a: 1, b: 2 }) // =&gt; true
1367
+ * shallowEqual({ a: 1 }, { a: 1, b: 2 }) // =&gt; false
1368
+ * shallowEqual({ a: 1 }, { a: 2 }) // =&gt; false
1369
+ */
1370
+ const shallowEqual = &lt;T extends Record&lt;string, unknown&gt;&gt;(a: T, b: T): boolean =&gt; {
1371
+ const keys = Object.keys(a)
1372
+ &nbsp;
1373
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (keys.length !== Object.keys(b).length) <span class="cstat-no" title="statement not covered" >return false</span>
1374
+ &nbsp;
1375
+ return keys.every((k) =&gt; {
1376
+ return a[k] === b[k]
1377
+ })
1378
+ }
1379
+ &nbsp;
1380
+ interface ConfigLayer {
1381
+ label: string
1382
+ path: string
1383
+ required: boolean
1384
+ }
1385
+ &nbsp;
1386
+ /**
1387
+ * Read a single layer of the merge chain: parse the JSON if the file exists
1388
+ * and validate it against the override schema. Returns `null` if an optional
1389
+ * layer is missing; throws if the layer is required, malformed, or invalid.
1390
+ * An empty/whitespace-only file is treated as `{}` (JSON.parse would throw).
1391
+ *
1392
+ * @example
1393
+ * await loadLayer({ label: '~/.infra-kit/infra-kit.json', path: '/missing.json', required: false })
1394
+ * // =&gt; null
1395
+ *
1396
+ * @example
1397
+ * // /home/me/.infra-kit/infra-kit.json: '{ "ide": { "provider": "cursor", "config": { "workspaceConfigPath": "./ws.code-workspace" } } }'
1398
+ * await loadLayer({ label: '~/.infra-kit/infra-kit.json', path: '/home/me/.infra-kit/infra-kit.json', required: false })
1399
+ * // =&gt; { ide: { provider: 'cursor', config: { workspaceConfigPath: './ws.code-workspace' } } }
1400
+ */
1401
+ const loadLayer = async (layer: ConfigLayer): Promise&lt;Record&lt;string, unknown&gt; | null&gt; =&gt; {
1402
+ const raw = await readIfExists(layer.path)
1403
+ &nbsp;
1404
+ if (raw === null) {
1405
+ <span class="missing-if-branch" title="if path not taken" >I</span>if (layer.required) {
1406
+ <span class="cstat-no" title="statement not covered" > throw new Error(`${layer.label} not found at ${layer.path}`)</span>
1407
+ }
1408
+ &nbsp;
1409
+ return null
1410
+ }
1411
+ &nbsp;
1412
+ let parsedRaw: unknown
1413
+ &nbsp;
1414
+ try {
1415
+ parsedRaw = raw.trim() === '' ? {} : JSON.parse(raw)
1416
+ } catch (err) {
1417
+ throw new Error(`Invalid JSON in ${layer.label} at ${layer.path}: ${(err as Error).message}`)
1418
+ }
1419
+ &nbsp;
1420
+ const result = infraKitOverrideConfigSchema.safeParse(parsedRaw)
1421
+ &nbsp;
1422
+ if (!result.success) {
1423
+ throw new Error(`Invalid ${layer.label} at ${layer.path}: ${z.prettifyError(result.error)}`)
1424
+ }
1425
+ &nbsp;
1426
+ return result.data as Record&lt;string, unknown&gt;
1427
+ }
1428
+ &nbsp;</pre></td></tr></table></pre>
1429
+
1430
+ <div class='push'></div><!-- for sticky footer -->
1431
+ </div><!-- /wrapper -->
1432
+ <div class='footer quiet pad2 space-top1 center small'>
1433
+ Code coverage generated by
1434
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1435
+ at 2026-07-02T09:20:45.872Z
1436
+ </div>
1437
+ <script src="../../../../prettify.js"></script>
1438
+ <script>
1439
+ window.onload = function () {
1440
+ prettyPrint();
1441
+ };
1442
+ </script>
1443
+ <script src="../../../../sorter.js"></script>
1444
+ <script src="../../../../block-navigation.js"></script>
1445
+ </body>
1446
+ </html>
1447
+