@hominis/fireforge 0.34.2 → 0.36.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 (360) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/README.md +43 -5
  3. package/dist/bin/fireforge.d.ts +4 -0
  4. package/dist/bin/fireforge.js +25 -6
  5. package/dist/src/cli.js +22 -5
  6. package/dist/src/commands/bootstrap-checks.js +0 -1
  7. package/dist/src/commands/bootstrap.d.ts +2 -1
  8. package/dist/src/commands/bootstrap.js +16 -7
  9. package/dist/src/commands/build.js +17 -3
  10. package/dist/src/commands/config.js +30 -10
  11. package/dist/src/commands/discard.js +24 -5
  12. package/dist/src/commands/doctor/post-rebase-audit.js +0 -1
  13. package/dist/src/commands/doctor-check-core.js +0 -1
  14. package/dist/src/commands/doctor-external-toolchains.d.ts +3 -0
  15. package/dist/src/commands/doctor-external-toolchains.js +54 -0
  16. package/dist/src/commands/doctor-furnace-jar.js +0 -1
  17. package/dist/src/commands/doctor-furnace-manifest-sync.js +0 -1
  18. package/dist/src/commands/doctor-furnace.js +2 -2
  19. package/dist/src/commands/doctor-working-tree.js +0 -1
  20. package/dist/src/commands/doctor.js +4 -1
  21. package/dist/src/commands/download.js +51 -15
  22. package/dist/src/commands/export-all.js +5 -3
  23. package/dist/src/commands/export-flow.js +12 -7
  24. package/dist/src/commands/export-placement-gate.js +0 -1
  25. package/dist/src/commands/export-placement-policy.js +0 -1
  26. package/dist/src/commands/export-shared.d.ts +5 -1
  27. package/dist/src/commands/export-shared.js +18 -6
  28. package/dist/src/commands/export.js +15 -10
  29. package/dist/src/commands/furnace/apply.js +22 -6
  30. package/dist/src/commands/furnace/chrome-doc-remove.js +0 -1
  31. package/dist/src/commands/furnace/chrome-doc-templates.js +0 -1
  32. package/dist/src/commands/furnace/chrome-doc-tests.js +0 -1
  33. package/dist/src/commands/furnace/chrome-doc.js +0 -1
  34. package/dist/src/commands/furnace/create-browser-test.js +0 -1
  35. package/dist/src/commands/furnace/create-dry-run.js +0 -1
  36. package/dist/src/commands/furnace/create-features.js +0 -1
  37. package/dist/src/commands/furnace/create-mochikit.js +0 -1
  38. package/dist/src/commands/furnace/create-readback.js +0 -1
  39. package/dist/src/commands/furnace/create-templates.js +0 -1
  40. package/dist/src/commands/furnace/create-validation.js +0 -1
  41. package/dist/src/commands/furnace/create-xpcshell.js +0 -1
  42. package/dist/src/commands/furnace/create.js +0 -1
  43. package/dist/src/commands/furnace/deploy.js +7 -83
  44. package/dist/src/commands/furnace/diff.js +0 -1
  45. package/dist/src/commands/furnace/index.js +59 -25
  46. package/dist/src/commands/furnace/init.js +0 -1
  47. package/dist/src/commands/furnace/list.js +0 -1
  48. package/dist/src/commands/furnace/override.js +0 -1
  49. package/dist/src/commands/furnace/preview.js +3 -3
  50. package/dist/src/commands/furnace/refresh.js +0 -1
  51. package/dist/src/commands/furnace/remove-state.d.ts +15 -0
  52. package/dist/src/commands/furnace/remove-state.js +47 -1
  53. package/dist/src/commands/furnace/remove.js +3 -9
  54. package/dist/src/commands/furnace/rename-browser-test.js +1 -5
  55. package/dist/src/commands/furnace/rename-helpers.d.ts +6 -0
  56. package/dist/src/commands/furnace/rename-helpers.js +30 -1
  57. package/dist/src/commands/furnace/rename-xpcshell.js +7 -6
  58. package/dist/src/commands/furnace/rename.js +15 -36
  59. package/dist/src/commands/furnace/scan.js +0 -1
  60. package/dist/src/commands/furnace/status.js +0 -1
  61. package/dist/src/commands/furnace/sync.js +76 -4
  62. package/dist/src/commands/furnace/validate.js +0 -1
  63. package/dist/src/commands/furnace/validation-output.js +0 -1
  64. package/dist/src/commands/import.js +35 -9
  65. package/dist/src/commands/lint-per-patch.js +19 -7
  66. package/dist/src/commands/lint.js +13 -3
  67. package/dist/src/commands/manifest.js +1 -2
  68. package/dist/src/commands/package.js +2 -1
  69. package/dist/src/commands/patch/compact.js +1 -1
  70. package/dist/src/commands/patch/delete.js +1 -1
  71. package/dist/src/commands/patch/index.js +1 -1
  72. package/dist/src/commands/patch/lint-ignore.js +21 -6
  73. package/dist/src/commands/patch/move-files.js +1 -1
  74. package/dist/src/commands/patch/patch-context.js +0 -1
  75. package/dist/src/commands/patch/rename.js +4 -4
  76. package/dist/src/commands/patch/reorder.js +3 -4
  77. package/dist/src/commands/patch/split-plan.js +2 -1
  78. package/dist/src/commands/patch/split.js +4 -4
  79. package/dist/src/commands/patch/staged-dependency.js +1 -1
  80. package/dist/src/commands/patch/tier.js +18 -5
  81. package/dist/src/commands/re-export-bulk-scan.js +0 -1
  82. package/dist/src/commands/re-export-files.js +1 -1
  83. package/dist/src/commands/re-export-options.js +0 -1
  84. package/dist/src/commands/re-export-scan.js +0 -1
  85. package/dist/src/commands/re-export.js +6 -4
  86. package/dist/src/commands/rebase/abort.js +2 -9
  87. package/dist/src/commands/rebase/confirm.js +0 -1
  88. package/dist/src/commands/rebase/conflict-summary.js +0 -1
  89. package/dist/src/commands/rebase/continue.js +0 -1
  90. package/dist/src/commands/rebase/index.d.ts +1 -1
  91. package/dist/src/commands/rebase/index.js +10 -15
  92. package/dist/src/commands/rebase/patch-loop.js +38 -7
  93. package/dist/src/commands/rebase/summary.js +2 -3
  94. package/dist/src/commands/rebase.js +0 -1
  95. package/dist/src/commands/register.js +1 -1
  96. package/dist/src/commands/reset.js +16 -9
  97. package/dist/src/commands/resolve.js +2 -2
  98. package/dist/src/commands/run.js +18 -6
  99. package/dist/src/commands/setup-support.js +0 -1
  100. package/dist/src/commands/setup.js +1 -2
  101. package/dist/src/commands/source.js +1 -2
  102. package/dist/src/commands/status-output.js +1 -12
  103. package/dist/src/commands/status.js +147 -133
  104. package/dist/src/commands/test-appdir.js +0 -1
  105. package/dist/src/commands/test-diagnose.js +18 -2
  106. package/dist/src/commands/test-modes.d.ts +15 -0
  107. package/dist/src/commands/test-modes.js +61 -0
  108. package/dist/src/commands/test-register.d.ts +4 -0
  109. package/dist/src/commands/test-register.js +64 -0
  110. package/dist/src/commands/test-run.d.ts +23 -7
  111. package/dist/src/commands/test-run.js +15 -14
  112. package/dist/src/commands/test.d.ts +0 -4
  113. package/dist/src/commands/test.js +95 -56
  114. package/dist/src/commands/token-coverage.js +0 -1
  115. package/dist/src/commands/token.js +1 -2
  116. package/dist/src/commands/typecheck.js +1 -1
  117. package/dist/src/commands/verify.js +3 -9
  118. package/dist/src/commands/watch.js +5 -1
  119. package/dist/src/commands/wire.js +1 -1
  120. package/dist/src/core/ast-utils.js +0 -1
  121. package/dist/src/core/brand-validation.js +0 -1
  122. package/dist/src/core/branding.js +0 -1
  123. package/dist/src/core/browser-wire.js +0 -1
  124. package/dist/src/core/build-audit-platform.js +0 -1
  125. package/dist/src/core/build-audit-registration.js +0 -1
  126. package/dist/src/core/build-audit-resolve.js +0 -1
  127. package/dist/src/core/build-audit-transforms.js +0 -1
  128. package/dist/src/core/build-audit.js +0 -1
  129. package/dist/src/core/build-baseline-types.js +0 -1
  130. package/dist/src/core/build-baseline.js +0 -1
  131. package/dist/src/core/build-prepare.js +21 -7
  132. package/dist/src/core/config-mutate.js +0 -1
  133. package/dist/src/core/config-paths.d.ts +2 -2
  134. package/dist/src/core/config-paths.js +6 -1
  135. package/dist/src/core/config-state.js +0 -1
  136. package/dist/src/core/config-validate-patch-policy.js +0 -1
  137. package/dist/src/core/config-validate-test-toolchains.d.ts +8 -0
  138. package/dist/src/core/config-validate-test-toolchains.js +105 -0
  139. package/dist/src/core/config-validate.js +3 -1
  140. package/dist/src/core/config.js +0 -1
  141. package/dist/src/core/destructive.js +0 -1
  142. package/dist/src/core/diff-hunks.js +13 -7
  143. package/dist/src/core/engine-changes.js +0 -1
  144. package/dist/src/core/engine-session-lock.d.ts +12 -0
  145. package/dist/src/core/engine-session-lock.js +45 -0
  146. package/dist/src/core/file-lock.d.ts +8 -0
  147. package/dist/src/core/file-lock.js +157 -48
  148. package/dist/src/core/firefox-archive.d.ts +4 -0
  149. package/dist/src/core/firefox-archive.js +6 -1
  150. package/dist/src/core/firefox-cache.js +67 -8
  151. package/dist/src/core/firefox-download.js +0 -1
  152. package/dist/src/core/firefox-extract.d.ts +21 -1
  153. package/dist/src/core/firefox-extract.js +178 -9
  154. package/dist/src/core/firefox-ignorefile.js +0 -1
  155. package/dist/src/core/firefox.d.ts +12 -0
  156. package/dist/src/core/firefox.js +64 -2
  157. package/dist/src/core/furnace-apply-dry-run.js +0 -1
  158. package/dist/src/core/furnace-apply-ftl.d.ts +7 -3
  159. package/dist/src/core/furnace-apply-ftl.js +10 -5
  160. package/dist/src/core/furnace-apply-helpers.js +0 -1
  161. package/dist/src/core/furnace-apply-output.js +2 -2
  162. package/dist/src/core/furnace-apply.d.ts +7 -1
  163. package/dist/src/core/furnace-apply.js +47 -13
  164. package/dist/src/core/furnace-checksum-utils.js +0 -1
  165. package/dist/src/core/furnace-config-array-utils.js +0 -1
  166. package/dist/src/core/furnace-config-custom.js +0 -1
  167. package/dist/src/core/furnace-config-order.js +0 -1
  168. package/dist/src/core/furnace-config-tokens.js +0 -1
  169. package/dist/src/core/furnace-config-validate.js +0 -1
  170. package/dist/src/core/furnace-config.d.ts +11 -0
  171. package/dist/src/core/furnace-config.js +37 -1
  172. package/dist/src/core/furnace-constants.js +0 -1
  173. package/dist/src/core/furnace-css-fragments.js +0 -1
  174. package/dist/src/core/furnace-graph-utils.js +0 -1
  175. package/dist/src/core/furnace-jsconfig.d.ts +2 -3
  176. package/dist/src/core/furnace-jsconfig.js +25 -18
  177. package/dist/src/core/furnace-marker.js +0 -1
  178. package/dist/src/core/furnace-operation.js +0 -1
  179. package/dist/src/core/furnace-refresh.js +0 -1
  180. package/dist/src/core/furnace-registration-ast.d.ts +14 -0
  181. package/dist/src/core/furnace-registration-ast.js +1 -2
  182. package/dist/src/core/furnace-registration-remove.js +0 -1
  183. package/dist/src/core/furnace-registration-validate.js +1 -5
  184. package/dist/src/core/furnace-registration.js +0 -1
  185. package/dist/src/core/furnace-rollback.js +0 -1
  186. package/dist/src/core/furnace-scanner.js +0 -1
  187. package/dist/src/core/furnace-staleness.js +0 -1
  188. package/dist/src/core/furnace-state-persist.d.ts +72 -0
  189. package/dist/src/core/furnace-state-persist.js +118 -0
  190. package/dist/src/core/furnace-step-errors.d.ts +23 -0
  191. package/dist/src/core/furnace-step-errors.js +25 -0
  192. package/dist/src/core/furnace-stories.js +0 -1
  193. package/dist/src/core/furnace-validate-accessibility.js +0 -1
  194. package/dist/src/core/furnace-validate-checks.js +0 -1
  195. package/dist/src/core/furnace-validate-compatibility.js +0 -1
  196. package/dist/src/core/furnace-validate-helpers.js +0 -1
  197. package/dist/src/core/furnace-validate-registration.js +7 -7
  198. package/dist/src/core/furnace-validate-structure.d.ts +8 -0
  199. package/dist/src/core/furnace-validate-structure.js +11 -2
  200. package/dist/src/core/furnace-validate.js +0 -1
  201. package/dist/src/core/furnace-version-drift.d.ts +6 -3
  202. package/dist/src/core/furnace-version-drift.js +6 -4
  203. package/dist/src/core/git-base.js +0 -1
  204. package/dist/src/core/git-diff.js +0 -1
  205. package/dist/src/core/git-file-ops.js +0 -1
  206. package/dist/src/core/git-status.d.ts +13 -0
  207. package/dist/src/core/git-status.js +32 -2
  208. package/dist/src/core/git.d.ts +10 -1
  209. package/dist/src/core/git.js +65 -8
  210. package/dist/src/core/license-headers.d.ts +16 -0
  211. package/dist/src/core/license-headers.js +19 -1
  212. package/dist/src/core/lint-cache.js +0 -1
  213. package/dist/src/core/lint-projection.js +0 -1
  214. package/dist/src/core/mach-build-artifacts.js +0 -1
  215. package/dist/src/core/mach-error-hints.js +27 -1
  216. package/dist/src/core/mach-mozconfig.js +0 -1
  217. package/dist/src/core/mach-python.js +0 -1
  218. package/dist/src/core/mach-resource-shim.js +0 -1
  219. package/dist/src/core/mach.js +0 -1
  220. package/dist/src/core/manifest-helpers.js +0 -1
  221. package/dist/src/core/manifest-register.js +0 -1
  222. package/dist/src/core/manifest-rules.js +0 -1
  223. package/dist/src/core/manifest-tokenizers.js +0 -1
  224. package/dist/src/core/marionette-port.d.ts +8 -0
  225. package/dist/src/core/marionette-port.js +34 -3
  226. package/dist/src/core/marionette-preflight.js +0 -1
  227. package/dist/src/core/markdown-table.js +0 -1
  228. package/dist/src/core/ownership-table.js +2 -9
  229. package/dist/src/core/parser-fallback.js +0 -1
  230. package/dist/src/core/patch-apply-fuzz.d.ts +27 -9
  231. package/dist/src/core/patch-apply-fuzz.js +71 -34
  232. package/dist/src/core/patch-apply.d.ts +30 -0
  233. package/dist/src/core/patch-apply.js +152 -39
  234. package/dist/src/core/patch-artifact-normalize.d.ts +18 -5
  235. package/dist/src/core/patch-artifact-normalize.js +19 -15
  236. package/dist/src/core/patch-export-coverage.js +0 -1
  237. package/dist/src/core/patch-export-metadata.js +0 -1
  238. package/dist/src/core/patch-export-update.js +2 -3
  239. package/dist/src/core/patch-export.d.ts +2 -6
  240. package/dist/src/core/patch-export.js +24 -48
  241. package/dist/src/core/patch-files.js +0 -1
  242. package/dist/src/core/patch-identifier-suggest.js +0 -1
  243. package/dist/src/core/patch-lint-checkjs.js +0 -1
  244. package/dist/src/core/patch-lint-chrome-jsdoc.js +0 -1
  245. package/dist/src/core/patch-lint-cross.js +0 -1
  246. package/dist/src/core/patch-lint-css.js +0 -1
  247. package/dist/src/core/patch-lint-diff-tag.js +0 -1
  248. package/dist/src/core/patch-lint-diff.d.ts +2 -1
  249. package/dist/src/core/patch-lint-diff.js +17 -32
  250. package/dist/src/core/patch-lint-imports.js +0 -1
  251. package/dist/src/core/patch-lint-jsdoc.js +0 -1
  252. package/dist/src/core/patch-lint-observer.js +0 -1
  253. package/dist/src/core/patch-lint-ownership.js +0 -1
  254. package/dist/src/core/patch-lint-reexports.js +0 -1
  255. package/dist/src/core/patch-lint.d.ts +37 -2
  256. package/dist/src/core/patch-lint.js +48 -24
  257. package/dist/src/core/patch-lock.js +0 -1
  258. package/dist/src/core/patch-manifest-consistency.js +9 -1
  259. package/dist/src/core/patch-manifest-io.d.ts +16 -0
  260. package/dist/src/core/patch-manifest-io.js +37 -12
  261. package/dist/src/core/patch-manifest-query.d.ts +6 -0
  262. package/dist/src/core/patch-manifest-query.js +27 -12
  263. package/dist/src/core/patch-manifest-resolve.js +0 -1
  264. package/dist/src/core/patch-manifest-validate.js +0 -1
  265. package/dist/src/core/patch-manifest.d.ts +1 -1
  266. package/dist/src/core/patch-manifest.js +1 -2
  267. package/dist/src/core/patch-parse.d.ts +59 -0
  268. package/dist/src/core/patch-parse.js +209 -92
  269. package/dist/src/core/patch-policy.js +0 -1
  270. package/dist/src/core/patch-registration-refs.js +16 -26
  271. package/dist/src/core/patch-source-metadata.js +0 -1
  272. package/dist/src/core/patch-transform.d.ts +4 -0
  273. package/dist/src/core/patch-transform.js +30 -38
  274. package/dist/src/core/rebase-session.js +0 -1
  275. package/dist/src/core/register-browser-content.js +0 -1
  276. package/dist/src/core/register-module.js +0 -1
  277. package/dist/src/core/register-result.js +0 -1
  278. package/dist/src/core/register-scaffold.js +0 -1
  279. package/dist/src/core/register-shared-css.js +0 -1
  280. package/dist/src/core/register-test-manifest.js +0 -1
  281. package/dist/src/core/register-xpcshell-test.js +0 -1
  282. package/dist/src/core/shared-ftl.js +0 -1
  283. package/dist/src/core/signal-critical.js +0 -1
  284. package/dist/src/core/smoke-patterns.js +0 -1
  285. package/dist/src/core/state-file.js +0 -1
  286. package/dist/src/core/status-classify.d.ts +16 -0
  287. package/dist/src/core/status-classify.js +24 -16
  288. package/dist/src/core/test-harness-crash.d.ts +64 -7
  289. package/dist/src/core/test-harness-crash.js +196 -15
  290. package/dist/src/core/test-harness-output.js +0 -1
  291. package/dist/src/core/test-path-scope.d.ts +62 -0
  292. package/dist/src/core/test-path-scope.js +148 -0
  293. package/dist/src/core/test-stale-check.js +0 -1
  294. package/dist/src/core/test-stale-symlink.js +0 -1
  295. package/dist/src/core/test-xpcshell-retry.js +0 -1
  296. package/dist/src/core/token-coverage.js +0 -1
  297. package/dist/src/core/token-dark-mode.js +0 -1
  298. package/dist/src/core/token-docs.js +0 -1
  299. package/dist/src/core/token-manager.js +0 -1
  300. package/dist/src/core/token-scaffold.js +0 -1
  301. package/dist/src/core/token-variant.js +0 -1
  302. package/dist/src/core/toolchain-preflight.d.ts +85 -0
  303. package/dist/src/core/toolchain-preflight.js +256 -0
  304. package/dist/src/core/typecheck-shim.d.ts +4 -1
  305. package/dist/src/core/typecheck-shim.js +61 -18
  306. package/dist/src/core/typecheck.js +0 -1
  307. package/dist/src/core/wire-destroy.js +0 -1
  308. package/dist/src/core/wire-dom-fragment.js +0 -1
  309. package/dist/src/core/wire-init.js +0 -1
  310. package/dist/src/core/wire-subscript.js +0 -1
  311. package/dist/src/core/wire-targets.js +0 -1
  312. package/dist/src/core/wire-utils.js +0 -1
  313. package/dist/src/core/xpcshell-appdir.js +1 -4
  314. package/dist/src/errors/base.d.ts +29 -0
  315. package/dist/src/errors/base.js +35 -1
  316. package/dist/src/errors/build.js +0 -1
  317. package/dist/src/errors/codes.d.ts +6 -0
  318. package/dist/src/errors/codes.js +6 -1
  319. package/dist/src/errors/config.js +0 -1
  320. package/dist/src/errors/download.js +2 -1
  321. package/dist/src/errors/furnace.d.ts +11 -1
  322. package/dist/src/errors/furnace.js +6 -5
  323. package/dist/src/errors/git.js +0 -1
  324. package/dist/src/errors/patch.d.ts +17 -0
  325. package/dist/src/errors/patch.js +29 -1
  326. package/dist/src/errors/rebase.js +0 -1
  327. package/dist/src/errors/run.js +1 -1
  328. package/dist/src/index.js +0 -1
  329. package/dist/src/types/cli.js +0 -1
  330. package/dist/src/types/commands/index.js +0 -1
  331. package/dist/src/types/commands/options.d.ts +20 -5
  332. package/dist/src/types/commands/options.js +0 -1
  333. package/dist/src/types/commands/patches.d.ts +8 -0
  334. package/dist/src/types/commands/patches.js +0 -1
  335. package/dist/src/types/commands/project.d.ts +11 -2
  336. package/dist/src/types/commands/project.js +0 -1
  337. package/dist/src/types/config.d.ts +32 -0
  338. package/dist/src/types/config.js +0 -1
  339. package/dist/src/types/furnace.d.ts +10 -0
  340. package/dist/src/types/furnace.js +0 -1
  341. package/dist/src/types/index.js +0 -1
  342. package/dist/src/types/typecheck.js +0 -1
  343. package/dist/src/utils/elapsed.js +0 -1
  344. package/dist/src/utils/errors.js +0 -1
  345. package/dist/src/utils/fs.js +37 -5
  346. package/dist/src/utils/logger.d.ts +7 -0
  347. package/dist/src/utils/logger.js +85 -3
  348. package/dist/src/utils/options.d.ts +15 -0
  349. package/dist/src/utils/options.js +25 -1
  350. package/dist/src/utils/package-root.js +11 -4
  351. package/dist/src/utils/parse.js +0 -1
  352. package/dist/src/utils/paths.js +0 -1
  353. package/dist/src/utils/platform.js +0 -1
  354. package/dist/src/utils/process.d.ts +33 -4
  355. package/dist/src/utils/process.js +183 -28
  356. package/dist/src/utils/regex.d.ts +13 -3
  357. package/dist/src/utils/regex.js +53 -4
  358. package/dist/src/utils/validation.d.ts +0 -12
  359. package/dist/src/utils/validation.js +13 -26
  360. package/package.json +8 -7
