@warlock.js/core 5.30.0 → 5.31.0

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 (797) hide show
  1. package/CHANGELOG.md +142 -36
  2. package/README.md +28 -23
  3. package/bin/source-load-hook.mjs +63 -0
  4. package/bin/warlock.js +102 -42
  5. package/esm/cli/commands/add.command.mjs +4 -2
  6. package/esm/cli/commands/add.command.mjs.map +1 -1
  7. package/esm/cli/commands/agents-md/agents-md-command.action.mjs +69 -0
  8. package/esm/cli/commands/agents-md/agents-md-command.action.mjs.map +1 -0
  9. package/esm/cli/commands/agents-md.command.mjs +38 -0
  10. package/esm/cli/commands/agents-md.command.mjs.map +1 -0
  11. package/esm/cli/commands/board/board-command.action.mjs +279 -0
  12. package/esm/cli/commands/board/board-command.action.mjs.map +1 -0
  13. package/esm/cli/commands/board.command.mjs +78 -0
  14. package/esm/cli/commands/board.command.mjs.map +1 -0
  15. package/esm/cli/commands/build.command.mjs +6 -1
  16. package/esm/cli/commands/build.command.mjs.map +1 -1
  17. package/esm/cli/commands/check/check-command.action.mjs +57 -0
  18. package/esm/cli/commands/check/check-command.action.mjs.map +1 -0
  19. package/esm/cli/commands/check/child-typecheck.mjs +66 -0
  20. package/esm/cli/commands/check/child-typecheck.mjs.map +1 -0
  21. package/esm/cli/commands/check/format-problems.mjs +43 -0
  22. package/esm/cli/commands/check/format-problems.mjs.map +1 -0
  23. package/esm/cli/commands/check/typecheck-command.action.mjs +61 -0
  24. package/esm/cli/commands/check/typecheck-command.action.mjs.map +1 -0
  25. package/esm/cli/commands/check.command.mjs +50 -0
  26. package/esm/cli/commands/check.command.mjs.map +1 -0
  27. package/esm/cli/commands/dev-server.command.mjs +9 -1
  28. package/esm/cli/commands/dev-server.command.mjs.map +1 -1
  29. package/esm/cli/commands/doctor/boot-for-diagnostics.mjs +8 -3
  30. package/esm/cli/commands/doctor/boot-for-diagnostics.mjs.map +1 -1
  31. package/esm/cli/commands/doctor/check.types.d.mts +76 -0
  32. package/esm/cli/commands/doctor/check.types.d.mts.map +1 -0
  33. package/esm/cli/commands/doctor/checks/config.check.mjs +1 -0
  34. package/esm/cli/commands/doctor/checks/config.check.mjs.map +1 -1
  35. package/esm/cli/commands/doctor/checks/connectors.check.mjs +2 -0
  36. package/esm/cli/commands/doctor/checks/connectors.check.mjs.map +1 -1
  37. package/esm/cli/commands/doctor/checks/handler-signature.check.mjs +1 -0
  38. package/esm/cli/commands/doctor/checks/handler-signature.check.mjs.map +1 -1
  39. package/esm/cli/commands/doctor/checks/health.check.mjs +3 -0
  40. package/esm/cli/commands/doctor/checks/health.check.mjs.map +1 -1
  41. package/esm/cli/commands/doctor/checks/jwt-secret.check.mjs +1 -0
  42. package/esm/cli/commands/doctor/checks/jwt-secret.check.mjs.map +1 -1
  43. package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs +1 -0
  44. package/esm/cli/commands/doctor/checks/locales-ts-deprecated.check.mjs.map +1 -1
  45. package/esm/cli/commands/doctor/checks/optional-peers.check.mjs +1 -0
  46. package/esm/cli/commands/doctor/checks/optional-peers.check.mjs.map +1 -1
  47. package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs +4 -0
  48. package/esm/cli/commands/doctor/checks/release-hygiene.check.mjs.map +1 -1
  49. package/esm/cli/commands/doctor/checks/routes.check.mjs +3 -0
  50. package/esm/cli/commands/doctor/checks/routes.check.mjs.map +1 -1
  51. package/esm/cli/commands/doctor/doctor-command.action.mjs +14 -6
  52. package/esm/cli/commands/doctor/doctor-command.action.mjs.map +1 -1
  53. package/esm/cli/commands/doctor/format-report.mjs +30 -2
  54. package/esm/cli/commands/doctor/format-report.mjs.map +1 -1
  55. package/esm/cli/commands/doctor.command.mjs +4 -0
  56. package/esm/cli/commands/doctor.command.mjs.map +1 -1
  57. package/esm/cli/commands/explain/explain-command.action.mjs +64 -0
  58. package/esm/cli/commands/explain/explain-command.action.mjs.map +1 -0
  59. package/esm/cli/commands/explain.command.mjs +23 -0
  60. package/esm/cli/commands/explain.command.mjs.map +1 -0
  61. package/esm/cli/commands/generate/generate.command.mjs +124 -124
  62. package/esm/cli/commands/generate/generate.command.mjs.map +1 -1
  63. package/esm/cli/commands/generate/generators/endpoint.generator.mjs +311 -0
  64. package/esm/cli/commands/generate/generators/endpoint.generator.mjs.map +1 -0
  65. package/esm/cli/commands/generate/generators/migration.generator.mjs +1 -1
  66. package/esm/cli/commands/generate/generators/migration.generator.mjs.map +1 -1
  67. package/esm/cli/commands/generate/generators/model.generator.mjs +1 -1
  68. package/esm/cli/commands/generate/templates/endpoint-stubs.mjs +341 -0
  69. package/esm/cli/commands/generate/templates/endpoint-stubs.mjs.map +1 -0
  70. package/esm/cli/commands/generate/templates/stubs.mjs +19 -6
  71. package/esm/cli/commands/generate/templates/stubs.mjs.map +1 -1
  72. package/esm/cli/commands/generate/utils/endpoint-schema.mjs +137 -0
  73. package/esm/cli/commands/generate/utils/endpoint-schema.mjs.map +1 -0
  74. package/esm/cli/commands/generate/utils/name-parser.mjs +1 -1
  75. package/esm/cli/commands/generate/utils/name-parser.mjs.map +1 -1
  76. package/esm/cli/commands/generate/utils/prompt.mjs.map +1 -1
  77. package/esm/cli/commands/generate/utils/writer.mjs +38 -13
  78. package/esm/cli/commands/generate/utils/writer.mjs.map +1 -1
  79. package/esm/cli/commands/inspect/inspect-command.action.mjs +72 -0
  80. package/esm/cli/commands/inspect/inspect-command.action.mjs.map +1 -0
  81. package/esm/cli/commands/inspect.command.mjs +39 -0
  82. package/esm/cli/commands/inspect.command.mjs.map +1 -0
  83. package/esm/cli/commands/mcp/mcp-command.action.mjs +103 -0
  84. package/esm/cli/commands/mcp/mcp-command.action.mjs.map +1 -0
  85. package/esm/cli/commands/mcp.command.mjs +76 -0
  86. package/esm/cli/commands/mcp.command.mjs.map +1 -0
  87. package/esm/cli/commands/openapi-generator.action.mjs.map +1 -1
  88. package/esm/cli/commands/openapi-generator.command.mjs.map +1 -1
  89. package/esm/cli/commands/postman-generator.action.mjs.map +1 -1
  90. package/esm/cli/commands/postman-generator.command.mjs.map +1 -1
  91. package/esm/cli/commands/routes/routes-diff.action.mjs +1 -1
  92. package/esm/cli/commands/test.command.mjs +131 -0
  93. package/esm/cli/commands/test.command.mjs.map +1 -0
  94. package/esm/cli/commands/trace/trace-command.action.mjs +145 -0
  95. package/esm/cli/commands/trace/trace-command.action.mjs.map +1 -0
  96. package/esm/cli/commands/trace.command.mjs +60 -0
  97. package/esm/cli/commands/trace.command.mjs.map +1 -0
  98. package/esm/cli/commands/typecheck.command.mjs +40 -0
  99. package/esm/cli/commands/typecheck.command.mjs.map +1 -0
  100. package/esm/cli/commands/upgrade.command.mjs +46 -0
  101. package/esm/cli/commands/upgrade.command.mjs.map +1 -0
  102. package/esm/cli/flush-and-exit.mjs +34 -0
  103. package/esm/cli/flush-and-exit.mjs.map +1 -0
  104. package/esm/cli/framework-cli-commands.mjs +23 -1
  105. package/esm/cli/framework-cli-commands.mjs.map +1 -1
  106. package/esm/cli/parse-cli-args.mjs +1 -0
  107. package/esm/cli/parse-cli-args.mjs.map +1 -1
  108. package/esm/config/config-loader.d.mts.map +1 -1
  109. package/esm/config/config-loader.mjs +34 -13
  110. package/esm/config/config-loader.mjs.map +1 -1
  111. package/esm/config/config-schema.d.mts +67 -0
  112. package/esm/config/config-schema.d.mts.map +1 -0
  113. package/esm/config/config-schema.mjs +77 -0
  114. package/esm/config/config-schema.mjs.map +1 -0
  115. package/esm/config/index.d.mts +6 -0
  116. package/esm/config/index.mjs +1 -0
  117. package/esm/connectors/assert-no-reserved-connector-names.d.mts.map +1 -1
  118. package/esm/connectors/assert-no-reserved-connector-names.mjs +2 -1
  119. package/esm/connectors/assert-no-reserved-connector-names.mjs.map +1 -1
  120. package/esm/connectors/assert-unique-connector-names.d.mts.map +1 -1
  121. package/esm/connectors/assert-unique-connector-names.mjs +26 -2
  122. package/esm/connectors/assert-unique-connector-names.mjs.map +1 -1
  123. package/esm/connectors/http-connector.d.mts.map +1 -1
  124. package/esm/connectors/http-connector.mjs +3 -2
  125. package/esm/connectors/http-connector.mjs.map +1 -1
  126. package/esm/connectors/single-server-warnings.mjs.map +1 -1
  127. package/esm/connectors/socket-connector.d.mts.map +1 -1
  128. package/esm/connectors/socket-connector.mjs.map +1 -1
  129. package/esm/container/index.d.mts.map +1 -1
  130. package/esm/container/index.mjs.map +1 -1
  131. package/esm/database/migrate-action.mjs.map +1 -1
  132. package/esm/database/models/database-log/database-log.d.mts +0 -28
  133. package/esm/database/models/database-log/database-log.d.mts.map +1 -1
  134. package/esm/database/seeds/seeder.errors.d.mts +4 -0
  135. package/esm/database/seeds/seeder.errors.d.mts.map +1 -1
  136. package/esm/database/seeds/seeder.errors.mjs +2 -0
  137. package/esm/database/seeds/seeder.errors.mjs.map +1 -1
  138. package/esm/dev-server/boot-precondition-error.mjs +1 -0
  139. package/esm/dev-server/boot-precondition-error.mjs.map +1 -1
  140. package/esm/dev-server/create-worker.mjs +15 -9
  141. package/esm/dev-server/create-worker.mjs.map +1 -1
  142. package/esm/dev-server/dev-agent-tooling.mjs +135 -0
  143. package/esm/dev-server/dev-agent-tooling.mjs.map +1 -0
  144. package/esm/dev-server/dev-logger.mjs.map +1 -1
  145. package/esm/dev-server/development-server.mjs +8 -0
  146. package/esm/dev-server/development-server.mjs.map +1 -1
  147. package/esm/dev-server/files-orchestrator.mjs +4 -5
  148. package/esm/dev-server/files-orchestrator.mjs.map +1 -1
  149. package/esm/dev-server/files-watcher.mjs +1 -1
  150. package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs +2 -3
  151. package/esm/dev-server/health-checker/checkers/eslint-health-checker.mjs.map +1 -1
  152. package/esm/dev-server/health-checker/checkers/oxlint-health-checker.mjs +33 -0
  153. package/esm/dev-server/health-checker/checkers/oxlint-health-checker.mjs.map +1 -0
  154. package/esm/dev-server/health-checker/default-health-checkers.mjs +31 -0
  155. package/esm/dev-server/health-checker/default-health-checkers.mjs.map +1 -0
  156. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts +9 -3
  157. package/esm/dev-server/health-checker/file-health-checker.contract.d.mts.map +1 -1
  158. package/esm/dev-server/health-checker/files-healthcare.manager.mjs +15 -4
  159. package/esm/dev-server/health-checker/files-healthcare.manager.mjs.map +1 -1
  160. package/esm/dev-server/health-checker/oxlint-runner.mjs +302 -0
  161. package/esm/dev-server/health-checker/oxlint-runner.mjs.map +1 -0
  162. package/esm/dev-server/health-checker/workers/oxlint-health.worker.d.mts +1 -0
  163. package/esm/dev-server/health-checker/workers/oxlint-health.worker.mjs +42 -0
  164. package/esm/dev-server/health-checker/workers/oxlint-health.worker.mjs.map +1 -0
  165. package/esm/dev-server/loader/loader-port-acks.mjs +1 -1
  166. package/esm/dev-server/loader/loader-port-acks.mjs.map +1 -1
  167. package/esm/dev-server/loader/register-loader.mjs +1 -1
  168. package/esm/dev-server/loader/register-loader.mjs.map +1 -1
  169. package/esm/dev-server/loader/resolve-hook.mjs +1 -1
  170. package/esm/dev-server/loader/transpile-cache.mjs +1 -1
  171. package/esm/dev-server/model-resource-typings.mjs.map +1 -1
  172. package/esm/dev-server/module-loader.mjs +1 -0
  173. package/esm/dev-server/module-loader.mjs.map +1 -1
  174. package/esm/dev-server/parse-imports.mjs +1 -1
  175. package/esm/dev-server/parse-imports.mjs.map +1 -1
  176. package/esm/dev-server/route-types-publisher.mjs +1 -1
  177. package/esm/dev-server/start-development-server.mjs.map +1 -1
  178. package/esm/dev-server/translation-keys-sources.mjs +1 -1
  179. package/esm/dev-server/translation-keys-sources.mjs.map +1 -1
  180. package/esm/dev-server/tsconfig-manager.mjs.map +1 -1
  181. package/esm/dev-server/type-generator.mjs +3 -3
  182. package/esm/dev-server/type-generator.mjs.map +1 -1
  183. package/esm/dev-server/types.d.mts.map +1 -1
  184. package/esm/errors/container-key-missing-error.mjs +1 -0
  185. package/esm/errors/container-key-missing-error.mjs.map +1 -1
  186. package/esm/errors/error-codes.d.mts +653 -0
  187. package/esm/errors/error-codes.d.mts.map +1 -0
  188. package/esm/errors/error-codes.mjs +634 -0
  189. package/esm/errors/error-codes.mjs.map +1 -0
  190. package/esm/errors/esbuild-binary-missing-error.mjs +1 -0
  191. package/esm/errors/esbuild-binary-missing-error.mjs.map +1 -1
  192. package/esm/errors/index.d.mts +3 -1
  193. package/esm/errors/index.mjs +3 -1
  194. package/esm/errors/unknown-locale-error.mjs +1 -0
  195. package/esm/errors/unknown-locale-error.mjs.map +1 -1
  196. package/esm/errors/warlock-error.d.mts +23 -0
  197. package/esm/errors/warlock-error.d.mts.map +1 -0
  198. package/esm/errors/warlock-error.mjs +22 -0
  199. package/esm/errors/warlock-error.mjs.map +1 -0
  200. package/esm/generations/add-command.action.mjs +19 -3
  201. package/esm/generations/add-command.action.mjs.map +1 -1
  202. package/esm/generations/features/access.feature.mjs +1 -1
  203. package/esm/generations/features/access.feature.mjs.map +1 -1
  204. package/esm/generations/features/bull-board.feature.mjs +1 -1
  205. package/esm/generations/features/bull-board.feature.mjs.map +1 -1
  206. package/esm/generations/features/mysql.feature.mjs.map +1 -1
  207. package/esm/generations/features/notifications.feature.mjs +5 -2
  208. package/esm/generations/features/notifications.feature.mjs.map +1 -1
  209. package/esm/generations/features/queue.feature.mjs +1 -1
  210. package/esm/generations/features/queue.feature.mjs.map +1 -1
  211. package/esm/generations/features/react-email.feature.mjs +1 -1
  212. package/esm/generations/features/react-email.feature.mjs.map +1 -1
  213. package/esm/generations/features/shadcn.feature.mjs +1 -1
  214. package/esm/generations/features/shadcn.feature.mjs.map +1 -1
  215. package/esm/generations/features/shared/link-ai-package-import.mjs +1 -1
  216. package/esm/generations/features/shared/link-ai-package-import.mjs.map +1 -1
  217. package/esm/generations/features/shared/merge-web-sitemap-config.mjs.map +1 -1
  218. package/esm/generations/features/shared/patch-tsconfig-include.mjs +1 -1
  219. package/esm/generations/features/shared/patch-tsconfig-include.mjs.map +1 -1
  220. package/esm/generations/features/shared/relocate-conflicting-home-route.mjs +1 -1
  221. package/esm/generations/features/shared/relocate-conflicting-home-route.mjs.map +1 -1
  222. package/esm/generations/features/sitemap.feature.mjs +1 -1
  223. package/esm/generations/features/sitemap.feature.mjs.map +1 -1
  224. package/esm/generations/features/tailwind.feature.mjs +1 -1
  225. package/esm/generations/features/tailwind.feature.mjs.map +1 -1
  226. package/esm/generations/features/test.feature.mjs +11 -6
  227. package/esm/generations/features/test.feature.mjs.map +1 -1
  228. package/esm/generations/features/web.feature.mjs +1 -1
  229. package/esm/generations/features/web.feature.mjs.map +1 -1
  230. package/esm/generations/generation-fs.mjs +73 -0
  231. package/esm/generations/generation-fs.mjs.map +1 -0
  232. package/esm/generations/generation-run.mjs +185 -0
  233. package/esm/generations/generation-run.mjs.map +1 -0
  234. package/esm/generations/stubs.mjs +155 -13
  235. package/esm/generations/stubs.mjs.map +1 -1
  236. package/esm/http/bounded-stream-queue.d.mts +10 -0
  237. package/esm/http/bounded-stream-queue.d.mts.map +1 -0
  238. package/esm/http/bounded-stream-queue.mjs +97 -0
  239. package/esm/http/bounded-stream-queue.mjs.map +1 -0
  240. package/esm/http/build-rate-limit-options.d.mts +13 -0
  241. package/esm/http/build-rate-limit-options.d.mts.map +1 -1
  242. package/esm/http/build-rate-limit-options.mjs.map +1 -1
  243. package/esm/http/conditional-request.d.mts +86 -0
  244. package/esm/http/conditional-request.d.mts.map +1 -0
  245. package/esm/http/conditional-request.mjs +121 -0
  246. package/esm/http/conditional-request.mjs.map +1 -0
  247. package/esm/http/csp.d.mts +2 -0
  248. package/esm/http/csp.d.mts.map +1 -1
  249. package/esm/http/csp.mjs +1 -0
  250. package/esm/http/csp.mjs.map +1 -1
  251. package/esm/http/csrf-origin-policy.mjs.map +1 -1
  252. package/esm/http/database/RequestLog.d.mts +24 -84
  253. package/esm/http/database/RequestLog.d.mts.map +1 -1
  254. package/esm/http/errors/errors.d.mts +2 -0
  255. package/esm/http/errors/errors.d.mts.map +1 -1
  256. package/esm/http/errors/errors.mjs +1 -0
  257. package/esm/http/errors/errors.mjs.map +1 -1
  258. package/esm/http/escape-header-value.d.mts +18 -0
  259. package/esm/http/escape-header-value.d.mts.map +1 -0
  260. package/esm/http/escape-header-value.mjs +27 -0
  261. package/esm/http/escape-header-value.mjs.map +1 -0
  262. package/esm/http/flush-pending-cookies.mjs.map +1 -1
  263. package/esm/http/index.d.mts +5 -2
  264. package/esm/http/index.mjs +4 -1
  265. package/esm/http/lazy-static.mjs +194 -0
  266. package/esm/http/lazy-static.mjs.map +1 -0
  267. package/esm/http/middleware/idempotency.middleware.mjs.map +1 -1
  268. package/esm/http/plugins.d.mts.map +1 -1
  269. package/esm/http/plugins.mjs +7 -4
  270. package/esm/http/plugins.mjs.map +1 -1
  271. package/esm/http/rate-limit-cache-store.mjs +2 -1
  272. package/esm/http/rate-limit-cache-store.mjs.map +1 -1
  273. package/esm/http/request-log-snapshot.d.mts +12 -5
  274. package/esm/http/request-log-snapshot.d.mts.map +1 -1
  275. package/esm/http/request-log-snapshot.mjs +83 -4
  276. package/esm/http/request-log-snapshot.mjs.map +1 -1
  277. package/esm/http/request.d.mts +2 -2
  278. package/esm/http/request.d.mts.map +1 -1
  279. package/esm/http/request.mjs +5 -4
  280. package/esm/http/request.mjs.map +1 -1
  281. package/esm/http/response.d.mts +11 -1
  282. package/esm/http/response.d.mts.map +1 -1
  283. package/esm/http/response.mjs +164 -76
  284. package/esm/http/response.mjs.map +1 -1
  285. package/esm/http/safe-redirect.d.mts +51 -0
  286. package/esm/http/safe-redirect.d.mts.map +1 -0
  287. package/esm/http/safe-redirect.mjs +80 -0
  288. package/esm/http/safe-redirect.mjs.map +1 -0
  289. package/esm/http/serialized.d.mts.map +1 -1
  290. package/esm/http/server.d.mts +3 -1
  291. package/esm/http/server.d.mts.map +1 -1
  292. package/esm/http/server.mjs +14 -4
  293. package/esm/http/server.mjs.map +1 -1
  294. package/esm/http/stream-transport.mjs +4 -2
  295. package/esm/http/stream-transport.mjs.map +1 -1
  296. package/esm/http/types.d.mts +44 -11
  297. package/esm/http/types.d.mts.map +1 -1
  298. package/esm/http/uploads/generate-image-variant.mjs +1 -1
  299. package/esm/http/uploads/generate-image-variants.d.mts +10 -7
  300. package/esm/http/uploads/generate-image-variants.d.mts.map +1 -1
  301. package/esm/http/uploads/generate-image-variants.mjs +61 -24
  302. package/esm/http/uploads/generate-image-variants.mjs.map +1 -1
  303. package/esm/http/uploads/image-variant-cache-entries.mjs +78 -0
  304. package/esm/http/uploads/image-variant-cache-entries.mjs.map +1 -0
  305. package/esm/http/uploads/image-variant-cache.mjs +72 -30
  306. package/esm/http/uploads/image-variant-cache.mjs.map +1 -1
  307. package/esm/http/uploads/image-variant-types.d.mts +2 -0
  308. package/esm/http/uploads/image-variant-types.d.mts.map +1 -1
  309. package/esm/http/uploads/image-variants-config-error.d.mts +3 -1
  310. package/esm/http/uploads/image-variants-config-error.d.mts.map +1 -1
  311. package/esm/http/uploads/image-variants-config-error.mjs +3 -2
  312. package/esm/http/uploads/image-variants-config-error.mjs.map +1 -1
  313. package/esm/http/uploads/load-variant-source.mjs +1 -1
  314. package/esm/http/uploads/load-variant-source.mjs.map +1 -1
  315. package/esm/http/uploads/purge-image-variants.d.mts +7 -2
  316. package/esm/http/uploads/purge-image-variants.d.mts.map +1 -1
  317. package/esm/http/uploads/purge-image-variants.mjs +16 -16
  318. package/esm/http/uploads/purge-image-variants.mjs.map +1 -1
  319. package/esm/http/uploads/remote-variant-source.mjs +115 -0
  320. package/esm/http/uploads/remote-variant-source.mjs.map +1 -0
  321. package/esm/http/uploads/resolve-image-variant.d.mts +3 -4
  322. package/esm/http/uploads/resolve-image-variant.d.mts.map +1 -1
  323. package/esm/http/uploads/resolve-image-variant.mjs +10 -18
  324. package/esm/http/uploads/resolve-image-variant.mjs.map +1 -1
  325. package/esm/http/uploads/resolve-image-variants-config.mjs +5 -3
  326. package/esm/http/uploads/resolve-image-variants-config.mjs.map +1 -1
  327. package/esm/http/uploads/resolve-remote-image-variant.mjs +89 -0
  328. package/esm/http/uploads/resolve-remote-image-variant.mjs.map +1 -0
  329. package/esm/http/uploads/trim-image-variant-cache.mjs +193 -0
  330. package/esm/http/uploads/trim-image-variant-cache.mjs.map +1 -0
  331. package/esm/http/uploads/uploaded-file.controller.d.mts +5 -3
  332. package/esm/http/uploads/uploaded-file.controller.d.mts.map +1 -1
  333. package/esm/http/uploads/uploaded-file.controller.mjs +16 -8
  334. package/esm/http/uploads/uploaded-file.controller.mjs.map +1 -1
  335. package/esm/http/uploads/variant-cache-key.mjs +1 -1
  336. package/esm/http/uploads-types.d.mts +6 -2
  337. package/esm/http/uploads-types.d.mts.map +1 -1
  338. package/esm/index.d.mts +17 -6
  339. package/esm/index.mjs +14 -3
  340. package/esm/localization/parse-locale-dictionary.d.mts +2 -0
  341. package/esm/localization/parse-locale-dictionary.d.mts.map +1 -1
  342. package/esm/localization/parse-locale-dictionary.mjs +1 -0
  343. package/esm/localization/parse-locale-dictionary.mjs.map +1 -1
  344. package/esm/mail/config.d.mts +12 -1
  345. package/esm/mail/config.d.mts.map +1 -1
  346. package/esm/mail/config.mjs +16 -1
  347. package/esm/mail/config.mjs.map +1 -1
  348. package/esm/mail/index.d.mts +1 -1
  349. package/esm/mail/index.mjs +1 -1
  350. package/esm/net/index.d.mts +2 -0
  351. package/esm/net/index.mjs +3 -0
  352. package/esm/openapi/build-openapi-document.d.mts.map +1 -1
  353. package/esm/openapi/build-openapi-document.mjs +8 -5
  354. package/esm/openapi/build-openapi-document.mjs.map +1 -1
  355. package/esm/openapi/error-responses.mjs +28 -2
  356. package/esm/openapi/error-responses.mjs.map +1 -1
  357. package/esm/openapi/postman/build-request-body.mjs.map +1 -1
  358. package/esm/openapi/postman/build-request-url.mjs.map +1 -1
  359. package/esm/openapi/postman/build-saved-responses.mjs.map +1 -1
  360. package/esm/openapi/postman/example-from-schema.d.mts.map +1 -1
  361. package/esm/openapi/postman/example-from-schema.mjs.map +1 -1
  362. package/esm/openapi/postman/openapi-to-postman-collection.d.mts.map +1 -1
  363. package/esm/openapi/postman/openapi-to-postman-collection.mjs.map +1 -1
  364. package/esm/openapi/postman/schema-refs.mjs.map +1 -1
  365. package/esm/openapi/postman/uuid-v5.mjs.map +1 -1
  366. package/esm/openapi/request-schemas.mjs.map +1 -1
  367. package/esm/openapi/response-schemas.mjs.map +1 -1
  368. package/esm/openapi/schema-registry.d.mts +1 -0
  369. package/esm/openapi/schema-registry.mjs.map +1 -1
  370. package/esm/openapi/security.mjs.map +1 -1
  371. package/esm/openapi/types.d.mts +3 -2
  372. package/esm/openapi/types.d.mts.map +1 -1
  373. package/esm/production/assert-generated-imports.mjs +1 -0
  374. package/esm/production/assert-generated-imports.mjs.map +1 -1
  375. package/esm/production/production-builder.mjs +12 -4
  376. package/esm/production/production-builder.mjs.map +1 -1
  377. package/esm/production/resolve-build-config.mjs +1 -0
  378. package/esm/production/resolve-build-config.mjs.map +1 -1
  379. package/esm/production/route-registration-child.mjs.map +1 -1
  380. package/esm/production/route-registration-snapshot.mjs.map +1 -1
  381. package/esm/repositories/contracts/query-builder.contract.d.mts.map +1 -1
  382. package/esm/repositories/contracts/types.d.mts.map +1 -1
  383. package/esm/repositories/repository.manager.mjs.map +1 -1
  384. package/esm/resource/resource.d.mts.map +1 -1
  385. package/esm/resource/resource.mjs.map +1 -1
  386. package/esm/resource/types.d.mts.map +1 -1
  387. package/esm/restful/restful.d.mts +5 -5
  388. package/esm/restful/restful.d.mts.map +1 -1
  389. package/esm/restful/restful.mjs.map +1 -1
  390. package/esm/router/build-route-rate-limit.mjs.map +1 -1
  391. package/esm/router/dev-dispatch.mjs +31 -12
  392. package/esm/router/dev-dispatch.mjs.map +1 -1
  393. package/esm/router/index.d.mts +4 -2
  394. package/esm/router/index.mjs +2 -0
  395. package/esm/router/log-request-lifecycle.mjs.map +1 -1
  396. package/esm/router/positional-handler-diagnostics.d.mts.map +1 -1
  397. package/esm/router/positional-handler-diagnostics.mjs.map +1 -1
  398. package/esm/router/resolve-route-rate-limit.mjs +47 -0
  399. package/esm/router/resolve-route-rate-limit.mjs.map +1 -0
  400. package/esm/router/resolve-route-validation.mjs +19 -0
  401. package/esm/router/resolve-route-validation.mjs.map +1 -0
  402. package/esm/router/route-guard-names.mjs +30 -0
  403. package/esm/router/route-guard-names.mjs.map +1 -0
  404. package/esm/router/route-name-taken-error.d.mts +14 -0
  405. package/esm/router/route-name-taken-error.d.mts.map +1 -0
  406. package/esm/router/route-name-taken-error.mjs +18 -0
  407. package/esm/router/route-name-taken-error.mjs.map +1 -0
  408. package/esm/router/router.d.mts +32 -13
  409. package/esm/router/router.d.mts.map +1 -1
  410. package/esm/router/router.mjs +71 -38
  411. package/esm/router/router.mjs.map +1 -1
  412. package/esm/router/types.d.mts +137 -17
  413. package/esm/router/types.d.mts.map +1 -1
  414. package/esm/router/unguarded-route-diagnostics.d.mts +40 -0
  415. package/esm/router/unguarded-route-diagnostics.d.mts.map +1 -0
  416. package/esm/router/unguarded-route-diagnostics.mjs +95 -0
  417. package/esm/router/unguarded-route-diagnostics.mjs.map +1 -0
  418. package/esm/storage/drivers/cloud-driver.d.mts.map +1 -1
  419. package/esm/storage/drivers/cloud-driver.mjs.map +1 -1
  420. package/esm/storage/drivers/local-driver.d.mts.map +1 -1
  421. package/esm/storage/drivers/local-driver.mjs.map +1 -1
  422. package/esm/storage/local-disk-roots.mjs +24 -0
  423. package/esm/storage/local-disk-roots.mjs.map +1 -0
  424. package/esm/storage/storage.d.mts +14 -0
  425. package/esm/storage/storage.d.mts.map +1 -1
  426. package/esm/storage/storage.mjs +22 -0
  427. package/esm/storage/storage.mjs.map +1 -1
  428. package/esm/storage/types.d.mts.map +1 -1
  429. package/esm/storage/utils/storage-not-initialized-error.d.mts +2 -0
  430. package/esm/storage/utils/storage-not-initialized-error.d.mts.map +1 -1
  431. package/esm/storage/utils/storage-not-initialized-error.mjs +1 -0
  432. package/esm/storage/utils/storage-not-initialized-error.mjs.map +1 -1
  433. package/esm/tests/authenticated-test-client.d.mts +32 -0
  434. package/esm/tests/authenticated-test-client.d.mts.map +1 -0
  435. package/esm/tests/authenticated-test-client.mjs +40 -0
  436. package/esm/tests/authenticated-test-client.mjs.map +1 -0
  437. package/esm/tests/factories.d.mts +59 -0
  438. package/esm/tests/factories.d.mts.map +1 -0
  439. package/esm/tests/factories.mjs +105 -0
  440. package/esm/tests/factories.mjs.map +1 -0
  441. package/esm/tests/fakes/cache-fake.d.mts +29 -0
  442. package/esm/tests/fakes/cache-fake.d.mts.map +1 -0
  443. package/esm/tests/fakes/cache-fake.mjs +79 -0
  444. package/esm/tests/fakes/cache-fake.mjs.map +1 -0
  445. package/esm/tests/fakes/clock-fake.d.mts +32 -0
  446. package/esm/tests/fakes/clock-fake.d.mts.map +1 -0
  447. package/esm/tests/fakes/clock-fake.mjs +69 -0
  448. package/esm/tests/fakes/clock-fake.mjs.map +1 -0
  449. package/esm/tests/fakes/fake-assertion-error.d.mts +13 -0
  450. package/esm/tests/fakes/fake-assertion-error.d.mts.map +1 -0
  451. package/esm/tests/fakes/fake-assertion-error.mjs +20 -0
  452. package/esm/tests/fakes/fake-assertion-error.mjs.map +1 -0
  453. package/esm/tests/fakes/ids-fake.d.mts +22 -0
  454. package/esm/tests/fakes/ids-fake.d.mts.map +1 -0
  455. package/esm/tests/fakes/ids-fake.mjs +57 -0
  456. package/esm/tests/fakes/ids-fake.mjs.map +1 -0
  457. package/esm/tests/fakes/index.d.mts +8 -0
  458. package/esm/tests/fakes/index.mjs +10 -0
  459. package/esm/tests/fakes/mail-fake.d.mts +41 -0
  460. package/esm/tests/fakes/mail-fake.d.mts.map +1 -0
  461. package/esm/tests/fakes/mail-fake.mjs +111 -0
  462. package/esm/tests/fakes/mail-fake.mjs.map +1 -0
  463. package/esm/tests/fakes/queue-fake.d.mts +48 -0
  464. package/esm/tests/fakes/queue-fake.d.mts.map +1 -0
  465. package/esm/tests/fakes/queue-fake.mjs +134 -0
  466. package/esm/tests/fakes/queue-fake.mjs.map +1 -0
  467. package/esm/tests/fakes/storage-fake.d.mts +31 -0
  468. package/esm/tests/fakes/storage-fake.d.mts.map +1 -0
  469. package/esm/tests/fakes/storage-fake.mjs +122 -0
  470. package/esm/tests/fakes/storage-fake.mjs.map +1 -0
  471. package/esm/tests/fakes/test-fakes.d.mts +39 -0
  472. package/esm/tests/fakes/test-fakes.d.mts.map +1 -0
  473. package/esm/tests/fakes/test-fakes.mjs +90 -0
  474. package/esm/tests/fakes/test-fakes.mjs.map +1 -0
  475. package/esm/tests/index.d.mts +14 -2
  476. package/esm/tests/index.mjs +15 -2
  477. package/esm/tests/snapshot-response.d.mts +34 -0
  478. package/esm/tests/snapshot-response.d.mts.map +1 -0
  479. package/esm/tests/snapshot-response.mjs +42 -0
  480. package/esm/tests/snapshot-response.mjs.map +1 -0
  481. package/esm/tests/start-http-development-server.d.mts +22 -0
  482. package/esm/tests/start-http-development-server.d.mts.map +1 -1
  483. package/esm/tests/start-http-development-server.mjs +36 -3
  484. package/esm/tests/start-http-development-server.mjs.map +1 -1
  485. package/esm/tests/test-helpers.d.mts +20 -1
  486. package/esm/tests/test-helpers.d.mts.map +1 -1
  487. package/esm/tests/test-helpers.mjs +40 -27
  488. package/esm/tests/test-helpers.mjs.map +1 -1
  489. package/esm/tests/test-http-server.d.mts +62 -0
  490. package/esm/tests/test-http-server.d.mts.map +1 -0
  491. package/esm/tests/test-http-server.mjs +119 -0
  492. package/esm/tests/test-http-server.mjs.map +1 -0
  493. package/esm/tests/vitest-setup.d.mts +11 -0
  494. package/esm/tests/vitest-setup.d.mts.map +1 -1
  495. package/esm/tests/vitest-setup.mjs +12 -4
  496. package/esm/tests/vitest-setup.mjs.map +1 -1
  497. package/esm/tooling/agents-md/agents-md-markers.d.mts +27 -0
  498. package/esm/tooling/agents-md/agents-md-markers.d.mts.map +1 -0
  499. package/esm/tooling/agents-md/agents-md-markers.mjs +59 -0
  500. package/esm/tooling/agents-md/agents-md-markers.mjs.map +1 -0
  501. package/esm/tooling/agents-md/agents-md-refresher.d.mts +36 -0
  502. package/esm/tooling/agents-md/agents-md-refresher.d.mts.map +1 -0
  503. package/esm/tooling/agents-md/agents-md-refresher.mjs +72 -0
  504. package/esm/tooling/agents-md/agents-md-refresher.mjs.map +1 -0
  505. package/esm/tooling/agents-md/index.mjs +7 -0
  506. package/esm/tooling/agents-md/installed-skills.d.mts +30 -0
  507. package/esm/tooling/agents-md/installed-skills.d.mts.map +1 -0
  508. package/esm/tooling/agents-md/installed-skills.mjs +74 -0
  509. package/esm/tooling/agents-md/installed-skills.mjs.map +1 -0
  510. package/esm/tooling/agents-md/render-agents-md.d.mts +33 -0
  511. package/esm/tooling/agents-md/render-agents-md.d.mts.map +1 -0
  512. package/esm/tooling/agents-md/render-agents-md.mjs +195 -0
  513. package/esm/tooling/agents-md/render-agents-md.mjs.map +1 -0
  514. package/esm/tooling/agents-md/write-agents-md.d.mts +33 -0
  515. package/esm/tooling/agents-md/write-agents-md.d.mts.map +1 -0
  516. package/esm/tooling/agents-md/write-agents-md.mjs +49 -0
  517. package/esm/tooling/agents-md/write-agents-md.mjs.map +1 -0
  518. package/esm/tooling/board/board-message.d.mts +31 -0
  519. package/esm/tooling/board/board-message.d.mts.map +1 -0
  520. package/esm/tooling/board/board-message.mjs +86 -0
  521. package/esm/tooling/board/board-message.mjs.map +1 -0
  522. package/esm/tooling/board/board.d.mts +109 -0
  523. package/esm/tooling/board/board.d.mts.map +1 -0
  524. package/esm/tooling/board/board.mjs +406 -0
  525. package/esm/tooling/board/board.mjs.map +1 -0
  526. package/esm/tooling/board/board.types.d.mts +72 -0
  527. package/esm/tooling/board/board.types.d.mts.map +1 -0
  528. package/esm/tooling/board/board.types.mjs +54 -0
  529. package/esm/tooling/board/board.types.mjs.map +1 -0
  530. package/esm/tooling/check/changed-files.d.mts +33 -0
  531. package/esm/tooling/check/changed-files.d.mts.map +1 -0
  532. package/esm/tooling/check/changed-files.mjs +73 -0
  533. package/esm/tooling/check/changed-files.mjs.map +1 -0
  534. package/esm/tooling/check/check-report.types.d.mts +62 -0
  535. package/esm/tooling/check/check-report.types.d.mts.map +1 -0
  536. package/esm/tooling/check/check-report.types.mjs +37 -0
  537. package/esm/tooling/check/check-report.types.mjs.map +1 -0
  538. package/esm/tooling/check/code-style-conventions.mjs +106 -0
  539. package/esm/tooling/check/code-style-conventions.mjs.map +1 -0
  540. package/esm/tooling/check/conventions-step.d.mts +34 -0
  541. package/esm/tooling/check/conventions-step.d.mts.map +1 -0
  542. package/esm/tooling/check/conventions-step.mjs +184 -0
  543. package/esm/tooling/check/conventions-step.mjs.map +1 -0
  544. package/esm/tooling/check/environment-step.d.mts +18 -0
  545. package/esm/tooling/check/environment-step.d.mts.map +1 -0
  546. package/esm/tooling/check/environment-step.mjs +78 -0
  547. package/esm/tooling/check/environment-step.mjs.map +1 -0
  548. package/esm/tooling/check/index.d.mts +8 -0
  549. package/esm/tooling/check/index.mjs +10 -0
  550. package/esm/tooling/check/lint-step.d.mts +19 -0
  551. package/esm/tooling/check/lint-step.d.mts.map +1 -0
  552. package/esm/tooling/check/lint-step.mjs +111 -0
  553. package/esm/tooling/check/lint-step.mjs.map +1 -0
  554. package/esm/tooling/check/request-input.mjs +132 -0
  555. package/esm/tooling/check/request-input.mjs.map +1 -0
  556. package/esm/tooling/check/run-check.d.mts +35 -0
  557. package/esm/tooling/check/run-check.d.mts.map +1 -0
  558. package/esm/tooling/check/run-check.mjs +192 -0
  559. package/esm/tooling/check/run-check.mjs.map +1 -0
  560. package/esm/tooling/check/run-tests.d.mts +48 -0
  561. package/esm/tooling/check/run-tests.d.mts.map +1 -0
  562. package/esm/tooling/check/run-tests.mjs +93 -0
  563. package/esm/tooling/check/run-tests.mjs.map +1 -0
  564. package/esm/tooling/check/security-conventions.mjs +648 -0
  565. package/esm/tooling/check/security-conventions.mjs.map +1 -0
  566. package/esm/tooling/check/source-ast.mjs +195 -0
  567. package/esm/tooling/check/source-ast.mjs.map +1 -0
  568. package/esm/tooling/check/source-files.mjs +27 -0
  569. package/esm/tooling/check/source-files.mjs.map +1 -0
  570. package/esm/tooling/check/tests-step.d.mts +34 -0
  571. package/esm/tooling/check/tests-step.d.mts.map +1 -0
  572. package/esm/tooling/check/tests-step.mjs +177 -0
  573. package/esm/tooling/check/tests-step.mjs.map +1 -0
  574. package/esm/tooling/dev-state/dev-server-state.d.mts +39 -0
  575. package/esm/tooling/dev-state/dev-server-state.d.mts.map +1 -0
  576. package/esm/tooling/dev-state/dev-server-state.mjs +67 -0
  577. package/esm/tooling/dev-state/dev-server-state.mjs.map +1 -0
  578. package/esm/tooling/devtools/devtools-client.d.mts +91 -0
  579. package/esm/tooling/devtools/devtools-client.d.mts.map +1 -0
  580. package/esm/tooling/devtools/devtools-client.mjs +155 -0
  581. package/esm/tooling/devtools/devtools-client.mjs.map +1 -0
  582. package/esm/tooling/generate/generation.d.mts +78 -0
  583. package/esm/tooling/generate/generation.d.mts.map +1 -0
  584. package/esm/tooling/generate/generation.mjs +123 -0
  585. package/esm/tooling/generate/generation.mjs.map +1 -0
  586. package/esm/tooling/generate/generator-spec.d.mts +57 -0
  587. package/esm/tooling/generate/generator-spec.d.mts.map +1 -0
  588. package/esm/tooling/generate/generator-spec.mjs +102 -0
  589. package/esm/tooling/generate/generator-spec.mjs.map +1 -0
  590. package/esm/tooling/generate/index.mjs +6 -0
  591. package/esm/tooling/generate/project-files.mjs +121 -0
  592. package/esm/tooling/generate/project-files.mjs.map +1 -0
  593. package/esm/tooling/generate/run-cli.d.mts +40 -0
  594. package/esm/tooling/generate/run-cli.d.mts.map +1 -0
  595. package/esm/tooling/generate/run-cli.mjs +93 -0
  596. package/esm/tooling/generate/run-cli.mjs.map +1 -0
  597. package/esm/tooling/generate/unified-diff.d.mts +37 -0
  598. package/esm/tooling/generate/unified-diff.d.mts.map +1 -0
  599. package/esm/tooling/generate/unified-diff.mjs +161 -0
  600. package/esm/tooling/generate/unified-diff.mjs.map +1 -0
  601. package/esm/tooling/index.d.mts +41 -0
  602. package/esm/tooling/index.mjs +45 -0
  603. package/esm/tooling/inspect/boot-for-inspect.d.mts +23 -0
  604. package/esm/tooling/inspect/boot-for-inspect.d.mts.map +1 -0
  605. package/esm/tooling/inspect/boot-for-inspect.mjs +63 -0
  606. package/esm/tooling/inspect/boot-for-inspect.mjs.map +1 -0
  607. package/esm/tooling/inspect/collect-config.mjs +77 -0
  608. package/esm/tooling/inspect/collect-config.mjs.map +1 -0
  609. package/esm/tooling/inspect/collect-models.d.mts +9 -0
  610. package/esm/tooling/inspect/collect-models.d.mts.map +1 -0
  611. package/esm/tooling/inspect/collect-models.mjs +154 -0
  612. package/esm/tooling/inspect/collect-models.mjs.map +1 -0
  613. package/esm/tooling/inspect/collect-packages.d.mts +10 -0
  614. package/esm/tooling/inspect/collect-packages.d.mts.map +1 -0
  615. package/esm/tooling/inspect/collect-packages.mjs +157 -0
  616. package/esm/tooling/inspect/collect-packages.mjs.map +1 -0
  617. package/esm/tooling/inspect/collect-pages.mjs +108 -0
  618. package/esm/tooling/inspect/collect-pages.mjs.map +1 -0
  619. package/esm/tooling/inspect/collect-routes.mjs +168 -0
  620. package/esm/tooling/inspect/collect-routes.mjs.map +1 -0
  621. package/esm/tooling/inspect/event-recorder.d.mts +37 -0
  622. package/esm/tooling/inspect/event-recorder.d.mts.map +1 -0
  623. package/esm/tooling/inspect/event-recorder.mjs +91 -0
  624. package/esm/tooling/inspect/event-recorder.mjs.map +1 -0
  625. package/esm/tooling/inspect/index.d.mts +7 -0
  626. package/esm/tooling/inspect/index.mjs +7 -0
  627. package/esm/tooling/inspect/inspect-app.d.mts +53 -0
  628. package/esm/tooling/inspect/inspect-app.d.mts.map +1 -0
  629. package/esm/tooling/inspect/inspect-app.mjs +92 -0
  630. package/esm/tooling/inspect/inspect-app.mjs.map +1 -0
  631. package/esm/tooling/inspect/inspect-report.schema.d.mts +15 -0
  632. package/esm/tooling/inspect/inspect-report.schema.d.mts.map +1 -0
  633. package/esm/tooling/inspect/inspect-report.schema.mjs +463 -0
  634. package/esm/tooling/inspect/inspect-report.schema.mjs.map +1 -0
  635. package/esm/tooling/inspect/inspect-report.types.d.mts +196 -0
  636. package/esm/tooling/inspect/inspect-report.types.d.mts.map +1 -0
  637. package/esm/tooling/inspect/inspect-report.types.mjs +33 -0
  638. package/esm/tooling/inspect/inspect-report.types.mjs.map +1 -0
  639. package/esm/tooling/mcp/create-mcp-context.d.mts +26 -0
  640. package/esm/tooling/mcp/create-mcp-context.d.mts.map +1 -0
  641. package/esm/tooling/mcp/create-mcp-context.mjs +75 -0
  642. package/esm/tooling/mcp/create-mcp-context.mjs.map +1 -0
  643. package/esm/tooling/mcp/db-schema.d.mts +49 -0
  644. package/esm/tooling/mcp/db-schema.d.mts.map +1 -0
  645. package/esm/tooling/mcp/db-schema.mjs +56 -0
  646. package/esm/tooling/mcp/db-schema.mjs.map +1 -0
  647. package/esm/tooling/mcp/docs-search.d.mts +72 -0
  648. package/esm/tooling/mcp/docs-search.d.mts.map +1 -0
  649. package/esm/tooling/mcp/docs-search.mjs +178 -0
  650. package/esm/tooling/mcp/docs-search.mjs.map +1 -0
  651. package/esm/tooling/mcp/index.mjs +9 -0
  652. package/esm/tooling/mcp/load-ai-tools.d.mts +62 -0
  653. package/esm/tooling/mcp/load-ai-tools.d.mts.map +1 -0
  654. package/esm/tooling/mcp/load-ai-tools.mjs +44 -0
  655. package/esm/tooling/mcp/load-ai-tools.mjs.map +1 -0
  656. package/esm/tooling/mcp/mcp-tools.d.mts +60 -0
  657. package/esm/tooling/mcp/mcp-tools.d.mts.map +1 -0
  658. package/esm/tooling/mcp/mcp-tools.mjs +513 -0
  659. package/esm/tooling/mcp/mcp-tools.mjs.map +1 -0
  660. package/esm/tooling/mcp/start-mcp-server.d.mts +56 -0
  661. package/esm/tooling/mcp/start-mcp-server.d.mts.map +1 -0
  662. package/esm/tooling/mcp/start-mcp-server.mjs +126 -0
  663. package/esm/tooling/mcp/start-mcp-server.mjs.map +1 -0
  664. package/esm/tooling/mcp/tool-input.d.mts +75 -0
  665. package/esm/tooling/mcp/tool-input.d.mts.map +1 -0
  666. package/esm/tooling/mcp/tool-input.mjs +72 -0
  667. package/esm/tooling/mcp/tool-input.mjs.map +1 -0
  668. package/esm/tooling/problem.d.mts +45 -0
  669. package/esm/tooling/problem.d.mts.map +1 -0
  670. package/esm/tooling/problem.mjs +28 -0
  671. package/esm/tooling/problem.mjs.map +1 -0
  672. package/esm/tooling/trace/trace-report.types.d.mts +71 -0
  673. package/esm/tooling/trace/trace-report.types.d.mts.map +1 -0
  674. package/esm/tooling/trace/trace-report.types.mjs +7 -0
  675. package/esm/tooling/trace/trace-report.types.mjs.map +1 -0
  676. package/esm/tooling/trace/trace-request.d.mts +83 -0
  677. package/esm/tooling/trace/trace-request.d.mts.map +1 -0
  678. package/esm/tooling/trace/trace-request.mjs +241 -0
  679. package/esm/tooling/trace/trace-request.mjs.map +1 -0
  680. package/esm/tooling/typecheck/index.d.mts +1 -0
  681. package/esm/tooling/typecheck/index.mjs +3 -0
  682. package/esm/tooling/typecheck/run-typecheck.d.mts +59 -0
  683. package/esm/tooling/typecheck/run-typecheck.d.mts.map +1 -0
  684. package/esm/tooling/typecheck/run-typecheck.mjs +153 -0
  685. package/esm/tooling/typecheck/run-typecheck.mjs.map +1 -0
  686. package/esm/upgrade/codemods/head-viewport.mjs +46 -0
  687. package/esm/upgrade/codemods/head-viewport.mjs.map +1 -0
  688. package/esm/upgrade/codemods/helpers.mjs +81 -0
  689. package/esm/upgrade/codemods/helpers.mjs.map +1 -0
  690. package/esm/upgrade/codemods/index.mjs +34 -0
  691. package/esm/upgrade/codemods/index.mjs.map +1 -0
  692. package/esm/upgrade/codemods/logger-sync-calls.mjs +57 -0
  693. package/esm/upgrade/codemods/logger-sync-calls.mjs.map +1 -0
  694. package/esm/upgrade/codemods/package-json.mjs +122 -0
  695. package/esm/upgrade/codemods/package-json.mjs.map +1 -0
  696. package/esm/upgrade/codemods/request-log-snapshot.mjs +82 -0
  697. package/esm/upgrade/codemods/request-log-snapshot.mjs.map +1 -0
  698. package/esm/upgrade/codemods/review-sites.mjs +262 -0
  699. package/esm/upgrade/codemods/review-sites.mjs.map +1 -0
  700. package/esm/upgrade/diff.mjs +119 -0
  701. package/esm/upgrade/diff.mjs.map +1 -0
  702. package/esm/upgrade/format-upgrade-report.mjs +32 -0
  703. package/esm/upgrade/format-upgrade-report.mjs.map +1 -0
  704. package/esm/upgrade/load-ts-morph.mjs +48 -0
  705. package/esm/upgrade/load-ts-morph.mjs.map +1 -0
  706. package/esm/upgrade/notes.mjs +16 -0
  707. package/esm/upgrade/notes.mjs.map +1 -0
  708. package/esm/upgrade/run-upgrade.mjs +246 -0
  709. package/esm/upgrade/run-upgrade.mjs.map +1 -0
  710. package/esm/upgrade/upgrade-command.action.mjs +37 -0
  711. package/esm/upgrade/upgrade-command.action.mjs.map +1 -0
  712. package/esm/upgrade/version.mjs +39 -0
  713. package/esm/upgrade/version.mjs.map +1 -0
  714. package/esm/use-cases/use-cases-registry.mjs.map +1 -1
  715. package/esm/utils/clock.d.mts +33 -0
  716. package/esm/utils/clock.d.mts.map +1 -0
  717. package/esm/utils/clock.mjs +27 -0
  718. package/esm/utils/clock.mjs.map +1 -0
  719. package/esm/utils/framework-vesion.mjs +1 -1
  720. package/esm/utils/framework-vesion.mjs.map +1 -1
  721. package/esm/utils/ids.d.mts +32 -0
  722. package/esm/utils/ids.d.mts.map +1 -0
  723. package/esm/utils/ids.mjs +33 -0
  724. package/esm/utils/ids.mjs.map +1 -0
  725. package/esm/utils/index.d.mts +3 -0
  726. package/esm/utils/index.mjs +3 -0
  727. package/esm/utils/runtime.d.mts +59 -0
  728. package/esm/utils/runtime.d.mts.map +1 -0
  729. package/esm/utils/runtime.mjs +85 -0
  730. package/esm/utils/runtime.mjs.map +1 -0
  731. package/esm/validation/index.d.mts +1 -1
  732. package/esm/validation/types.d.mts +57 -2
  733. package/esm/validation/types.d.mts.map +1 -1
  734. package/esm/validation/validateAll.mjs +19 -2
  735. package/esm/validation/validateAll.mjs.map +1 -1
  736. package/esm/validation/validation-failure-status.mjs +15 -0
  737. package/esm/validation/validation-failure-status.mjs.map +1 -0
  738. package/esm/validation/validators/file-validator.d.mts +0 -16
  739. package/esm/validation/validators/file-validator.d.mts.map +1 -1
  740. package/esm/warlock-config/bundle-config.mjs +1 -1
  741. package/esm/warlock-config/types.d.mts +27 -3
  742. package/esm/warlock-config/types.d.mts.map +1 -1
  743. package/llms-full.txt +3166 -736
  744. package/llms.txt +16 -6
  745. package/package.json +43 -13
  746. package/schemas/inspect-report.schema.json +554 -0
  747. package/skills/README.md +9 -0
  748. package/skills/add-connector/SKILL.md +26 -38
  749. package/skills/benchmark-code/SKILL.md +30 -24
  750. package/skills/build-restful/SKILL.md +14 -14
  751. package/skills/build-url/SKILL.md +18 -18
  752. package/skills/configure-app/SKILL.md +107 -14
  753. package/skills/create-controller/SKILL.md +25 -12
  754. package/skills/create-module/SKILL.md +3 -3
  755. package/skills/define-resource/SKILL.md +32 -29
  756. package/skills/encrypt-data/SKILL.md +21 -19
  757. package/skills/generate-openapi/SKILL.md +50 -24
  758. package/skills/hash-password/SKILL.md +2 -2
  759. package/skills/health-checks/SKILL.md +24 -7
  760. package/skills/index.md +9 -4
  761. package/skills/lower-stage3-decorators/SKILL.md +4 -4
  762. package/skills/make-endpoint/SKILL.md +110 -0
  763. package/skills/model-factories/SKILL.md +92 -0
  764. package/skills/process-image/SKILL.md +32 -30
  765. package/skills/register-route/SKILL.md +109 -10
  766. package/skills/request-memo/SKILL.md +1 -1
  767. package/skills/request-tracing/SKILL.md +4 -1
  768. package/skills/resolve-path/SKILL.md +45 -44
  769. package/skills/retry-operation/SKILL.md +20 -11
  770. package/skills/run-app/SKILL.md +106 -22
  771. package/skills/send-response/SKILL.md +179 -14
  772. package/skills/store-file/SKILL.md +93 -53
  773. package/skills/test-fakes/SKILL.md +123 -0
  774. package/skills/test-http/SKILL.md +125 -21
  775. package/skills/test-service/SKILL.md +41 -1
  776. package/skills/update-packages/SKILL.md +29 -18
  777. package/skills/upgrade-from-5-29/SKILL.md +413 -0
  778. package/skills/upload-file/SKILL.md +31 -33
  779. package/skills/use-app-context/SKILL.md +38 -31
  780. package/skills/use-middleware/SKILL.md +45 -25
  781. package/skills/use-model-transformers/SKILL.md +37 -28
  782. package/skills/use-repository/SKILL.md +2 -2
  783. package/skills/validate-input/SKILL.md +72 -28
  784. package/skills/warlock-agents-md/SKILL.md +96 -0
  785. package/skills/warlock-board/SKILL.md +123 -0
  786. package/skills/warlock-check/SKILL.md +132 -0
  787. package/skills/warlock-conventions/SKILL.md +115 -0
  788. package/skills/warlock-doctor/SKILL.md +55 -22
  789. package/skills/warlock-inspect/SKILL.md +134 -0
  790. package/skills/warlock-mcp/SKILL.md +120 -0
  791. package/skills/warlock-routes/SKILL.md +18 -11
  792. package/skills/warlock-trace/SKILL.md +81 -0
  793. package/skills/wire-socket/SKILL.md +8 -8
  794. package/skills/write-seeder/SKILL.md +46 -32
  795. package/skills/write-use-case/SKILL.md +40 -27
  796. package/esm/http/uploads/matches-if-none-match.mjs +0 -13
  797. package/esm/http/uploads/matches-if-none-match.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oxlint-health-checker.mjs","names":[],"sources":["../../../../../../../../../../packages/core/src/dev-server/health-checker/checkers/oxlint-health-checker.ts"],"sourcesContent":["import type { FileManager } from \"../../file-manager\";\nimport type { FileHealthResult } from \"../file-health-result\";\nimport { OxlintRunner } from \"../oxlint-runner\";\nimport { BaseHealthChecker } from \"./base-health-checker\";\n\nexport class OxlintHealthChecker extends BaseHealthChecker {\n public name = \"Oxlint\";\n public workerPath = \"./workers/oxlint-health.worker\";\n private runner = new OxlintRunner();\n\n public initialize(): this {\n this.runner.initialize(process.cwd());\n return this;\n }\n\n public async validate(file: FileManager, result: FileHealthResult): Promise<FileHealthResult> {\n try {\n const [checked] = await this.runner.checkFiles([\n { path: file.absolutePath, relativePath: file.relativePath },\n ]);\n if (checked?.errors.length) result.addErrors(checked.errors);\n if (checked?.warnings.length) result.addWarnings(checked.warnings);\n } catch (error) {\n console.warn(\n \"Oxlint Health Checker:\",\n error instanceof Error ? error.message : String(error),\n );\n }\n return result;\n }\n}\n"],"mappings":";;;;AAKA,IAAa,sBAAb,cAAyC,kBAAkB;;;cAC3C;oBACM;gBACH,IAAI,aAAa;;CAElC,AAAO,aAAmB;EACxB,KAAK,OAAO,WAAW,QAAQ,IAAI,CAAC;EACpC,OAAO;CACT;CAEA,MAAa,SAAS,MAAmB,QAAqD;EAC5F,IAAI;GACF,MAAM,CAAC,WAAW,MAAM,KAAK,OAAO,WAAW,CAC7C;IAAE,MAAM,KAAK;IAAc,cAAc,KAAK;GAAa,CAC7D,CAAC;GACD,IAAI,SAAS,OAAO,QAAQ,OAAO,UAAU,QAAQ,MAAM;GAC3D,IAAI,SAAS,SAAS,QAAQ,OAAO,YAAY,QAAQ,QAAQ;EACnE,SAAS,OAAO;GACd,QAAQ,KACN,0BACA,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CACvD;EACF;EACA,OAAO;CACT;AACF"}
