movehat 0.1.9 → 0.2.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 (445) hide show
  1. package/README.md +2 -2
  2. package/dist/__tests__/deployContract.test.d.ts +2 -0
  3. package/dist/__tests__/deployContract.test.d.ts.map +1 -0
  4. package/dist/__tests__/deployContract.test.js +368 -0
  5. package/dist/__tests__/deployContract.test.js.map +1 -0
  6. package/dist/__tests__/errors.test.d.ts +2 -0
  7. package/dist/__tests__/errors.test.d.ts.map +1 -0
  8. package/dist/__tests__/errors.test.js +46 -0
  9. package/dist/__tests__/errors.test.js.map +1 -0
  10. package/dist/__tests__/fixtures/sigint-deploy-harness.d.ts +24 -0
  11. package/dist/__tests__/fixtures/sigint-deploy-harness.d.ts.map +1 -0
  12. package/dist/__tests__/fixtures/sigint-deploy-harness.js +82 -0
  13. package/dist/__tests__/fixtures/sigint-deploy-harness.js.map +1 -0
  14. package/dist/__tests__/fork/api.test.d.ts +2 -0
  15. package/dist/__tests__/fork/api.test.d.ts.map +1 -0
  16. package/dist/__tests__/fork/api.test.js +110 -0
  17. package/dist/__tests__/fork/api.test.js.map +1 -0
  18. package/dist/__tests__/harness/Harness.createLive.test.d.ts +2 -0
  19. package/dist/__tests__/harness/Harness.createLive.test.d.ts.map +1 -0
  20. package/dist/__tests__/harness/Harness.createLive.test.js +53 -0
  21. package/dist/__tests__/harness/Harness.createLive.test.js.map +1 -0
  22. package/dist/__tests__/harness/Harness.proxy.test.d.ts +2 -0
  23. package/dist/__tests__/harness/Harness.proxy.test.d.ts.map +1 -0
  24. package/dist/__tests__/harness/Harness.proxy.test.js +93 -0
  25. package/dist/__tests__/harness/Harness.proxy.test.js.map +1 -0
  26. package/dist/__tests__/harness/_fixture.d.ts +54 -0
  27. package/dist/__tests__/harness/_fixture.d.ts.map +1 -0
  28. package/dist/__tests__/harness/_fixture.js +69 -0
  29. package/dist/__tests__/harness/_fixture.js.map +1 -0
  30. package/dist/__tests__/harness/codeObject.deploy.test.d.ts +2 -0
  31. package/dist/__tests__/harness/codeObject.deploy.test.d.ts.map +1 -0
  32. package/dist/__tests__/harness/codeObject.deploy.test.js +288 -0
  33. package/dist/__tests__/harness/codeObject.deploy.test.js.map +1 -0
  34. package/dist/__tests__/harness/codeObject.upgrade.test.d.ts +2 -0
  35. package/dist/__tests__/harness/codeObject.upgrade.test.d.ts.map +1 -0
  36. package/dist/__tests__/harness/codeObject.upgrade.test.js +138 -0
  37. package/dist/__tests__/harness/codeObject.upgrade.test.js.map +1 -0
  38. package/dist/__tests__/harness/script.test.d.ts +2 -0
  39. package/dist/__tests__/harness/script.test.d.ts.map +1 -0
  40. package/dist/__tests__/harness/script.test.js +219 -0
  41. package/dist/__tests__/harness/script.test.js.map +1 -0
  42. package/dist/__tests__/harness/view.test.d.ts +2 -0
  43. package/dist/__tests__/harness/view.test.d.ts.map +1 -0
  44. package/dist/__tests__/harness/view.test.js +92 -0
  45. package/dist/__tests__/harness/view.test.js.map +1 -0
  46. package/dist/__tests__/runtime.test.d.ts +2 -0
  47. package/dist/__tests__/runtime.test.d.ts.map +1 -0
  48. package/dist/__tests__/runtime.test.js +141 -0
  49. package/dist/__tests__/runtime.test.js.map +1 -0
  50. package/dist/cli.js +2 -1
  51. package/dist/cli.js.map +1 -1
  52. package/dist/commands/__tests__/compile.test.d.ts +2 -0
  53. package/dist/commands/__tests__/compile.test.d.ts.map +1 -0
  54. package/dist/commands/__tests__/compile.test.js +351 -0
  55. package/dist/commands/__tests__/compile.test.js.map +1 -0
  56. package/dist/commands/__tests__/init.test.d.ts +2 -0
  57. package/dist/commands/__tests__/init.test.d.ts.map +1 -0
  58. package/dist/commands/__tests__/init.test.js +101 -0
  59. package/dist/commands/__tests__/init.test.js.map +1 -0
  60. package/dist/commands/__tests__/run.test.d.ts +2 -0
  61. package/dist/commands/__tests__/run.test.d.ts.map +1 -0
  62. package/dist/commands/__tests__/run.test.js +166 -0
  63. package/dist/commands/__tests__/run.test.js.map +1 -0
  64. package/dist/commands/__tests__/test-move.test.d.ts +2 -0
  65. package/dist/commands/__tests__/test-move.test.d.ts.map +1 -0
  66. package/dist/commands/__tests__/test-move.test.js +59 -0
  67. package/dist/commands/__tests__/test-move.test.js.map +1 -0
  68. package/dist/commands/__tests__/test.test.d.ts +2 -0
  69. package/dist/commands/__tests__/test.test.d.ts.map +1 -0
  70. package/dist/commands/__tests__/test.test.js +168 -0
  71. package/dist/commands/__tests__/test.test.js.map +1 -0
  72. package/dist/commands/__tests__/update.test.d.ts +2 -0
  73. package/dist/commands/__tests__/update.test.d.ts.map +1 -0
  74. package/dist/commands/__tests__/update.test.js +176 -0
  75. package/dist/commands/__tests__/update.test.js.map +1 -0
  76. package/dist/commands/compile.d.ts +7 -1
  77. package/dist/commands/compile.d.ts.map +1 -1
  78. package/dist/commands/compile.js +150 -33
  79. package/dist/commands/compile.js.map +1 -1
  80. package/dist/commands/fork/__tests__/create.test.d.ts +2 -0
  81. package/dist/commands/fork/__tests__/create.test.d.ts.map +1 -0
  82. package/dist/commands/fork/__tests__/create.test.js +108 -0
  83. package/dist/commands/fork/__tests__/create.test.js.map +1 -0
  84. package/dist/commands/fork/__tests__/fund.test.d.ts +2 -0
  85. package/dist/commands/fork/__tests__/fund.test.d.ts.map +1 -0
  86. package/dist/commands/fork/__tests__/fund.test.js +72 -0
  87. package/dist/commands/fork/__tests__/fund.test.js.map +1 -0
  88. package/dist/commands/fork/__tests__/list.test.d.ts +2 -0
  89. package/dist/commands/fork/__tests__/list.test.d.ts.map +1 -0
  90. package/dist/commands/fork/__tests__/list.test.js +119 -0
  91. package/dist/commands/fork/__tests__/list.test.js.map +1 -0
  92. package/dist/commands/fork/__tests__/serve.test.d.ts +2 -0
  93. package/dist/commands/fork/__tests__/serve.test.d.ts.map +1 -0
  94. package/dist/commands/fork/__tests__/serve.test.js +97 -0
  95. package/dist/commands/fork/__tests__/serve.test.js.map +1 -0
  96. package/dist/commands/fork/__tests__/view-resource.test.d.ts +2 -0
  97. package/dist/commands/fork/__tests__/view-resource.test.d.ts.map +1 -0
  98. package/dist/commands/fork/__tests__/view-resource.test.js +77 -0
  99. package/dist/commands/fork/__tests__/view-resource.test.js.map +1 -0
  100. package/dist/commands/fork/create.d.ts +1 -1
  101. package/dist/commands/fork/create.d.ts.map +1 -1
  102. package/dist/commands/fork/create.js +3 -2
  103. package/dist/commands/fork/create.js.map +1 -1
  104. package/dist/commands/fork/fund.d.ts.map +1 -1
  105. package/dist/commands/fork/fund.js +15 -8
  106. package/dist/commands/fork/fund.js.map +1 -1
  107. package/dist/commands/fork/list.d.ts.map +1 -1
  108. package/dist/commands/fork/list.js +2 -1
  109. package/dist/commands/fork/list.js.map +1 -1
  110. package/dist/commands/fork/serve.d.ts +1 -0
  111. package/dist/commands/fork/serve.d.ts.map +1 -1
  112. package/dist/commands/fork/serve.js +4 -2
  113. package/dist/commands/fork/serve.js.map +1 -1
  114. package/dist/commands/fork/view-resource.d.ts.map +1 -1
  115. package/dist/commands/fork/view-resource.js +10 -5
  116. package/dist/commands/fork/view-resource.js.map +1 -1
  117. package/dist/commands/run.d.ts +15 -0
  118. package/dist/commands/run.d.ts.map +1 -1
  119. package/dist/commands/run.js +50 -27
  120. package/dist/commands/run.js.map +1 -1
  121. package/dist/commands/test-move.d.ts.map +1 -1
  122. package/dist/commands/test-move.js +3 -2
  123. package/dist/commands/test-move.js.map +1 -1
  124. package/dist/commands/test.js +52 -46
  125. package/dist/commands/test.js.map +1 -1
  126. package/dist/commands/update.d.ts.map +1 -1
  127. package/dist/commands/update.js +15 -13
  128. package/dist/commands/update.js.map +1 -1
  129. package/dist/core/AccountManager.d.ts +1 -1
  130. package/dist/core/AccountManager.d.ts.map +1 -1
  131. package/dist/core/AccountManager.js +20 -7
  132. package/dist/core/AccountManager.js.map +1 -1
  133. package/dist/core/Publisher.d.ts +31 -0
  134. package/dist/core/Publisher.d.ts.map +1 -0
  135. package/dist/core/Publisher.js +248 -0
  136. package/dist/core/Publisher.js.map +1 -0
  137. package/dist/core/__tests__/AccountManager.test.d.ts +2 -0
  138. package/dist/core/__tests__/AccountManager.test.d.ts.map +1 -0
  139. package/dist/core/__tests__/AccountManager.test.js +239 -0
  140. package/dist/core/__tests__/AccountManager.test.js.map +1 -0
  141. package/dist/core/__tests__/config.test.d.ts +2 -0
  142. package/dist/core/__tests__/config.test.d.ts.map +1 -0
  143. package/dist/core/__tests__/config.test.js +311 -0
  144. package/dist/core/__tests__/config.test.js.map +1 -0
  145. package/dist/core/__tests__/deployments.test.d.ts +2 -0
  146. package/dist/core/__tests__/deployments.test.d.ts.map +1 -0
  147. package/dist/core/__tests__/deployments.test.js +201 -0
  148. package/dist/core/__tests__/deployments.test.js.map +1 -0
  149. package/dist/core/__tests__/shell.test.d.ts +2 -0
  150. package/dist/core/__tests__/shell.test.d.ts.map +1 -0
  151. package/dist/core/__tests__/shell.test.js +107 -0
  152. package/dist/core/__tests__/shell.test.js.map +1 -0
  153. package/dist/core/config.d.ts +13 -1
  154. package/dist/core/config.d.ts.map +1 -1
  155. package/dist/core/config.js +80 -11
  156. package/dist/core/config.js.map +1 -1
  157. package/dist/core/contract.d.ts +1 -1
  158. package/dist/core/contract.d.ts.map +1 -1
  159. package/dist/core/contract.js +15 -4
  160. package/dist/core/contract.js.map +1 -1
  161. package/dist/core/deployments.d.ts +2 -2
  162. package/dist/core/deployments.d.ts.map +1 -1
  163. package/dist/core/deployments.js +8 -6
  164. package/dist/core/deployments.js.map +1 -1
  165. package/dist/core/movementProfile.d.ts +34 -0
  166. package/dist/core/movementProfile.d.ts.map +1 -0
  167. package/dist/core/movementProfile.js +150 -0
  168. package/dist/core/movementProfile.js.map +1 -0
  169. package/dist/core/shell.d.ts +23 -7
  170. package/dist/core/shell.d.ts.map +1 -1
  171. package/dist/core/shell.js +32 -14
  172. package/dist/core/shell.js.map +1 -1
  173. package/dist/errors.d.ts +35 -0
  174. package/dist/errors.d.ts.map +1 -1
  175. package/dist/errors.js +54 -0
  176. package/dist/errors.js.map +1 -1
  177. package/dist/fork/__tests__/manager.test.d.ts +2 -0
  178. package/dist/fork/__tests__/manager.test.d.ts.map +1 -0
  179. package/dist/fork/__tests__/manager.test.js +309 -0
  180. package/dist/fork/__tests__/manager.test.js.map +1 -0
  181. package/dist/fork/__tests__/server.test.d.ts +2 -0
  182. package/dist/fork/__tests__/server.test.d.ts.map +1 -0
  183. package/dist/fork/__tests__/server.test.js +54 -0
  184. package/dist/fork/__tests__/server.test.js.map +1 -0
  185. package/dist/fork/__tests__/storage.test.d.ts +2 -0
  186. package/dist/fork/__tests__/storage.test.d.ts.map +1 -0
  187. package/dist/fork/__tests__/storage.test.js +222 -0
  188. package/dist/fork/__tests__/storage.test.js.map +1 -0
  189. package/dist/fork/__tests__/test.test.d.ts +2 -0
  190. package/dist/fork/__tests__/test.test.d.ts.map +1 -0
  191. package/dist/fork/__tests__/test.test.js +81 -0
  192. package/dist/fork/__tests__/test.test.js.map +1 -0
  193. package/dist/fork/api.d.ts +14 -3
  194. package/dist/fork/api.d.ts.map +1 -1
  195. package/dist/fork/api.js +25 -14
  196. package/dist/fork/api.js.map +1 -1
  197. package/dist/fork/manager.d.ts +23 -9
  198. package/dist/fork/manager.d.ts.map +1 -1
  199. package/dist/fork/manager.js +79 -36
  200. package/dist/fork/manager.js.map +1 -1
  201. package/dist/fork/server.d.ts +11 -3
  202. package/dist/fork/server.d.ts.map +1 -1
  203. package/dist/fork/server.js +45 -13
  204. package/dist/fork/server.js.map +1 -1
  205. package/dist/fork/storage.d.ts +4 -4
  206. package/dist/fork/storage.d.ts.map +1 -1
  207. package/dist/fork/storage.js +7 -9
  208. package/dist/fork/storage.js.map +1 -1
  209. package/dist/fork/test.d.ts +13 -4
  210. package/dist/fork/test.d.ts.map +1 -1
  211. package/dist/fork/test.js +36 -27
  212. package/dist/fork/test.js.map +1 -1
  213. package/dist/harness/Harness.d.ts +124 -0
  214. package/dist/harness/Harness.d.ts.map +1 -0
  215. package/dist/harness/Harness.js +193 -0
  216. package/dist/harness/Harness.js.map +1 -0
  217. package/dist/harness/codeObject.d.ts +31 -0
  218. package/dist/harness/codeObject.d.ts.map +1 -0
  219. package/dist/harness/codeObject.js +271 -0
  220. package/dist/harness/codeObject.js.map +1 -0
  221. package/dist/harness/errors.d.ts +14 -0
  222. package/dist/harness/errors.d.ts.map +1 -0
  223. package/dist/harness/errors.js +22 -0
  224. package/dist/harness/errors.js.map +1 -0
  225. package/dist/harness/index.d.ts +4 -0
  226. package/dist/harness/index.d.ts.map +1 -0
  227. package/dist/harness/index.js +3 -0
  228. package/dist/harness/index.js.map +1 -0
  229. package/dist/harness/proxy.d.ts +7 -0
  230. package/dist/harness/proxy.d.ts.map +1 -0
  231. package/dist/harness/proxy.js +36 -0
  232. package/dist/harness/proxy.js.map +1 -0
  233. package/dist/harness/script.d.ts +21 -0
  234. package/dist/harness/script.d.ts.map +1 -0
  235. package/dist/harness/script.js +155 -0
  236. package/dist/harness/script.js.map +1 -0
  237. package/dist/harness/view.d.ts +22 -0
  238. package/dist/harness/view.d.ts.map +1 -0
  239. package/dist/harness/view.js +28 -0
  240. package/dist/harness/view.js.map +1 -0
  241. package/dist/helpers/__tests__/semver-utils.test.d.ts +2 -0
  242. package/dist/helpers/__tests__/semver-utils.test.d.ts.map +1 -0
  243. package/dist/helpers/__tests__/semver-utils.test.js +103 -0
  244. package/dist/helpers/__tests__/semver-utils.test.js.map +1 -0
  245. package/dist/helpers/index.d.ts +3 -2
  246. package/dist/helpers/index.d.ts.map +1 -1
  247. package/dist/helpers/index.js +2 -2
  248. package/dist/helpers/index.js.map +1 -1
  249. package/dist/helpers/move-tests.d.ts +3 -3
  250. package/dist/helpers/move-tests.d.ts.map +1 -1
  251. package/dist/helpers/move-tests.js +21 -20
  252. package/dist/helpers/move-tests.js.map +1 -1
  253. package/dist/helpers/npm-registry.d.ts.map +1 -1
  254. package/dist/helpers/npm-registry.js +1 -3
  255. package/dist/helpers/npm-registry.js.map +1 -1
  256. package/dist/helpers/semver-utils.d.ts.map +1 -1
  257. package/dist/helpers/semver-utils.js +4 -3
  258. package/dist/helpers/semver-utils.js.map +1 -1
  259. package/dist/helpers/setup.d.ts.map +1 -1
  260. package/dist/helpers/setup.js +6 -4
  261. package/dist/helpers/setup.js.map +1 -1
  262. package/dist/helpers/setupLocalTesting.d.ts +32 -27
  263. package/dist/helpers/setupLocalTesting.d.ts.map +1 -1
  264. package/dist/helpers/setupLocalTesting.js +179 -180
  265. package/dist/helpers/setupLocalTesting.js.map +1 -1
  266. package/dist/helpers/testFixtures.d.ts +19 -53
  267. package/dist/helpers/testFixtures.d.ts.map +1 -1
  268. package/dist/helpers/testFixtures.js +89 -107
  269. package/dist/helpers/testFixtures.js.map +1 -1
  270. package/dist/index.d.ts +4 -2
  271. package/dist/index.d.ts.map +1 -1
  272. package/dist/index.js +7 -3
  273. package/dist/index.js.map +1 -1
  274. package/dist/node/LocalNodeManager.d.ts +9 -1
  275. package/dist/node/LocalNodeManager.d.ts.map +1 -1
  276. package/dist/node/LocalNodeManager.js +75 -58
  277. package/dist/node/LocalNodeManager.js.map +1 -1
  278. package/dist/node/__tests__/LocalNodeManager.test.d.ts +2 -0
  279. package/dist/node/__tests__/LocalNodeManager.test.d.ts.map +1 -0
  280. package/dist/node/__tests__/LocalNodeManager.test.js +349 -0
  281. package/dist/node/__tests__/LocalNodeManager.test.js.map +1 -0
  282. package/dist/runtime.d.ts +12 -15
  283. package/dist/runtime.d.ts.map +1 -1
  284. package/dist/runtime.js +28 -239
  285. package/dist/runtime.js.map +1 -1
  286. package/dist/templates/README.md +1 -1
  287. package/dist/templates/movehat.config.ts +10 -0
  288. package/dist/templates/package.json +2 -1
  289. package/dist/templates/scripts/deploy-counter.ts +46 -38
  290. package/dist/templates/tests/Counter.test.ts +39 -51
  291. package/dist/templates/types/movehat.d.ts +6 -9
  292. package/dist/types/config.d.ts +8 -0
  293. package/dist/types/config.d.ts.map +1 -1
  294. package/dist/types/fork.d.ts +7 -1
  295. package/dist/types/fork.d.ts.map +1 -1
  296. package/dist/types/harness.d.ts +166 -0
  297. package/dist/types/harness.d.ts.map +1 -0
  298. package/dist/types/harness.js +2 -0
  299. package/dist/types/harness.js.map +1 -0
  300. package/dist/types/runtime.d.ts +7 -1
  301. package/dist/types/runtime.d.ts.map +1 -1
  302. package/dist/ui/__tests__/colors.test.d.ts +2 -0
  303. package/dist/ui/__tests__/colors.test.d.ts.map +1 -0
  304. package/dist/ui/__tests__/colors.test.js +127 -0
  305. package/dist/ui/__tests__/colors.test.js.map +1 -0
  306. package/dist/ui/colors.d.ts.map +1 -1
  307. package/dist/ui/colors.js +6 -2
  308. package/dist/ui/colors.js.map +1 -1
  309. package/dist/ui/logger.d.ts +17 -0
  310. package/dist/ui/logger.d.ts.map +1 -1
  311. package/dist/ui/logger.js +22 -0
  312. package/dist/ui/logger.js.map +1 -1
  313. package/dist/ui/symbols.d.ts +1 -0
  314. package/dist/ui/symbols.d.ts.map +1 -1
  315. package/dist/ui/symbols.js +7 -1
  316. package/dist/ui/symbols.js.map +1 -1
  317. package/dist/utils/__tests__/address.test.d.ts +2 -0
  318. package/dist/utils/__tests__/address.test.d.ts.map +1 -0
  319. package/dist/utils/__tests__/address.test.js +70 -0
  320. package/dist/utils/__tests__/address.test.js.map +1 -0
  321. package/dist/utils/__tests__/childProcessAdapter.test.d.ts +2 -0
  322. package/dist/utils/__tests__/childProcessAdapter.test.d.ts.map +1 -0
  323. package/dist/utils/__tests__/childProcessAdapter.test.js +217 -0
  324. package/dist/utils/__tests__/childProcessAdapter.test.js.map +1 -0
  325. package/dist/utils/__tests__/runCli.test.d.ts +2 -0
  326. package/dist/utils/__tests__/runCli.test.d.ts.map +1 -0
  327. package/dist/utils/__tests__/runCli.test.js +187 -0
  328. package/dist/utils/__tests__/runCli.test.js.map +1 -0
  329. package/dist/utils/address.d.ts +33 -0
  330. package/dist/utils/address.d.ts.map +1 -0
  331. package/dist/utils/address.js +52 -0
  332. package/dist/utils/address.js.map +1 -0
  333. package/dist/utils/childProcessAdapter.d.ts +93 -0
  334. package/dist/utils/childProcessAdapter.d.ts.map +1 -0
  335. package/dist/utils/childProcessAdapter.js +109 -0
  336. package/dist/utils/childProcessAdapter.js.map +1 -0
  337. package/dist/utils/parseCliOutput.d.ts +20 -0
  338. package/dist/utils/parseCliOutput.d.ts.map +1 -0
  339. package/dist/utils/parseCliOutput.js +26 -0
  340. package/dist/utils/parseCliOutput.js.map +1 -0
  341. package/dist/utils/redact.d.ts +15 -0
  342. package/dist/utils/redact.d.ts.map +1 -0
  343. package/dist/utils/redact.js +24 -0
  344. package/dist/utils/redact.js.map +1 -0
  345. package/dist/utils/runCli.d.ts +24 -0
  346. package/dist/utils/runCli.d.ts.map +1 -0
  347. package/dist/utils/runCli.js +37 -0
  348. package/dist/utils/runCli.js.map +1 -0
  349. package/package.json +14 -4
  350. package/src/__tests__/deployContract.test.ts +429 -0
  351. package/src/__tests__/errors.test.ts +84 -0
  352. package/src/__tests__/fixtures/sigint-deploy-harness.ts +95 -0
  353. package/src/__tests__/fork/api.test.ts +143 -0
  354. package/src/__tests__/harness/Harness.createLive.test.ts +57 -0
  355. package/src/__tests__/harness/Harness.proxy.test.ts +115 -0
  356. package/src/__tests__/harness/_fixture.ts +131 -0
  357. package/src/__tests__/harness/codeObject.deploy.test.ts +319 -0
  358. package/src/__tests__/harness/codeObject.upgrade.test.ts +156 -0
  359. package/src/__tests__/harness/script.test.ts +245 -0
  360. package/src/__tests__/harness/view.test.ts +104 -0
  361. package/src/__tests__/runtime.test.ts +182 -0
  362. package/src/cli.ts +2 -1
  363. package/src/commands/__tests__/compile.test.ts +407 -0
  364. package/src/commands/__tests__/init.test.ts +125 -0
  365. package/src/commands/__tests__/run.test.ts +192 -0
  366. package/src/commands/__tests__/test-move.test.ts +81 -0
  367. package/src/commands/__tests__/test.test.ts +204 -0
  368. package/src/commands/__tests__/update.test.ts +223 -0
  369. package/src/commands/compile.ts +168 -32
  370. package/src/commands/fork/__tests__/create.test.ts +132 -0
  371. package/src/commands/fork/__tests__/fund.test.ts +104 -0
  372. package/src/commands/fork/__tests__/list.test.ts +139 -0
  373. package/src/commands/fork/__tests__/serve.test.ts +121 -0
  374. package/src/commands/fork/__tests__/view-resource.test.ts +101 -0
  375. package/src/commands/fork/create.ts +4 -3
  376. package/src/commands/fork/fund.ts +16 -9
  377. package/src/commands/fork/list.ts +3 -2
  378. package/src/commands/fork/serve.ts +6 -3
  379. package/src/commands/fork/view-resource.ts +11 -6
  380. package/src/commands/run.ts +54 -28
  381. package/src/commands/test-move.ts +4 -3
  382. package/src/commands/test.ts +56 -44
  383. package/src/commands/update.ts +19 -16
  384. package/src/core/AccountManager.ts +23 -10
  385. package/src/core/Publisher.ts +322 -0
  386. package/src/core/__tests__/AccountManager.test.ts +290 -0
  387. package/src/core/__tests__/config.test.ts +377 -0
  388. package/src/core/__tests__/deployments.test.ts +247 -0
  389. package/src/core/__tests__/shell.test.ts +138 -0
  390. package/src/core/config.ts +96 -12
  391. package/src/core/contract.ts +13 -4
  392. package/src/core/deployments.ts +13 -11
  393. package/src/core/movementProfile.ts +179 -0
  394. package/src/core/shell.ts +34 -14
  395. package/src/errors.ts +60 -0
  396. package/src/fork/__tests__/manager.test.ts +385 -0
  397. package/src/fork/__tests__/server.test.ts +65 -0
  398. package/src/fork/__tests__/storage.test.ts +281 -0
  399. package/src/fork/__tests__/test.test.ts +97 -0
  400. package/src/fork/api.ts +28 -14
  401. package/src/fork/manager.ts +88 -43
  402. package/src/fork/server.ts +53 -19
  403. package/src/fork/storage.ts +12 -15
  404. package/src/fork/test.ts +58 -32
  405. package/src/harness/Harness.ts +228 -0
  406. package/src/harness/codeObject.ts +388 -0
  407. package/src/harness/errors.ts +22 -0
  408. package/src/harness/index.ts +3 -0
  409. package/src/harness/proxy.ts +40 -0
  410. package/src/harness/script.ts +196 -0
  411. package/src/harness/view.ts +34 -0
  412. package/src/helpers/__tests__/semver-utils.test.ts +121 -0
  413. package/src/helpers/index.ts +2 -8
  414. package/src/helpers/move-tests.ts +27 -23
  415. package/src/helpers/npm-registry.ts +4 -3
  416. package/src/helpers/semver-utils.ts +4 -3
  417. package/src/helpers/setup.ts +6 -4
  418. package/src/helpers/setupLocalTesting.ts +219 -200
  419. package/src/helpers/testFixtures.ts +106 -118
  420. package/src/index.ts +9 -3
  421. package/src/node/LocalNodeManager.ts +87 -62
  422. package/src/node/__tests__/LocalNodeManager.test.ts +452 -0
  423. package/src/runtime.ts +30 -288
  424. package/src/templates/README.md +1 -1
  425. package/src/templates/movehat.config.ts +10 -0
  426. package/src/templates/package.json +2 -1
  427. package/src/templates/scripts/deploy-counter.ts +46 -38
  428. package/src/templates/tests/Counter.test.ts +39 -51
  429. package/src/templates/types/movehat.d.ts +6 -9
  430. package/src/types/config.ts +8 -0
  431. package/src/types/fork.ts +7 -1
  432. package/src/types/harness.ts +182 -0
  433. package/src/types/runtime.ts +11 -3
  434. package/src/ui/__tests__/colors.test.ts +156 -0
  435. package/src/ui/colors.ts +5 -2
  436. package/src/ui/logger.ts +22 -0
  437. package/src/ui/symbols.ts +7 -1
  438. package/src/utils/__tests__/address.test.ts +93 -0
  439. package/src/utils/__tests__/childProcessAdapter.test.ts +266 -0
  440. package/src/utils/__tests__/runCli.test.ts +240 -0
  441. package/src/utils/address.ts +56 -0
  442. package/src/utils/childProcessAdapter.ts +215 -0
  443. package/src/utils/parseCliOutput.ts +27 -0
  444. package/src/utils/redact.ts +24 -0
  445. package/src/utils/runCli.ts +64 -0