@@ -3,6 +3,19 @@ import * as p from '@clack/prompts';
3
3
  import pc from 'picocolors';
4
4
  /** Whether verbose mode is enabled */
5
5
  let verboseMode = false;
6
+ /**
7
+ * Whether machine-output mode is active (`--json` / `--raw`).
8
+ *
9
+ * In machine mode, stdout belongs EXCLUSIVELY to the machine-readable
10
+ * payload: all human-facing diagnostics (intro/outro banners, info, warn,
11
+ * error, steps, notes) are routed to stderr as plain unstyled lines.
12
+ * Before this mode existed, clack's log helpers wrote styled warnings to
13
+ * stdout *before* the JSON body — a truncated-directory warning during
14
+ * `status --json` broke every `JSON.parse(stdout)` consumer, and error
15
+ * objects on the machine contract were followed by a styled duplicate on
16
+ * the same stream.
17
+ */
18
+ let machineOutputMode = false;
6
19
  /**
7
20
  * Enables or disables verbose mode.
8
21
  * @param enabled - Whether to enable verbose output
@@ -10,6 +23,21 @@ let verboseMode = false;
10
23
  export function setVerbose(enabled) {
11
24
  verboseMode = enabled;
12
25
  }
26
+ /**
27
+ * Switches the logger into (or out of) machine-output mode. Commands with
28
+ * `--json`/`--raw` flags call this before producing any output.
29
+ */
30
+ export function setMachineOutputMode(enabled) {
31
+ machineOutputMode = enabled;
32
+ }
33
+ /** True when machine-output mode is active. */
34
+ export function isMachineOutputMode() {
35
+ return machineOutputMode;
36
+ }
37
+ /** Writes a plain diagnostic line to stderr (machine-mode side channel). */
38
+ function writeDiagnostic(prefix, message) {
39
+ process.stderr.write(`${prefix}${message}\n`);
40
+ }
13
41
  /**
14
42
  * Checks if verbose mode is enabled.
15
43
  * @returns True if verbose mode is enabled
@@ -22,43 +50,75 @@ function isVerbose() {
22
50
  * @param message - Message to display
23
51
  */
