@celljs/cli 3.8.0 → 4.0.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 (758) hide show
  1. package/README.md +442 -1
  2. package/agent/guide.md +39 -0
  3. package/bin/cell.js +2 -0
  4. package/lib/agent/agent-guide.d.ts +39 -0
  5. package/lib/agent/agent-guide.d.ts.map +1 -0
  6. package/lib/agent/agent-guide.js +67 -0
  7. package/lib/agent/agent-guide.js.map +1 -0
  8. package/lib/build/executable-compiler.d.ts +44 -0
  9. package/lib/build/executable-compiler.d.ts.map +1 -0
  10. package/lib/build/executable-compiler.js +145 -0
  11. package/lib/build/executable-compiler.js.map +1 -0
  12. package/lib/build/executable-compiler.spec.d.ts +2 -0
  13. package/lib/build/executable-compiler.spec.d.ts.map +1 -0
  14. package/lib/build/executable-compiler.spec.js +71 -0
  15. package/lib/build/executable-compiler.spec.js.map +1 -0
  16. package/lib/build/single-compile.spec.d.ts +2 -0
  17. package/lib/build/single-compile.spec.d.ts.map +1 -0
  18. package/lib/build/single-compile.spec.js +135 -0
  19. package/lib/build/single-compile.spec.js.map +1 -0
  20. package/lib/check/project-checker.d.ts +85 -0
  21. package/lib/check/project-checker.d.ts.map +1 -0
  22. package/lib/check/project-checker.js +332 -0
  23. package/lib/check/project-checker.js.map +1 -0
  24. package/lib/check/project-checker.spec.d.ts +2 -0
  25. package/lib/check/project-checker.spec.d.ts.map +1 -0
  26. package/lib/check/project-checker.spec.js +147 -0
  27. package/lib/check/project-checker.spec.js.map +1 -0
  28. package/lib/cli/agent-command.d.ts +15 -0
  29. package/lib/cli/agent-command.d.ts.map +1 -0
  30. package/lib/cli/agent-command.js +42 -0
  31. package/lib/cli/agent-command.js.map +1 -0
  32. package/lib/cli/build-command.d.ts +84 -0
  33. package/lib/cli/build-command.d.ts.map +1 -0
  34. package/lib/cli/build-command.js +170 -0
  35. package/lib/cli/build-command.js.map +1 -0
  36. package/lib/cli/cell-cli.d.ts +35 -0
  37. package/lib/cli/cell-cli.d.ts.map +1 -0
  38. package/lib/cli/cell-cli.js +159 -0
  39. package/lib/cli/cell-cli.js.map +1 -0
  40. package/lib/cli/cell-cli.spec.d.ts +2 -0
  41. package/lib/cli/cell-cli.spec.d.ts.map +1 -0
  42. package/lib/cli/cell-cli.spec.js +195 -0
  43. package/lib/cli/cell-cli.spec.js.map +1 -0
  44. package/lib/cli/check-command.d.ts +31 -0
  45. package/lib/cli/check-command.d.ts.map +1 -0
  46. package/lib/cli/check-command.js +67 -0
  47. package/lib/cli/check-command.js.map +1 -0
  48. package/lib/cli/command.d.ts +24 -0
  49. package/lib/cli/command.d.ts.map +1 -0
  50. package/lib/cli/command.js +10 -0
  51. package/lib/cli/command.js.map +1 -0
  52. package/lib/cli/config-command.d.ts +29 -0
  53. package/lib/cli/config-command.d.ts.map +1 -0
  54. package/lib/cli/config-command.js +71 -0
  55. package/lib/cli/config-command.js.map +1 -0
  56. package/lib/cli/config-command.spec.d.ts +2 -0
  57. package/lib/cli/config-command.spec.d.ts.map +1 -0
  58. package/lib/cli/config-command.spec.js +79 -0
  59. package/lib/cli/config-command.spec.js.map +1 -0
  60. package/lib/cli/deploy-command.d.ts +41 -0
  61. package/lib/cli/deploy-command.d.ts.map +1 -0
  62. package/lib/cli/deploy-command.js +114 -0
  63. package/lib/cli/deploy-command.js.map +1 -0
  64. package/lib/cli/dev-command.d.ts +47 -0
  65. package/lib/cli/dev-command.d.ts.map +1 -0
  66. package/lib/cli/dev-command.js +219 -0
  67. package/lib/cli/dev-command.js.map +1 -0
  68. package/lib/cli/dev-command.spec.d.ts +2 -0
  69. package/lib/cli/dev-command.spec.d.ts.map +1 -0
  70. package/lib/cli/dev-command.spec.js +149 -0
  71. package/lib/cli/dev-command.spec.js.map +1 -0
  72. package/lib/cli/docs-command.d.ts +19 -0
  73. package/lib/cli/docs-command.d.ts.map +1 -0
  74. package/lib/cli/docs-command.js +47 -0
  75. package/lib/cli/docs-command.js.map +1 -0
  76. package/lib/cli/info-command.d.ts +44 -0
  77. package/lib/cli/info-command.d.ts.map +1 -0
  78. package/lib/cli/info-command.js +39 -0
  79. package/lib/cli/info-command.js.map +1 -0
  80. package/lib/cli/info-command.spec.d.ts +2 -0
  81. package/lib/cli/info-command.spec.d.ts.map +1 -0
  82. package/lib/cli/info-command.spec.js +236 -0
  83. package/lib/cli/info-command.spec.js.map +1 -0
  84. package/lib/cli/init-command.d.ts +20 -0
  85. package/lib/cli/init-command.d.ts.map +1 -0
  86. package/lib/cli/init-command.js +43 -0
  87. package/lib/cli/init-command.js.map +1 -0
  88. package/lib/cli/main.d.ts +2 -0
  89. package/lib/cli/main.d.ts.map +1 -0
  90. package/lib/cli/main.js +3 -0
  91. package/lib/cli/main.js.map +1 -0
  92. package/lib/cli/mcp-command.d.ts +34 -0
  93. package/lib/cli/mcp-command.d.ts.map +1 -0
  94. package/lib/cli/mcp-command.js +85 -0
  95. package/lib/cli/mcp-command.js.map +1 -0
  96. package/lib/cli/mcp-command.spec.d.ts +2 -0
  97. package/lib/cli/mcp-command.spec.d.ts.map +1 -0
  98. package/lib/cli/mcp-command.spec.js +132 -0
  99. package/lib/cli/mcp-command.spec.js.map +1 -0
  100. package/lib/cli/preview-command.d.ts +24 -0
  101. package/lib/cli/preview-command.d.ts.map +1 -0
  102. package/lib/cli/preview-command.js +91 -0
  103. package/lib/cli/preview-command.js.map +1 -0
  104. package/lib/cli/reporter.d.ts +26 -0
  105. package/lib/cli/reporter.d.ts.map +1 -0
  106. package/lib/cli/reporter.js +58 -0
  107. package/lib/cli/reporter.js.map +1 -0
  108. package/lib/config/config-build.spec.d.ts +2 -0
  109. package/lib/config/config-build.spec.d.ts.map +1 -0
  110. package/lib/config/config-build.spec.js +111 -0
  111. package/lib/config/config-build.spec.js.map +1 -0
  112. package/lib/config/config-explainer.d.ts +48 -0
  113. package/lib/config/config-explainer.d.ts.map +1 -0
  114. package/lib/config/config-explainer.js +130 -0
  115. package/lib/config/config-explainer.js.map +1 -0
  116. package/lib/config/config-file-loader.d.ts +22 -0
  117. package/lib/config/config-file-loader.d.ts.map +1 -0
  118. package/lib/config/config-file-loader.js +63 -0
  119. package/lib/config/config-file-loader.js.map +1 -0
  120. package/lib/config/config-resolver.d.ts +111 -0
  121. package/lib/config/config-resolver.d.ts.map +1 -0
  122. package/lib/config/config-resolver.js +215 -0
  123. package/lib/config/config-resolver.js.map +1 -0
  124. package/lib/config/config-resolver.spec.d.ts +2 -0
  125. package/lib/config/config-resolver.spec.d.ts.map +1 -0
  126. package/lib/config/config-resolver.spec.js +159 -0
  127. package/lib/config/config-resolver.spec.js.map +1 -0
  128. package/lib/config/config-validator.d.ts +35 -0
  129. package/lib/config/config-validator.d.ts.map +1 -0
  130. package/lib/config/config-validator.js +160 -0
  131. package/lib/config/config-validator.js.map +1 -0
  132. package/lib/config/config-validator.spec.d.ts +2 -0
  133. package/lib/config/config-validator.spec.d.ts.map +1 -0
  134. package/lib/config/config-validator.spec.js +77 -0
  135. package/lib/config/config-validator.spec.js.map +1 -0
  136. package/lib/config/define-config.d.ts +4 -0
  137. package/lib/config/define-config.d.ts.map +1 -0
  138. package/lib/config/define-config.js +5 -0
  139. package/lib/config/define-config.js.map +1 -0
  140. package/lib/config/types.d.ts +53 -0
  141. package/lib/config/types.d.ts.map +1 -0
  142. package/lib/config/types.js +2 -0
  143. package/lib/config/types.js.map +1 -0
  144. package/lib/deploy/cloud-api.d.ts +58 -0
  145. package/lib/deploy/cloud-api.d.ts.map +1 -0
  146. package/lib/deploy/cloud-api.js +189 -0
  147. package/lib/deploy/cloud-api.js.map +1 -0
  148. package/lib/deploy/code-package.d.ts +15 -0
  149. package/lib/deploy/code-package.d.ts.map +1 -0
  150. package/lib/deploy/code-package.js +40 -0
  151. package/lib/deploy/code-package.js.map +1 -0
  152. package/lib/deploy/deploy-utils.spec.d.ts +2 -0
  153. package/lib/deploy/deploy-utils.spec.d.ts.map +1 -0
  154. package/lib/deploy/deploy-utils.spec.js +56 -0
  155. package/lib/deploy/deploy-utils.spec.js.map +1 -0
  156. package/lib/deploy/deployer-registry.d.ts +11 -0
  157. package/lib/deploy/deployer-registry.d.ts.map +1 -0
  158. package/lib/deploy/deployer-registry.js +40 -0
  159. package/lib/deploy/deployer-registry.js.map +1 -0
  160. package/lib/deploy/request-signer.d.ts +51 -0
  161. package/lib/deploy/request-signer.d.ts.map +1 -0
  162. package/lib/deploy/request-signer.js +109 -0
  163. package/lib/deploy/request-signer.js.map +1 -0
  164. package/lib/deploy/zip-writer.d.ts +32 -0
  165. package/lib/deploy/zip-writer.d.ts.map +1 -0
  166. package/lib/deploy/zip-writer.js +114 -0
  167. package/lib/deploy/zip-writer.js.map +1 -0
  168. package/lib/docs/docs-index.d.ts +54 -0
  169. package/lib/docs/docs-index.d.ts.map +1 -0
  170. package/lib/docs/docs-index.js +140 -0
  171. package/lib/docs/docs-index.js.map +1 -0
  172. package/lib/docs/docs-index.spec.d.ts +2 -0
  173. package/lib/docs/docs-index.spec.d.ts.map +1 -0
  174. package/lib/docs/docs-index.spec.js +52 -0
  175. package/lib/docs/docs-index.spec.js.map +1 -0
  176. package/lib/events/event-bus.d.ts +30 -0
  177. package/lib/events/event-bus.d.ts.map +1 -0
  178. package/lib/events/event-bus.js +81 -0
  179. package/lib/events/event-bus.js.map +1 -0
  180. package/lib/events/event-bus.spec.d.ts +2 -0
  181. package/lib/events/event-bus.spec.d.ts.map +1 -0
  182. package/lib/events/event-bus.spec.js +69 -0
  183. package/lib/events/event-bus.spec.js.map +1 -0
  184. package/lib/events/hook-runner.d.ts +27 -0
  185. package/lib/events/hook-runner.d.ts.map +1 -0
  186. package/lib/events/hook-runner.js +65 -0
  187. package/lib/events/hook-runner.js.map +1 -0
  188. package/lib/events/hook-runner.spec.d.ts +2 -0
  189. package/lib/events/hook-runner.spec.d.ts.map +1 -0
  190. package/lib/events/hook-runner.spec.js +36 -0
  191. package/lib/events/hook-runner.spec.js.map +1 -0
  192. package/lib/index.d.ts +57 -1
  193. package/lib/index.d.ts.map +1 -1
  194. package/lib/index.js +57 -2
  195. package/lib/index.js.map +1 -1
  196. package/lib/info/project-inspector.d.ts +143 -0
  197. package/lib/info/project-inspector.d.ts.map +1 -0
  198. package/lib/info/project-inspector.js +244 -0
  199. package/lib/info/project-inspector.js.map +1 -0
  200. package/lib/init/project-initializer.d.ts +44 -0
  201. package/lib/init/project-initializer.d.ts.map +1 -0
  202. package/lib/init/project-initializer.js +90 -0
  203. package/lib/init/project-initializer.js.map +1 -0
  204. package/lib/init/project-initializer.spec.d.ts +2 -0
  205. package/lib/init/project-initializer.spec.d.ts.map +1 -0
  206. package/lib/init/project-initializer.spec.js +88 -0
  207. package/lib/init/project-initializer.spec.js.map +1 -0
  208. package/lib/mcp/dev-activity.d.ts +34 -0
  209. package/lib/mcp/dev-activity.d.ts.map +1 -0
  210. package/lib/mcp/dev-activity.js +46 -0
  211. package/lib/mcp/dev-activity.js.map +1 -0
  212. package/lib/mcp/dev-mcp-endpoint.d.ts +62 -0
  213. package/lib/mcp/dev-mcp-endpoint.d.ts.map +1 -0
  214. package/lib/mcp/dev-mcp-endpoint.js +280 -0
  215. package/lib/mcp/dev-mcp-endpoint.js.map +1 -0
  216. package/lib/mcp/dev-mcp-endpoint.spec.d.ts +2 -0
  217. package/lib/mcp/dev-mcp-endpoint.spec.d.ts.map +1 -0
  218. package/lib/mcp/dev-mcp-endpoint.spec.js +143 -0
  219. package/lib/mcp/dev-mcp-endpoint.spec.js.map +1 -0
  220. package/lib/mcp/mcp-server.d.ts +64 -0
  221. package/lib/mcp/mcp-server.d.ts.map +1 -0
  222. package/lib/mcp/mcp-server.js +201 -0
  223. package/lib/mcp/mcp-server.js.map +1 -0
  224. package/lib/mcp/mcp-server.spec.d.ts +2 -0
  225. package/lib/mcp/mcp-server.spec.d.ts.map +1 -0
  226. package/lib/mcp/mcp-server.spec.js +136 -0
  227. package/lib/mcp/mcp-server.spec.js.map +1 -0
  228. package/lib/mcp/project-mcp-tools.d.ts +35 -0
  229. package/lib/mcp/project-mcp-tools.d.ts.map +1 -0
  230. package/lib/mcp/project-mcp-tools.js +199 -0
  231. package/lib/mcp/project-mcp-tools.js.map +1 -0
  232. package/lib/modules/module-host.d.ts +118 -0
  233. package/lib/modules/module-host.d.ts.map +1 -0
  234. package/lib/modules/module-host.js +405 -0
  235. package/lib/modules/module-host.js.map +1 -0
  236. package/lib/modules/module-host.spec.d.ts +2 -0
  237. package/lib/modules/module-host.spec.d.ts.map +1 -0
  238. package/lib/modules/module-host.spec.js +220 -0
  239. package/lib/modules/module-host.spec.js.map +1 -0
  240. package/lib/preset/builtin-presets.d.ts +9 -0
  241. package/lib/preset/builtin-presets.d.ts.map +1 -0
  242. package/lib/preset/builtin-presets.js +24 -0
  243. package/lib/preset/builtin-presets.js.map +1 -0
  244. package/lib/preset/cloudflare/cloudflare-deployer.d.ts +26 -0
  245. package/lib/preset/cloudflare/cloudflare-deployer.d.ts.map +1 -0
  246. package/lib/preset/cloudflare/cloudflare-deployer.js +116 -0
  247. package/lib/preset/cloudflare/cloudflare-deployer.js.map +1 -0
  248. package/lib/preset/cloudflare/cloudflare-preset.d.ts +16 -0
  249. package/lib/preset/cloudflare/cloudflare-preset.d.ts.map +1 -0
  250. package/lib/preset/cloudflare/cloudflare-preset.js +97 -0
  251. package/lib/preset/cloudflare/cloudflare-preset.js.map +1 -0
  252. package/lib/preset/cloudflare/cloudflare.spec.d.ts +2 -0
  253. package/lib/preset/cloudflare/cloudflare.spec.d.ts.map +1 -0
  254. package/lib/preset/cloudflare/cloudflare.spec.js +212 -0
  255. package/lib/preset/cloudflare/cloudflare.spec.js.map +1 -0
  256. package/lib/preset/cloudflare/wrangler-config.d.ts +50 -0
  257. package/lib/preset/cloudflare/wrangler-config.d.ts.map +1 -0
  258. package/lib/preset/cloudflare/wrangler-config.js +160 -0
  259. package/lib/preset/cloudflare/wrangler-config.js.map +1 -0
  260. package/lib/preset/cloudflare/wrangler-config.spec.d.ts +2 -0
  261. package/lib/preset/cloudflare/wrangler-config.spec.d.ts.map +1 -0
  262. package/lib/preset/cloudflare/wrangler-config.spec.js +112 -0
  263. package/lib/preset/cloudflare/wrangler-config.spec.js.map +1 -0
  264. package/lib/preset/cloudflare/wrangler.d.ts +38 -0
  265. package/lib/preset/cloudflare/wrangler.d.ts.map +1 -0
  266. package/lib/preset/cloudflare/wrangler.js +90 -0
  267. package/lib/preset/cloudflare/wrangler.js.map +1 -0
  268. package/lib/preset/cloudflare/wrangler.spec.d.ts +2 -0
  269. package/lib/preset/cloudflare/wrangler.spec.d.ts.map +1 -0
  270. package/lib/preset/cloudflare/wrangler.spec.js +64 -0
  271. package/lib/preset/cloudflare/wrangler.spec.js.map +1 -0
  272. package/lib/preset/fc/fc-deployer.d.ts +50 -0
  273. package/lib/preset/fc/fc-deployer.d.ts.map +1 -0
  274. package/lib/preset/fc/fc-deployer.js +209 -0
  275. package/lib/preset/fc/fc-deployer.js.map +1 -0
  276. package/lib/preset/fc/fc-preset.d.ts +20 -0
  277. package/lib/preset/fc/fc-preset.d.ts.map +1 -0
  278. package/lib/preset/fc/fc-preset.js +46 -0
  279. package/lib/preset/fc/fc-preset.js.map +1 -0
  280. package/lib/preset/lambda/lambda-deployer.d.ts +50 -0
  281. package/lib/preset/lambda/lambda-deployer.d.ts.map +1 -0
  282. package/lib/preset/lambda/lambda-deployer.js +274 -0
  283. package/lib/preset/lambda/lambda-deployer.js.map +1 -0
  284. package/lib/preset/lambda/lambda-preset.d.ts +14 -0
  285. package/lib/preset/lambda/lambda-preset.d.ts.map +1 -0
  286. package/lib/preset/lambda/lambda-preset.js +44 -0
  287. package/lib/preset/lambda/lambda-preset.js.map +1 -0
  288. package/lib/preset/preset-output.d.ts +19 -0
  289. package/lib/preset/preset-output.d.ts.map +1 -0
  290. package/lib/preset/preset-output.js +45 -0
  291. package/lib/preset/preset-output.js.map +1 -0
  292. package/lib/preset/preset-registry.d.ts +16 -0
  293. package/lib/preset/preset-registry.d.ts.map +1 -0
  294. package/lib/preset/preset-registry.js +58 -0
  295. package/lib/preset/preset-registry.js.map +1 -0
  296. package/lib/preset/preset-registry.spec.d.ts +2 -0
  297. package/lib/preset/preset-registry.spec.d.ts.map +1 -0
  298. package/lib/preset/preset-registry.spec.js +28 -0
  299. package/lib/preset/preset-registry.spec.js.map +1 -0
  300. package/lib/preset/scf/scf-deployer.d.ts +54 -0
  301. package/lib/preset/scf/scf-deployer.d.ts.map +1 -0
  302. package/lib/preset/scf/scf-deployer.js +202 -0
  303. package/lib/preset/scf/scf-deployer.js.map +1 -0
  304. package/lib/preset/scf/scf-preset.d.ts +19 -0
  305. package/lib/preset/scf/scf-preset.d.ts.map +1 -0
  306. package/lib/preset/scf/scf-preset.js +43 -0
  307. package/lib/preset/scf/scf-preset.js.map +1 -0
  308. package/lib/preset/serverless-deployers.spec.d.ts +2 -0
  309. package/lib/preset/serverless-deployers.spec.d.ts.map +1 -0
  310. package/lib/preset/serverless-deployers.spec.js +307 -0
  311. package/lib/preset/serverless-deployers.spec.js.map +1 -0
  312. package/lib/preset/serverless-presets.spec.d.ts +2 -0
  313. package/lib/preset/serverless-presets.spec.d.ts.map +1 -0
  314. package/lib/preset/serverless-presets.spec.js +280 -0
  315. package/lib/preset/serverless-presets.spec.js.map +1 -0
  316. package/lib/preset/serverless-scripts.d.ts +29 -0
  317. package/lib/preset/serverless-scripts.d.ts.map +1 -0
  318. package/lib/preset/serverless-scripts.js +120 -0
  319. package/lib/preset/serverless-scripts.js.map +1 -0
  320. package/lib/preset/vercel/vercel-deployer.d.ts +38 -0
  321. package/lib/preset/vercel/vercel-deployer.d.ts.map +1 -0
  322. package/lib/preset/vercel/vercel-deployer.js +160 -0
  323. package/lib/preset/vercel/vercel-deployer.js.map +1 -0
  324. package/lib/preset/vercel/vercel-preset.d.ts +19 -0
  325. package/lib/preset/vercel/vercel-preset.d.ts.map +1 -0
  326. package/lib/preset/vercel/vercel-preset.js +102 -0
  327. package/lib/preset/vercel/vercel-preset.js.map +1 -0
  328. package/lib/test/fixture-project.d.ts +17 -0
  329. package/lib/test/fixture-project.d.ts.map +1 -0
  330. package/lib/test/fixture-project.js +43 -0
  331. package/lib/test/fixture-project.js.map +1 -0
  332. package/lib/testing/create-test-app.d.ts +27 -0
  333. package/lib/testing/create-test-app.d.ts.map +1 -0
  334. package/lib/testing/create-test-app.js +54 -0
  335. package/lib/testing/create-test-app.js.map +1 -0
  336. package/lib/testing/create-test-app.spec.d.ts +2 -0
  337. package/lib/testing/create-test-app.spec.d.ts.map +1 -0
  338. package/lib/testing/create-test-app.spec.js +66 -0
  339. package/lib/testing/create-test-app.spec.js.map +1 -0
  340. package/lib/toolchain/toolchain.d.ts +49 -0
  341. package/lib/toolchain/toolchain.d.ts.map +1 -0
  342. package/lib/toolchain/toolchain.js +100 -0
  343. package/lib/toolchain/toolchain.js.map +1 -0
  344. package/lib/utils/json-util.d.ts +11 -0
  345. package/lib/utils/json-util.d.ts.map +1 -0
  346. package/lib/utils/json-util.js +73 -0
  347. package/lib/utils/json-util.js.map +1 -0
  348. package/lib/utils/json-util.spec.d.ts +2 -0
  349. package/lib/utils/json-util.spec.d.ts.map +1 -0
  350. package/lib/utils/json-util.spec.js +18 -0
  351. package/lib/utils/json-util.spec.js.map +1 -0
  352. package/lib/utils/text-util.d.ts +19 -0
  353. package/lib/utils/text-util.d.ts.map +1 -0
  354. package/lib/utils/text-util.js +66 -0
  355. package/lib/utils/text-util.js.map +1 -0
  356. package/lib/utils/text-util.spec.d.ts +2 -0
  357. package/lib/utils/text-util.spec.d.ts.map +1 -0
  358. package/lib/utils/text-util.spec.js +22 -0
  359. package/lib/utils/text-util.spec.js.map +1 -0
  360. package/package.json +28 -30
  361. package/src/agent/agent-guide.ts +90 -0
  362. package/src/build/executable-compiler.ts +179 -0
  363. package/src/check/project-checker.ts +365 -0
  364. package/src/cli/agent-command.ts +46 -0
  365. package/src/cli/build-command.ts +189 -0
  366. package/src/cli/cell-cli.ts +174 -0
  367. package/src/cli/check-command.ts +74 -0
  368. package/src/cli/command.ts +29 -0
  369. package/src/cli/config-command.ts +73 -0
  370. package/src/cli/deploy-command.ts +122 -0
  371. package/src/cli/dev-command.ts +232 -0
  372. package/src/cli/docs-command.ts +53 -0
  373. package/src/cli/info-command.ts +40 -0
  374. package/src/cli/init-command.ts +53 -0
  375. package/src/cli/main.ts +3 -0
  376. package/src/cli/mcp-command.ts +98 -0
  377. package/src/cli/preview-command.ts +98 -0
  378. package/src/cli/reporter.ts +67 -0
  379. package/src/config/config-explainer.ts +158 -0
  380. package/src/config/config-file-loader.ts +76 -0
  381. package/src/config/config-resolver.ts +300 -0
  382. package/src/config/config-validator.ts +208 -0
  383. package/src/config/define-config.ts +6 -0
  384. package/src/config/types.ts +57 -0
  385. package/src/deploy/cloud-api.ts +194 -0
  386. package/src/deploy/code-package.ts +44 -0
  387. package/src/deploy/deployer-registry.ts +44 -0
  388. package/src/deploy/request-signer.ts +155 -0
  389. package/src/deploy/zip-writer.ts +132 -0
  390. package/src/docs/docs-index.ts +174 -0
  391. package/src/events/event-bus.ts +94 -0
  392. package/src/events/hook-runner.ts +78 -0
  393. package/src/index.ts +57 -0
  394. package/src/info/project-inspector.ts +352 -0
  395. package/src/init/project-initializer.ts +111 -0
  396. package/src/mcp/dev-activity.ts +71 -0
  397. package/src/mcp/dev-mcp-endpoint.ts +323 -0
  398. package/src/mcp/mcp-server.ts +251 -0
  399. package/src/mcp/project-mcp-tools.ts +216 -0
  400. package/src/modules/module-host.ts +489 -0
  401. package/src/preset/builtin-presets.ts +26 -0
  402. package/src/preset/cloudflare/cloudflare-deployer.ts +126 -0
  403. package/src/preset/cloudflare/cloudflare-preset.ts +97 -0
  404. package/src/preset/cloudflare/wrangler-config.ts +173 -0
  405. package/src/preset/cloudflare/wrangler.ts +113 -0
  406. package/src/preset/fc/fc-deployer.ts +237 -0
  407. package/src/preset/fc/fc-preset.ts +51 -0
  408. package/src/preset/lambda/lambda-deployer.ts +317 -0
  409. package/src/preset/lambda/lambda-preset.ts +45 -0
  410. package/src/preset/preset-output.ts +55 -0
  411. package/src/preset/preset-registry.ts +65 -0
  412. package/src/preset/scf/scf-deployer.ts +232 -0
  413. package/src/preset/scf/scf-preset.ts +45 -0
  414. package/src/preset/serverless-scripts.ts +132 -0
  415. package/src/preset/vercel/vercel-deployer.ts +168 -0
  416. package/src/preset/vercel/vercel-preset.ts +111 -0
  417. package/src/test/fixture-project.ts +50 -0
  418. package/src/testing/create-test-app.ts +73 -0
  419. package/src/toolchain/toolchain.ts +121 -0
  420. package/src/utils/json-util.ts +67 -0
  421. package/src/utils/text-util.ts +68 -0
  422. package/templates/backend/README.md +13 -0
  423. package/templates/backend/_gitignore +5 -0
  424. package/templates/backend/cell.yml +3 -0
  425. package/templates/backend/package.json +23 -0
  426. package/templates/{file-service/src → backend/src/node}/home-controller.ts +5 -2
  427. package/templates/{file-service/src → backend/src/node}/module.ts +0 -1
  428. package/templates/backend/template.json +3 -0
  429. package/templates/backend/test/app.spec.ts +19 -0
  430. package/templates/backend/tsconfig.json +25 -0
  431. package/templates/fullstack/README.md +13 -0
  432. package/templates/fullstack/_gitignore +5 -0
  433. package/templates/fullstack/cell.yml +6 -0
  434. package/templates/fullstack/package.json +27 -0
  435. package/templates/fullstack/src/browser/home.view.tsx +19 -0
  436. package/templates/{cell-component/src → fullstack/src/browser}/module.ts +1 -1
  437. package/templates/fullstack/src/common/greeting-protocol.ts +5 -0
  438. package/templates/fullstack/src/node/greeting-server.ts +13 -0
  439. package/templates/{admin-app/src/browser → fullstack/src/node}/module.ts +2 -1
  440. package/templates/fullstack/template.json +3 -0
  441. package/templates/fullstack/test/app.spec.ts +18 -0
  442. package/templates/fullstack/tsconfig.json +27 -0
  443. package/bin/cell +0 -2
  444. package/lib/build/build-manager.d.ts +0 -9
  445. package/lib/build/build-manager.d.ts.map +0 -1
  446. package/lib/build/build-manager.js +0 -41
  447. package/lib/build/build-manager.js.map +0 -1
  448. package/lib/build/build.d.ts +0 -6
  449. package/lib/build/build.d.ts.map +0 -1
  450. package/lib/build/build.js +0 -16
  451. package/lib/build/build.js.map +0 -1
  452. package/lib/cell-main.d.ts +0 -2
  453. package/lib/cell-main.d.ts.map +0 -1
  454. package/lib/cell-main.js +0 -110
  455. package/lib/cell-main.js.map +0 -1
  456. package/lib/cell.d.ts +0 -2
  457. package/lib/cell.d.ts.map +0 -1
  458. package/lib/cell.js +0 -194
  459. package/lib/cell.js.map +0 -1
  460. package/lib/config/config.d.ts +0 -12
  461. package/lib/config/config.d.ts.map +0 -1
  462. package/lib/config/config.js +0 -48
  463. package/lib/config/config.js.map +0 -1
  464. package/lib/deploy/deploy.d.ts +0 -7
  465. package/lib/deploy/deploy.d.ts.map +0 -1
  466. package/lib/deploy/deploy.js +0 -30
  467. package/lib/deploy/deploy.js.map +0 -1
  468. package/lib/info/info.d.ts +0 -6
  469. package/lib/info/info.d.ts.map +0 -1
  470. package/lib/info/info.js +0 -21
  471. package/lib/info/info.js.map +0 -1
  472. package/lib/init/init-manager.d.ts +0 -33
  473. package/lib/init/init-manager.d.ts.map +0 -1
  474. package/lib/init/init-manager.js +0 -141
  475. package/lib/init/init-manager.js.map +0 -1
  476. package/lib/init/init.d.ts +0 -4
  477. package/lib/init/init.d.ts.map +0 -1
  478. package/lib/init/init.js +0 -17
  479. package/lib/init/init.js.map +0 -1
  480. package/lib/init/templates.d.ts +0 -2
  481. package/lib/init/templates.d.ts.map +0 -1
  482. package/lib/init/templates.js +0 -23
  483. package/lib/init/templates.js.map +0 -1
  484. package/lib/package.spec.d.ts +0 -2
  485. package/lib/package.spec.d.ts.map +0 -1
  486. package/lib/package.spec.js +0 -7
  487. package/lib/package.spec.js.map +0 -1
  488. package/lib/props/props.d.ts +0 -9
  489. package/lib/props/props.d.ts.map +0 -1
  490. package/lib/props/props.js +0 -49
  491. package/lib/props/props.js.map +0 -1
  492. package/lib/serve/serve-manager.d.ts +0 -8
  493. package/lib/serve/serve-manager.d.ts.map +0 -1
  494. package/lib/serve/serve-manager.js +0 -44
  495. package/lib/serve/serve-manager.js.map +0 -1
  496. package/lib/serve/serve.d.ts +0 -8
  497. package/lib/serve/serve.d.ts.map +0 -1
  498. package/lib/serve/serve.js +0 -25
  499. package/lib/serve/serve.js.map +0 -1
  500. package/lib/update/update.d.ts +0 -9
  501. package/lib/update/update.d.ts.map +0 -1
  502. package/lib/update/update.js +0 -56
  503. package/lib/update/update.js.map +0 -1
  504. package/lib/utils/banner-util.d.ts +0 -6
  505. package/lib/utils/banner-util.d.ts.map +0 -1
  506. package/lib/utils/banner-util.js +0 -44
  507. package/lib/utils/banner-util.js.map +0 -1
  508. package/lib/utils/index.d.ts +0 -2
  509. package/lib/utils/index.d.ts.map +0 -1
  510. package/lib/utils/index.js +0 -18
  511. package/lib/utils/index.js.map +0 -1
  512. package/src/build/build-manager.ts +0 -50
  513. package/src/build/build.ts +0 -17
  514. package/src/cell-main.ts +0 -125
  515. package/src/cell.ts +0 -215
  516. package/src/config/config.ts +0 -56
  517. package/src/deploy/deploy.ts +0 -31
  518. package/src/info/info.ts +0 -23
  519. package/src/init/init-manager.ts +0 -163
  520. package/src/init/init.ts +0 -15
  521. package/src/init/templates.ts +0 -19
  522. package/src/package.spec.ts +0 -5
  523. package/src/props/props.ts +0 -48
  524. package/src/serve/serve-manager.ts +0 -51
  525. package/src/serve/serve.ts +0 -29
  526. package/src/update/update.ts +0 -61
  527. package/src/utils/banner-util.ts +0 -41
  528. package/src/utils/index.ts +0 -1
  529. package/templates/accounts/README.md +0 -92
  530. package/templates/accounts/cell-database.yml +0 -17
  531. package/templates/accounts/cell-locale.yml +0 -17
  532. package/templates/accounts/cell-oauth2.0.yml +0 -8
  533. package/templates/accounts/cell-theme.yml +0 -9
  534. package/templates/accounts/cell.yml +0 -10
  535. package/templates/accounts/favicon.ico +0 -0
  536. package/templates/accounts/package.json +0 -48
  537. package/templates/accounts/src/browser/home.view.tsx +0 -86
  538. package/templates/accounts/src/browser/index.ts +0 -3
  539. package/templates/accounts/src/browser/login.view.tsx +0 -78
  540. package/templates/accounts/src/browser/module.ts +0 -3
  541. package/templates/accounts/src/common/entity-protocol.ts +0 -7
  542. package/templates/accounts/src/common/index.ts +0 -1
  543. package/templates/accounts/src/node/authentication/authentication-success-handler.ts +0 -69
  544. package/templates/accounts/src/node/authentication/index.ts +0 -1
  545. package/templates/accounts/src/node/entity/base-entity.ts +0 -13
  546. package/templates/accounts/src/node/entity/connection.ts +0 -52
  547. package/templates/accounts/src/node/entity/index.ts +0 -1
  548. package/templates/accounts/src/node/entity/user.ts +0 -73
  549. package/templates/accounts/src/node/error/error.ts +0 -14
  550. package/templates/accounts/src/node/error/index.ts +0 -1
  551. package/templates/accounts/src/node/index.ts +0 -2
  552. package/templates/accounts/src/node/module.ts +0 -9
  553. package/templates/accounts/src/node/user/index.ts +0 -4
  554. package/templates/accounts/src/node/user/user-protocol.ts +0 -19
  555. package/templates/accounts/src/node/user/user-repository.ts +0 -72
  556. package/templates/accounts/src/node/user/user-service.ts +0 -36
  557. package/templates/accounts/tsconfig.json +0 -32
  558. package/templates/admin-app/.github/workflows/deploy.yml +0 -25
  559. package/templates/admin-app/.vscode/launch.json +0 -23
  560. package/templates/admin-app/README.md +0 -92
  561. package/templates/admin-app/cell-database.yml +0 -7
  562. package/templates/admin-app/cell.yml +0 -93
  563. package/templates/admin-app/package.json +0 -37
  564. package/templates/admin-app/src/browser/user.view.tsx +0 -40
  565. package/templates/admin-app/src/common/index.ts +0 -1
  566. package/templates/admin-app/src/common/user-protocol.ts +0 -23
  567. package/templates/admin-app/src/node/entity/index.ts +0 -1
  568. package/templates/admin-app/src/node/entity/user.ts +0 -15
  569. package/templates/admin-app/src/node/module.ts +0 -8
  570. package/templates/admin-app/src/node/user-service.ts +0 -41
  571. package/templates/admin-app/tsconfig.json +0 -32
  572. package/templates/backend-app/.github/workflows/deploy.yml +0 -25
  573. package/templates/backend-app/.vscode/launch.json +0 -23
  574. package/templates/backend-app/README.md +0 -92
  575. package/templates/backend-app/cell.yml +0 -0
  576. package/templates/backend-app/package.json +0 -33
  577. package/templates/backend-app/src/home-controller.ts +0 -11
  578. package/templates/backend-app/src/module.ts +0 -4
  579. package/templates/backend-app/src/user-controller.ts +0 -48
  580. package/templates/backend-app/test/home-controller.spec.ts +0 -19
  581. package/templates/backend-app/tsconfig.json +0 -32
  582. package/templates/cell-component/README.md +0 -27
  583. package/templates/cell-component/cell.yml +0 -0
  584. package/templates/cell-component/package.json +0 -29
  585. package/templates/cell-component/src/echo-service.ts +0 -16
  586. package/templates/cell-component/src/index.ts +0 -1
  587. package/templates/cell-component/src/package.spec.ts +0 -5
  588. package/templates/cell-component/tsconfig.json +0 -37
  589. package/templates/database-app/.github/workflows/deploy.yml +0 -25
  590. package/templates/database-app/.vscode/launch.json +0 -23
  591. package/templates/database-app/README.md +0 -92
  592. package/templates/database-app/cell.yml +0 -17
  593. package/templates/database-app/package.json +0 -31
  594. package/templates/database-app/src/entity/index.ts +0 -1
  595. package/templates/database-app/src/entity/user.ts +0 -13
  596. package/templates/database-app/src/home-controller.ts +0 -11
  597. package/templates/database-app/src/module.ts +0 -8
  598. package/templates/database-app/src/user-controller.ts +0 -43
  599. package/templates/database-app/tsconfig.json +0 -32
  600. package/templates/docker-app/.github/workflows/deploy.yml +0 -25
  601. package/templates/docker-app/.vscode/launch.json +0 -23
  602. package/templates/docker-app/Dockerfile +0 -27
  603. package/templates/docker-app/README.md +0 -93
  604. package/templates/docker-app/cell.yml +0 -0
  605. package/templates/docker-app/package.json +0 -31
  606. package/templates/docker-app/src/browser/assets/logo.png +0 -0
  607. package/templates/docker-app/src/browser/css-shims.d.ts +0 -30
  608. package/templates/docker-app/src/browser/hello.view.tsx +0 -31
  609. package/templates/docker-app/src/browser/module.ts +0 -3
  610. package/templates/docker-app/src/browser/style/hello.module.scss +0 -4
  611. package/templates/docker-app/src/common/welcome-protocol.ts +0 -5
  612. package/templates/docker-app/src/node/module.ts +0 -3
  613. package/templates/docker-app/src/node/welcome-server.ts +0 -9
  614. package/templates/docker-app/tsconfig.json +0 -33
  615. package/templates/file-service/.github/workflows/deploy.yml +0 -25
  616. package/templates/file-service/.vscode/launch.json +0 -23
  617. package/templates/file-service/README.md +0 -92
  618. package/templates/file-service/cell.yml +0 -12
  619. package/templates/file-service/package.json +0 -34
  620. package/templates/file-service/src/file-controller.ts +0 -47
  621. package/templates/file-service/tsconfig.json +0 -32
  622. package/templates/jwt-app/.github/workflows/deploy.yml +0 -25
  623. package/templates/jwt-app/.vscode/launch.json +0 -23
  624. package/templates/jwt-app/README.md +0 -92
  625. package/templates/jwt-app/cell.yml +0 -4
  626. package/templates/jwt-app/package.json +0 -36
  627. package/templates/jwt-app/src/context.ts +0 -16
  628. package/templates/jwt-app/src/error-handler.ts +0 -30
  629. package/templates/jwt-app/src/error.ts +0 -4
  630. package/templates/jwt-app/src/home-controller.ts +0 -23
  631. package/templates/jwt-app/src/index.ts +0 -5
  632. package/templates/jwt-app/src/jwt-middleware.ts +0 -36
  633. package/templates/jwt-app/src/module.ts +0 -3
  634. package/templates/jwt-app/test/home-controller.spec.ts +0 -19
  635. package/templates/jwt-app/tsconfig.json +0 -32
  636. package/templates/koa-app/app.js +0 -8
  637. package/templates/koa-app/package.json +0 -9
  638. package/templates/microservice/.github/workflows/deploy.yml +0 -28
  639. package/templates/microservice/.vscode/launch.json +0 -24
  640. package/templates/microservice/README.md +0 -92
  641. package/templates/microservice/examples/backend-app/README.md +0 -92
  642. package/templates/microservice/examples/backend-app/cell-remote.yml +0 -4
  643. package/templates/microservice/examples/backend-app/cell.yml +0 -3
  644. package/templates/microservice/examples/backend-app/package.json +0 -32
  645. package/templates/microservice/examples/backend-app/src/api-controller.ts +0 -31
  646. package/templates/microservice/examples/backend-app/src/module.ts +0 -3
  647. package/templates/microservice/examples/backend-app/tsconfig.json +0 -32
  648. package/templates/microservice/package.json +0 -20
  649. package/templates/microservice/packages/api/README.md +0 -92
  650. package/templates/microservice/packages/api/cell.yml +0 -0
  651. package/templates/microservice/packages/api/package.json +0 -25
  652. package/templates/microservice/packages/api/src/common/api-protocol.ts +0 -10
  653. package/templates/microservice/packages/api/src/common/index.ts +0 -1
  654. package/templates/microservice/packages/api/tsconfig.json +0 -30
  655. package/templates/microservice/packages/serviceA/.vscode/launch.json +0 -23
  656. package/templates/microservice/packages/serviceA/README.md +0 -92
  657. package/templates/microservice/packages/serviceA/cell.yml +0 -6
  658. package/templates/microservice/packages/serviceA/package.json +0 -29
  659. package/templates/microservice/packages/serviceA/src/node/module.ts +0 -3
  660. package/templates/microservice/packages/serviceA/src/node/service-a.ts +0 -9
  661. package/templates/microservice/packages/serviceA/tsconfig.json +0 -30
  662. package/templates/microservice/packages/serviceB/README.md +0 -92
  663. package/templates/microservice/packages/serviceB/cell.yml +0 -5
  664. package/templates/microservice/packages/serviceB/package.json +0 -29
  665. package/templates/microservice/packages/serviceB/src/node/module.ts +0 -3
  666. package/templates/microservice/packages/serviceB/src/node/service-b.ts +0 -9
  667. package/templates/microservice/packages/serviceB/tsconfig.json +0 -30
  668. package/templates/microservice/tsconfig.json +0 -32
  669. package/templates/mycli/.vscode/launch.json +0 -33
  670. package/templates/mycli/bin/mycli +0 -2
  671. package/templates/mycli/bin/mycli-deploy +0 -2
  672. package/templates/mycli/bin/mycli-init +0 -2
  673. package/templates/mycli/package.json +0 -33
  674. package/templates/mycli/src/bootstrap.ts +0 -7
  675. package/templates/mycli/src/constants.ts +0 -1
  676. package/templates/mycli/src/deploy/deploy-manager.ts +0 -12
  677. package/templates/mycli/src/deploy/deploy.ts +0 -16
  678. package/templates/mycli/src/deploy/index.ts +0 -1
  679. package/templates/mycli/src/index.ts +0 -2
  680. package/templates/mycli/src/init/index.ts +0 -1
  681. package/templates/mycli/src/init/init-manager.ts +0 -85
  682. package/templates/mycli/src/init/init.ts +0 -25
  683. package/templates/mycli/src/init/templates.ts +0 -3
  684. package/templates/mycli/src/module.ts +0 -3
  685. package/templates/mycli/src/mycli.ts +0 -13
  686. package/templates/mycli/templates/application-template/README.md +0 -0
  687. package/templates/mycli/tsconfig.json +0 -32
  688. package/templates/nest-app/.eslintrc.js +0 -25
  689. package/templates/nest-app/.prettierrc +0 -4
  690. package/templates/nest-app/README.md +0 -73
  691. package/templates/nest-app/nest-cli.json +0 -8
  692. package/templates/nest-app/package.json +0 -69
  693. package/templates/nest-app/src/app.controller.spec.ts +0 -22
  694. package/templates/nest-app/src/app.controller.ts +0 -12
  695. package/templates/nest-app/src/app.module.ts +0 -10
  696. package/templates/nest-app/src/app.service.ts +0 -8
  697. package/templates/nest-app/src/main.ts +0 -8
  698. package/templates/nest-app/test/app.e2e-spec.ts +0 -24
  699. package/templates/nest-app/test/jest-e2e.json +0 -9
  700. package/templates/nest-app/tsconfig.build.json +0 -12
  701. package/templates/nest-app/tsconfig.json +0 -25
  702. package/templates/nextjs-app/.eslintrc.json +0 -3
  703. package/templates/nextjs-app/README.md +0 -34
  704. package/templates/nextjs-app/next.config.js +0 -6
  705. package/templates/nextjs-app/package.json +0 -20
  706. package/templates/nextjs-app/pages/_app.js +0 -7
  707. package/templates/nextjs-app/pages/api/hello.js +0 -5
  708. package/templates/nextjs-app/pages/index.js +0 -69
  709. package/templates/nextjs-app/public/favicon.ico +0 -0
  710. package/templates/nextjs-app/public/vercel.svg +0 -4
  711. package/templates/nextjs-app/styles/Home.module.css +0 -116
  712. package/templates/nextjs-app/styles/globals.css +0 -16
  713. package/templates/sample-app/.github/workflows/deploy.yml +0 -25
  714. package/templates/sample-app/.vscode/launch.json +0 -23
  715. package/templates/sample-app/README.md +0 -92
  716. package/templates/sample-app/cell.yml +0 -0
  717. package/templates/sample-app/package.json +0 -31
  718. package/templates/sample-app/src/browser/assets/logo.png +0 -0
  719. package/templates/sample-app/src/browser/css-shims.d.ts +0 -30
  720. package/templates/sample-app/src/browser/hello.view.tsx +0 -31
  721. package/templates/sample-app/src/browser/module.ts +0 -3
  722. package/templates/sample-app/src/browser/style/hello.module.scss +0 -4
  723. package/templates/sample-app/src/common/welcome-protocol.ts +0 -5
  724. package/templates/sample-app/src/node/module.ts +0 -3
  725. package/templates/sample-app/src/node/welcome-server.ts +0 -9
  726. package/templates/sample-app/tsconfig.json +0 -32
  727. package/templates/schedule/.github/workflows/deploy.yml +0 -25
  728. package/templates/schedule/.vscode/launch.json +0 -23
  729. package/templates/schedule/README.md +0 -92
  730. package/templates/schedule/cell.yml +0 -1
  731. package/templates/schedule/package.json +0 -29
  732. package/templates/schedule/src/module.ts +0 -3
  733. package/templates/schedule/src/scheduler.ts +0 -10
  734. package/templates/schedule/tsconfig.json +0 -32
  735. package/templates/standalone-app/package.json +0 -17
  736. package/templates/standalone-app/src/app.service.ts +0 -10
  737. package/templates/standalone-app/src/main.ts +0 -14
  738. package/templates/standalone-app/src/module.ts +0 -3
  739. package/templates/standalone-app/tsconfig.json +0 -30
  740. package/templates/vue-app/.github/workflows/deploy.yml +0 -25
  741. package/templates/vue-app/.vscode/launch.json +0 -23
  742. package/templates/vue-app/README.md +0 -92
  743. package/templates/vue-app/cell.yml +0 -0
  744. package/templates/vue-app/package.json +0 -32
  745. package/templates/vue-app/src/browser/App.vue +0 -32
  746. package/templates/vue-app/src/browser/app.ts +0 -7
  747. package/templates/vue-app/src/browser/components/HelloWorld.vue +0 -42
  748. package/templates/vue-app/src/browser/declare.d.ts +0 -7
  749. package/templates/vue-app/src/browser/images/logo.png +0 -0
  750. package/templates/vue-app/src/browser/module.ts +0 -3
  751. package/templates/vue-app/src/browser/router.ts +0 -13
  752. package/templates/vue-app/src/browser/shims-vue.d.ts +0 -5
  753. package/templates/vue-app/src/browser/views/About.vue +0 -5
  754. package/templates/vue-app/src/browser/views/Root.vue +0 -37
  755. package/templates/vue-app/src/common/welcome-protocol.ts +0 -5
  756. package/templates/vue-app/src/node/module.ts +0 -3
  757. package/templates/vue-app/src/node/welcome-server.ts +0 -9
  758. package/templates/vue-app/tsconfig.json +0 -32