@@ -0,0 +1,121 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { existsSync, mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+
6
+ const serverStart = vi.fn();
7
+ const serverStop = vi.fn();
8
+ const ForkServerCtor = vi.fn();
9
+ const loadUserConfigMock = vi.fn();
10
+
11
+ vi.mock("../../../fork/server.js", () => ({
12
+ ForkServer: class {
13
+ constructor(forkPath: string, port: number, host: string) {
14
+ ForkServerCtor(forkPath, port, host);
15
+ }
16
+ start = serverStart;
17
+ stop = serverStop;
18
+ },
19
+ }));
20
+
21
+ vi.mock("../../../core/config.js", () => ({
22
+ loadUserConfig: loadUserConfigMock,
23
+ }));
24
+
25
+ const { default: forkServeCommand } = await import("../serve.js");
26
+
27
+ describe("forkServeCommand", () => {
28
+ let tmpCwd: string;
29
+ let origCwd: string;
30
+ let exitSpy: ReturnType<typeof vi.spyOn>;
31
+
32
+ beforeEach(() => {
33
+ serverStart.mockReset().mockResolvedValue(undefined);
34
+ serverStop.mockReset().mockResolvedValue(undefined);
35
+ ForkServerCtor.mockReset();
36
+ loadUserConfigMock.mockReset();
37
+ origCwd = process.cwd();
38
+ tmpCwd = mkdtempSync(join(tmpdir(), "movehat-forkserve-"));
39
+ process.chdir(tmpCwd);
40
+ exitSpy = vi
41
+ .spyOn(process, "exit")
42
+ .mockImplementation(((code?: number) => {
43
+ throw new Error(`__test_exit_${code ?? 0}__`);
44
+ }) as never);
45
+ vi.spyOn(console, "log").mockImplementation(() => undefined);
46
+ vi.spyOn(console, "error").mockImplementation(() => undefined);
47
+ });
48
+
49
+ afterEach(() => {
50
+ process.chdir(origCwd);
51
+ if (existsSync(tmpCwd)) rmSync(tmpCwd, { recursive: true, force: true });
52
+ vi.restoreAllMocks();
53
+ });
54
+
55
+ it("happy path: starts server with explicit fork path + default port/host", async () => {
56
+ const forkPath = join(tmpCwd, "myfork");
57
+ mkdirSync(forkPath, { recursive: true });
58
+ writeFileSync(join(forkPath, "metadata.json"), "{}");
59
+
60
+ await forkServeCommand({ fork: forkPath });
61
+
62
+ expect(ForkServerCtor).toHaveBeenCalledWith(forkPath, 8080, "127.0.0.1");
63
+ expect(serverStart).toHaveBeenCalledTimes(1);
64
+ });
65
+
66
+ it("respects --port and --host overrides", async () => {
67
+ const forkPath = join(tmpCwd, "myfork");
68
+ mkdirSync(forkPath, { recursive: true });
69
+ writeFileSync(join(forkPath, "metadata.json"), "{}");
70
+
71
+ await forkServeCommand({ fork: forkPath, port: 9999, host: "0.0.0.0" });
72
+
73
+ expect(ForkServerCtor).toHaveBeenCalledWith(forkPath, 9999, "0.0.0.0");
74
+ });
75
+
76
+ it("resolves fork path from defaultNetwork when --fork is omitted", async () => {
77
+ loadUserConfigMock.mockResolvedValueOnce({
78
+ defaultNetwork: "testnet",
79
+ networks: { testnet: { url: "x", chainId: "testnet" } },
80
+ });
81
+ const expectedPath = join(tmpCwd, ".movehat", "forks", "testnet-fork");
82
+ mkdirSync(expectedPath, { recursive: true });
83
+ writeFileSync(join(expectedPath, "metadata.json"), "{}");
84
+
85
+ await forkServeCommand({});
86
+
87
+ // macOS /var → /private/var symlink — match by suffix.
88
+ const passedPath = ForkServerCtor.mock.calls[0]![0] as string;
89
+ expect(passedPath).toMatch(/\.movehat\/forks\/testnet-fork$/);
90
+ });
91
+
92
+ it("exits 1 when the fork's metadata.json is missing", async () => {
93
+ const forkPath = join(tmpCwd, "missing-fork");
94
+
95
+ await expect(forkServeCommand({ fork: forkPath })).rejects.toThrow(
96
+ "__test_exit_1__"
97
+ );
98
+ expect(serverStart).not.toHaveBeenCalled();
99
+ });
100
+
101
+ it("exits 1 when the configured network is unknown", async () => {
102
+ loadUserConfigMock.mockResolvedValueOnce({
103
+ defaultNetwork: "ghost",
104
+ networks: {},
105
+ });
106
+
107
+ await expect(forkServeCommand({})).rejects.toThrow("__test_exit_1__");
108
+ expect(serverStart).not.toHaveBeenCalled();
109
+ });
110
+
111
+ it("exits 1 when server.start throws", async () => {
112
+ const forkPath = join(tmpCwd, "myfork");
113
+ mkdirSync(forkPath, { recursive: true });
114
+ writeFileSync(join(forkPath, "metadata.json"), "{}");
115
+ serverStart.mockRejectedValueOnce(new Error("EADDRINUSE"));
116
+
117
+ await expect(forkServeCommand({ fork: forkPath })).rejects.toThrow(
118
+ "__test_exit_1__"
119
+ );
120
+ });
121
+ });
@@ -0,0 +1,101 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2
+
3
+ const forkManagerLoad = vi.fn();
4
+ const forkManagerGetResource = vi.fn();
5
+ const ForkManagerCtor = vi.fn();
6
+
7
+ vi.mock("../../../fork/manager.js", () => ({
8
+ ForkManager: class {
9
+ constructor(forkPath: string) {
10
+ ForkManagerCtor(forkPath);
11
+ }
12
+ load = forkManagerLoad;
13
+ getResource = forkManagerGetResource;
14
+ },
15
+ }));
16
+
17
+ const { default: forkViewResourceCommand } = await import("../view-resource.js");
18
+
19
+ describe("forkViewResourceCommand", () => {
20
+ let exitSpy: ReturnType<typeof vi.spyOn>;
21
+ let logSpy: ReturnType<typeof vi.spyOn>;
22
+
23
+ beforeEach(() => {
24
+ forkManagerLoad.mockReset();
25
+ forkManagerGetResource.mockReset();
26
+ ForkManagerCtor.mockReset();
27
+ exitSpy = vi
28
+ .spyOn(process, "exit")
29
+ .mockImplementation(((code?: number) => {
30
+ throw new Error(`__test_exit_${code ?? 0}__`);
31
+ }) as never);
32
+ logSpy = vi.spyOn(console, "log").mockImplementation(() => undefined);
33
+ vi.spyOn(console, "error").mockImplementation(() => undefined);
34
+ });
35
+
36
+ afterEach(() => {
37
+ vi.restoreAllMocks();
38
+ });
39
+
40
+ it("exits 1 when --account is missing", async () => {
41
+ await expect(
42
+ forkViewResourceCommand({
43
+ account: "",
44
+ resource: "0x1::aptos_coin::AptosCoin",
45
+ } as never)
46
+ ).rejects.toThrow("__test_exit_1__");
47
+ expect(forkManagerLoad).not.toHaveBeenCalled();
48
+ });
49
+
50
+ it("exits 1 when --resource is missing", async () => {
51
+ await expect(
52
+ forkViewResourceCommand({
53
+ account: "0xabc",
54
+ resource: "",
55
+ } as never)
56
+ ).rejects.toThrow("__test_exit_1__");
57
+ expect(forkManagerLoad).not.toHaveBeenCalled();
58
+ });
59
+
60
+ it("happy path: loads the fork, fetches the resource, JSON-pretty-prints it", async () => {
61
+ forkManagerGetResource.mockResolvedValueOnce({ coin: { value: "1000" } });
62
+
63
+ await forkViewResourceCommand({
64
+ account: "0xabc",
65
+ resource: "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>",
66
+ fork: "/tmp/fork",
67
+ } as never);
68
+
69
+ expect(forkManagerLoad).toHaveBeenCalledTimes(1);
70
+ expect(forkManagerGetResource).toHaveBeenCalledWith(
71
+ "0xabc",
72
+ "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>"
73
+ );
74
+ // Pretty-printed JSON appears in stdout.
75
+ const printed = logSpy.mock.calls.flat().join(" ");
76
+ expect(printed).toContain("1000");
77
+ });
78
+
79
+ it("defaults forkPath to <cwd>/.movehat/forks/testnet-fork when --fork is omitted", async () => {
80
+ forkManagerGetResource.mockResolvedValueOnce({});
81
+
82
+ await forkViewResourceCommand({
83
+ account: "0xabc",
84
+ resource: "0x1::a::B",
85
+ } as never);
86
+
87
+ const passed = ForkManagerCtor.mock.calls[0]![0] as string;
88
+ expect(passed).toMatch(/\.movehat\/forks\/testnet-fork$/);
89
+ });
90
+
91
+ it("exits 1 when getResource throws (resource not found)", async () => {
92
+ forkManagerGetResource.mockRejectedValueOnce(new Error("not found"));
93
+
94
+ await expect(
95
+ forkViewResourceCommand({
96
+ account: "0xabc",
97
+ resource: "0x1::missing::X",
98
+ } as never)
99
+ ).rejects.toThrow("__test_exit_1__");
100
+ });
101
+ });
@@ -12,7 +12,7 @@ interface ForkCreateOptions {
12
12
  }
13
13
 
14
14
  /**
15
- * Create a local fork of a Movement/Aptos network
15
+ * Create a local fork of a Movement network
16
16
  *
17
17
  * This command:
18
18
  * - Connects to the specified network RPC endpoint
@@ -100,9 +100,10 @@ export default async function forkCreateCommand(options: ForkCreateOptions = {})
100
100
  logger.item(formatCommand('movehat fork list'), 2);
101
101
  logger.newline();
102
102
 
103
- } catch (error: any) {
103
+ } catch (error) {
104
104
  logger.newline();
105
- logger.error(`Error: ${error.message}`);
105
+ const msg = error instanceof Error ? error.message : String(error);
106
+ logger.error(`Error: ${msg}`);
106
107
  logger.newline();
107
108
  process.exit(1);
108
109
  }
@@ -1,5 +1,6 @@
1
1
  import { join } from 'path';
2
2
  import { ForkManager } from '../../fork/manager.js';
3
+ import { logger } from '../../ui/index.js';
3
4
 
4
5
  interface ForkFundOptions {
5
6
  fork?: string;
@@ -30,11 +31,13 @@ export default async function forkFundCommand(options: ForkFundOptions) {
30
31
  const forkPath = options.fork || join(process.cwd(), '.movehat', 'forks', 'testnet-fork');
31
32
  const coinType = options.coinType || '0x1::aptos_coin::AptosCoin';
32
33
 
33
- console.log(`\n💰 Funding account in fork`);
34
- console.log(` Fork: ${forkPath}`);
35
- console.log(` Account: ${options.account}`);
36
- console.log(` Amount: ${amount}`);
37
- console.log(` Coin Type: ${coinType}\n`);
34
+ logger.newline();
35
+ logger.step("Funding account in fork");
36
+ logger.plain(` Fork: ${forkPath}`);
37
+ logger.plain(` Account: ${options.account}`);
38
+ logger.plain(` Amount: ${amount}`);
39
+ logger.plain(` Coin Type: ${coinType}`);
40
+ logger.newline();
38
41
 
39
42
  // Load fork
40
43
  const forkManager = new ForkManager(forkPath);
@@ -47,11 +50,15 @@ export default async function forkFundCommand(options: ForkFundOptions) {
47
50
  const resourceType = `0x1::coin::CoinStore<${coinType}>`;
48
51
  const coinStore = await forkManager.getResource(options.account, resourceType);
49
52
 
50
- console.log(`\n✅ Account funded successfully!`);
51
- console.log(` New balance: ${coinStore.coin.value}\n`);
53
+ logger.newline();
54
+ logger.success("Account funded successfully!");
55
+ logger.plain(` New balance: ${coinStore.coin.value}`);
56
+ logger.newline();
52
57
 
53
- } catch (error: any) {
54
- console.error(`\n❌ Error: ${error.message}\n`);
58
+ } catch (error) {
59
+ logger.newline();
60
+ logger.error(error instanceof Error ? error.message : String(error));
61
+ logger.newline();
55
62
  process.exit(1);
56
63
  }
57
64
  }
@@ -88,9 +88,10 @@ export default async function forkListCommand() {
88
88
  logger.item(formatCommand('movehat fork fund --fork <PATH> --account <ADDR> --amount <AMOUNT>'), 2);
89
89
  logger.newline();
90
90
 
91
- } catch (error: any) {
91
+ } catch (error) {
92
92
  logger.newline();
93
- logger.error(`Error: ${error.message}`);
93
+ const msg = error instanceof Error ? error.message : String(error);
94
+ logger.error(`Error: ${msg}`);
94
95
  logger.newline();
95
96
  process.exit(1);
96
97
  }
@@ -6,6 +6,7 @@ import { ForkServer } from '../../fork/server.js';
6
6
  interface ForkServeOptions {
7
7
  fork?: string;
8
8
  port?: number;
9
+ host?: string;
9
10
  }
10
11
 
11
12
  /**
@@ -43,9 +44,10 @@ export default async function forkServeCommand(options: ForkServeOptions): Promi
43
44
 
44
45
  // Get port (already validated by Commander's parsePort in cli.ts)
45
46
  const port = options.port ?? 8080;
47
+ const host = options.host ?? '127.0.0.1';
46
48
 
47
49
  // Create and start server
48
- const server = new ForkServer(forkPath, port);
50
+ const server = new ForkServer(forkPath, port, host);
49
51
 
50
52
  // Handle graceful shutdown (use 'once' to prevent duplicate shutdowns)
51
53
  const shutdown = async () => {
@@ -70,8 +72,9 @@ export default async function forkServeCommand(options: ForkServeOptions): Promi
70
72
  process.removeListener('SIGTERM', sigtermHandler);
71
73
  }
72
74
 
73
- } catch (error: any) {
74
- console.error(`\nError starting fork server:`, error.message);
75
+ } catch (error) {
76
+ const msg = error instanceof Error ? error.message : String(error);
77
+ console.error(`\nError starting fork server:`, msg);
75
78
  process.exit(1);
76
79
  }
77
80
  }
@@ -1,5 +1,6 @@
1
1
  import { join } from 'path';
2
2
  import { ForkManager } from '../../fork/manager.js';
3
+ import { logger } from '../../ui/index.js';
3
4
 
4
5
  interface ForkViewResourceOptions {
5
6
  fork?: string;
@@ -23,10 +24,12 @@ export default async function forkViewResourceCommand(options: ForkViewResourceO
23
24
  // Determine fork path
24
25
  const forkPath = options.fork || join(process.cwd(), '.movehat', 'forks', 'testnet-fork');
25
26
 
26
- console.log(`\n🔍 Viewing resource from fork`);
27
- console.log(` Fork: ${forkPath}`);
28
- console.log(` Account: ${options.account}`);
29
- console.log(` Resource: ${options.resource}\n`);
27
+ logger.newline();
28
+ logger.step("Viewing resource from fork");
29
+ logger.plain(` Fork: ${forkPath}`);
30
+ logger.plain(` Account: ${options.account}`);
31
+ logger.plain(` Resource: ${options.resource}`);
32
+ logger.newline();
30
33
 
31
34
  // Load fork
32
35
  const forkManager = new ForkManager(forkPath);
@@ -39,8 +42,10 @@ export default async function forkViewResourceCommand(options: ForkViewResourceO
39
42
  console.log(JSON.stringify(resource, null, 2));
40
43
  console.log('');
41
44
 
42
- } catch (error: any) {
43
- console.error(`\n❌ Error: ${error.message}\n`);
45
+ } catch (error) {
46
+ logger.newline();
47
+ logger.error(error instanceof Error ? error.message : String(error));
48
+ logger.newline();
44
49
  process.exit(1);
45
50
  }
46
51
  }
@@ -1,14 +1,37 @@
1
- import { spawn } from "child_process";
2
1
  import { resolve, extname, dirname, join } from "path";
3
2
  import { existsSync } from "fs";
4
3
  import { fileURLToPath } from "url";
5
4
  import { createRequire } from "module";
5
+ import { runCli } from "../utils/runCli.js";
6
+ import { logger } from "../ui/index.js";
7
+ import type { RunResult } from "../utils/childProcessAdapter.js";
8
+
9
+ /**
10
+ * Apply the exit policy for a child whose output was inherited by the
11
+ * parent. When the child dies via signal, re-raise it on the parent so
12
+ * shells and wrappers see the standard 128+N exit convention. Otherwise
13
+ * forward the numeric exit code, clamping any unexpected -1 to 1 (a -1
14
+ * would mask to 255 on Unix and drop signal-context).
15
+ *
16
+ * Exported so the branch is testable in isolation (a unit test against
17
+ * the full runCommand requires mocking fs + tsx resolution + runCli, all
18
+ * for 4 lines of policy).
19
+ *
20
+ * @internal
21
+ */
22
+ export function propagateRunResultExit(result: RunResult): void {
23
+ if (result.signal) {
24
+ process.kill(process.pid, result.signal);
25
+ return;
26
+ }
27
+ process.exit(result.exitCode >= 0 ? result.exitCode : 1);
28
+ }
6
29
 
7
30
  export default async function runCommand(scriptPath: string) {
8
31
  if (!scriptPath) {
9
- console.error("❌ Error: No script path provided");
10
- console.error("Usage: movehat run <script-path> [--network <name>]");
11
- console.error("Example: movehat run scripts/deploy-counter.ts --network testnet");
32
+ logger.error("No script path provided");
33
+ logger.plain("Usage: movehat run <script-path> [--network <name>]");
34
+ logger.plain("Example: movehat run scripts/deploy-counter.ts --network testnet");
12
35
  process.exit(1);
13
36
  }
14
37
 
@@ -16,24 +39,24 @@ export default async function runCommand(scriptPath: string) {
16
39
 
17
40
  // Check if file exists
18
41
  if (!existsSync(fullPath)) {
19
- console.error(`❌ Script not found: ${scriptPath}`);
42
+ logger.error(`Script not found: ${scriptPath}`);
20
43
  process.exit(1);
21
44
  }
22
45
 
23
46
  // Check if it's a TypeScript or JavaScript file
24
47
  const ext = extname(fullPath);
25
48
  if (![".ts", ".js", ".mjs"].includes(ext)) {
26
- console.error(`❌ Unsupported file type: ${ext}`);
27
- console.error("Supported extensions: .ts, .js, .mjs");
49
+ logger.error(`Unsupported file type: ${ext}`);
50
+ logger.plain("Supported extensions: .ts, .js, .mjs");
28
51
  process.exit(1);
29
52
  }
30
53
 
31
54
  const network = process.env.MH_CLI_NETWORK;
32
- console.log(`🚀 Running script: ${scriptPath}`);
55
+ logger.step(`Running script: ${scriptPath}`);
33
56
  if (network) {
34
- console.log(` Network: ${network}`);
57
+ logger.plain(` Network: ${network}`);
35
58
  }
36
- console.log();
59
+ logger.newline();
37
60
 
38
61
  // Find tsx binary - try multiple locations for compatibility
39
62
  // Uses require.resolve for cross-platform compatibility (works on Windows, macOS, Linux)
@@ -72,28 +95,31 @@ export default async function runCommand(scriptPath: string) {
72
95
  }
73
96
 
74
97
  if (!tsxPath) {
75
- console.error("❌ Error: tsx binary not found");
76
- console.error(" Make sure 'tsx' is installed in your project:");
77
- console.error(" npm install --save-dev tsx");
98
+ logger.error("tsx binary not found");
99
+ logger.plain(" Make sure 'tsx' is installed in your project:");
100
+ logger.plain(" npm install --save-dev tsx");
78
101
  process.exit(1);
79
102
  }
80
103
 
81
104
  // Execute script with tsx (handles both .ts and .js files)
82
- // Using 'node' to execute tsx for cross-platform compatibility
83
- const child = spawn("node", [tsxPath, fullPath], {
84
- stdio: "inherit",
85
- env: {
86
- ...process.env,
87
- // MH_CLI_NETWORK is already set by the CLI hook
88
- },
89
- });
90
-
91
- child.on("exit", (code) => {
92
- process.exit(code || 0);
93
- });
105
+ // Using 'node' to execute tsx for cross-platform compatibility.
106
+ try {
107
+ const result = await runCli(
108
+ {
109
+ command: "node",
110
+ args: [tsxPath, fullPath],
111
+ env: {
112
+ ...process.env,
113
+ // MH_CLI_NETWORK is already set by the CLI hook
114
+ },
115
+ inheritStdio: true,
116
+ },
117
+ { throwOnNonZeroExit: false }
118
+ );
94
119
 
95
- child.on("error", (error) => {
96
- console.error(`❌ Failed to execute script: ${error.message}`);
120
+ propagateRunResultExit(result);
121
+ } catch (error) {
122
+ logger.error(`Failed to execute script: ${(error as Error).message}`);
97
123
  process.exit(1);
98
- });
124
+ }
99
125
  }
@@ -16,10 +16,11 @@ export default async function testMoveCommand(options: TestMoveOptions = {}) {
16
16
  });
17
17
 
18
18
  process.exit(0);
19
- } catch (err: any) {
19
+ } catch (err) {
20
20
  console.error("\n✗ Move tests failed");
21
- if (err.message) {
22
- console.error(` ${err.message}`);
21
+ const msg = err instanceof Error ? err.message : String(err);
22
+ if (msg) {
23
+ console.error(` ${msg}`);
23
24
  }
24
25
  process.exit(1);
25
26
  }
@@ -1,9 +1,9 @@
1
- import { spawn } from "child_process";
2
1
  import { join } from "path";
3
2
  import { existsSync } from "fs";
4
3
  import prompts from "prompts";
5
4
  import { runMoveTests } from "../helpers/move-tests.js";
6
5
  import { logger, colors, symbols } from "../ui/index.js";
6
+ import { runCli } from "../utils/runCli.js";
7
7
 
8
8
  interface TestOptions {
9
9
  move?: boolean;
@@ -194,57 +194,69 @@ async function runAllTests(filter?: string): Promise<void> {
194
194
  /**
195
195
  * Run TypeScript tests using Mocha
196
196
  */
197
- function runTypeScriptTests(watch: boolean = false): Promise<void> {
198
- return new Promise((resolve, reject) => {
199
- const testDir = join(process.cwd(), "tests");
197
+ async function runTypeScriptTests(watch: boolean = false): Promise<void> {
198
+ const testDir = join(process.cwd(), "tests");
200
199
 
201
- if (!existsSync(testDir)) {
202
- console.log(`${colors.muted(symbols.info)} No TypeScript tests found ${colors.muted("(tests/ directory not found)")}`);
203
- console.log(` ${colors.muted("Skipping TypeScript tests...")}`);
204
- logger.newline();
205
- resolve();
206
- return;
207
- }
200
+ if (!existsSync(testDir)) {
201
+ console.log(`${colors.muted(symbols.info)} No TypeScript tests found ${colors.muted("(tests/ directory not found)")}`);
202
+ console.log(` ${colors.muted("Skipping TypeScript tests...")}`);
203
+ logger.newline();
204
+ return;
205
+ }
208
206
 
209
- const mochaPath = join(process.cwd(), "node_modules", ".bin", "mocha");
207
+ const mochaPath = join(process.cwd(), "node_modules", ".bin", "mocha");
210
208
 
211
- if (!existsSync(mochaPath)) {
212
- logger.error("Mocha not found in project dependencies");
213
- console.log(` ${colors.muted("Install it with:")} ${colors.info("npm install --save-dev mocha")}`);
214
- reject(new Error("Mocha not found"));
215
- return;
216
- }
209
+ if (!existsSync(mochaPath)) {
210
+ logger.error("Mocha not found in project dependencies");
211
+ console.log(` ${colors.muted("Install it with:")} ${colors.info("npm install --save-dev mocha")}`);
212
+ throw new Error("Mocha not found");
213
+ }
217
214
 
218
- const args = watch ? ["--watch"] : [];
215
+ const args = watch ? ["--watch"] : [];
219
216
 
220
- const child = spawn(mochaPath, args, {
221
- stdio: "inherit",
222
- env: {
223
- ...process.env,
217
+ // Watch mode: Mocha never exits. We fire-and-forget runCli so it owns the
218
+ // terminal until the user Ctrl+Cs the parent (which kills the child via
219
+ // inherited stdio). Attach .catch so a spawn-time failure doesn't become
220
+ // an unhandled rejection.
221
+ if (watch) {
222
+ runCli(
223
+ {
224
+ command: mochaPath,
225
+ args,
226
+ env: { ...process.env },
227
+ inheritStdio: true,
224
228
  },
229
+ { throwOnNonZeroExit: false }
230
+ ).catch((error) => {
231
+ logger.error(`Mocha watch crashed: ${(error as Error).message}`);
232
+ process.exit(1);
225
233
  });
226
234
 
227
- // In watch mode, Mocha never exits, so resolve immediately
228
- if (watch) {
229
- console.log(`${colors.info(symbols.info)} Watch mode active. Press Ctrl+C to exit.`);
230
- logger.newline();
231
- resolve();
232
- return;
233
- }
235
+ console.log(`${colors.info(symbols.info)} Watch mode active. Press Ctrl+C to exit.`);
236
+ logger.newline();
237
+ return;
238
+ }
234
239
 
235
- // Non-watch mode: wait for exit
236
- child.on("exit", (code) => {
237
- if (code === 0) {
238
- resolve();
239
- } else {
240
- const exitCode = typeof code === "number" ? code : 1;
241
- reject(new Error(`TypeScript tests failed with exit code ${exitCode}`));
242
- }
243
- });
240
+ // Non-watch mode: await the run, surface the exit code as a thrown error
241
+ // so the orchestrator above can summarize the failure.
242
+ let result;
243
+ try {
244
+ result = await runCli(
245
+ {
246
+ command: mochaPath,
247
+ args,
248
+ env: { ...process.env },
249
+ inheritStdio: true,
250
+ },
251
+ { throwOnNonZeroExit: false }
252
+ );
253
+ } catch (error) {
254
+ logger.error(`Failed to run TypeScript tests: ${(error as Error).message}`);
255
+ throw error;
256
+ }
244
257
 
245
- child.on("error", (error) => {
246
- logger.error(`Failed to run TypeScript tests: ${error.message}`);
247
- reject(error);
248
- });
249
- });
258
+ if (result.exitCode === 0) {
259
+ return;
260
+ }
261
+ throw new Error(`TypeScript tests failed with exit code ${result.exitCode}`);
250
262
  }