@@ -0,0 +1,31 @@
1
+ import { EslintHealthChecker } from "./checkers/eslint-health-checker.mjs";
2
+ import { findOxlint } from "./oxlint-runner.mjs";
3
+ import { OxlintHealthChecker } from "./checkers/oxlint-health-checker.mjs";
4
+ import { TypescriptHealthChecker } from "./checkers/typescript-health-checker.mjs";
5
+ import path from "node:path";
6
+ import { existsSync } from "node:fs";
7
+
8
+ //#region ../../packages/core/src/dev-server/health-checker/default-health-checkers.ts
9
+ /** Whether the app has an ESLint flat config at its root. */
10
+ function hasEslint(cwd) {
11
+ return [
12
+ "js",
13
+ "mjs",
14
+ "cjs",
15
+ "ts",
16
+ "mts",
17
+ "cts"
18
+ ].some((extension) => existsSync(path.join(cwd, `eslint.config.${extension}`)));
19
+ }
20
+ /** Explicit arrays remain custom-only; built-in booleans select among available checkers. */
21
+ function defaultHealthCheckers(options = {}, cwd = process.cwd()) {
22
+ const checkers = [];
23
+ if (options.typescript !== false) checkers.push(new TypescriptHealthChecker());
24
+ if (options.eslint !== false && hasEslint(cwd)) checkers.push(new EslintHealthChecker());
25
+ if (options.oxlint !== false && findOxlint(cwd)) checkers.push(new OxlintHealthChecker());
26
+ return checkers;
27
+ }
28
+
29
+ //#endregion
30
+ export { defaultHealthCheckers, hasEslint };
31
+ //# sourceMappingURL=default-health-checkers.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-health-checkers.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/dev-server/health-checker/default-health-checkers.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { EslintHealthChecker } from \"./checkers/eslint-health-checker\";\nimport { OxlintHealthChecker } from \"./checkers/oxlint-health-checker\";\nimport { TypescriptHealthChecker } from \"./checkers/typescript-health-checker\";\nimport type {\n BuiltInHealthCheckerOptions,\n FileHealthCheckerContract,\n} from \"./file-health-checker.contract\";\nimport { findOxlint } from \"./oxlint-runner\";\n\n/** Whether the app has an ESLint flat config at its root. */\nexport function hasEslint(cwd: string): boolean {\n // ESLint is a core dependency, so an app needs only its configuration.\n return [\"js\", \"mjs\", \"cjs\", \"ts\", \"mts\", \"cts\"].some((extension) =>\n existsSync(path.join(cwd, `eslint.config.${extension}`)),\n );\n}\n\n/** Explicit arrays remain custom-only; built-in booleans select among available checkers. */\nexport function defaultHealthCheckers(\n options: BuiltInHealthCheckerOptions = {},\n cwd = process.cwd(),\n): FileHealthCheckerContract[] {\n const checkers: FileHealthCheckerContract[] = [];\n if (options.typescript !== false) checkers.push(new TypescriptHealthChecker());\n if (options.eslint !== false && hasEslint(cwd)) checkers.push(new EslintHealthChecker());\n if (options.oxlint !== false && findOxlint(cwd)) checkers.push(new OxlintHealthChecker());\n return checkers;\n}\n"],"mappings":";;;;;;;;;AAYA,SAAgB,UAAU,KAAsB;CAE9C,OAAO;EAAC;EAAM;EAAO;EAAO;EAAM;EAAO;CAAK,CAAC,CAAC,MAAM,cACpD,WAAW,KAAK,KAAK,KAAK,iBAAiB,WAAW,CAAC,CACzD;AACF;;AAGA,SAAgB,sBACd,UAAuC,CAAC,GACxC,MAAM,QAAQ,IAAI,GACW;CAC7B,MAAM,WAAwC,CAAC;CAC/C,IAAI,QAAQ,eAAe,OAAO,SAAS,KAAK,IAAI,wBAAwB,CAAC;CAC7E,IAAI,QAAQ,WAAW,SAAS,UAAU,GAAG,GAAG,SAAS,KAAK,IAAI,oBAAoB,CAAC;CACvF,IAAI,QAAQ,WAAW,SAAS,WAAW,GAAG,GAAG,SAAS,KAAK,IAAI,oBAAoB,CAAC;CACxF,OAAO;AACT"}
@@ -30,8 +30,8 @@ interface FileHealthCheckerContract {
30
30
  *
31
31
  * The path should be relative to the checker's location, without file extension.
32
32
  * The system automatically handles:
33
- * - `.ts` extension in development (with tsx loader)
34
- * - `.js` extension in production (compiled)
33
+ * - `.ts` extension in development (through tsx)
34
+ * - `.mjs` extension in production (compiled)
35
35
  *
36
36
  * @example "./workers/ts-health.worker"
37
37
  */
@@ -58,6 +58,12 @@ interface FileHealthCheckerContract {
58
58
  */
59
59
  stats(): Promise<HealthCheckerFilesStats>;
60
60
  }
61
+ /** Select built-in background checks; installed/configured linters run by default. */
62
+ type BuiltInHealthCheckerOptions = {
63
+ typescript?: boolean;
64
+ eslint?: boolean;
65
+ oxlint?: boolean;
66
+ };
61
67
  //#endregion
62
- export { FileHealthCheckerContract };
68
+ export { BuiltInHealthCheckerOptions, FileHealthCheckerContract };
63
69
  //# sourceMappingURL=file-health-checker.contract.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-health-checker.contract.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/dev-server/health-checker/file-health-checker.contract.ts"],"mappings":";;;;KAGY,uBAAA;EACV,IAAA;EACA,KAAA;IACE,OAAA;IACA,SAAA;EAAA;EAEF,QAAA;IACE,KAAA;IACA,UAAA;EAAA;EAEF,MAAA;IACE,KAAA;IACA,UAAA;EAAA;AAAA;AAAA,UAIa,yBAAA;EAJH;AAAA;AAId;EAIE,IAAA;;;;;;;;;;;;;;EAeA,UAAA;EAWA;;;;EALA,UAAA;EAUiB;;;EALjB,aAAA,CAAc,KAAA,EAAO,WAAA,KAAgB,OAAA;EAU/B;;;EALN,UAAA,CAAW,IAAA,EAAM,WAAA;EAUR;;;EALT,KAAA,CAAM,IAAA,EAAM,WAAA,GAAc,OAAA,CAAQ,gBAAA;;;;EAKlC,KAAA,IAAS,OAAA,CAAQ,uBAAA;AAAA"}
1
+ {"version":3,"file":"file-health-checker.contract.d.mts","names":[],"sources":["../../../../../../../../../packages/core/src/dev-server/health-checker/file-health-checker.contract.ts"],"mappings":";;;;KAGY,uBAAA;EACV,IAAA;EACA,KAAA;IACE,OAAA;IACA,SAAA;EAAA;EAEF,QAAA;IACE,KAAA;IACA,UAAA;EAAA;EAEF,MAAA;IACE,KAAA;IACA,UAAA;EAAA;AAAA;AAAA,UAIa,yBAAA;EAJH;AAAA;AAId;EAIE,IAAA;;;;;;;;;;;;;;EAeA,UAAA;EAWA;;;;EALA,UAAA;EAUiB;;;EALjB,aAAA,CAAc,KAAA,EAAO,WAAA,KAAgB,OAAA;EAU/B;;;EALN,UAAA,CAAW,IAAA,EAAM,WAAA;EAUR;;;EALT,KAAA,CAAM,IAAA,EAAM,WAAA,GAAc,OAAA,CAAQ,gBAAA;EASxB;;;EAJV,KAAA,IAAS,OAAA,CAAQ,uBAAA;AAAA;;KAIP,2BAAA;EACV,UAAA;EACA,MAAA;EACA,MAAA;AAAA"}
@@ -353,10 +353,21 @@ var FilesHealthcareManager = class {
353
353
  * Shutdown all workers
354
354
  */
355
355
  async shutdown() {
356
- for (const [name, worker] of this.workers) try {
357
- worker.postMessage({ type: "shutdown" });
358
- await worker.terminate();
359
- } catch {}
356
+ await Promise.all([...this.workers.values()].map(async (worker) => {
357
+ try {
358
+ await new Promise((resolve) => {
359
+ const finish = () => {
360
+ clearTimeout(timer);
361
+ worker.off("exit", finish);
362
+ resolve();
363
+ };
364
+ const timer = setTimeout(finish, 500);
365
+ worker.once("exit", finish);
366
+ worker.postMessage({ type: "shutdown" });
367
+ });
368
+ await worker.terminate();
369
+ } catch {}
370
+ }));
360
371
  this.workers.clear();
361
372
  this.workerInitPromises.clear();
362
373
  this.checkerStats.clear();
@@ -1 +1 @@
1
- {"version":3,"file":"files-healthcare.manager.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/dev-server/health-checker/files-healthcare.manager.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { Worker } from \"worker_threads\";\nimport { createWorker } from \"../create-worker\";\nimport { devLogInfo } from \"../dev-logger\";\nimport type { FileManager } from \"../file-manager\";\nimport type {\n FileHealthCheckerContract,\n HealthCheckerFilesStats,\n} from \"./file-health-checker.contract\";\n\n/**\n * Serialized file data to send to workers\n */\ntype SerializedFile = {\n path: string;\n content: string;\n relativePath: string;\n};\n\n/**\n * Diagnostic message from worker\n */\ntype DiagnosticMessage = {\n type: \"error\" | \"warning\";\n message: string;\n lineNumber: number;\n columnNumber: number;\n length: number;\n filePath: string;\n relativePath: string;\n ruleId?: string;\n};\n\n/**\n * File check result from worker\n */\ntype FileCheckResult = {\n path: string;\n relativePath: string;\n healthy: boolean;\n errors: DiagnosticMessage[];\n warnings: DiagnosticMessage[];\n};\n\n/**\n * Worker response type\n */\ntype WorkerResponse =\n | { type: \"initialized\"; success: boolean; hasConfig?: boolean; error?: string }\n | { type: \"results\"; results: FileCheckResult[] }\n | { type: \"error\"; message: string };\n\n/**\n * Files Healthcare Manager\n *\n * Manages health checkers for file validation during development.\n * Supports both main-thread and worker-based checkers.\n *\n * Checkers with `workerPath` run in dedicated worker threads for performance.\n * Checkers without `workerPath` run in the main thread.\n *\n * @example\n * ```typescript\n * const manager = new FilesHealthcareManager(files);\n *\n * manager.setHealthCheckers([\n * new TypescriptHealthChecker(), // Has workerPath → runs in worker\n * new CustomChecker(), // No workerPath → runs in main thread\n * ]);\n *\n * await manager.initialize();\n * await manager.validateAllFiles();\n * ```\n */\nexport class FilesHealthcareManager {\n /**\n * Registered health checkers\n */\n private healthCheckers: FileHealthCheckerContract[] = [];\n\n /**\n * Active worker instances (checkerName → Worker)\n */\n private workers = new Map<string, Worker>();\n\n /**\n * Worker initialization promises (for ensuring workers are ready)\n */\n private workerInitPromises = new Map<string, Promise<boolean>>();\n\n /**\n * Per-worker queue that serializes check requests\n */\n private workerQueues = new Map<string, Promise<void>>();\n\n /**\n * Aggregated stats for each checker\n */\n private checkerStats = new Map<\n string,\n {\n totalFiles: number;\n healthyFiles: number;\n defectiveFiles: number;\n totalErrors: number;\n totalWarnings: number;\n filesWithErrors: number;\n filesWithWarnings: number;\n }\n >();\n\n /**\n * Constructor\n * @param files - Map of tracked files\n */\n public constructor(private readonly files: Map<string, FileManager>) {}\n\n /**\n * Add health checkers to the manager\n * @param checkers - Checkers to add\n */\n public addHealthCheckers(...checkers: FileHealthCheckerContract[]): FilesHealthcareManager {\n this.healthCheckers.push(...checkers);\n return this;\n }\n\n /**\n * Set (replace) all health checkers\n * @param checkers - New set of checkers\n */\n public setHealthCheckers(checkers: FileHealthCheckerContract[]): FilesHealthcareManager {\n this.healthCheckers = checkers;\n return this;\n }\n\n /**\n * Initialize all health checkers\n *\n * For checkers with `workerPath`, spawns dedicated worker threads.\n * For other checkers, calls their `initialize()` method directly.\n */\n public async initialize(): Promise<void> {\n const initPromises = this.healthCheckers.map(async (checker) => {\n // Initialize stats for this checker\n this.checkerStats.set(checker.name, {\n totalFiles: 0,\n healthyFiles: 0,\n defectiveFiles: 0,\n totalErrors: 0,\n totalWarnings: 0,\n filesWithErrors: 0,\n filesWithWarnings: 0,\n });\n\n if (checker.workerPath) {\n // Spawn dedicated worker for this checker\n await this.spawnWorker(checker);\n } else {\n // Initialize checker on main thread\n checker.initialize();\n }\n });\n\n await Promise.all(initPromises);\n }\n\n /**\n * Spawn a worker for a checker\n */\n private async spawnWorker(checker: FileHealthCheckerContract): Promise<void> {\n if (!checker.workerPath) return;\n\n const worker = createWorker(checker.workerPath, import.meta.url, {\n workerData: { cwd: process.cwd() },\n });\n\n this.workers.set(checker.name, worker);\n\n // Create init promise\n const initPromise = new Promise<boolean>((resolve) => {\n const handler = (response: WorkerResponse) => {\n if (response.type === \"initialized\") {\n worker.off(\"message\", handler);\n resolve(response.success);\n }\n };\n\n worker.on(\"message\", handler);\n\n // Handle worker errors\n worker.on(\"error\", (error) => {\n console.error(`Health Checker Worker Error (${checker.name}):`, error);\n resolve(false);\n });\n\n // Send init message\n worker.postMessage({ type: \"init\", config: { cwd: process.cwd() } });\n });\n\n this.workerInitPromises.set(checker.name, initPromise);\n\n // Wait for initialization\n await initPromise;\n }\n\n /**\n * Validate all tracked files\n */\n public async validateAllFiles(): Promise<void> {\n const allFiles = Array.from(this.files.values());\n await this.checkFiles(allFiles);\n\n // Display stats\n await this.displayStats();\n }\n\n /**\n * Check the given files with all registered checkers\n *\n * All checkers run in parallel for performance.\n * Worker-based checkers communicate via postMessage.\n * Main-thread checkers are called directly.\n */\n public async checkFiles(files: FileManager[]): Promise<void> {\n const checkPromises = this.healthCheckers.map(async (checker) => {\n if (checker.workerPath) {\n return this.runInWorker(checker.name, files);\n } else {\n return this.runInline(checker, files);\n }\n });\n\n const results = await Promise.all(checkPromises);\n\n // Display any errors/warnings\n for (const checkerResults of results) {\n for (const result of checkerResults) {\n if (!result.healthy) {\n this.displayFileResults(result);\n }\n }\n }\n }\n\n /**\n * Run checker in worker thread\n */\n private async runInWorker(checkerName: string, files: FileManager[]): Promise<FileCheckResult[]> {\n const worker = this.workers.get(checkerName);\n\n if (!worker) {\n return files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n\n // Wait for worker to be initialized\n const initPromise = this.workerInitPromises.get(checkerName);\n if (initPromise) {\n const success = await initPromise;\n if (!success) {\n return files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n }\n\n // Serialize files for worker\n const serializedFiles: SerializedFile[] = files.map((f) => ({\n path: f.absolutePath,\n content: f.source,\n relativePath: f.relativePath,\n }));\n\n // Workers reply without a request id, so calls are serialized per worker:\n // exactly one \"check\" is in flight and its reply can only belong to it.\n const previous = this.workerQueues.get(checkerName) ?? Promise.resolve();\n\n const current = previous.then(() =>\n this.postCheck(checkerName, worker, files, serializedFiles),\n );\n\n this.workerQueues.set(\n checkerName,\n current.then(\n () => undefined,\n () => undefined,\n ),\n );\n\n return current;\n }\n\n /**\n * Post one check to the worker and wait for its single reply.\n * Resolves as healthy if the worker errors or exits so callers never hang.\n */\n private postCheck(\n checkerName: string,\n worker: Worker,\n files: FileManager[],\n serializedFiles: SerializedFile[],\n ): Promise<FileCheckResult[]> {\n return new Promise((resolve) => {\n const fallback = () =>\n files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n\n const cleanup = () => {\n worker.off(\"message\", handler);\n worker.off(\"error\", onFailure);\n worker.off(\"exit\", onFailure);\n };\n\n const onFailure = () => {\n cleanup();\n resolve(fallback());\n };\n\n const handler = (response: WorkerResponse) => {\n if (response.type === \"results\") {\n cleanup();\n\n // Update stats\n this.updateStats(checkerName, response.results);\n\n resolve(response.results);\n } else if (response.type === \"error\") {\n cleanup();\n resolve(fallback());\n }\n };\n\n worker.on(\"message\", handler);\n worker.on(\"error\", onFailure);\n worker.on(\"exit\", onFailure);\n worker.postMessage({ type: \"check\", files: serializedFiles });\n });\n }\n\n /**\n * Run checker inline (main thread)\n */\n private async runInline(\n checker: FileHealthCheckerContract,\n files: FileManager[],\n ): Promise<FileCheckResult[]> {\n const results: FileCheckResult[] = [];\n\n for (const file of files) {\n const healthResult = await checker.check(file);\n const stats = healthResult.getStats();\n\n results.push({\n path: file.absolutePath,\n relativePath: file.relativePath,\n healthy: stats.state === \"healthy\",\n errors: healthResult.messages\n .filter((m) => m.type === \"error\")\n .map((m) => ({\n type: \"error\" as const,\n message: m.message,\n lineNumber: m.lineNumber,\n columnNumber: m.columnNumber,\n length: m.length || 1,\n filePath: file.absolutePath,\n relativePath: file.relativePath,\n ruleId: m.ruleId,\n })),\n warnings: healthResult.messages\n .filter((m) => m.type === \"warning\")\n .map((m) => ({\n type: \"warning\" as const,\n message: m.message,\n lineNumber: m.lineNumber,\n columnNumber: m.columnNumber,\n length: m.length || 1,\n filePath: file.absolutePath,\n relativePath: file.relativePath,\n ruleId: m.ruleId,\n })),\n });\n }\n\n // Update stats\n const checkerResults = results;\n this.updateStats(checker.name, checkerResults);\n\n return results;\n }\n\n /**\n * Update aggregated stats for a checker\n */\n private updateStats(checkerName: string, results: FileCheckResult[]): void {\n const stats = this.checkerStats.get(checkerName);\n if (!stats) return;\n\n for (const result of results) {\n stats.totalFiles++;\n if (result.healthy) {\n stats.healthyFiles++;\n } else {\n stats.defectiveFiles++;\n }\n stats.totalErrors += result.errors.length;\n stats.totalWarnings += result.warnings.length;\n if (result.errors.length > 0) stats.filesWithErrors++;\n if (result.warnings.length > 0) stats.filesWithWarnings++;\n }\n }\n\n /**\n * Detect when files are changed\n */\n public async onFileChanges(files: FileManager[]): Promise<void> {\n // Notify workers of file changes\n const serializedFiles: SerializedFile[] = files.map((f) => ({\n path: f.absolutePath,\n content: f.source,\n relativePath: f.relativePath,\n }));\n\n for (const [, worker] of this.workers) {\n worker.postMessage({ type: \"fileChanges\", files: serializedFiles });\n }\n\n // Notify inline checkers\n await Promise.all(\n this.healthCheckers.filter((c) => !c.workerPath).map((c) => c.onFileChanges(files)),\n );\n }\n\n /**\n * Remove files from tracking\n * Notifies both inline checkers and worker-based checkers about removed files\n */\n public removeFiles(files: FileManager[]): void {\n // Notify inline checkers\n this.healthCheckers\n .filter((c) => !c.workerPath)\n .forEach((checker) => files.forEach((file) => checker.removeFile(file)));\n\n // Notify workers about deleted files\n if (files.length > 0) {\n const deletedPaths = files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n }));\n\n for (const [, worker] of this.workers) {\n worker.postMessage({ type: \"filesDeleted\", files: deletedPaths });\n }\n }\n }\n\n /**\n * Display file results (errors/warnings)\n */\n private displayFileResults(result: FileCheckResult): void {\n const fileName = result.relativePath.replace(/\\\\/g, \"/\");\n\n // Display errors\n for (const error of result.errors) {\n const icon = colors.redBright(\"✖\");\n const level = colors.redBright(colors.bold(\"ERROR\"));\n console.log(\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${error.lineNumber},${error.columnNumber})`)}`,\n );\n if (error.ruleId) {\n console.log(\n ` ${colors.magentaBright(error.ruleId)} ${colors.dim(\"→\")} ${colors.red(error.message)}`,\n );\n } else {\n console.log(` ${colors.dim(\"→\")} ${colors.red(error.message)}`);\n }\n }\n\n // Display warnings\n for (const warning of result.warnings) {\n const icon = colors.yellowBright(\"⚠\");\n const level = colors.yellowBright(colors.bold(\"WARNING\"));\n console.log(\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${warning.lineNumber},${warning.columnNumber})`)}`,\n );\n if (warning.ruleId) {\n console.log(\n ` ${colors.magentaBright(warning.ruleId)} ${colors.dim(\"→\")} ${colors.yellow(warning.message)}`,\n );\n } else {\n console.log(` ${colors.dim(\"→\")} ${colors.yellow(warning.message)}`);\n }\n }\n }\n\n /**\n * Display stats for all health checkers\n */\n private async displayStats(): Promise<void> {\n const allStats: HealthCheckerFilesStats[] = [];\n\n for (const checker of this.healthCheckers) {\n const stats = this.checkerStats.get(checker.name);\n if (stats) {\n allStats.push({\n name: checker.name,\n files: {\n healthy: stats.healthyFiles,\n defective: stats.defectiveFiles,\n },\n warnings: {\n total: stats.totalWarnings,\n totalFiles: stats.filesWithWarnings,\n },\n errors: {\n total: stats.totalErrors,\n totalFiles: stats.filesWithErrors,\n },\n });\n }\n }\n\n console.log(\"\\n\");\n console.log(colors.bold(colors.cyan(\"━\".repeat(80))));\n devLogInfo(colors.bold(\" 📊 Health Checker Statistics\"));\n console.log(colors.bold(colors.cyan(\"━\".repeat(80))));\n console.log(\"\");\n\n allStats.forEach((stats: HealthCheckerFilesStats, index: number) => {\n const totalFiles = stats.files.healthy + stats.files.defective;\n const hasIssues = stats.files.defective > 0;\n\n // Checker name with icon\n const statusIcon = hasIssues ? \"⚠️\" : \"✅\";\n console.log(colors.bold(` ${statusIcon} ${stats.name}`));\n console.log(colors.dim(\" \" + \"─\".repeat(76)));\n\n // Files summary\n const filesLine = ` Files: ${colors.white(totalFiles.toString())} total │ ${colors.green(\"✓ \" + stats.files.healthy)} healthy │ ${hasIssues ? colors.red(\"✗ \" + stats.files.defective) : colors.dim(\"✗ 0\")} defective`;\n console.log(filesLine);\n\n // Issues summary\n const warningsText =\n stats.warnings.total > 0\n ? colors.yellow(`⚠ ${stats.warnings.total} warnings`)\n : colors.dim(\"⚠ 0 warnings\");\n\n const errorsText =\n stats.errors.total > 0\n ? colors.red(`✗ ${stats.errors.total} errors`)\n : colors.dim(\"✗ 0 errors\");\n\n console.log(` Issues: ${warningsText} │ ${errorsText}`);\n\n // Add spacing between checkers\n if (index < allStats.length - 1) {\n console.log(\"\");\n }\n });\n\n console.log(\"\");\n console.log(colors.bold(colors.cyan(\"━\".repeat(80))));\n console.log(\"\");\n }\n\n /**\n * Shutdown all workers\n */\n public async shutdown(): Promise<void> {\n for (const [name, worker] of this.workers) {\n try {\n worker.postMessage({ type: \"shutdown\" });\n await worker.terminate();\n } catch {\n // Worker may already be terminated\n }\n }\n\n this.workers.clear();\n this.workerInitPromises.clear();\n this.checkerStats.clear();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"files-healthcare.manager.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/dev-server/health-checker/files-healthcare.manager.ts"],"sourcesContent":["import { colors } from \"@mongez/copper\";\nimport type { Worker } from \"worker_threads\";\nimport { createWorker } from \"../create-worker\";\nimport { devLogInfo } from \"../dev-logger\";\nimport type { FileManager } from \"../file-manager\";\nimport type {\n FileHealthCheckerContract,\n HealthCheckerFilesStats,\n} from \"./file-health-checker.contract\";\n\n/**\n * Serialized file data to send to workers\n */\ntype SerializedFile = {\n path: string;\n content: string;\n relativePath: string;\n};\n\n/**\n * Diagnostic message from worker\n */\ntype DiagnosticMessage = {\n type: \"error\" | \"warning\";\n message: string;\n lineNumber: number;\n columnNumber: number;\n length: number;\n filePath: string;\n relativePath: string;\n ruleId?: string;\n};\n\n/**\n * File check result from worker\n */\ntype FileCheckResult = {\n path: string;\n relativePath: string;\n healthy: boolean;\n errors: DiagnosticMessage[];\n warnings: DiagnosticMessage[];\n};\n\n/**\n * Worker response type\n */\ntype WorkerResponse =\n | { type: \"initialized\"; success: boolean; hasConfig?: boolean; error?: string }\n | { type: \"results\"; results: FileCheckResult[] }\n | { type: \"error\"; message: string };\n\n/**\n * Files Healthcare Manager\n *\n * Manages health checkers for file validation during development.\n * Supports both main-thread and worker-based checkers.\n *\n * Checkers with `workerPath` run in dedicated worker threads for performance.\n * Checkers without `workerPath` run in the main thread.\n *\n * @example\n * ```typescript\n * const manager = new FilesHealthcareManager(files);\n *\n * manager.setHealthCheckers([\n * new TypescriptHealthChecker(), // Has workerPath → runs in worker\n * new CustomChecker(), // No workerPath → runs in main thread\n * ]);\n *\n * await manager.initialize();\n * await manager.validateAllFiles();\n * ```\n */\nexport class FilesHealthcareManager {\n /**\n * Registered health checkers\n */\n private healthCheckers: FileHealthCheckerContract[] = [];\n\n /**\n * Active worker instances (checkerName → Worker)\n */\n private workers = new Map<string, Worker>();\n\n /**\n * Worker initialization promises (for ensuring workers are ready)\n */\n private workerInitPromises = new Map<string, Promise<boolean>>();\n\n /**\n * Per-worker queue that serializes check requests\n */\n private workerQueues = new Map<string, Promise<void>>();\n\n /**\n * Aggregated stats for each checker\n */\n private checkerStats = new Map<\n string,\n {\n totalFiles: number;\n healthyFiles: number;\n defectiveFiles: number;\n totalErrors: number;\n totalWarnings: number;\n filesWithErrors: number;\n filesWithWarnings: number;\n }\n >();\n\n /**\n * Constructor\n * @param files - Map of tracked files\n */\n public constructor(private readonly files: Map<string, FileManager>) {}\n\n /**\n * Add health checkers to the manager\n * @param checkers - Checkers to add\n */\n public addHealthCheckers(...checkers: FileHealthCheckerContract[]): FilesHealthcareManager {\n this.healthCheckers.push(...checkers);\n return this;\n }\n\n /**\n * Set (replace) all health checkers\n * @param checkers - New set of checkers\n */\n public setHealthCheckers(checkers: FileHealthCheckerContract[]): FilesHealthcareManager {\n this.healthCheckers = checkers;\n return this;\n }\n\n /**\n * Initialize all health checkers\n *\n * For checkers with `workerPath`, spawns dedicated worker threads.\n * For other checkers, calls their `initialize()` method directly.\n */\n public async initialize(): Promise<void> {\n const initPromises = this.healthCheckers.map(async (checker) => {\n // Initialize stats for this checker\n this.checkerStats.set(checker.name, {\n totalFiles: 0,\n healthyFiles: 0,\n defectiveFiles: 0,\n totalErrors: 0,\n totalWarnings: 0,\n filesWithErrors: 0,\n filesWithWarnings: 0,\n });\n\n if (checker.workerPath) {\n // Spawn dedicated worker for this checker\n await this.spawnWorker(checker);\n } else {\n // Initialize checker on main thread\n checker.initialize();\n }\n });\n\n await Promise.all(initPromises);\n }\n\n /**\n * Spawn a worker for a checker\n */\n private async spawnWorker(checker: FileHealthCheckerContract): Promise<void> {\n if (!checker.workerPath) return;\n\n const worker = createWorker(checker.workerPath, import.meta.url, {\n workerData: { cwd: process.cwd() },\n });\n\n this.workers.set(checker.name, worker);\n\n // Create init promise\n const initPromise = new Promise<boolean>((resolve) => {\n const handler = (response: WorkerResponse) => {\n if (response.type === \"initialized\") {\n worker.off(\"message\", handler);\n resolve(response.success);\n }\n };\n\n worker.on(\"message\", handler);\n\n // Handle worker errors\n worker.on(\"error\", (error) => {\n console.error(`Health Checker Worker Error (${checker.name}):`, error);\n resolve(false);\n });\n\n // Send init message\n worker.postMessage({ type: \"init\", config: { cwd: process.cwd() } });\n });\n\n this.workerInitPromises.set(checker.name, initPromise);\n\n // Wait for initialization\n await initPromise;\n }\n\n /**\n * Validate all tracked files\n */\n public async validateAllFiles(): Promise<void> {\n const allFiles = Array.from(this.files.values());\n await this.checkFiles(allFiles);\n\n // Display stats\n await this.displayStats();\n }\n\n /**\n * Check the given files with all registered checkers\n *\n * All checkers run in parallel for performance.\n * Worker-based checkers communicate via postMessage.\n * Main-thread checkers are called directly.\n */\n public async checkFiles(files: FileManager[]): Promise<void> {\n const checkPromises = this.healthCheckers.map(async (checker) => {\n if (checker.workerPath) {\n return this.runInWorker(checker.name, files);\n } else {\n return this.runInline(checker, files);\n }\n });\n\n const results = await Promise.all(checkPromises);\n\n // Display any errors/warnings\n for (const checkerResults of results) {\n for (const result of checkerResults) {\n if (!result.healthy) {\n this.displayFileResults(result);\n }\n }\n }\n }\n\n /**\n * Run checker in worker thread\n */\n private async runInWorker(checkerName: string, files: FileManager[]): Promise<FileCheckResult[]> {\n const worker = this.workers.get(checkerName);\n\n if (!worker) {\n return files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n\n // Wait for worker to be initialized\n const initPromise = this.workerInitPromises.get(checkerName);\n if (initPromise) {\n const success = await initPromise;\n if (!success) {\n return files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n }\n }\n\n // Serialize files for worker\n const serializedFiles: SerializedFile[] = files.map((f) => ({\n path: f.absolutePath,\n content: f.source,\n relativePath: f.relativePath,\n }));\n\n // Workers reply without a request id, so calls are serialized per worker:\n // exactly one \"check\" is in flight and its reply can only belong to it.\n const previous = this.workerQueues.get(checkerName) ?? Promise.resolve();\n\n const current = previous.then(() =>\n this.postCheck(checkerName, worker, files, serializedFiles),\n );\n\n this.workerQueues.set(\n checkerName,\n current.then(\n () => undefined,\n () => undefined,\n ),\n );\n\n return current;\n }\n\n /**\n * Post one check to the worker and wait for its single reply.\n * Resolves as healthy if the worker errors or exits so callers never hang.\n */\n private postCheck(\n checkerName: string,\n worker: Worker,\n files: FileManager[],\n serializedFiles: SerializedFile[],\n ): Promise<FileCheckResult[]> {\n return new Promise((resolve) => {\n const fallback = () =>\n files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n\n const cleanup = () => {\n worker.off(\"message\", handler);\n worker.off(\"error\", onFailure);\n worker.off(\"exit\", onFailure);\n };\n\n const onFailure = () => {\n cleanup();\n resolve(fallback());\n };\n\n const handler = (response: WorkerResponse) => {\n if (response.type === \"results\") {\n cleanup();\n\n // Update stats\n this.updateStats(checkerName, response.results);\n\n resolve(response.results);\n } else if (response.type === \"error\") {\n cleanup();\n resolve(fallback());\n }\n };\n\n worker.on(\"message\", handler);\n worker.on(\"error\", onFailure);\n worker.on(\"exit\", onFailure);\n worker.postMessage({ type: \"check\", files: serializedFiles });\n });\n }\n\n /**\n * Run checker inline (main thread)\n */\n private async runInline(\n checker: FileHealthCheckerContract,\n files: FileManager[],\n ): Promise<FileCheckResult[]> {\n const results: FileCheckResult[] = [];\n\n for (const file of files) {\n const healthResult = await checker.check(file);\n const stats = healthResult.getStats();\n\n results.push({\n path: file.absolutePath,\n relativePath: file.relativePath,\n healthy: stats.state === \"healthy\",\n errors: healthResult.messages\n .filter((m) => m.type === \"error\")\n .map((m) => ({\n type: \"error\" as const,\n message: m.message,\n lineNumber: m.lineNumber,\n columnNumber: m.columnNumber,\n length: m.length || 1,\n filePath: file.absolutePath,\n relativePath: file.relativePath,\n ruleId: m.ruleId,\n })),\n warnings: healthResult.messages\n .filter((m) => m.type === \"warning\")\n .map((m) => ({\n type: \"warning\" as const,\n message: m.message,\n lineNumber: m.lineNumber,\n columnNumber: m.columnNumber,\n length: m.length || 1,\n filePath: file.absolutePath,\n relativePath: file.relativePath,\n ruleId: m.ruleId,\n })),\n });\n }\n\n // Update stats\n const checkerResults = results;\n this.updateStats(checker.name, checkerResults);\n\n return results;\n }\n\n /**\n * Update aggregated stats for a checker\n */\n private updateStats(checkerName: string, results: FileCheckResult[]): void {\n const stats = this.checkerStats.get(checkerName);\n if (!stats) return;\n\n for (const result of results) {\n stats.totalFiles++;\n if (result.healthy) {\n stats.healthyFiles++;\n } else {\n stats.defectiveFiles++;\n }\n stats.totalErrors += result.errors.length;\n stats.totalWarnings += result.warnings.length;\n if (result.errors.length > 0) stats.filesWithErrors++;\n if (result.warnings.length > 0) stats.filesWithWarnings++;\n }\n }\n\n /**\n * Detect when files are changed\n */\n public async onFileChanges(files: FileManager[]): Promise<void> {\n // Notify workers of file changes\n const serializedFiles: SerializedFile[] = files.map((f) => ({\n path: f.absolutePath,\n content: f.source,\n relativePath: f.relativePath,\n }));\n\n for (const [, worker] of this.workers) {\n worker.postMessage({ type: \"fileChanges\", files: serializedFiles });\n }\n\n // Notify inline checkers\n await Promise.all(\n this.healthCheckers.filter((c) => !c.workerPath).map((c) => c.onFileChanges(files)),\n );\n }\n\n /**\n * Remove files from tracking\n * Notifies both inline checkers and worker-based checkers about removed files\n */\n public removeFiles(files: FileManager[]): void {\n // Notify inline checkers\n this.healthCheckers\n .filter((c) => !c.workerPath)\n .forEach((checker) => files.forEach((file) => checker.removeFile(file)));\n\n // Notify workers about deleted files\n if (files.length > 0) {\n const deletedPaths = files.map((f) => ({\n path: f.absolutePath,\n relativePath: f.relativePath,\n }));\n\n for (const [, worker] of this.workers) {\n worker.postMessage({ type: \"filesDeleted\", files: deletedPaths });\n }\n }\n }\n\n /**\n * Display file results (errors/warnings)\n */\n private displayFileResults(result: FileCheckResult): void {\n const fileName = result.relativePath.replace(/\\\\/g, \"/\");\n\n // Display errors\n for (const error of result.errors) {\n const icon = colors.redBright(\"✖\");\n const level = colors.redBright(colors.bold(\"ERROR\"));\n console.log(\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${error.lineNumber},${error.columnNumber})`)}`,\n );\n if (error.ruleId) {\n console.log(\n ` ${colors.magentaBright(error.ruleId)} ${colors.dim(\"→\")} ${colors.red(error.message)}`,\n );\n } else {\n console.log(` ${colors.dim(\"→\")} ${colors.red(error.message)}`);\n }\n }\n\n // Display warnings\n for (const warning of result.warnings) {\n const icon = colors.yellowBright(\"⚠\");\n const level = colors.yellowBright(colors.bold(\"WARNING\"));\n console.log(\n `\\n${icon} ${level} ${colors.dim(\"in\")} ${colors.cyanBright(fileName)}${colors.dim(`(${warning.lineNumber},${warning.columnNumber})`)}`,\n );\n if (warning.ruleId) {\n console.log(\n ` ${colors.magentaBright(warning.ruleId)} ${colors.dim(\"→\")} ${colors.yellow(warning.message)}`,\n );\n } else {\n console.log(` ${colors.dim(\"→\")} ${colors.yellow(warning.message)}`);\n }\n }\n }\n\n /**\n * Display stats for all health checkers\n */\n private async displayStats(): Promise<void> {\n const allStats: HealthCheckerFilesStats[] = [];\n\n for (const checker of this.healthCheckers) {\n const stats = this.checkerStats.get(checker.name);\n if (stats) {\n allStats.push({\n name: checker.name,\n files: {\n healthy: stats.healthyFiles,\n defective: stats.defectiveFiles,\n },\n warnings: {\n total: stats.totalWarnings,\n totalFiles: stats.filesWithWarnings,\n },\n errors: {\n total: stats.totalErrors,\n totalFiles: stats.filesWithErrors,\n },\n });\n }\n }\n\n console.log(\"\\n\");\n console.log(colors.bold(colors.cyan(\"━\".repeat(80))));\n devLogInfo(colors.bold(\" 📊 Health Checker Statistics\"));\n console.log(colors.bold(colors.cyan(\"━\".repeat(80))));\n console.log(\"\");\n\n allStats.forEach((stats: HealthCheckerFilesStats, index: number) => {\n const totalFiles = stats.files.healthy + stats.files.defective;\n const hasIssues = stats.files.defective > 0;\n\n // Checker name with icon\n const statusIcon = hasIssues ? \"⚠️\" : \"✅\";\n console.log(colors.bold(` ${statusIcon} ${stats.name}`));\n console.log(colors.dim(\" \" + \"─\".repeat(76)));\n\n // Files summary\n const filesLine = ` Files: ${colors.white(totalFiles.toString())} total │ ${colors.green(\"✓ \" + stats.files.healthy)} healthy │ ${hasIssues ? colors.red(\"✗ \" + stats.files.defective) : colors.dim(\"✗ 0\")} defective`;\n console.log(filesLine);\n\n // Issues summary\n const warningsText =\n stats.warnings.total > 0\n ? colors.yellow(`⚠ ${stats.warnings.total} warnings`)\n : colors.dim(\"⚠ 0 warnings\");\n\n const errorsText =\n stats.errors.total > 0\n ? colors.red(`✗ ${stats.errors.total} errors`)\n : colors.dim(\"✗ 0 errors\");\n\n console.log(` Issues: ${warningsText} │ ${errorsText}`);\n\n // Add spacing between checkers\n if (index < allStats.length - 1) {\n console.log(\"\");\n }\n });\n\n console.log(\"\");\n console.log(colors.bold(colors.cyan(\"━\".repeat(80))));\n console.log(\"\");\n }\n\n /**\n * Shutdown all workers\n */\n public async shutdown(): Promise<void> {\n await Promise.all(\n [...this.workers.values()].map(async (worker) => {\n try {\n // Let the shutdown handler release CLI children before forced termination.\n await new Promise<void>((resolve) => {\n const finish = () => {\n clearTimeout(timer);\n worker.off(\"exit\", finish);\n resolve();\n };\n const timer = setTimeout(finish, 500);\n worker.once(\"exit\", finish);\n worker.postMessage({ type: \"shutdown\" });\n });\n await worker.terminate();\n } catch {\n // Worker may already be terminated.\n }\n }),\n );\n\n this.workers.clear();\n this.workerInitPromises.clear();\n this.checkerStats.clear();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,302 @@
1
+ import { createRequire } from "node:module";
2
+ import path from "node:path";
3
+ import { existsSync, readFileSync } from "node:fs";
4
+ import { execFile } from "node:child_process";
5
+
6
+ //#region ../../packages/core/src/dev-server/health-checker/oxlint-runner.ts
7
+ const CONFIG_FILES = [
8
+ ".oxlintrc.json",
9
+ ".oxlintrc.jsonc",
10
+ "oxlint.config.ts",
11
+ "oxlint.config.mts"
12
+ ];
13
+ /** Whether the app has an oxlint config file at its root. */
14
+ function hasOxlintConfig(cwd) {
15
+ return CONFIG_FILES.some((name) => existsSync(path.join(cwd, name)));
16
+ }
17
+ /** Resolve the app's optional CLI package, without using global PATH binaries. */
18
+ function findOxlint(cwd) {
19
+ if (!hasOxlintConfig(cwd)) return void 0;
20
+ try {
21
+ const packagePath = createRequire(path.join(cwd, "package.json")).resolve("oxlint/package.json");
22
+ const manifest = JSON.parse(readFileSync(packagePath, "utf8"));
23
+ const bin = typeof manifest.bin === "string" ? manifest.bin : manifest.bin?.oxlint;
24
+ if (typeof bin !== "string") return void 0;
25
+ const binaryPath = path.resolve(path.dirname(packagePath), bin);
26
+ return existsSync(binaryPath) ? binaryPath : void 0;
27
+ } catch {
28
+ return;
29
+ }
30
+ }
31
+ function record(value) {
32
+ return value !== null && typeof value === "object" && !Array.isArray(value);
33
+ }
34
+ function coordinate(value) {
35
+ return typeof value === "number" && Number.isFinite(value) ? Math.max(1, Math.trunc(value)) : 1;
36
+ }
37
+ var OxlintOutputParseError = class extends Error {};
38
+ function outputDetail(stdout, stderr) {
39
+ return [stderr.trim(), stdout.trim()].filter(Boolean).join("\n").slice(0, 2e3);
40
+ }
41
+ /** Most output one CLI run may write before Node stops it. */
42
+ const MAX_OUTPUT_BYTES = 8 * 1024 * 1024;
43
+ /**
44
+ * Most files passed to one CLI run. An 8 MiB report holds roughly 16,000
45
+ * diagnostics, so a batch of thousands of files with several diagnostics each
46
+ * could overflow it; a batch that still overflows is split in half and retried.
47
+ */
48
+ const MAX_FILES_PER_BATCH = 500;
49
+ /**
50
+ * How long `shutdown()` waits after SIGTERM before sending SIGKILL. Below the
51
+ * health-check manager's 500 ms wait for its workers, so a child that ignores
52
+ * SIGTERM is still reaped before the worker is terminated.
53
+ */
54
+ const SHUTDOWN_KILL_GRACE_MS = 250;
55
+ const MAX_BUFFER_CODE = "ERR_CHILD_PROCESS_STDIO_MAXBUFFER";
56
+ /** The OS refused the command line: too long overall, or one argument too long. */
57
+ const COMMAND_TOO_LONG_CODES = new Set(["E2BIG", "ENAMETOOLONG"]);
58
+ /** A failed CLI run; `code` keeps the process or spawn error code (`E2BIG`, maxBuffer, …). */
59
+ var OxlintCommandError = class extends Error {
60
+ constructor(message, code) {
61
+ super(message);
62
+ this.code = code;
63
+ this.name = "OxlintCommandError";
64
+ }
65
+ };
66
+ /** A check stopped because the runner is shutting down; not a lint or tool failure. */
67
+ var OxlintCheckCancelledError = class extends Error {
68
+ constructor() {
69
+ super("Oxlint check cancelled: the development server is shutting down.");
70
+ this.name = "OxlintCheckCancelledError";
71
+ }
72
+ };
73
+ function errorCodeOf(error) {
74
+ const code = error?.code;
75
+ return typeof code === "string" ? code : void 0;
76
+ }
77
+ function oxlintCommandError(error, stdout, stderr) {
78
+ return new OxlintCommandError(`Oxlint could not check changed files: ${error.code === MAX_BUFFER_CODE ? `produced more than ${MAX_OUTPUT_BYTES / (1024 * 1024)} MiB of output` : error.killed ? "timed out or terminated (30s limit)" : `failed (code ${String(error.code ?? "unknown")}${error.signal ? `, signal ${error.signal}` : ""})`}${outputDetail(stdout, stderr) ? `\n${outputDetail(stdout, stderr)}` : ""}`, typeof error.code === "string" ? error.code : void 0);
79
+ }
80
+ function parseOxlintResults(output, files, cwd) {
81
+ let report;
82
+ try {
83
+ report = JSON.parse(output);
84
+ } catch {
85
+ throw new OxlintOutputParseError(`Oxlint could not check changed files: ${output.trim().slice(0, 2e3) || "empty diagnostics report"}`);
86
+ }
87
+ if (!record(report) || !Array.isArray(report.diagnostics)) throw new Error("Oxlint returned an invalid JSON diagnostics report.");
88
+ const results = files.map((file) => ({
89
+ path: file.path,
90
+ relativePath: file.relativePath,
91
+ healthy: true,
92
+ errors: [],
93
+ warnings: []
94
+ }));
95
+ const byPath = new Map(results.map((result) => [path.resolve(result.path), result]));
96
+ for (const diagnostic of report.diagnostics) {
97
+ if (!record(diagnostic) || typeof diagnostic.message !== "string") continue;
98
+ if (diagnostic.severity !== "error" && diagnostic.severity !== "warning") continue;
99
+ const target = typeof diagnostic.filename === "string" ? byPath.get(path.resolve(cwd, diagnostic.filename)) : void 0;
100
+ if (!target) throw new Error(`Oxlint: ${diagnostic.message}`);
101
+ const label = Array.isArray(diagnostic.labels) ? diagnostic.labels.find(record) : void 0;
102
+ const span = record(label) && record(label.span) ? label.span : {};
103
+ const message = {
104
+ type: diagnostic.severity,
105
+ message: diagnostic.message,
106
+ lineNumber: coordinate(span.line),
107
+ columnNumber: coordinate(span.column),
108
+ length: coordinate(span.length),
109
+ filePath: target.path,
110
+ relativePath: target.relativePath,
111
+ ...typeof diagnostic.code === "string" ? { ruleId: diagnostic.code } : {}
112
+ };
113
+ target.healthy = false;
114
+ (message.type === "error" ? target.errors : target.warnings).push(message);
115
+ }
116
+ return results;
117
+ }
118
+ /**
119
+ * The share of the command-line budget one argument uses. Windows counts
120
+ * UTF-16 characters plus quoting and a separator. POSIX `execve` counts the
121
+ * argument's bytes, its NUL terminator and its slot in the `argv` pointer
122
+ * array (8 bytes on 64-bit systems), all against `ARG_MAX`.
123
+ */
124
+ function oxlintArgumentSize(argument, platform) {
125
+ return platform === "win32" ? argument.length + 3 : Buffer.byteLength(argument) + 1 + 8;
126
+ }
127
+ /**
128
+ * The command-line budget per platform, well below the real limits: Linux's
129
+ * `ARG_MAX` is about 2 MB (512 KiB here), Windows allows 32,767 characters
130
+ * (24 KiB here) and other systems get 128 KiB.
131
+ */
132
+ function commandLineLimit(platform) {
133
+ return platform === "win32" ? 24 * 1024 : platform === "linux" ? 512 * 1024 : 128 * 1024;
134
+ }
135
+ function uncheckedResult(file, code) {
136
+ return {
137
+ path: file.path,
138
+ relativePath: file.relativePath,
139
+ healthy: false,
140
+ errors: [],
141
+ warnings: [{
142
+ type: "warning",
143
+ message: `Oxlint could not check this file: its path is too long for one command line (${code}).`,
144
+ lineNumber: 1,
145
+ columnNumber: 1,
146
+ length: 1,
147
+ filePath: file.path,
148
+ relativePath: file.relativePath
149
+ }]
150
+ };
151
+ }
152
+ const OXLINT_FLAGS = [
153
+ "--format=json",
154
+ "--threads=1",
155
+ "--no-error-on-unmatched-pattern",
156
+ "--"
157
+ ];
158
+ function healthy(file) {
159
+ return {
160
+ path: file.path,
161
+ relativePath: file.relativePath,
162
+ healthy: true,
163
+ errors: [],
164
+ warnings: []
165
+ };
166
+ }
167
+ /** Invoked in a dedicated worker during development; lints only the supplied disk files. */
168
+ var OxlintRunner = class {
169
+ constructor(dependencies = {}) {
170
+ this.dependencies = dependencies;
171
+ this.cwd = process.cwd();
172
+ this.children = /* @__PURE__ */ new Set();
173
+ this.shuttingDown = false;
174
+ }
175
+ initialize(cwd) {
176
+ this.cwd = cwd;
177
+ this.binaryPath = findOxlint(cwd);
178
+ this.shuttingDown = false;
179
+ return {
180
+ success: true,
181
+ hasConfig: this.binaryPath !== void 0
182
+ };
183
+ }
184
+ /**
185
+ * Stop every running CLI child: SIGTERM first, then SIGKILL after
186
+ * {@link SHUTDOWN_KILL_GRACE_MS} for a child that ignores it. Pending checks
187
+ * reject with {@link OxlintCheckCancelledError}.
188
+ */
189
+ async shutdown() {
190
+ this.shuttingDown = true;
191
+ await Promise.all([...this.children].map((child) => new Promise((resolve) => {
192
+ if (child.exitCode !== null || child.signalCode !== null) {
193
+ resolve();
194
+ return;
195
+ }
196
+ const timer = setTimeout(() => child.kill("SIGKILL"), 250);
197
+ child.once("close", () => {
198
+ clearTimeout(timer);
199
+ resolve();
200
+ });
201
+ child.kill("SIGTERM");
202
+ })));
203
+ this.children.clear();
204
+ }
205
+ execute(binaryPath, args, cwd) {
206
+ if (this.dependencies.execute) return this.dependencies.execute(binaryPath, args, cwd);
207
+ return new Promise((resolve, reject) => {
208
+ const child = execFile(process.execPath, [binaryPath, ...args], {
209
+ cwd,
210
+ encoding: "utf8",
211
+ windowsHide: true,
212
+ timeout: 3e4,
213
+ maxBuffer: MAX_OUTPUT_BYTES
214
+ }, (error, stdout, stderr) => {
215
+ this.children.delete(child);
216
+ if (error && this.shuttingDown) {
217
+ reject(new OxlintCheckCancelledError());
218
+ return;
219
+ }
220
+ if (error && (error.code !== 1 || error.killed)) {
221
+ reject(oxlintCommandError(error, stdout, stderr));
222
+ return;
223
+ }
224
+ resolve({
225
+ stdout,
226
+ stderr
227
+ });
228
+ });
229
+ this.children.add(child);
230
+ });
231
+ }
232
+ /**
233
+ * Lint one batch. A batch whose report overflows the output buffer is split
234
+ * in half and retried, down to single files; a single file whose path the OS
235
+ * refuses as too long is reported as unchecked instead of failing the check.
236
+ */
237
+ async checkBatch(binaryPath, filesInBatch) {
238
+ if (this.shuttingDown) throw new OxlintCheckCancelledError();
239
+ let output;
240
+ try {
241
+ output = await this.execute(binaryPath, [...OXLINT_FLAGS, ...filesInBatch.map((file) => path.relative(this.cwd, file.path))], this.cwd);
242
+ } catch (error) {
243
+ if (this.shuttingDown) throw new OxlintCheckCancelledError();
244
+ const code = errorCodeOf(error);
245
+ if (code === MAX_BUFFER_CODE && filesInBatch.length > 1) {
246
+ const middle = Math.ceil(filesInBatch.length / 2);
247
+ return [...await this.checkBatch(binaryPath, filesInBatch.slice(0, middle)), ...await this.checkBatch(binaryPath, filesInBatch.slice(middle))];
248
+ }
249
+ const [only] = filesInBatch;
250
+ if (code && COMMAND_TOO_LONG_CODES.has(code) && only && filesInBatch.length === 1) return [uncheckedResult(only, code)];
251
+ throw error;
252
+ }
253
+ try {
254
+ return parseOxlintResults(output.stdout, filesInBatch, this.cwd);
255
+ } catch (error) {
256
+ if (!(error instanceof OxlintOutputParseError)) throw error;
257
+ const detail = outputDetail(output.stdout, output.stderr) || "empty diagnostics report";
258
+ throw new Error(`Oxlint could not check changed files: ${detail}`, { cause: error });
259
+ }
260
+ }
261
+ async checkFiles(files) {
262
+ const exists = this.dependencies.exists ?? existsSync;
263
+ const lintable = files.filter((file) => /\.[cm]?[jt]sx?$/i.test(file.path) && exists(file.path));
264
+ const binaryPath = this.binaryPath;
265
+ if (!binaryPath || lintable.length === 0) return files.map(healthy);
266
+ const platform = this.dependencies.platform ?? process.platform;
267
+ const limit = this.dependencies.commandLineLimit ?? commandLineLimit(platform);
268
+ const size = (arg) => oxlintArgumentSize(arg, platform);
269
+ const baseSize = [
270
+ process.execPath,
271
+ binaryPath,
272
+ ...OXLINT_FLAGS
273
+ ].reduce((sum, arg) => sum + size(arg), 0);
274
+ const batches = [];
275
+ let batch = [];
276
+ let batchSize = baseSize;
277
+ const flush = () => {
278
+ if (batch.length) batches.push(batch);
279
+ batch = [];
280
+ batchSize = baseSize;
281
+ };
282
+ for (const file of lintable) {
283
+ const argumentSize = size(path.relative(this.cwd, file.path));
284
+ if (baseSize + argumentSize > limit) {
285
+ flush();
286
+ batches.push([file]);
287
+ continue;
288
+ }
289
+ if (batch.length >= 500 || batchSize + argumentSize > limit) flush();
290
+ batch.push(file);
291
+ batchSize += argumentSize;
292
+ }
293
+ flush();
294
+ const results = new Map(files.map((file) => [file.path, healthy(file)]));
295
+ for (const filesInBatch of batches) for (const result of await this.checkBatch(binaryPath, filesInBatch)) results.set(result.path, result);
296
+ return files.map((file) => results.get(file.path) ?? healthy(file));
297
+ }
298
+ };
299
+
300
+ //#endregion
301
+ export { OxlintCheckCancelledError, OxlintRunner, findOxlint, hasOxlintConfig };
302
+ //# sourceMappingURL=oxlint-runner.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oxlint-runner.mjs","names":[],"sources":["../../../../../../../../../packages/core/src/dev-server/health-checker/oxlint-runner.ts"],"sourcesContent":["import { execFile, type ChildProcess } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport path from \"node:path\";\n\nexport type OxlintFile = { path: string; relativePath: string };\nexport type OxlintMessage = {\n type: \"error\" | \"warning\";\n message: string;\n lineNumber: number;\n columnNumber: number;\n length: number;\n filePath: string;\n relativePath: string;\n ruleId?: string;\n};\nexport type OxlintFileResult = OxlintFile & {\n healthy: boolean;\n errors: OxlintMessage[];\n warnings: OxlintMessage[];\n};\n\nconst CONFIG_FILES = [\".oxlintrc.json\", \".oxlintrc.jsonc\", \"oxlint.config.ts\", \"oxlint.config.mts\"];\n\n/** Whether the app has an oxlint config file at its root. */\nexport function hasOxlintConfig(cwd: string): boolean {\n return CONFIG_FILES.some((name) => existsSync(path.join(cwd, name)));\n}\n\n/** Resolve the app's optional CLI package, without using global PATH binaries. */\nexport function findOxlint(cwd: string): string | undefined {\n if (!hasOxlintConfig(cwd)) return undefined;\n try {\n const require = createRequire(path.join(cwd, \"package.json\"));\n const packagePath = require.resolve(\"oxlint/package.json\");\n const manifest = JSON.parse(readFileSync(packagePath, \"utf8\")) as {\n bin?: { oxlint?: unknown } | string;\n };\n const bin = typeof manifest.bin === \"string\" ? manifest.bin : manifest.bin?.oxlint;\n if (typeof bin !== \"string\") return undefined;\n const binaryPath = path.resolve(path.dirname(packagePath), bin);\n return existsSync(binaryPath) ? binaryPath : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction record(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction coordinate(value: unknown): number {\n return typeof value === \"number\" && Number.isFinite(value) ? Math.max(1, Math.trunc(value)) : 1;\n}\n\nclass OxlintOutputParseError extends Error {}\n\nfunction outputDetail(stdout: string, stderr: string): string {\n return [stderr.trim(), stdout.trim()].filter(Boolean).join(\"\\n\").slice(0, 2000);\n}\n\n/** Most output one CLI run may write before Node stops it. */\nconst MAX_OUTPUT_BYTES = 8 * 1024 * 1024;\n\n/**\n * Most files passed to one CLI run. An 8 MiB report holds roughly 16,000\n * diagnostics, so a batch of thousands of files with several diagnostics each\n * could overflow it; a batch that still overflows is split in half and retried.\n */\nexport const MAX_FILES_PER_BATCH = 500;\n\n/**\n * How long `shutdown()` waits after SIGTERM before sending SIGKILL. Below the\n * health-check manager's 500 ms wait for its workers, so a child that ignores\n * SIGTERM is still reaped before the worker is terminated.\n */\nexport const SHUTDOWN_KILL_GRACE_MS = 250;\n\nconst MAX_BUFFER_CODE = \"ERR_CHILD_PROCESS_STDIO_MAXBUFFER\";\n/** The OS refused the command line: too long overall, or one argument too long. */\nconst COMMAND_TOO_LONG_CODES = new Set([\"E2BIG\", \"ENAMETOOLONG\"]);\n\n/** A failed CLI run; `code` keeps the process or spawn error code (`E2BIG`, maxBuffer, …). */\nexport class OxlintCommandError extends Error {\n public constructor(\n message: string,\n public readonly code?: string,\n ) {\n super(message);\n this.name = \"OxlintCommandError\";\n }\n}\n\n/** A check stopped because the runner is shutting down; not a lint or tool failure. */\nexport class OxlintCheckCancelledError extends Error {\n public constructor() {\n super(\"Oxlint check cancelled: the development server is shutting down.\");\n this.name = \"OxlintCheckCancelledError\";\n }\n}\n\nfunction errorCodeOf(error: unknown): string | undefined {\n const code = (error as { code?: unknown } | null)?.code;\n return typeof code === \"string\" ? code : undefined;\n}\n\nexport function oxlintCommandError(\n error: { code?: unknown; signal?: string | null; killed?: boolean },\n stdout: string,\n stderr: string,\n): OxlintCommandError {\n const status =\n error.code === MAX_BUFFER_CODE\n ? `produced more than ${MAX_OUTPUT_BYTES / (1024 * 1024)} MiB of output`\n : error.killed\n ? \"timed out or terminated (30s limit)\"\n : `failed (code ${String(error.code ?? \"unknown\")}${error.signal ? `, signal ${error.signal}` : \"\"})`;\n return new OxlintCommandError(\n `Oxlint could not check changed files: ${status}${outputDetail(stdout, stderr) ? `\\n${outputDetail(stdout, stderr)}` : \"\"}`,\n typeof error.code === \"string\" ? error.code : undefined,\n );\n}\n\nexport function parseOxlintResults(\n output: string,\n files: OxlintFile[],\n cwd: string,\n): OxlintFileResult[] {\n let report: unknown;\n try {\n report = JSON.parse(output);\n } catch {\n throw new OxlintOutputParseError(\n `Oxlint could not check changed files: ${output.trim().slice(0, 2000) || \"empty diagnostics report\"}`,\n );\n }\n if (!record(report) || !Array.isArray(report.diagnostics)) {\n throw new Error(\"Oxlint returned an invalid JSON diagnostics report.\");\n }\n const results = files.map((file): OxlintFileResult => ({\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n }));\n const byPath = new Map(results.map((result) => [path.resolve(result.path), result]));\n for (const diagnostic of report.diagnostics) {\n if (!record(diagnostic) || typeof diagnostic.message !== \"string\") continue;\n if (diagnostic.severity !== \"error\" && diagnostic.severity !== \"warning\") continue;\n const target =\n typeof diagnostic.filename === \"string\"\n ? byPath.get(path.resolve(cwd, diagnostic.filename))\n : undefined;\n if (!target) {\n throw new Error(`Oxlint: ${diagnostic.message}`);\n }\n const label = Array.isArray(diagnostic.labels) ? diagnostic.labels.find(record) : undefined;\n const span = record(label) && record(label.span) ? label.span : {};\n const message: OxlintMessage = {\n type: diagnostic.severity,\n message: diagnostic.message,\n lineNumber: coordinate(span.line),\n columnNumber: coordinate(span.column),\n length: coordinate(span.length),\n filePath: target.path,\n relativePath: target.relativePath,\n ...(typeof diagnostic.code === \"string\" ? { ruleId: diagnostic.code } : {}),\n };\n target.healthy = false;\n (message.type === \"error\" ? target.errors : target.warnings).push(message);\n }\n return results;\n}\n\ntype OxlintCommandOutput = { stdout: string; stderr: string };\ntype OxlintRunnerDependencies = {\n execute?: (binaryPath: string, args: string[], cwd: string) => Promise<OxlintCommandOutput>;\n exists?: (file: string) => boolean;\n platform?: NodeJS.Platform;\n /** Overrides the per-platform command-line budget, in the units of {@link oxlintArgumentSize}. */\n commandLineLimit?: number;\n};\n\n/**\n * The share of the command-line budget one argument uses. Windows counts\n * UTF-16 characters plus quoting and a separator. POSIX `execve` counts the\n * argument's bytes, its NUL terminator and its slot in the `argv` pointer\n * array (8 bytes on 64-bit systems), all against `ARG_MAX`.\n */\nexport function oxlintArgumentSize(argument: string, platform: NodeJS.Platform): number {\n return platform === \"win32\" ? argument.length + 3 : Buffer.byteLength(argument) + 1 + 8;\n}\n\n/**\n * The command-line budget per platform, well below the real limits: Linux's\n * `ARG_MAX` is about 2 MB (512 KiB here), Windows allows 32,767 characters\n * (24 KiB here) and other systems get 128 KiB.\n */\nfunction commandLineLimit(platform: NodeJS.Platform): number {\n return platform === \"win32\" ? 24 * 1024 : platform === \"linux\" ? 512 * 1024 : 128 * 1024;\n}\n\nfunction uncheckedResult(file: OxlintFile, code: string): OxlintFileResult {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: false,\n errors: [],\n warnings: [\n {\n type: \"warning\",\n message: `Oxlint could not check this file: its path is too long for one command line (${code}).`,\n lineNumber: 1,\n columnNumber: 1,\n length: 1,\n filePath: file.path,\n relativePath: file.relativePath,\n },\n ],\n };\n}\n\nconst OXLINT_FLAGS = [\"--format=json\", \"--threads=1\", \"--no-error-on-unmatched-pattern\", \"--\"];\n\nfunction healthy(file: OxlintFile): OxlintFileResult {\n return {\n path: file.path,\n relativePath: file.relativePath,\n healthy: true,\n errors: [],\n warnings: [],\n };\n}\n\n/** Invoked in a dedicated worker during development; lints only the supplied disk files. */\nexport class OxlintRunner {\n private binaryPath?: string;\n private cwd = process.cwd();\n private readonly children = new Set<ChildProcess>();\n private shuttingDown = false;\n\n public constructor(private readonly dependencies: OxlintRunnerDependencies = {}) {}\n\n public initialize(cwd: string): { success: boolean; hasConfig: boolean } {\n this.cwd = cwd;\n this.binaryPath = findOxlint(cwd);\n this.shuttingDown = false;\n return { success: true, hasConfig: this.binaryPath !== undefined };\n }\n\n /**\n * Stop every running CLI child: SIGTERM first, then SIGKILL after\n * {@link SHUTDOWN_KILL_GRACE_MS} for a child that ignores it. Pending checks\n * reject with {@link OxlintCheckCancelledError}.\n */\n public async shutdown(): Promise<void> {\n this.shuttingDown = true;\n await Promise.all(\n [...this.children].map(\n (child) =>\n new Promise<void>((resolve) => {\n if (child.exitCode !== null || child.signalCode !== null) {\n resolve();\n return;\n }\n const timer = setTimeout(() => child.kill(\"SIGKILL\"), SHUTDOWN_KILL_GRACE_MS);\n child.once(\"close\", () => {\n clearTimeout(timer);\n resolve();\n });\n child.kill(\"SIGTERM\");\n }),\n ),\n );\n this.children.clear();\n }\n\n private execute(binaryPath: string, args: string[], cwd: string): Promise<OxlintCommandOutput> {\n if (this.dependencies.execute) return this.dependencies.execute(binaryPath, args, cwd);\n return new Promise((resolve, reject) => {\n const child = execFile(\n process.execPath,\n [binaryPath, ...args],\n {\n cwd,\n encoding: \"utf8\",\n windowsHide: true,\n timeout: 30_000,\n maxBuffer: MAX_OUTPUT_BYTES,\n },\n (error, stdout, stderr) => {\n this.children.delete(child);\n if (error && this.shuttingDown) {\n reject(new OxlintCheckCancelledError());\n return;\n }\n // Exit 1 with a JSON report is the normal result for lint errors.\n if (error && (error.code !== 1 || error.killed)) {\n reject(oxlintCommandError(error, stdout, stderr));\n return;\n }\n resolve({ stdout, stderr });\n },\n );\n this.children.add(child);\n });\n }\n\n /**\n * Lint one batch. A batch whose report overflows the output buffer is split\n * in half and retried, down to single files; a single file whose path the OS\n * refuses as too long is reported as unchecked instead of failing the check.\n */\n private async checkBatch(\n binaryPath: string,\n filesInBatch: OxlintFile[],\n ): Promise<OxlintFileResult[]> {\n if (this.shuttingDown) throw new OxlintCheckCancelledError();\n let output: OxlintCommandOutput;\n try {\n output = await this.execute(\n binaryPath,\n [...OXLINT_FLAGS, ...filesInBatch.map((file) => path.relative(this.cwd, file.path))],\n this.cwd,\n );\n } catch (error) {\n if (this.shuttingDown) throw new OxlintCheckCancelledError();\n const code = errorCodeOf(error);\n if (code === MAX_BUFFER_CODE && filesInBatch.length > 1) {\n const middle = Math.ceil(filesInBatch.length / 2);\n return [\n ...(await this.checkBatch(binaryPath, filesInBatch.slice(0, middle))),\n ...(await this.checkBatch(binaryPath, filesInBatch.slice(middle))),\n ];\n }\n const [only] = filesInBatch;\n if (code && COMMAND_TOO_LONG_CODES.has(code) && only && filesInBatch.length === 1) {\n return [uncheckedResult(only, code)];\n }\n throw error;\n }\n try {\n return parseOxlintResults(output.stdout, filesInBatch, this.cwd);\n } catch (error) {\n if (!(error instanceof OxlintOutputParseError)) throw error;\n const detail = outputDetail(output.stdout, output.stderr) || \"empty diagnostics report\";\n throw new Error(`Oxlint could not check changed files: ${detail}`, { cause: error });\n }\n }\n\n public async checkFiles(files: OxlintFile[]): Promise<OxlintFileResult[]> {\n const exists = this.dependencies.exists ?? existsSync;\n const lintable = files.filter(\n (file) => /\\.[cm]?[jt]sx?$/i.test(file.path) && exists(file.path),\n );\n const binaryPath = this.binaryPath;\n if (!binaryPath || lintable.length === 0) return files.map(healthy);\n const platform = this.dependencies.platform ?? process.platform;\n const limit = this.dependencies.commandLineLimit ?? commandLineLimit(platform);\n const size = (arg: string) => oxlintArgumentSize(arg, platform);\n const baseSize = [process.execPath, binaryPath, ...OXLINT_FLAGS].reduce(\n (sum, arg) => sum + size(arg),\n 0,\n );\n const batches: OxlintFile[][] = [];\n let batch: OxlintFile[] = [];\n let batchSize = baseSize;\n const flush = () => {\n if (batch.length) batches.push(batch);\n batch = [];\n batchSize = baseSize;\n };\n for (const file of lintable) {\n const argumentSize = size(path.relative(this.cwd, file.path));\n if (baseSize + argumentSize > limit) {\n // Over the conservative budget on its own: run it alone, since the\n // real limit is usually far higher.\n flush();\n batches.push([file]);\n continue;\n }\n if (batch.length >= MAX_FILES_PER_BATCH || batchSize + argumentSize > limit) flush();\n batch.push(file);\n batchSize += argumentSize;\n }\n flush();\n const results = new Map(files.map((file) => [file.path, healthy(file)]));\n for (const filesInBatch of batches) {\n for (const result of await this.checkBatch(binaryPath, filesInBatch)) {\n results.set(result.path, result);\n }\n }\n return files.map((file) => results.get(file.path) ?? healthy(file));\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { OxlintCheckCancelledError, OxlintRunner } from "../oxlint-runner.mjs";
2
+ import { parentPort, workerData } from "node:worker_threads";
3
+
4
+ //#region ../../packages/core/src/dev-server/health-checker/workers/oxlint-health.worker.ts
5
+ const runner = new OxlintRunner();
6
+ process.once("exit", () => runner.shutdown());
7
+ parentPort?.once("close", () => runner.shutdown());
8
+ parentPort?.on("message", async (message) => {
9
+ try {
10
+ switch (message.type) {
11
+ case "init":
12
+ parentPort?.postMessage({
13
+ type: "initialized",
14
+ ...runner.initialize(message.config.cwd)
15
+ });
16
+ break;
17
+ case "check":
18
+ parentPort?.postMessage({
19
+ type: "results",
20
+ results: await runner.checkFiles(message.files)
21
+ });
22
+ break;
23
+ case "filesDeleted": break;
24
+ case "shutdown":
25
+ await runner.shutdown();
26
+ process.exit(0);
27
+ }
28
+ } catch (error) {
29
+ const detail = error instanceof Error ? error.message : String(error);
30
+ if (!(error instanceof OxlintCheckCancelledError)) console.warn("Oxlint Health Checker:", detail);
31
+ parentPort?.postMessage({
32
+ type: "error",
33
+ message: detail
34
+ });
35
+ }
36
+ });
37
+ const data = workerData;
38
+ if (data?.autoInit) runner.initialize(data.cwd ?? process.cwd());
39
+
40
+ //#endregion
41
+ export { };
42
+ //# sourceMappingURL=oxlint-health.worker.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oxlint-health.worker.mjs","names":[],"sources":["../../../../../../../../../../packages/core/src/dev-server/health-checker/workers/oxlint-health.worker.ts"],"sourcesContent":["import { parentPort, workerData } from \"node:worker_threads\";\nimport { OxlintCheckCancelledError, OxlintRunner, type OxlintFile } from \"../oxlint-runner\";\n\ntype WorkerMessage =\n | { type: \"init\"; config: { cwd: string } }\n | { type: \"check\"; files: OxlintFile[] }\n | { type: \"filesDeleted\"; files: OxlintFile[] }\n | { type: \"shutdown\" };\n\nconst runner = new OxlintRunner();\nprocess.once(\"exit\", () => runner.shutdown());\nparentPort?.once(\"close\", () => runner.shutdown());\nparentPort?.on(\"message\", async (message: WorkerMessage) => {\n try {\n switch (message.type) {\n case \"init\":\n parentPort?.postMessage({ type: \"initialized\", ...runner.initialize(message.config.cwd) });\n break;\n case \"check\":\n parentPort?.postMessage({\n type: \"results\",\n results: await runner.checkFiles(message.files),\n });\n break;\n case \"filesDeleted\":\n // The CLI reads current disk contents and holds no persistent file cache.\n break;\n case \"shutdown\":\n await runner.shutdown();\n process.exit(0);\n }\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n // A check cut short by shutdown is expected; only real failures are printed.\n if (!(error instanceof OxlintCheckCancelledError))\n console.warn(\"Oxlint Health Checker:\", detail);\n parentPort?.postMessage({ type: \"error\", message: detail });\n }\n});\n\nconst data = workerData as { autoInit?: boolean; cwd?: string } | undefined;\nif (data?.autoInit) runner.initialize(data.cwd ?? process.cwd());\n"],"mappings":";;;;AASA,MAAM,SAAS,IAAI,aAAa;AAChC,QAAQ,KAAK,cAAc,OAAO,SAAS,CAAC;AAC5C,YAAY,KAAK,eAAe,OAAO,SAAS,CAAC;AACjD,YAAY,GAAG,WAAW,OAAO,YAA2B;CAC1D,IAAI;EACF,QAAQ,QAAQ,MAAhB;GACE,KAAK;IACH,YAAY,YAAY;KAAE,MAAM;KAAe,GAAG,OAAO,WAAW,QAAQ,OAAO,GAAG;IAAE,CAAC;IACzF;GACF,KAAK;IACH,YAAY,YAAY;KACtB,MAAM;KACN,SAAS,MAAM,OAAO,WAAW,QAAQ,KAAK;IAChD,CAAC;IACD;GACF,KAAK,gBAEH;GACF,KAAK;IACH,MAAM,OAAO,SAAS;IACtB,QAAQ,KAAK,CAAC;EAClB;CACF,SAAS,OAAO;EACd,MAAM,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EAEpE,IAAI,EAAE,iBAAiB,4BACrB,QAAQ,KAAK,0BAA0B,MAAM;EAC/C,YAAY,YAAY;GAAE,MAAM;GAAS,SAAS;EAAO,CAAC;CAC5D;AACF,CAAC;AAED,MAAM,OAAO;AACb,IAAI,MAAM,UAAU,OAAO,WAAW,KAAK,OAAO,QAAQ,IAAI,CAAC"}