24
52
  export function verbose(message) {
25
- if (isVerbose()) {
26
- p.log.info(`[debug] ${message}`);
53
+ if (!isVerbose())
54
+ return;
55
+ if (machineOutputMode) {
56
+ writeDiagnostic('[debug] ', message);
57
+ return;
27
58
  }
59
+ p.log.info(`[debug] ${message}`);
28
60
  }
29
61
  function supportsInteractiveSpinner() {
30
62
  return process.stdout.isTTY && process.stderr.isTTY;
31
63
  }
32
64
  /** Displays the top-level intro banner for a command. */
33
65
  export function intro(message) {
66
+ if (machineOutputMode)
67
+ return;
34
68
  p.intro(message);
35
69
  }
36
70
  /** Displays the closing outro banner for a command. */
37
71
  export function outro(message) {
72
+ if (machineOutputMode)
73
+ return;
38
74
  p.outro(message);
39
75
  }
40
76
  /** Logs an informational message. */
41
77
  export function info(message) {
78
+ if (machineOutputMode) {
79
+ writeDiagnostic('', message);
80
+ return;
81
+ }
42
82
  p.log.info(message);
43
83
  }
44
84
  /** Logs a success message. */
45
85
  export function success(message) {
86
+ if (machineOutputMode) {
87
+ writeDiagnostic('', message);
88
+ return;
89
+ }
46
90
  p.log.success(message);
47
91
  }
48
92
  /** Logs a warning message. */
49
93
  export function warn(message) {
94
+ if (machineOutputMode) {
95
+ writeDiagnostic('warning: ', message);
96
+ return;
97
+ }
50
98
  p.log.warn(message);
51
99
  }
52
100
  /** Logs an error message. */
53
101
  export function error(message) {
102
+ if (machineOutputMode) {
103
+ writeDiagnostic('error: ', message);
104
+ return;
105
+ }
54
106
  p.log.error(message);
55
107
  }
56
108
  /** Logs an in-progress step message. */
57
109
  export function step(message) {
110
+ if (machineOutputMode) {
111
+ writeDiagnostic('', message);
112
+ return;
113
+ }
58
114
  p.log.step(message);
59
115
  }
60
116
  /** Logs a plain message without a status prefix. */
61
117
  export function message(message) {
118
+ if (machineOutputMode) {
119
+ writeDiagnostic('', message);
120
+ return;
121
+ }
62
122
  p.log.message(message);
63
123
  }
64
124
  /** Formats text using the success color without logging it. */
@@ -75,6 +135,21 @@ export function formatErrorText(message) {
75
135
  * @returns Spinner handle with message(), stop(), and error() methods
76
136
  */
77
137
  export function spinner(initialMessage) {
138
+ if (machineOutputMode) {
139
+ // Spinner progress is diagnostics; keep stdout clean for the payload.
140
+ return {
141
+ message: (msg) => {
142
+ writeDiagnostic('', msg);
143
+ },
144
+ stop: (msg) => {
145
+ if (msg)
146
+ writeDiagnostic('', msg);
147
+ },
148
+ error: (msg) => {
149
+ writeDiagnostic('error: ', msg ?? 'Failed');
150
+ },
151
+ };
152
+ }
78
153
  if (!supportsInteractiveSpinner()) {
79
154
  let latestMessage = initialMessage;
80
155
  return {
@@ -107,6 +182,10 @@ export function spinner(initialMessage) {
107
182
  }
108
183
  /** Emits a cancellation message. */
109
184
  export function cancel(message) {
185
+ if (machineOutputMode) {
186
+ writeDiagnostic('cancelled: ', message);
187
+ return;
188
+ }
110
189
  p.cancel(message);
111
190
  }
112
191
  /** Checks whether a prompt result represents a user cancellation. */
@@ -115,6 +194,9 @@ export function isCancel(value) {
115
194
  }
116
195
  /** Displays a titled note block for follow-up details. */
117
196
  export function note(message, title) {
197
+ if (machineOutputMode) {
198
+ writeDiagnostic('', title ? `${title}: ${message}` : message);
199
+ return;
200
+ }
118
201
  p.note(message, title);
119
202
  }
120
- //# sourceMappingURL=logger.js.map
@@ -6,3 +6,18 @@
6
6
  export declare function pickDefined<T extends Record<string, unknown>>(obj: T): {
7
7
  [K in keyof T]+?: Exclude<T[K], undefined>;
8
8
  };
9
+ /**
10
+ * Wraps an option-argument parser so its failures surface through
11
+ * commander's own invalid-argument channel.
12
+ *
13
+ * Commander only treats errors whose `code` is `'commander.invalidArgument'`
14
+ * as argument-validation failures; anything else re-throws out of
15
+ * `parseAsync`, BYPASSING `withErrorHandling` entirely and landing in the
16
+ * bin's `main().catch` as an unformatted `Fatal error: …` dump with exit 1.
17
+ * That was the observed behavior for `run --smoke-exit abc` (plain Error),
18
+ * `test --harness-retries 99` (GeneralError), and `export --order 0`
19
+ * (FireForge InvalidArgumentError, whose `code` is a numeric ExitCode).
20
+ * Every `.argParser()`/option-parser callback must be wrapped with this
21
+ * helper (or throw commander's InvalidArgumentError directly).
22
+ */
23
+ export declare function commanderArgParser<T>(parse: (raw: string) => T): (raw: string) => T;
@@ -13,4 +13,28 @@ export function pickDefined(obj) {
13
13
  }
14
14
  return result;
15
15
  }
16
- //# sourceMappingURL=options.js.map
16
+ import { InvalidArgumentError as CommanderInvalidArgumentError } from 'commander';
17
+ /**
18
+ * Wraps an option-argument parser so its failures surface through
19
+ * commander's own invalid-argument channel.
20
+ *
21
+ * Commander only treats errors whose `code` is `'commander.invalidArgument'`
22
+ * as argument-validation failures; anything else re-throws out of
23
+ * `parseAsync`, BYPASSING `withErrorHandling` entirely and landing in the
24
+ * bin's `main().catch` as an unformatted `Fatal error: …` dump with exit 1.
25
+ * That was the observed behavior for `run --smoke-exit abc` (plain Error),
26
+ * `test --harness-retries 99` (GeneralError), and `export --order 0`
27
+ * (FireForge InvalidArgumentError, whose `code` is a numeric ExitCode).
28
+ * Every `.argParser()`/option-parser callback must be wrapped with this
29
+ * helper (or throw commander's InvalidArgumentError directly).
30
+ */
31
+ export function commanderArgParser(parse) {
32
+ return (raw) => {
33
+ try {
34
+ return parse(raw);
35
+ }
36
+ catch (error) {
37
+ throw new CommanderInvalidArgumentError(error instanceof Error ? error.message : String(error));
38
+ }
39
+ };
40
+ }
@@ -34,8 +34,8 @@ export function getPackageRoot() {
34
34
  }
35
35
  let current = dirname(fileURLToPath(import.meta.url));
36
36
  for (;;) {
37
+ const packagePath = join(current, 'package.json');
37
38
  try {
38
- const packagePath = join(current, 'package.json');
39
39
  const pkg = readPackageMetadata(packagePath);
40
40
  if (isFireForgePackageMetadata(pkg)) {
41
41
  cachedPackageRoot = current;
@@ -43,8 +43,16 @@ export function getPackageRoot() {
43
43
  }
44
44
  }
45
45
  catch (error) {
46
- void error;
47
- // no package.json herekeep walking
46
+ // Absent package.json: keep walking. A package.json that EXISTS but
47
+ // fails to parse is a different animal walking past it could bind
48
+ // to a wrong ancestor package (any parent exposing bin.fireforge) or
49
+ // end in the unhelpful generic "could not locate" error, hiding the
50
+ // actual syntax problem.
51
+ const code = error.code;
52
+ if (code !== 'ENOENT' && code !== 'ENOTDIR') {
53
+ throw new Error(`Found ${packagePath} but could not parse it: ` +
54
+ (error instanceof Error ? error.message : String(error)), { cause: error });
55
+ }
48
56
  }
49
57
  const parent = dirname(current);
50
58
  if (parent === current) {
@@ -66,4 +74,3 @@ export function getPackageVersion() {
66
74
  const packageRoot = getPackageRoot();
67
75
  return readPackageMetadata(join(packageRoot, 'package.json')).version;
68
76
  }
69
- //# sourceMappingURL=package-root.js.map
@@ -212,4 +212,3 @@ export function parseObject(data, label) {
212
212
  }
213
213
  return new ParsedRecord(data, label);
214
214
  }
215
- //# sourceMappingURL=parse.js.map
@@ -75,4 +75,3 @@ export function toRootRelativePath(root, candidate) {
75
75
  }
76
76
  return normalizePathSlashes(relative(resolvedRoot, resolvedCandidate));
77
77
  }
78
- //# sourceMappingURL=paths.js.map
@@ -53,4 +53,3 @@ export function isWindows() {
53
53
  export function getExecutableExtension() {
54
54
  return isWindows() ? '.exe' : '';
55
55
  }
56
- //# sourceMappingURL=platform.js.map
@@ -8,6 +8,16 @@ export interface ExecResult {
8
8
  stderr: string;
9
9
  /** Process exit code */
10
10
  exitCode: number;
11
+ /**
12
+ * True when `stdout` was cut off at the 50 MB collector cap. Optional so
13
+ * existing mocks stay valid; absent means "not truncated". Callers that
14
+ * feed the output into safety decisions (e.g. archive-listing scans) must
15
+ * treat `true` as a hard failure — a truncated listing looks exactly like
16
+ * a complete one otherwise.
17
+ */
18
+ stdoutTruncated?: boolean;
19
+ /** True when `stderr` was cut off at the 50 MB collector cap. See {@link ExecResult.stdoutTruncated}. */
20
+ stderrTruncated?: boolean;
11
21
  }
12
22
  /**
13
23
  * Options for command execution.
@@ -49,6 +59,13 @@ export interface StreamOptions extends ExecOptions {
49
59
  * @returns Exit code of the process
50
60
  */
51
61
  export declare function execStream(command: string, args: string[], options?: StreamOptions): Promise<number>;
62
+ /**
63
+ * Waits (bounded) for every tracked child process to close. Called by the
64
+ * bin signal handler after forwarding SIGINT/SIGTERM, so the parent stays
65
+ * alive long enough for the grace-then-SIGKILL escalation to actually run.
66
+ * Resolves immediately when no children are active.
67
+ */
68
+ export declare function waitForActiveChildShutdown(timeoutMs: number): Promise<void>;
52
69
  /**
53
70
  * Executes a command and inherits stdio (shows output directly).
54
71
  *
@@ -81,8 +98,16 @@ export declare function execInheritCapture(command: string, args: string[], opti
81
98
  }): Promise<ExecResult>;
82
99
  /** Per-line callback for smoke-run stream dispatch. */
83
100
  export type SmokeLineCallback = (line: string) => void;
84
- /** Options for {@link execSmokeRun}. */
85
- export interface SmokeRunOptions extends ExecOptions {
101
+ /**
102
+ * Options for {@link execSmokeRun}.
103
+ *
104
+ * Deliberately omits `ExecOptions.timeout`: the smoke run's only deadline is
105
+ * {@link SmokeRunOptions.smokeTimeoutMs}, which signals the whole process
106
+ * group. Inheriting `timeout` used to be a leaky trap — it was accepted by
107
+ * the type but silently ignored, so a caller setting it got no deadline at
108
+ * all.
109
+ */
110
+ export interface SmokeRunOptions extends Omit<ExecOptions, 'timeout'> {
86
111
  /**
87
112
  * Hard deadline in milliseconds. When it elapses the child process
88
113
  * group is sent SIGTERM and, after `killGraceMs`, SIGKILL. The returned
@@ -138,8 +163,12 @@ export interface SmokeRunResult extends ExecResult {
138
163
  * that inherited the group.
139
164
  *
140
165
  * Windows fallback: `detached: true` does not create an equivalent group
141
- * there, so we degrade to `child.kill()` and log a best-effort warning
142
- * via the `onStderrLine` callback if the caller wired one.
166
+ * there, so we kill the descendant tree with `taskkill /pid <pid> /T /F`
167
+ * instead. taskkill has no graceful-signal equivalent both the deadline
168
+ * and the grace re-invocation are forced kills, so Windows children get
169
+ * no shutdown window (best-effort; Windows is untested, see README).
170
+ * `child.kill()` is still sent as a direct-child fallback in case
171
+ * taskkill itself is unavailable.
143
172
  */
144
173
  export declare function execSmokeRun(command: string, args: string[], options: SmokeRunOptions): Promise<SmokeRunResult>;
145
174
  /**