@@ -0,0 +1,155 @@
1
+ import { createHash, createHmac, randomBytes } from 'node:crypto';
2
+
3
+ export interface SignableRequest {
4
+ method: string;
5
+ host: string;
6
+ /** Path without the query, e.g. `/2023-03-30/functions/app`. */
7
+ path: string;
8
+ query?: Record<string, string>;
9
+ headers?: Record<string, string>;
10
+ body?: string;
11
+ }
12
+
13
+ const sha256 = (data: string | Buffer) => createHash('sha256').update(data).digest('hex');
14
+ const hmac = (key: string | Buffer, data: string) => createHmac('sha256', key).update(data).digest();
15
+
16
+ /** RFC 3986 encoding, as the three clouds canonicalise paths and queries. */
17
+ export function rfc3986(value: string): string {
18
+ return encodeURIComponent(value).replace(/[!'()*]/g, c => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
19
+ }
20
+
21
+ function canonicalQuery(query: Record<string, string> = {}): string {
22
+ return Object.keys(query)
23
+ .sort()
24
+ .map(key => `${rfc3986(key)}=${rfc3986(query[key])}`)
25
+ .join('&');
26
+ }
27
+
28
+ function canonicalPath(path: string): string {
29
+ return path
30
+ .split('/')
31
+ .map(segment => rfc3986(decodeURIComponent(segment)))
32
+ .join('/');
33
+ }
34
+
35
+ /** Lowercased headers, sorted, as `name:value` lines and the list of their names. */
36
+ function canonicalHeaders(headers: Record<string, string>): { lines: string; names: string } {
37
+ const entries = Object.entries(headers)
38
+ .map(([k, v]) => [k.toLowerCase(), String(v).trim()] as const)
39
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
40
+ return { lines: entries.map(([k, v]) => `${k}:${v}\n`).join(''), names: entries.map(([k]) => k).join(';') };
41
+ }
42
+
43
+ /**
44
+ * The request signatures of the cloud APIs Cell deploys to, written against their published
45
+ * algorithms (no SDKs): Alibaba Cloud ACS3-HMAC-SHA256, Tencent Cloud TC3-HMAC-SHA256 and AWS
46
+ * Signature Version 4. Each returns the headers to send, `Authorization` included.
47
+ */
48
+ export namespace RequestSigner {
49
+ export interface AlibabaCredentials {
50
+ accessKeyId: string;
51
+ accessKeySecret: string;
52
+ securityToken?: string;
53
+ }
54
+
55
+ export function acs3(
56
+ request: SignableRequest & { action: string; version: string },
57
+ credentials: AlibabaCredentials,
58
+ now = new Date(),
59
+ nonce = randomBytes(16).toString('hex'),
60
+ ): Record<string, string> {
61
+ const body = request.body ?? '';
62
+ const headers: Record<string, string> = {
63
+ host: request.host,
64
+ 'x-acs-action': request.action,
65
+ 'x-acs-content-sha256': sha256(body),
66
+ 'x-acs-date': now.toISOString().replace(/\.\d{3}Z$/, 'Z'),
67
+ 'x-acs-signature-nonce': nonce,
68
+ 'x-acs-version': request.version,
69
+ ...(credentials.securityToken ? { 'x-acs-security-token': credentials.securityToken } : {}),
70
+ ...(request.headers ?? {}),
71
+ };
72
+ const signed = canonicalHeaders(
73
+ Object.fromEntries(Object.entries(headers).filter(([k]) => k === 'host' || k === 'content-type' || k.startsWith('x-acs-'))),
74
+ );
75
+ const canonical = [
76
+ request.method,
77
+ canonicalPath(request.path),
78
+ canonicalQuery(request.query),
79
+ signed.lines,
80
+ signed.names,
81
+ headers['x-acs-content-sha256'],
82
+ ].join('\n');
83
+ const signature = createHmac('sha256', credentials.accessKeySecret)
84
+ .update(`ACS3-HMAC-SHA256\n${sha256(canonical)}`)
85
+ .digest('hex');
86
+ return {
87
+ ...headers,
88
+ authorization: `ACS3-HMAC-SHA256 Credential=${credentials.accessKeyId},SignedHeaders=${signed.names},Signature=${signature}`,
89
+ };
90
+ }
91
+
92
+ export interface TencentCredentials {
93
+ secretId: string;
94
+ secretKey: string;
95
+ token?: string;
96
+ }
97
+
98
+ /** A Tencent Cloud API 3.0 call: POST of JSON to `<service>.tencentcloudapi.com`. */
99
+ export function tc3(
100
+ request: { service: string; host: string; action: string; version: string; region?: string; body: string },
101
+ credentials: TencentCredentials,
102
+ now = new Date(),
103
+ ): Record<string, string> {
104
+ const timestamp = Math.floor(now.getTime() / 1000);
105
+ const date = new Date(timestamp * 1000).toISOString().slice(0, 10);
106
+ const contentType = 'application/json; charset=utf-8';
107
+ const canonical = ['POST', '/', '', `content-type:${contentType}\nhost:${request.host}\n`, 'content-type;host', sha256(request.body)].join('\n');
108
+ const scope = `${date}/${request.service}/tc3_request`;
109
+ const toSign = ['TC3-HMAC-SHA256', String(timestamp), scope, sha256(canonical)].join('\n');
110
+ const key = hmac(hmac(hmac(`TC3${credentials.secretKey}`, date), request.service), 'tc3_request');
111
+ const signature = createHmac('sha256', key).update(toSign).digest('hex');
112
+ return {
113
+ authorization: `TC3-HMAC-SHA256 Credential=${credentials.secretId}/${scope}, SignedHeaders=content-type;host, Signature=${signature}`,
114
+ 'content-type': contentType,
115
+ host: request.host,
116
+ 'x-tc-action': request.action,
117
+ 'x-tc-timestamp': String(timestamp),
118
+ 'x-tc-version': request.version,
119
+ ...(request.region ? { 'x-tc-region': request.region } : {}),
120
+ ...(credentials.token ? { 'x-tc-token': credentials.token } : {}),
121
+ };
122
+ }
123
+
124
+ export interface AwsCredentials {
125
+ accessKeyId: string;
126
+ secretAccessKey: string;
127
+ sessionToken?: string;
128
+ }
129
+
130
+ export function sigv4(
131
+ request: SignableRequest & { service: string; region: string },
132
+ credentials: AwsCredentials,
133
+ now = new Date(),
134
+ ): Record<string, string> {
135
+ const amzDate = now.toISOString().replace(/[:-]|\.\d{3}/g, '');
136
+ const date = amzDate.slice(0, 8);
137
+ const body = request.body ?? '';
138
+ const headers: Record<string, string> = {
139
+ host: request.host,
140
+ 'x-amz-date': amzDate,
141
+ ...(credentials.sessionToken ? { 'x-amz-security-token': credentials.sessionToken } : {}),
142
+ ...(request.headers ?? {}),
143
+ };
144
+ const signed = canonicalHeaders(headers);
145
+ const canonical = [request.method, canonicalPath(request.path), canonicalQuery(request.query), signed.lines, signed.names, sha256(body)].join('\n');
146
+ const scope = `${date}/${request.region}/${request.service}/aws4_request`;
147
+ const toSign = ['AWS4-HMAC-SHA256', amzDate, scope, sha256(canonical)].join('\n');
148
+ const key = hmac(hmac(hmac(hmac(`AWS4${credentials.secretAccessKey}`, date), request.region), request.service), 'aws4_request');
149
+ const signature = createHmac('sha256', key).update(toSign).digest('hex');
150
+ return {
151
+ ...headers,
152
+ authorization: `AWS4-HMAC-SHA256 Credential=${credentials.accessKeyId}/${scope}, SignedHeaders=${signed.names}, Signature=${signature}`,
153
+ };
154
+ }
155
+ }
@@ -0,0 +1,132 @@
1
+ import { readdirSync, readFileSync, statSync } from 'node:fs';
2
+ import { join, sep } from 'node:path';
3
+ import { deflateRawSync } from 'node:zlib';
4
+
5
+ interface ZipEntry {
6
+ name: Buffer;
7
+ crc: number;
8
+ size: number;
9
+ compressed: Buffer;
10
+ method: 0 | 8;
11
+ mode: number;
12
+ offset: number;
13
+ }
14
+
15
+ /**
16
+ * Writes zip archives (the code packages of FC, SCF and Lambda) without a dependency: deflate from
17
+ * node:zlib, Unix permissions in the external attributes so start scripts stay executable, a fixed
18
+ * timestamp so the same output gives the same archive.
19
+ */
20
+ export class ZipWriter {
21
+ /** 1980-01-01 00:00, the earliest DOS date. */
22
+ static readonly DOS_DATE = (0 << 9) | (1 << 5) | 1;
23
+ protected static readonly CRC_TABLE = ZipWriter.crcTable();
24
+
25
+ protected readonly entries: ZipEntry[] = [];
26
+ protected readonly chunks: Buffer[] = [];
27
+ protected offset = 0;
28
+
29
+ /** Adds every file under `dir`, sorted, at `prefix` (`a/b` style) in the archive. */
30
+ addDirectory(dir: string, prefix = ''): this {
31
+ for (const name of (readdirSync(dir, { recursive: true }) as string[]).sort()) {
32
+ const file = join(dir, name);
33
+ const stat = statSync(file);
34
+ if (stat.isFile()) {
35
+ this.add(`${prefix}${name.split(sep).join('/')}`, readFileSync(file), stat.mode & 0o777);
36
+ }
37
+ }
38
+ return this;
39
+ }
40
+
41
+ add(name: string, content: Buffer | string, mode = 0o644): this {
42
+ const data = typeof content === 'string' ? Buffer.from(content) : content;
43
+ const deflated = deflateRawSync(data, { level: 9 });
44
+ const stored = deflated.length >= data.length;
45
+ const entry: ZipEntry = {
46
+ name: Buffer.from(name),
47
+ crc: ZipWriter.crc32(data),
48
+ size: data.length,
49
+ compressed: stored ? data : deflated,
50
+ method: stored ? 0 : 8,
51
+ mode,
52
+ offset: this.offset,
53
+ };
54
+ const header = Buffer.alloc(30);
55
+ header.writeUInt32LE(0x04034b50, 0);
56
+ header.writeUInt16LE(20, 4);
57
+ header.writeUInt16LE(0x0800, 6);
58
+ header.writeUInt16LE(entry.method, 8);
59
+ header.writeUInt16LE(0, 10);
60
+ header.writeUInt16LE(ZipWriter.DOS_DATE, 12);
61
+ header.writeUInt32LE(entry.crc, 14);
62
+ header.writeUInt32LE(entry.compressed.length, 18);
63
+ header.writeUInt32LE(entry.size, 22);
64
+ header.writeUInt16LE(entry.name.length, 26);
65
+ header.writeUInt16LE(0, 28);
66
+ this.push(header, entry.name, entry.compressed);
67
+ this.entries.push(entry);
68
+ return this;
69
+ }
70
+
71
+ toBuffer(): Buffer {
72
+ const start = this.offset;
73
+ const central: Buffer[] = [];
74
+ for (const entry of this.entries) {
75
+ const header = Buffer.alloc(46);
76
+ header.writeUInt32LE(0x02014b50, 0);
77
+ // Made by Unix (3), so the external attributes carry the file mode.
78
+ header.writeUInt16LE((3 << 8) | 20, 4);
79
+ header.writeUInt16LE(20, 6);
80
+ header.writeUInt16LE(0x0800, 8);
81
+ header.writeUInt16LE(entry.method, 10);
82
+ header.writeUInt16LE(0, 12);
83
+ header.writeUInt16LE(ZipWriter.DOS_DATE, 14);
84
+ header.writeUInt32LE(entry.crc, 16);
85
+ header.writeUInt32LE(entry.compressed.length, 20);
86
+ header.writeUInt32LE(entry.size, 24);
87
+ header.writeUInt16LE(entry.name.length, 28);
88
+ header.writeUInt32LE(((0o100000 | entry.mode) << 16) >>> 0, 38);
89
+ header.writeUInt32LE(entry.offset, 42);
90
+ central.push(header, entry.name);
91
+ }
92
+ const size = central.reduce((n, b) => n + b.length, 0);
93
+ const end = Buffer.alloc(22);
94
+ end.writeUInt32LE(0x06054b50, 0);
95
+ end.writeUInt16LE(this.entries.length, 8);
96
+ end.writeUInt16LE(this.entries.length, 10);
97
+ end.writeUInt32LE(size, 12);
98
+ end.writeUInt32LE(start, 16);
99
+ return Buffer.concat([...this.chunks, ...central, end]);
100
+ }
101
+
102
+ get files(): number {
103
+ return this.entries.length;
104
+ }
105
+
106
+ protected push(...buffers: Buffer[]): void {
107
+ for (const buffer of buffers) {
108
+ this.chunks.push(buffer);
109
+ this.offset += buffer.length;
110
+ }
111
+ }
112
+
113
+ static crc32(data: Buffer): number {
114
+ let crc = 0xffffffff;
115
+ for (let i = 0; i < data.length; i++) {
116
+ crc = ZipWriter.CRC_TABLE[(crc ^ data[i]) & 0xff] ^ (crc >>> 8);
117
+ }
118
+ return (crc ^ 0xffffffff) >>> 0;
119
+ }
120
+
121
+ protected static crcTable(): Uint32Array {
122
+ const table = new Uint32Array(256);
123
+ for (let n = 0; n < 256; n++) {
124
+ let c = n;
125
+ for (let k = 0; k < 8; k++) {
126
+ c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
127
+ }
128
+ table[n] = c >>> 0;
129
+ }
130
+ return table;
131
+ }
132
+ }
@@ -0,0 +1,174 @@
1
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
2
+ import { join, relative } from 'node:path';
3
+
4
+ /** Where documentation is read from: a directory of Markdown or one file, and who provides it. */
5
+ export interface DocsSource {
6
+ path: string;
7
+ /** Component or toolchain module that provides it. */
8
+ source: string;
9
+ }
10
+
11
+ /** A section of a Markdown file: from one heading to the next. */
12
+ export interface DocsSection {
13
+ /** Relative to the project root. */
14
+ file: string;
15
+ line: number;
16
+ title: string;
17
+ source: string;
18
+ text: string;
19
+ }
20
+
21
+ export interface DocsHit extends Omit<DocsSection, 'text'> {
22
+ score: number;
23
+ text: string;
24
+ /** The section was longer than the text. */
25
+ truncated?: true;
26
+ }
27
+
28
+ /**
29
+ * Searches the Markdown that ships with the installed components and toolchain modules (README.md
30
+ * and `docs/` of each component, `cell.addDocs()` directories), so agents read the docs of the
31
+ * versions the project uses (docs/design/agent-first.md R7). Sections are ranked by how many query
32
+ * words they contain, headings counting more.
33
+ */
34
+ export class DocsIndex {
35
+ static readonly MAX_TEXT = 1500;
36
+ static readonly MAX_FILES = 2000;
37
+
38
+ protected sections?: DocsSection[];
39
+ protected fileCount = 0;
40
+
41
+ constructor(
42
+ protected readonly root: string,
43
+ protected readonly sources: DocsSource[],
44
+ ) {}
45
+
46
+ /** README.md and docs/ of each component directory, then the modules' docs directories. */
47
+ static sourcesOf(components: readonly { name: string; dir: string }[], moduleDocs: readonly { source: string; value: string }[]): DocsSource[] {
48
+ return [
49
+ ...components.flatMap(c => [
50
+ { path: join(c.dir, 'README.md'), source: c.name },
51
+ { path: join(c.dir, 'docs'), source: c.name },
52
+ ]),
53
+ ...moduleDocs.map(d => ({ path: d.value, source: d.source })),
54
+ ].filter(s => existsSync(s.path));
55
+ }
56
+
57
+ get files(): number {
58
+ this.load();
59
+ return this.fileCount;
60
+ }
61
+
62
+ search(query: string, limit = 5): DocsHit[] {
63
+ const terms = DocsIndex.terms(query);
64
+ if (terms.length === 0) {
65
+ return [];
66
+ }
67
+ const hits: DocsHit[] = [];
68
+ for (const section of this.load()) {
69
+ const title = section.title.toLowerCase();
70
+ const body = section.text.toLowerCase();
71
+ let score = 0;
72
+ let matched = 0;
73
+ for (const term of terms) {
74
+ const inTitle = DocsIndex.count(title, term);
75
+ const inBody = Math.min(DocsIndex.count(body, term), 10);
76
+ if (inTitle + inBody > 0) {
77
+ matched++;
78
+ score += inTitle * 5 + inBody;
79
+ }
80
+ }
81
+ if (matched > 0) {
82
+ // Sections with every word come first.
83
+ score = Math.round(score * (matched / terms.length) ** 2 * 100) / 100;
84
+ const truncated = section.text.length > DocsIndex.MAX_TEXT;
85
+ hits.push({
86
+ ...section,
87
+ score,
88
+ text: truncated ? `${section.text.slice(0, DocsIndex.MAX_TEXT)}…` : section.text,
89
+ ...(truncated ? { truncated: true as const } : {}),
90
+ });
91
+ }
92
+ }
93
+ return hits.sort((a, b) => b.score - a.score || a.file.localeCompare(b.file) || a.line - b.line).slice(0, limit);
94
+ }
95
+
96
+ /** Lowercased words of the query; words of two characters or fewer only when nothing else is left. */
97
+ static terms(query: string): string[] {
98
+ const words = [
99
+ ...new Set(
100
+ query
101
+ .toLowerCase()
102
+ .split(/[\s,;:!?()[\]{}"'\x60]+/)
103
+ .filter(Boolean),
104
+ ),
105
+ ];
106
+ const long = words.filter(w => w.length > 2);
107
+ return long.length > 0 ? long : words;
108
+ }
109
+
110
+ protected static count(text: string, term: string): number {
111
+ let n = 0;
112
+ for (let i = text.indexOf(term); i !== -1; i = text.indexOf(term, i + term.length)) {
113
+ n++;
114
+ }
115
+ return n;
116
+ }
117
+
118
+ protected load(): DocsSection[] {
119
+ if (!this.sections) {
120
+ this.sections = [];
121
+ const seen = new Set<string>();
122
+ for (const { path, source } of this.sources) {
123
+ for (const file of this.markdownFiles(path)) {
124
+ if (seen.has(file) || seen.size >= DocsIndex.MAX_FILES) {
125
+ continue;
126
+ }
127
+ seen.add(file);
128
+ this.sections.push(...DocsIndex.split(readFileSync(file, 'utf8'), relative(this.root, file) || file, source));
129
+ }
130
+ }
131
+ this.fileCount = seen.size;
132
+ }
133
+ return this.sections;
134
+ }
135
+
136
+ protected markdownFiles(path: string): string[] {
137
+ if (statSync(path).isFile()) {
138
+ return /\.mdx?$/i.test(path) ? [path] : [];
139
+ }
140
+ return (readdirSync(path, { recursive: true }) as string[])
141
+ .filter(name => /\.mdx?$/i.test(name) && !name.split(/[\\/]/).includes('node_modules'))
142
+ .map(name => join(path, name))
143
+ .filter(file => statSync(file).isFile())
144
+ .sort();
145
+ }
146
+
147
+ /** Splits Markdown at headings, ignoring `#` lines inside fenced code. */
148
+ static split(markdown: string, file: string, source: string): DocsSection[] {
149
+ const sections: DocsSection[] = [];
150
+ let current: DocsSection = { file, line: 1, title: file, source, text: '' };
151
+ const lines: string[] = [];
152
+ let fence = false;
153
+ const flush = () => {
154
+ current.text = lines.join('\n').trim();
155
+ if (current.text || current.title !== file) {
156
+ sections.push(current);
157
+ }
158
+ lines.length = 0;
159
+ };
160
+ markdown.split(/\r?\n/).forEach((line, i) => {
161
+ if (/^\s*(\x60\x60\x60|~~~)/.test(line)) {
162
+ fence = !fence;
163
+ }
164
+ const heading = fence ? null : /^#{1,6}\s+(.+?)\s*#*\s*$/.exec(line);
165
+ if (heading) {
166
+ flush();
167
+ current = { file, line: i + 1, title: heading[1], source, text: '' };
168
+ }
169
+ lines.push(line);
170
+ });
171
+ flush();
172
+ return sections;
173
+ }
174
+ }
@@ -0,0 +1,94 @@
1
+ import { CellError, type CellEventName, EVENT_RULES, type GateResult } from '@celljs/kit';
2
+
3
+ export type EventHandler = (event: any) => unknown;
4
+
5
+ interface Subscription {
6
+ handler: EventHandler;
7
+ /** Who registered the handler: a module name or `hooks`; reported when it fails. */
8
+ source: string;
9
+ }
10
+
11
+ /**
12
+ * Dispatches toolchain events by the fixed rule of each event (docs/design/modules.md §3.2). Handlers
13
+ * run one after another in registration order; a dispatch works on a snapshot of the handlers.
14
+ */
15
+ export class EventBus {
16
+ protected readonly handlers = new Map<CellEventName, Subscription[]>();
17
+
18
+ /**
19
+ * @param onNotifyError where failures of notification handlers go instead of failing the dispatch:
20
+ * `cell dev` keeps running (docs/design/modules.md §3.4); builds leave it unset and fail.
21
+ */
22
+ constructor(protected readonly onNotifyError?: (error: CellError) => void) {}
23
+
24
+ on(event: CellEventName, handler: EventHandler, source = 'unknown'): () => void {
25
+ const list = this.handlers.get(event) ?? [];
26
+ const subscription = { handler, source };
27
+ this.handlers.set(event, [...list, subscription]);
28
+ return () =>
29
+ this.handlers.set(
30
+ event,
31
+ (this.handlers.get(event) ?? []).filter(s => s !== subscription),
32
+ );
33
+ }
34
+
35
+ /** Notification and mutation events: every handler runs; the first failure stops the dispatch. */
36
+ async emit<E extends object>(event: CellEventName, payload: E): Promise<E> {
37
+ if (EVENT_RULES[event] === 'gate') {
38
+ throw new Error(`${event} is a gate event; dispatch it with gate().`);
39
+ }
40
+ for (const { handler, source } of this.snapshot(event)) {
41
+ try {
42
+ await handler(payload);
43
+ } catch (error) {
44
+ const failure = EventBus.handlerError(event, source, error);
45
+ if (this.onNotifyError && EVENT_RULES[event] === 'notify') {
46
+ this.onNotifyError(failure);
47
+ continue;
48
+ }
49
+ throw failure;
50
+ }
51
+ }
52
+ return payload;
53
+ }
54
+
55
+ /** Gate events: the first handler returning `{ cancel: true }` or throwing (fail closed) stops the operation. */
56
+ async gate(event: CellEventName, payload: object): Promise<GateResult | undefined> {
57
+ if (EVENT_RULES[event] !== 'gate') {
58
+ throw new Error(`${event} is not a gate event; dispatch it with emit().`);
59
+ }
60
+ for (const { handler, source } of this.snapshot(event)) {
61
+ let result: unknown;
62
+ try {
63
+ result = await handler(payload);
64
+ } catch (error) {
65
+ return {
66
+ cancel: true,
67
+ reason: `${source} failed on ${event}: ${CellError.is(error) ? error.message : String((error as Error)?.message ?? error)}`,
68
+ };
69
+ }
70
+ const gate = result as Partial<GateResult> | undefined;
71
+ if (gate?.cancel === true) {
72
+ return { cancel: true, reason: gate.reason ?? `cancelled by ${source}` };
73
+ }
74
+ }
75
+ return undefined;
76
+ }
77
+
78
+ protected snapshot(event: CellEventName): Subscription[] {
79
+ return [...(this.handlers.get(event) ?? [])];
80
+ }
81
+
82
+ /** Cell errors keep their code; anything else becomes `CELL_MODULE_ERROR` naming the source. */
83
+ static handlerError(event: CellEventName, source: string, error: unknown): CellError {
84
+ if (CellError.is(error)) {
85
+ return error;
86
+ }
87
+ return new CellError({
88
+ code: 'CELL_MODULE_ERROR',
89
+ message: `${source} failed on ${event}: ${(error as Error)?.message ?? String(error)}`,
90
+ hint: `Fix the ${event} handler of ${source}.`,
91
+ cause: error,
92
+ });
93
+ }
94
+ }
@@ -0,0 +1,78 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { delimiter, dirname, join } from 'node:path';
3
+ import { CellError, EVENT_RULES, type HookableEventName } from '@celljs/kit';
4
+ import type { EventBus } from './event-bus.js';
5
+
6
+ export interface HookRunnerOptions {
7
+ root: string;
8
+ preset: string;
9
+ mode: string[];
10
+ /** Absolute output directory, passed to commands as `CELL_OUT_DIR`. */
11
+ outDir: string;
12
+ /** Send command output to stderr, keeping stdout for the JSON result. */
13
+ quiet?: boolean;
14
+ env?: NodeJS.ProcessEnv;
15
+ }
16
+
17
+ /**
18
+ * Runs the shell commands of cell.config.ts `hooks` on their events: in the project root, without
19
+ * standard input, with `CELL_EVENT`, `CELL_PRESET`, `CELL_MODE` and `CELL_OUT_DIR` set. A failing command cancels a
20
+ * gate event and fails a notification event.
21
+ */
22
+ export class HookRunner {
23
+ constructor(protected readonly options: HookRunnerOptions) {}
24
+
25
+ register(bus: EventBus, hooks: Partial<Record<HookableEventName, string>>): void {
26
+ for (const [event, command] of Object.entries(hooks) as [HookableEventName, string][]) {
27
+ bus.on(event, () => this.handle(event, command), 'hooks');
28
+ }
29
+ }
30
+
31
+ protected async handle(event: HookableEventName, command: string): Promise<unknown> {
32
+ const code = await this.exec(event, command);
33
+ if (code === 0) {
34
+ return undefined;
35
+ }
36
+ if (EVENT_RULES[event] === 'gate') {
37
+ return { cancel: true, reason: `hooks['${event}'] (${command}) exited with code ${code}` };
38
+ }
39
+ throw new CellError({
40
+ code: 'CELL_HOOK_FAILED',
41
+ message: `hooks['${event}'] (${command}) exited with code ${code}.`,
42
+ hint: 'Fix the command, or run it by hand in the project root to see the failure.',
43
+ });
44
+ }
45
+
46
+ /** Like package.json scripts: `node_modules/.bin` of the project and its ancestors come first on PATH. */
47
+ static withLocalBins(env: NodeJS.ProcessEnv, root: string): NodeJS.ProcessEnv {
48
+ const key = Object.keys(env).find(k => k.toUpperCase() === 'PATH') ?? 'PATH';
49
+ const bins: string[] = [];
50
+ for (let dir = root; ; dir = dirname(dir)) {
51
+ bins.push(join(dir, 'node_modules', '.bin'));
52
+ if (dirname(dir) === dir) {
53
+ break;
54
+ }
55
+ }
56
+ return { ...env, [key]: [...bins, env[key]].filter(Boolean).join(delimiter) };
57
+ }
58
+
59
+ exec(event: HookableEventName, command: string): Promise<number> {
60
+ const { root, preset, mode, outDir, quiet, env } = this.options;
61
+ return new Promise((resolve, reject) => {
62
+ const child = spawn(command, {
63
+ shell: true,
64
+ cwd: root,
65
+ env: {
66
+ ...HookRunner.withLocalBins(env ?? process.env, root),
67
+ CELL_EVENT: event,
68
+ CELL_PRESET: preset,
69
+ CELL_MODE: mode.join(','),
70
+ CELL_OUT_DIR: outDir,
71
+ },
72
+ stdio: ['ignore', quiet ? 2 : 'inherit', 'inherit'],
73
+ });
74
+ child.on('error', reject);
75
+ child.on('close', (code, signal) => resolve(code ?? (signal ? 128 : 1)));
76
+ });
77
+ }
78
+ }