command-stream 0.8.2 → 0.9.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 (500) hide show
  1. package/js/examples/01-basic-streaming.mjs +14 -0
  2. package/js/examples/02-async-iterator.mjs +9 -0
  3. package/js/examples/03-file-and-console.mjs +16 -0
  4. package/js/examples/04-claude-jq-pipe.mjs +16 -0
  5. package/js/examples/CI-DEBUG-README.md +138 -0
  6. package/js/examples/README-examples.mjs +111 -0
  7. package/js/examples/README.md +345 -0
  8. package/js/examples/STREAMING_INTERFACES_SUMMARY.md +116 -0
  9. package/js/examples/add-test-timeouts.js +107 -0
  10. package/js/examples/ansi-default-preserved.mjs +11 -0
  11. package/js/examples/ansi-global-config.mjs +12 -0
  12. package/js/examples/ansi-reset-default.mjs +12 -0
  13. package/js/examples/ansi-strip-utils.mjs +12 -0
  14. package/js/examples/baseline-child-process.mjs +23 -0
  15. package/js/examples/baseline-claude-test.mjs +47 -0
  16. package/js/examples/baseline-working.mjs +34 -0
  17. package/js/examples/capture-mirror-comparison.mjs +23 -0
  18. package/js/examples/capture-mirror-default.mjs +11 -0
  19. package/js/examples/capture-mirror-performance.mjs +16 -0
  20. package/js/examples/capture-mirror-show-only.mjs +16 -0
  21. package/js/examples/capture-mirror-silent-processing.mjs +16 -0
  22. package/js/examples/ci-debug-baseline-vs-library.mjs +265 -0
  23. package/js/examples/ci-debug-es-module-loading.mjs +184 -0
  24. package/js/examples/ci-debug-signal-handling.mjs +225 -0
  25. package/js/examples/ci-debug-stdout-buffering.mjs +94 -0
  26. package/js/examples/ci-debug-test-timeouts.mjs +259 -0
  27. package/js/examples/claude-exact-file-output.mjs +20 -0
  28. package/js/examples/claude-exact-jq.mjs +13 -0
  29. package/js/examples/claude-exact-streaming.mjs +13 -0
  30. package/js/examples/claude-jq-pipeline.mjs +13 -0
  31. package/js/examples/claude-json-stream.mjs +39 -0
  32. package/js/examples/claude-streaming-basic.mjs +99 -0
  33. package/js/examples/claude-streaming-demo.mjs +126 -0
  34. package/js/examples/claude-streaming-final.mjs +20 -0
  35. package/js/examples/cleanup-verification-test.mjs +115 -0
  36. package/js/examples/colors-buffer-processing.mjs +14 -0
  37. package/js/examples/colors-default-preserved.mjs +15 -0
  38. package/js/examples/colors-per-command-config.mjs +15 -0
  39. package/js/examples/colors-strip-ansi.mjs +13 -0
  40. package/js/examples/commandstream-jq.mjs +29 -0
  41. package/js/examples/commandstream-working.mjs +23 -0
  42. package/js/examples/comprehensive-streams-demo.mjs +121 -0
  43. package/js/examples/ctrl-c-concurrent-processes.mjs +20 -0
  44. package/js/examples/ctrl-c-long-running-command.mjs +20 -0
  45. package/js/examples/ctrl-c-real-system-command.mjs +17 -0
  46. package/js/examples/ctrl-c-sleep-command.mjs +17 -0
  47. package/js/examples/ctrl-c-stdin-forwarding.mjs +20 -0
  48. package/js/examples/ctrl-c-virtual-command.mjs +17 -0
  49. package/js/examples/debug-already-started.mjs +20 -0
  50. package/js/examples/debug-ansi-processing.mjs +42 -0
  51. package/js/examples/debug-basic-streaming.mjs +44 -0
  52. package/js/examples/debug-buildshellcommand.mjs +82 -0
  53. package/js/examples/debug-child-process.mjs +43 -0
  54. package/js/examples/debug-child-state.mjs +55 -0
  55. package/js/examples/debug-chunking.mjs +38 -0
  56. package/js/examples/debug-command-parsing.mjs +61 -0
  57. package/js/examples/debug-complete-consolidation.mjs +97 -0
  58. package/js/examples/debug-echo-args.mjs +22 -0
  59. package/js/examples/debug-emit-timing.mjs +28 -0
  60. package/js/examples/debug-end-event.mjs +56 -0
  61. package/js/examples/debug-errexit.mjs +16 -0
  62. package/js/examples/debug-event-emission.mjs +40 -0
  63. package/js/examples/debug-event-timing.mjs +67 -0
  64. package/js/examples/debug-event-vs-result.mjs +30 -0
  65. package/js/examples/debug-exact-command.mjs +28 -0
  66. package/js/examples/debug-exact-test-scenario.mjs +44 -0
  67. package/js/examples/debug-execution-path.mjs +27 -0
  68. package/js/examples/debug-exit-command.mjs +38 -0
  69. package/js/examples/debug-exit-virtual.mjs +54 -0
  70. package/js/examples/debug-finish-consolidation.mjs +44 -0
  71. package/js/examples/debug-force-cleanup.mjs +47 -0
  72. package/js/examples/debug-getter-basic.mjs +13 -0
  73. package/js/examples/debug-getter-direct.mjs +23 -0
  74. package/js/examples/debug-getter-internals.mjs +61 -0
  75. package/js/examples/debug-handler-detection.mjs +65 -0
  76. package/js/examples/debug-idempotent-finish.mjs +54 -0
  77. package/js/examples/debug-idempotent-kill.mjs +58 -0
  78. package/js/examples/debug-interpolation-individual.mjs +88 -0
  79. package/js/examples/debug-interpolation-issue.mjs +101 -0
  80. package/js/examples/debug-jq-streaming.mjs +57 -0
  81. package/js/examples/debug-jq-tty-colors.mjs +168 -0
  82. package/js/examples/debug-kill-cleanup.mjs +56 -0
  83. package/js/examples/debug-kill-method.mjs +33 -0
  84. package/js/examples/debug-listener-interference.mjs +38 -0
  85. package/js/examples/debug-listener-lifecycle.mjs +50 -0
  86. package/js/examples/debug-listener-timing.mjs +62 -0
  87. package/js/examples/debug-listeners-property.mjs +34 -0
  88. package/js/examples/debug-map-methods.mjs +39 -0
  89. package/js/examples/debug-not-awaited-cleanup.mjs +106 -0
  90. package/js/examples/debug-off-method.mjs +28 -0
  91. package/js/examples/debug-option-merging.mjs +17 -0
  92. package/js/examples/debug-options.mjs +36 -0
  93. package/js/examples/debug-output.mjs +25 -0
  94. package/js/examples/debug-pattern-matching.mjs +69 -0
  95. package/js/examples/debug-pipeline-cat.mjs +28 -0
  96. package/js/examples/debug-pipeline-cleanup.mjs +71 -0
  97. package/js/examples/debug-pipeline-error-detailed.mjs +78 -0
  98. package/js/examples/debug-pipeline-error.mjs +65 -0
  99. package/js/examples/debug-pipeline-issue.mjs +26 -0
  100. package/js/examples/debug-pipeline-method.mjs +22 -0
  101. package/js/examples/debug-pipeline-stream.mjs +66 -0
  102. package/js/examples/debug-pipeline.mjs +14 -0
  103. package/js/examples/debug-process-exit-trace.mjs +41 -0
  104. package/js/examples/debug-process-path.mjs +38 -0
  105. package/js/examples/debug-property-check.mjs +29 -0
  106. package/js/examples/debug-resource-cleanup.mjs +83 -0
  107. package/js/examples/debug-shell-args.mjs +103 -0
  108. package/js/examples/debug-sigint-child-handler.mjs +44 -0
  109. package/js/examples/debug-sigint-forwarding.mjs +61 -0
  110. package/js/examples/debug-sigint-handler-install.mjs +79 -0
  111. package/js/examples/debug-sigint-handler-order.mjs +85 -0
  112. package/js/examples/debug-sigint-listeners.mjs +48 -0
  113. package/js/examples/debug-sigint-start-pattern.mjs +62 -0
  114. package/js/examples/debug-sigint-timer.mjs +40 -0
  115. package/js/examples/debug-simple-command.mjs +49 -0
  116. package/js/examples/debug-simple-getter.mjs +30 -0
  117. package/js/examples/debug-simple.mjs +39 -0
  118. package/js/examples/debug-simplified-finished.mjs +102 -0
  119. package/js/examples/debug-stack-overflow.mjs +25 -0
  120. package/js/examples/debug-stdin-simple.mjs +28 -0
  121. package/js/examples/debug-stdin.mjs +28 -0
  122. package/js/examples/debug-stream-emitter-isolated.mjs +45 -0
  123. package/js/examples/debug-stream-emitter.mjs +25 -0
  124. package/js/examples/debug-stream-events.mjs +70 -0
  125. package/js/examples/debug-stream-generator.mjs +23 -0
  126. package/js/examples/debug-stream-getter-issue.mjs +37 -0
  127. package/js/examples/debug-stream-getter.mjs +19 -0
  128. package/js/examples/debug-stream-internals.mjs +64 -0
  129. package/js/examples/debug-stream-method.mjs +46 -0
  130. package/js/examples/debug-stream-object.mjs +58 -0
  131. package/js/examples/debug-stream-properties.mjs +37 -0
  132. package/js/examples/debug-stream-timing.mjs +28 -0
  133. package/js/examples/debug-streaming.mjs +24 -0
  134. package/js/examples/debug-test-isolation.mjs +54 -0
  135. package/js/examples/debug-test-state.mjs +27 -0
  136. package/js/examples/debug-user-sigint.mjs +19 -0
  137. package/js/examples/debug-virtual-disable.mjs +21 -0
  138. package/js/examples/debug-virtual-vs-real.mjs +68 -0
  139. package/js/examples/debug-with-trace.mjs +23 -0
  140. package/js/examples/debug_parent_stream.mjs +22 -0
  141. package/js/examples/emulate-claude-stream.mjs +30 -0
  142. package/js/examples/emulated-streaming-direct.mjs +22 -0
  143. package/js/examples/emulated-streaming-jq-pipe.mjs +22 -0
  144. package/js/examples/emulated-streaming-sh-pipe.mjs +23 -0
  145. package/js/examples/events-build-process.mjs +73 -0
  146. package/js/examples/events-concurrent-streams.mjs +51 -0
  147. package/js/examples/events-error-handling.mjs +59 -0
  148. package/js/examples/events-file-monitoring.mjs +66 -0
  149. package/js/examples/events-interactive-simulation.mjs +69 -0
  150. package/js/examples/events-log-processing.mjs +72 -0
  151. package/js/examples/events-network-monitoring.mjs +68 -0
  152. package/js/examples/events-ping-basic.mjs +37 -0
  153. package/js/examples/events-progress-tracking.mjs +55 -0
  154. package/js/examples/events-stdin-input.mjs +34 -0
  155. package/js/examples/example-ansi-ls.mjs +39 -0
  156. package/js/examples/example-top.mjs +27 -0
  157. package/js/examples/final-ping-stdin-proof.mjs +88 -0
  158. package/js/examples/final-test-shell-operators.mjs +123 -0
  159. package/js/examples/final-working-examples.mjs +162 -0
  160. package/js/examples/gh-auth-test.mjs +103 -0
  161. package/js/examples/gh-delete-hang-test.mjs +79 -0
  162. package/js/examples/gh-gist-creation-test.mjs +276 -0
  163. package/js/examples/gh-gist-minimal-test.mjs +89 -0
  164. package/js/examples/gh-hang-exact-original.mjs +83 -0
  165. package/js/examples/gh-hang-reproduction.mjs +151 -0
  166. package/js/examples/gh-hang-test-with-redirect.mjs +45 -0
  167. package/js/examples/gh-hang-test-without-redirect.mjs +43 -0
  168. package/js/examples/gh-minimal-hang-check.mjs +33 -0
  169. package/js/examples/gh-operations-with-cd.mjs +187 -0
  170. package/js/examples/gh-output-test.mjs +102 -0
  171. package/js/examples/gh-reproduce-hang.mjs +41 -0
  172. package/js/examples/git-operations-with-cd.mjs +186 -0
  173. package/js/examples/interactive-math-calc.mjs +45 -0
  174. package/js/examples/interactive-top-fixed.mjs +25 -0
  175. package/js/examples/interactive-top-improved.mjs +72 -0
  176. package/js/examples/interactive-top-pty-logging.mjs +69 -0
  177. package/js/examples/interactive-top-pty.mjs +27 -0
  178. package/js/examples/interactive-top-with-logging.mjs +56 -0
  179. package/js/examples/interactive-top.mjs +29 -0
  180. package/js/examples/jq-color-demo.mjs +53 -0
  181. package/js/examples/jq-colors-streaming.mjs +42 -0
  182. package/js/examples/manual-ctrl-c-test.mjs +50 -0
  183. package/js/examples/methods-multiple-options.mjs +25 -0
  184. package/js/examples/methods-run-basic.mjs +10 -0
  185. package/js/examples/methods-start-basic.mjs +10 -0
  186. package/js/examples/node-compat-data-events.mjs +36 -0
  187. package/js/examples/node-compat-readable-event.mjs +29 -0
  188. package/js/examples/node-compat-small-buffer.mjs +33 -0
  189. package/js/examples/options-capture-false.mjs +12 -0
  190. package/js/examples/options-combined-settings.mjs +13 -0
  191. package/js/examples/options-custom-input.mjs +16 -0
  192. package/js/examples/options-default-behavior.mjs +10 -0
  193. package/js/examples/options-maximum-performance.mjs +15 -0
  194. package/js/examples/options-mirror-false.mjs +10 -0
  195. package/js/examples/options-performance-mode.mjs +13 -0
  196. package/js/examples/options-performance-optimization.mjs +14 -0
  197. package/js/examples/options-run-alias-demo.mjs +15 -0
  198. package/js/examples/options-run-alias.mjs +10 -0
  199. package/js/examples/options-silent-execution.mjs +14 -0
  200. package/js/examples/options-streaming-capture.mjs +24 -0
  201. package/js/examples/options-streaming-multiple.mjs +35 -0
  202. package/js/examples/options-streaming-silent.mjs +21 -0
  203. package/js/examples/options-streaming-stdin.mjs +21 -0
  204. package/js/examples/ping-streaming-filtered.mjs +22 -0
  205. package/js/examples/ping-streaming-interruptible.mjs +47 -0
  206. package/js/examples/ping-streaming-silent.mjs +24 -0
  207. package/js/examples/ping-streaming-simple.mjs +13 -0
  208. package/js/examples/ping-streaming-statistics.mjs +49 -0
  209. package/js/examples/ping-streaming-timestamps.mjs +22 -0
  210. package/js/examples/ping-streaming.mjs +48 -0
  211. package/js/examples/prove-ping-stdin-limitation.mjs +94 -0
  212. package/js/examples/readme-example.mjs +39 -0
  213. package/js/examples/realtime-json-stream.mjs +143 -0
  214. package/js/examples/reliable-stdin-commands.mjs +135 -0
  215. package/js/examples/reproduce-issue-135-v2.mjs +15 -0
  216. package/js/examples/reproduce-issue-135.mjs +17 -0
  217. package/js/examples/shell-cd-behavior.mjs +88 -0
  218. package/js/examples/sigint-forwarding-test.mjs +60 -0
  219. package/js/examples/sigint-handler-test.mjs +72 -0
  220. package/js/examples/simple-async-test.mjs +49 -0
  221. package/js/examples/simple-claude-test.mjs +17 -0
  222. package/js/examples/simple-event-test.mjs +33 -0
  223. package/js/examples/simple-jq-streaming.mjs +48 -0
  224. package/js/examples/simple-stream-demo.mjs +35 -0
  225. package/js/examples/simple-test-sleep.js +30 -0
  226. package/js/examples/simple-working-stdin.mjs +30 -0
  227. package/js/examples/streaming-behavior-test.mjs +116 -0
  228. package/js/examples/streaming-direct-command.mjs +21 -0
  229. package/js/examples/streaming-filtered-output.mjs +33 -0
  230. package/js/examples/streaming-grep-pipeline.mjs +21 -0
  231. package/js/examples/streaming-interactive-stdin.mjs +24 -0
  232. package/js/examples/streaming-jq-pipeline.mjs +23 -0
  233. package/js/examples/streaming-multistage-pipeline.mjs +23 -0
  234. package/js/examples/streaming-pipes-event-pattern.mjs +27 -0
  235. package/js/examples/streaming-pipes-multistage.mjs +22 -0
  236. package/js/examples/streaming-pipes-realtime-jq.mjs +23 -0
  237. package/js/examples/streaming-progress-tracking.mjs +34 -0
  238. package/js/examples/streaming-reusable-configs.mjs +52 -0
  239. package/js/examples/streaming-silent-capture.mjs +20 -0
  240. package/js/examples/streaming-test-simple.mjs +70 -0
  241. package/js/examples/streaming-virtual-pipeline.mjs +18 -0
  242. package/js/examples/syntax-basic-comparison.mjs +31 -0
  243. package/js/examples/syntax-basic-options.mjs +12 -0
  244. package/js/examples/syntax-combined-options.mjs +19 -0
  245. package/js/examples/syntax-command-chaining.mjs +12 -0
  246. package/js/examples/syntax-custom-directory.mjs +10 -0
  247. package/js/examples/syntax-custom-environment.mjs +13 -0
  248. package/js/examples/syntax-custom-stdin.mjs +10 -0
  249. package/js/examples/syntax-mixed-regular.mjs +11 -0
  250. package/js/examples/syntax-mixed-usage.mjs +15 -0
  251. package/js/examples/syntax-multiple-listeners.mjs +87 -0
  252. package/js/examples/syntax-piping-comparison.mjs +32 -0
  253. package/js/examples/syntax-reusable-config.mjs +16 -0
  254. package/js/examples/syntax-reusable-configs.mjs +21 -0
  255. package/js/examples/syntax-silent-operations.mjs +10 -0
  256. package/js/examples/syntax-stdin-option.mjs +12 -0
  257. package/js/examples/temp-sigint-test.mjs +21 -0
  258. package/js/examples/test-actual-buildshell.mjs +44 -0
  259. package/js/examples/test-async-streams-working.mjs +102 -0
  260. package/js/examples/test-async-streams.mjs +90 -0
  261. package/js/examples/test-auth-parse.mjs +74 -0
  262. package/js/examples/test-auto-quoting.mjs +57 -0
  263. package/js/examples/test-auto-start-fix.mjs +95 -0
  264. package/js/examples/test-baseline-sigint.mjs +38 -0
  265. package/js/examples/test-buffer-behavior.mjs +39 -0
  266. package/js/examples/test-buffers-simple.mjs +35 -0
  267. package/js/examples/test-bun-specific-issue.mjs +106 -0
  268. package/js/examples/test-bun-streaming.mjs +81 -0
  269. package/js/examples/test-cat-direct.mjs +41 -0
  270. package/js/examples/test-cat-pipe.mjs +34 -0
  271. package/js/examples/test-cd-behavior.mjs +42 -0
  272. package/js/examples/test-child-process-timing.mjs +53 -0
  273. package/js/examples/test-child-sigint-handler.mjs +62 -0
  274. package/js/examples/test-cleanup-simple.mjs +21 -0
  275. package/js/examples/test-comprehensive-tracing.mjs +58 -0
  276. package/js/examples/test-correct-space-handling.mjs +46 -0
  277. package/js/examples/test-ctrl-c-debug.mjs +44 -0
  278. package/js/examples/test-ctrl-c-inherit.mjs +30 -0
  279. package/js/examples/test-ctrl-c-sleep.mjs +31 -0
  280. package/js/examples/test-ctrl-c.mjs +17 -0
  281. package/js/examples/test-debug-new-options.mjs +55 -0
  282. package/js/examples/test-debug-pty.mjs +49 -0
  283. package/js/examples/test-debug-tee.mjs +38 -0
  284. package/js/examples/test-debug.mjs +25 -0
  285. package/js/examples/test-direct-jq.mjs +47 -0
  286. package/js/examples/test-direct-pipe-reading.mjs +119 -0
  287. package/js/examples/test-direct-pipe.sh +28 -0
  288. package/js/examples/test-double-quoting-prevention.mjs +138 -0
  289. package/js/examples/test-edge-cases-quoting.mjs +89 -0
  290. package/js/examples/test-events.mjs +37 -0
  291. package/js/examples/test-explicit-stdio.mjs +51 -0
  292. package/js/examples/test-final-streaming.mjs +71 -0
  293. package/js/examples/test-fix.mjs +71 -0
  294. package/js/examples/test-incremental-streaming.mjs +46 -0
  295. package/js/examples/test-individual-spawn.mjs +35 -0
  296. package/js/examples/test-inherit-stdout-not-stdin.mjs +133 -0
  297. package/js/examples/test-injection-protection.mjs +77 -0
  298. package/js/examples/test-interactive-streaming.mjs +140 -0
  299. package/js/examples/test-interactive-top.md +24 -0
  300. package/js/examples/test-interactive.mjs +17 -0
  301. package/js/examples/test-interpolation.mjs +14 -0
  302. package/js/examples/test-interrupt.mjs +40 -0
  303. package/js/examples/test-issue-135-comprehensive.mjs +41 -0
  304. package/js/examples/test-issue12-detailed.mjs +89 -0
  305. package/js/examples/test-issue12-exact.mjs +33 -0
  306. package/js/examples/test-jq-color.mjs +57 -0
  307. package/js/examples/test-jq-colors.mjs +41 -0
  308. package/js/examples/test-jq-compact.mjs +33 -0
  309. package/js/examples/test-jq-native.sh +10 -0
  310. package/js/examples/test-jq-pipeline-behavior.mjs +80 -0
  311. package/js/examples/test-jq-realtime.mjs +40 -0
  312. package/js/examples/test-manual-start.mjs +54 -0
  313. package/js/examples/test-mixed-quoting.mjs +88 -0
  314. package/js/examples/test-multi-stream.mjs +50 -0
  315. package/js/examples/test-multistage-debug.mjs +44 -0
  316. package/js/examples/test-native-spawn-vs-command-stream.mjs +154 -0
  317. package/js/examples/test-no-parse-pipeline.mjs +33 -0
  318. package/js/examples/test-non-virtual.mjs +52 -0
  319. package/js/examples/test-operators.mjs +53 -0
  320. package/js/examples/test-parent-continues.mjs +44 -0
  321. package/js/examples/test-path-interpolation.mjs +86 -0
  322. package/js/examples/test-ping-kill-and-stdin.mjs +98 -0
  323. package/js/examples/test-ping.mjs +12 -0
  324. package/js/examples/test-pty-spawn.mjs +101 -0
  325. package/js/examples/test-pty.mjs +38 -0
  326. package/js/examples/test-quote-behavior-summary.mjs +110 -0
  327. package/js/examples/test-quote-edge-cases.mjs +69 -0
  328. package/js/examples/test-quote-parsing.mjs +23 -0
  329. package/js/examples/test-raw-function.mjs +153 -0
  330. package/js/examples/test-raw-streaming.mjs +47 -0
  331. package/js/examples/test-readme-examples.mjs +142 -0
  332. package/js/examples/test-real-cat.mjs +28 -0
  333. package/js/examples/test-real-commands.mjs +21 -0
  334. package/js/examples/test-real-shell.mjs +31 -0
  335. package/js/examples/test-real-stdin-commands.mjs +160 -0
  336. package/js/examples/test-runner-batched.mjs +98 -0
  337. package/js/examples/test-runner-simple.mjs +80 -0
  338. package/js/examples/test-runner.mjs +67 -0
  339. package/js/examples/test-scope-parse.mjs +31 -0
  340. package/js/examples/test-sh-pipeline.mjs +24 -0
  341. package/js/examples/test-shell-detection.mjs +71 -0
  342. package/js/examples/test-shell-parser.mjs +37 -0
  343. package/js/examples/test-sigint-behavior.mjs +241 -0
  344. package/js/examples/test-sigint-handling.sh +14 -0
  345. package/js/examples/test-simple-pipe.mjs +12 -0
  346. package/js/examples/test-simple-streaming.mjs +32 -0
  347. package/js/examples/test-sleep-stdin.js +27 -0
  348. package/js/examples/test-sleep.mjs +56 -0
  349. package/js/examples/test-smart-quoting.mjs +180 -0
  350. package/js/examples/test-spaces-in-path.mjs +48 -0
  351. package/js/examples/test-special-chars-quoting.mjs +54 -0
  352. package/js/examples/test-stdin-after-start.mjs +39 -0
  353. package/js/examples/test-stdin-simple.mjs +67 -0
  354. package/js/examples/test-stdin-timing.mjs +74 -0
  355. package/js/examples/test-stdio-combinations.mjs +124 -0
  356. package/js/examples/test-stream-access.mjs +84 -0
  357. package/js/examples/test-stream-cleanup.mjs +27 -0
  358. package/js/examples/test-stream-readers.mjs +152 -0
  359. package/js/examples/test-streaming-final.mjs +57 -0
  360. package/js/examples/test-streaming-interfaces.mjs +141 -0
  361. package/js/examples/test-streaming-timing.mjs +27 -0
  362. package/js/examples/test-streaming.mjs +32 -0
  363. package/js/examples/test-streams-stdin-comprehensive.mjs +134 -0
  364. package/js/examples/test-streams-stdin-ctrl-c.mjs +96 -0
  365. package/js/examples/test-template-literal.mjs +26 -0
  366. package/js/examples/test-template-vs-interpolation.mjs +49 -0
  367. package/js/examples/test-timing.mjs +41 -0
  368. package/js/examples/test-top-inherit-stdout-stdin-control.mjs +123 -0
  369. package/js/examples/test-top-quit-stdin.mjs +118 -0
  370. package/js/examples/test-trace-option.mjs +21 -0
  371. package/js/examples/test-user-double-quotes.mjs +36 -0
  372. package/js/examples/test-user-single-quotes.mjs +36 -0
  373. package/js/examples/test-verbose.mjs +18 -0
  374. package/js/examples/test-verbose2.mjs +32 -0
  375. package/js/examples/test-virtual-streaming.mjs +125 -0
  376. package/js/examples/test-waiting-command.mjs +52 -0
  377. package/js/examples/test-waiting-commands.mjs +83 -0
  378. package/js/examples/test-watch-mode.mjs +104 -0
  379. package/js/examples/test-yes-cancellation.mjs +26 -0
  380. package/js/examples/test-yes-detailed.mjs +58 -0
  381. package/js/examples/test-yes-trace.mjs +28 -0
  382. package/js/examples/trace-abort-controller.mjs +30 -0
  383. package/js/examples/trace-error-handling.mjs +22 -0
  384. package/js/examples/trace-pipeline-command.mjs +22 -0
  385. package/js/examples/trace-signal-handling.mjs +35 -0
  386. package/js/examples/trace-simple-command.mjs +18 -0
  387. package/js/examples/trace-stderr-output.mjs +22 -0
  388. package/js/examples/verify-fix-both-runtimes.mjs +73 -0
  389. package/js/examples/verify-issue12-fixed.mjs +78 -0
  390. package/js/examples/which-command-common-commands.mjs +19 -0
  391. package/js/examples/which-command-gh-test.mjs +23 -0
  392. package/js/examples/which-command-nonexistent.mjs +20 -0
  393. package/js/examples/which-command-system-comparison.mjs +28 -0
  394. package/js/examples/working-example.mjs +13 -0
  395. package/js/examples/working-stdin-examples.mjs +138 -0
  396. package/js/examples/working-streaming-demo.mjs +49 -0
  397. package/{src → js/src}/$.mjs +20 -4
  398. package/{src → js/src}/$.utils.mjs +14 -2
  399. package/js/tests/$.features.test.mjs +283 -0
  400. package/js/tests/$.test.mjs +935 -0
  401. package/js/tests/builtin-commands.test.mjs +387 -0
  402. package/js/tests/bun-shell-path-fix.test.mjs +115 -0
  403. package/js/tests/bun.features.test.mjs +189 -0
  404. package/js/tests/cd-virtual-command.test.mjs +622 -0
  405. package/js/tests/cleanup-verification.test.mjs +127 -0
  406. package/js/tests/ctrl-c-baseline.test.mjs +207 -0
  407. package/js/tests/ctrl-c-basic.test.mjs +220 -0
  408. package/js/tests/ctrl-c-library.test.mjs +197 -0
  409. package/js/tests/ctrl-c-signal.test.mjs +915 -0
  410. package/js/tests/examples.test.mjs +252 -0
  411. package/js/tests/execa.features.test.mjs +198 -0
  412. package/js/tests/gh-commands.test.mjs +164 -0
  413. package/js/tests/gh-gist-operations.test.mjs +221 -0
  414. package/js/tests/git-gh-cd.test.mjs +466 -0
  415. package/js/tests/interactive-option.test.mjs +114 -0
  416. package/js/tests/interactive-streaming.test.mjs +307 -0
  417. package/js/tests/issue-135-final.test.mjs +58 -0
  418. package/js/tests/jq-color-behavior.test.mjs +140 -0
  419. package/js/tests/jq.test.mjs +318 -0
  420. package/js/tests/options-examples.test.mjs +106 -0
  421. package/js/tests/options-syntax.test.mjs +112 -0
  422. package/js/tests/path-interpolation.test.mjs +412 -0
  423. package/js/tests/pipe.test.mjs +291 -0
  424. package/js/tests/raw-function.test.mjs +266 -0
  425. package/js/tests/readme-examples.test.mjs +427 -0
  426. package/js/tests/resource-cleanup-internals.test.mjs +669 -0
  427. package/js/tests/shell-settings.test.mjs +279 -0
  428. package/js/tests/sigint-cleanup-isolated.test.mjs +151 -0
  429. package/js/tests/sigint-cleanup.test.mjs +118 -0
  430. package/js/tests/start-run-edge-cases.test.mjs +152 -0
  431. package/js/tests/start-run-options.test.mjs +181 -0
  432. package/js/tests/stderr-output-handling.test.mjs +279 -0
  433. package/js/tests/streaming-interfaces.test.mjs +194 -0
  434. package/js/tests/sync.test.mjs +297 -0
  435. package/js/tests/system-pipe.test.mjs +226 -0
  436. package/js/tests/test-cleanup.mjs +200 -0
  437. package/js/tests/test-helper-fixed.mjs +148 -0
  438. package/js/tests/test-helper-v2.mjs +118 -0
  439. package/js/tests/test-helper.mjs +171 -0
  440. package/js/tests/test-sigint-child.js +15 -0
  441. package/js/tests/text-method.test.mjs +225 -0
  442. package/js/tests/virtual.test.mjs +364 -0
  443. package/js/tests/yes-command-cleanup.test.mjs +208 -0
  444. package/js/tests/zx.features.test.mjs +233 -0
  445. package/package.json +13 -12
  446. package/rust/Cargo.lock +947 -0
  447. package/rust/Cargo.toml +47 -0
  448. package/rust/src/commands/basename.rs +69 -0
  449. package/rust/src/commands/cat.rs +123 -0
  450. package/rust/src/commands/cd.rs +67 -0
  451. package/rust/src/commands/cp.rs +187 -0
  452. package/rust/src/commands/dirname.rs +57 -0
  453. package/rust/src/commands/echo.rs +73 -0
  454. package/rust/src/commands/env.rs +33 -0
  455. package/rust/src/commands/exit.rs +36 -0
  456. package/rust/src/commands/false.rs +24 -0
  457. package/rust/src/commands/ls.rs +182 -0
  458. package/rust/src/commands/mkdir.rs +98 -0
  459. package/rust/src/commands/mod.rs +200 -0
  460. package/rust/src/commands/mv.rs +180 -0
  461. package/rust/src/commands/pwd.rs +28 -0
  462. package/rust/src/commands/rm.rs +150 -0
  463. package/rust/src/commands/seq.rs +179 -0
  464. package/rust/src/commands/sleep.rs +97 -0
  465. package/rust/src/commands/test.rs +204 -0
  466. package/rust/src/commands/touch.rs +99 -0
  467. package/rust/src/commands/true.rs +24 -0
  468. package/rust/src/commands/which.rs +87 -0
  469. package/rust/src/commands/yes.rs +99 -0
  470. package/rust/src/lib.rs +492 -0
  471. package/rust/src/main.rs +37 -0
  472. package/rust/src/shell_parser.rs +565 -0
  473. package/rust/src/utils.rs +335 -0
  474. package/rust/tests/builtin_commands.rs +549 -0
  475. package/rust/tests/process_runner.rs +286 -0
  476. package/rust/tests/shell_parser.rs +296 -0
  477. package/rust/tests/utils.rs +282 -0
  478. package/rust/tests/virtual_commands.rs +199 -0
  479. /package/{src → js/src}/commands/$.basename.mjs +0 -0
  480. /package/{src → js/src}/commands/$.cat.mjs +0 -0
  481. /package/{src → js/src}/commands/$.cd.mjs +0 -0
  482. /package/{src → js/src}/commands/$.cp.mjs +0 -0
  483. /package/{src → js/src}/commands/$.dirname.mjs +0 -0
  484. /package/{src → js/src}/commands/$.echo.mjs +0 -0
  485. /package/{src → js/src}/commands/$.env.mjs +0 -0
  486. /package/{src → js/src}/commands/$.exit.mjs +0 -0
  487. /package/{src → js/src}/commands/$.false.mjs +0 -0
  488. /package/{src → js/src}/commands/$.ls.mjs +0 -0
  489. /package/{src → js/src}/commands/$.mkdir.mjs +0 -0
  490. /package/{src → js/src}/commands/$.mv.mjs +0 -0
  491. /package/{src → js/src}/commands/$.pwd.mjs +0 -0
  492. /package/{src → js/src}/commands/$.rm.mjs +0 -0
  493. /package/{src → js/src}/commands/$.seq.mjs +0 -0
  494. /package/{src → js/src}/commands/$.sleep.mjs +0 -0
  495. /package/{src → js/src}/commands/$.test.mjs +0 -0
  496. /package/{src → js/src}/commands/$.touch.mjs +0 -0
  497. /package/{src → js/src}/commands/$.true.mjs +0 -0
  498. /package/{src → js/src}/commands/$.which.mjs +0 -0
  499. /package/{src → js/src}/commands/$.yes.mjs +0 -0
  500. /package/{src → js/src}/shell-parser.mjs +0 -0
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== JQ Streaming Debug ===');
6
+
7
+ console.log('Testing the exact command that was failing...');
8
+
9
+ const cmd = $`sh -c 'echo "{\\"id\\":1}"; sleep 0.5; echo "{\\"id\\":2}"; sleep 0.5; echo "{\\"id\\":3}"' | jq -c .`;
10
+
11
+ console.log('Getting stream...');
12
+
13
+ // Set a timeout to prevent infinite hang
14
+ const timeout = setTimeout(() => {
15
+ console.log('TIMEOUT: JQ stream took too long');
16
+ process.exit(1);
17
+ }, 10000);
18
+
19
+ try {
20
+ let chunkCount = 0;
21
+ let buffer = '';
22
+
23
+ console.log('Starting stream iteration...');
24
+ for await (const chunk of cmd.stream()) {
25
+ if (chunk.type === 'stdout') {
26
+ chunkCount++;
27
+ buffer += chunk.data.toString();
28
+
29
+ console.log(
30
+ `Chunk ${chunkCount}:`,
31
+ JSON.stringify(chunk.data.toString())
32
+ );
33
+
34
+ // Process complete lines
35
+ const lines = buffer.split('\n');
36
+ buffer = lines.pop() || '';
37
+
38
+ for (const line of lines) {
39
+ if (line.trim()) {
40
+ console.log('Complete line:', JSON.stringify(line.trim()));
41
+ }
42
+ }
43
+
44
+ // Safety break after getting some output
45
+ if (chunkCount >= 5) {
46
+ console.log('Safety break after 5 chunks');
47
+ break;
48
+ }
49
+ }
50
+ }
51
+
52
+ clearTimeout(timeout);
53
+ console.log('JQ streaming completed with', chunkCount, 'chunks');
54
+ } catch (error) {
55
+ clearTimeout(timeout);
56
+ console.log('JQ streaming error:', error.message);
57
+ }
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Debug script to understand jq TTY and color behavior
5
+ * This helps diagnose why the test behaves differently in different environments
6
+ */
7
+
8
+ import { $ } from '../src/$.mjs';
9
+ import { spawn } from 'child_process';
10
+
11
+ const testJson =
12
+ '{"message": "hello", "number": 42, "active": true, "data": null}';
13
+
14
+ console.log('='.repeat(60));
15
+ console.log('JQ TTY AND COLOR BEHAVIOR DIAGNOSTIC');
16
+ console.log('='.repeat(60));
17
+
18
+ // 1. Check current environment
19
+ console.log('\n1. ENVIRONMENT INFORMATION:');
20
+ console.log('-'.repeat(40));
21
+ console.log('Node version:', process.version);
22
+ console.log('Platform:', process.platform);
23
+ console.log('TTY Status:');
24
+ console.log(' - process.stdout.isTTY:', process.stdout.isTTY);
25
+ console.log(' - process.stderr.isTTY:', process.stderr.isTTY);
26
+ console.log(' - process.stdin.isTTY:', process.stdin.isTTY);
27
+ console.log('Environment variables:');
28
+ console.log(' - TERM:', process.env.TERM || '(not set)');
29
+ console.log(' - COLORTERM:', process.env.COLORTERM || '(not set)');
30
+ console.log(' - NO_COLOR:', process.env.NO_COLOR || '(not set)');
31
+ console.log(' - FORCE_COLOR:', process.env.FORCE_COLOR || '(not set)');
32
+ console.log(' - CI:', process.env.CI || '(not set)');
33
+
34
+ // 2. Test jq version and capabilities
35
+ console.log('\n2. JQ VERSION AND CAPABILITIES:');
36
+ console.log('-'.repeat(40));
37
+ try {
38
+ const jqVersion = await $`jq --version`;
39
+ console.log('jq version:', jqVersion.stdout.trim());
40
+ } catch (e) {
41
+ console.log('Error getting jq version:', e.message);
42
+ }
43
+
44
+ // 3. Test default jq behavior through command-stream
45
+ console.log('\n3. JQ THROUGH COMMAND-STREAM (default):');
46
+ console.log('-'.repeat(40));
47
+ const defaultResult = await $`echo ${testJson} | jq .`;
48
+ const hasDefaultColors = /\u001b\[\d+/.test(defaultResult.stdout);
49
+ console.log('Exit code:', defaultResult.code);
50
+ console.log('Has ANSI color codes:', hasDefaultColors);
51
+ console.log('Output length:', defaultResult.stdout.length);
52
+ console.log(
53
+ 'First 150 chars (raw):',
54
+ JSON.stringify(defaultResult.stdout.substring(0, 150))
55
+ );
56
+
57
+ // 4. Test with explicit color flag
58
+ console.log('\n4. JQ WITH EXPLICIT COLOR FLAG (-C):');
59
+ console.log('-'.repeat(40));
60
+ const colorResult = await $`echo ${testJson} | jq -C .`;
61
+ const hasExplicitColors = /\u001b\[\d+/.test(colorResult.stdout);
62
+ console.log('Has ANSI color codes:', hasExplicitColors);
63
+ console.log('Output length:', colorResult.stdout.length);
64
+ console.log(
65
+ 'First 150 chars (raw):',
66
+ JSON.stringify(colorResult.stdout.substring(0, 150))
67
+ );
68
+
69
+ // 5. Test with explicit no-color flag
70
+ console.log('\n5. JQ WITH EXPLICIT NO-COLOR FLAG (-M):');
71
+ console.log('-'.repeat(40));
72
+ const noColorResult = await $`echo ${testJson} | jq -M .`;
73
+ const hasNoColors = /\u001b\[\d+/.test(noColorResult.stdout);
74
+ console.log('Has ANSI color codes:', hasNoColors);
75
+ console.log('Output length:', noColorResult.stdout.length);
76
+ console.log(
77
+ 'First 150 chars (raw):',
78
+ JSON.stringify(noColorResult.stdout.substring(0, 150))
79
+ );
80
+
81
+ // 6. Test jq directly with Node's spawn (bypassing command-stream)
82
+ console.log('\n6. JQ DIRECTLY VIA NODE SPAWN:');
83
+ console.log('-'.repeat(40));
84
+ await new Promise((resolve) => {
85
+ const echo = spawn('echo', [testJson]);
86
+ const jq = spawn('jq', ['.']);
87
+
88
+ let output = '';
89
+ echo.stdout.pipe(jq.stdin);
90
+
91
+ jq.stdout.on('data', (data) => {
92
+ output += data.toString();
93
+ });
94
+
95
+ jq.on('close', () => {
96
+ const hasSpawnColors = /\u001b\[\d+/.test(output);
97
+ console.log('Has ANSI color codes:', hasSpawnColors);
98
+ console.log('Output length:', output.length);
99
+ console.log(
100
+ 'First 150 chars (raw):',
101
+ JSON.stringify(output.substring(0, 150))
102
+ );
103
+ resolve();
104
+ });
105
+ });
106
+
107
+ // 7. Test with environment variable manipulation
108
+ console.log('\n7. JQ WITH ENVIRONMENT VARIABLES:');
109
+ console.log('-'.repeat(40));
110
+
111
+ // Test with NO_COLOR
112
+ process.env.NO_COLOR = '1';
113
+ const noColorEnvResult = await $`echo ${testJson} | jq .`;
114
+ const hasNoColorEnv = /\u001b\[\d+/.test(noColorEnvResult.stdout);
115
+ console.log('With NO_COLOR=1, has colors:', hasNoColorEnv);
116
+ delete process.env.NO_COLOR;
117
+
118
+ // Test with FORCE_COLOR
119
+ process.env.FORCE_COLOR = '1';
120
+ const forceColorEnvResult = await $`echo ${testJson} | jq .`;
121
+ const hasForceColorEnv = /\u001b\[\d+/.test(forceColorEnvResult.stdout);
122
+ console.log('With FORCE_COLOR=1, has colors:', hasForceColorEnv);
123
+ delete process.env.FORCE_COLOR;
124
+
125
+ // 8. Summary and test recommendation
126
+ console.log('\n8. ANALYSIS AND RECOMMENDATION:');
127
+ console.log('-'.repeat(40));
128
+ console.log('Default behavior has colors:', hasDefaultColors);
129
+ console.log('Explicit -C has colors:', hasExplicitColors);
130
+ console.log('Explicit -M has colors:', hasNoColors);
131
+ console.log('Direct spawn has colors:', /\u001b\[\d+/.test(''));
132
+
133
+ if (hasDefaultColors && !process.stdout.isTTY) {
134
+ console.log(
135
+ '\n⚠️ UNEXPECTED: jq is outputting colors in non-TTY environment by default'
136
+ );
137
+ console.log('This might be due to:');
138
+ console.log(' - jq configuration or alias');
139
+ console.log(' - Environment variables affecting color output');
140
+ console.log(' - Different jq version behavior');
141
+ } else if (!hasDefaultColors && process.stdout.isTTY) {
142
+ console.log(
143
+ '\n⚠️ UNEXPECTED: jq is NOT outputting colors in TTY environment by default'
144
+ );
145
+ console.log('This might be due to:');
146
+ console.log(" - Pipe detection (jq sees it's in a pipe)");
147
+ console.log(' - Environment variables suppressing colors');
148
+ } else {
149
+ console.log('\n✅ jq behavior matches expected TTY detection');
150
+ }
151
+
152
+ console.log('\n9. RECOMMENDED TEST FIX:');
153
+ console.log('-'.repeat(40));
154
+ console.log('The test should handle both scenarios:');
155
+ console.log(' 1. When jq auto-detects TTY and colors accordingly');
156
+ console.log(' 2. When jq is affected by environment variables or config');
157
+ console.log('\nSuggested approach:');
158
+ console.log(' - Test explicit -C and -M flags (predictable behavior)');
159
+ console.log(
160
+ ' - For default behavior, accept both colored and non-colored output'
161
+ );
162
+ console.log(
163
+ ' - Focus on testing that output is valid JSON regardless of colors'
164
+ );
165
+
166
+ console.log(`\n${'='.repeat(60)}`);
167
+ console.log('DIAGNOSTIC COMPLETE');
168
+ console.log('='.repeat(60));
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ function getSigintHandlerCount() {
6
+ const sigintListeners = process.listeners('SIGINT');
7
+ const commandStreamListeners = sigintListeners.filter((l) => {
8
+ const str = l.toString();
9
+ return (
10
+ str.includes('activeProcessRunners') ||
11
+ str.includes('ProcessRunner') ||
12
+ str.includes('activeChildren')
13
+ );
14
+ });
15
+ return commandStreamListeners.length;
16
+ }
17
+
18
+ console.log('=== Kill Cleanup Debug ===');
19
+
20
+ console.log('Initial SIGINT handlers:', getSigintHandlerCount());
21
+
22
+ // Test killing like the failing test does
23
+ const runner = $`seq 1 100`;
24
+ const promise = runner.start();
25
+
26
+ console.log('After starting command:', getSigintHandlerCount(), 'handlers');
27
+
28
+ // Let it start generating
29
+ await new Promise((resolve) => setTimeout(resolve, 10));
30
+
31
+ console.log('Before killing:', getSigintHandlerCount(), 'handlers');
32
+
33
+ // Kill it before it completes
34
+ runner.kill();
35
+
36
+ console.log('Immediately after kill:', getSigintHandlerCount(), 'handlers');
37
+
38
+ try {
39
+ await promise;
40
+ } catch (e) {
41
+ console.log('Expected error after kill:', e.message);
42
+ }
43
+
44
+ console.log(
45
+ 'After awaiting killed promise:',
46
+ getSigintHandlerCount(),
47
+ 'handlers'
48
+ );
49
+ console.log('runner.finished:', runner.finished);
50
+
51
+ // Wait a bit more
52
+ await new Promise((resolve) => setTimeout(resolve, 50));
53
+
54
+ console.log('After 50ms wait:', getSigintHandlerCount(), 'handlers');
55
+
56
+ console.log('Test completed.');
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('Testing kill() method');
6
+
7
+ try {
8
+ const runner = $`sleep 5`;
9
+ console.log('Created runner');
10
+
11
+ // Give it time to start
12
+ setTimeout(async () => {
13
+ console.log('Killing the command');
14
+ try {
15
+ runner.kill('SIGINT');
16
+ console.log('Kill method called successfully');
17
+ } catch (error) {
18
+ console.error('Error in kill():', error.message);
19
+ console.error('Error stack:', error.stack);
20
+ }
21
+ }, 500);
22
+
23
+ console.log('Awaiting runner');
24
+ const result = await runner.catch((error) => {
25
+ console.log('Runner caught error:', error.message);
26
+ return { code: error.code || 130 };
27
+ });
28
+
29
+ console.log('Final result:', result);
30
+ } catch (error) {
31
+ console.error('Outer error:', error.message);
32
+ console.error('Stack:', error.stack);
33
+ }
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Listener Interference Debug ===');
6
+
7
+ async function testWithoutStream() {
8
+ console.log('\n1. Test without calling stream():');
9
+ const cmd = $`echo "test1"`;
10
+
11
+ cmd.on('end', () => console.log('END listener called'));
12
+ cmd.on('exit', () => console.log('EXIT listener called'));
13
+
14
+ console.log('Listeners before await:', cmd.listeners);
15
+ await cmd;
16
+ console.log('Listeners after await:', cmd.listeners);
17
+ }
18
+
19
+ async function testWithStream() {
20
+ console.log('\n2. Test after calling stream():');
21
+ const cmd = $`echo "test2"`;
22
+
23
+ cmd.on('end', () => console.log('END listener called'));
24
+ cmd.on('exit', () => console.log('EXIT listener called'));
25
+
26
+ console.log('Listeners before stream():', cmd.listeners);
27
+
28
+ // Just call stream() to get the generator, but don't iterate
29
+ const streamGen = cmd.stream();
30
+
31
+ console.log('Listeners after stream():', cmd.listeners);
32
+
33
+ await cmd;
34
+ console.log('Listeners after await:', cmd.listeners);
35
+ }
36
+
37
+ await testWithoutStream();
38
+ await testWithStream();
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Listener Lifecycle Debug ===');
6
+
7
+ const cmd = $`echo "test"`;
8
+
9
+ // Track the instance identity
10
+ console.log('Command instance ID:', cmd.toString());
11
+
12
+ // Add listeners
13
+ cmd.on('data', () => console.log('DATA listener called'));
14
+ cmd.on('end', () => console.log('END listener called'));
15
+ cmd.on('exit', () => console.log('EXIT listener called'));
16
+
17
+ console.log('After adding listeners:', cmd.listeners.size, 'listeners');
18
+
19
+ // Override _runVirtual to track listeners during execution
20
+ const original_runVirtual = cmd._runVirtual;
21
+ if (original_runVirtual) {
22
+ cmd._runVirtual = function (...args) {
23
+ console.log('At start of _runVirtual:', this.listeners.size, 'listeners');
24
+ console.log('Instance check:', this === cmd ? 'SAME' : 'DIFFERENT');
25
+
26
+ const result = original_runVirtual.apply(this, args);
27
+
28
+ console.log('At end of _runVirtual:', this.listeners.size, 'listeners');
29
+ return result;
30
+ };
31
+ }
32
+
33
+ // Also override emit to see the context
34
+ const originalEmit = cmd.emit;
35
+ cmd.emit = function (event, ...args) {
36
+ console.log(
37
+ `Emitting ${event}: instance check:`,
38
+ this === cmd ? 'SAME' : 'DIFFERENT'
39
+ );
40
+ console.log(`Emitting ${event}: listeners map size:`, this.listeners.size);
41
+ console.log(
42
+ `Emitting ${event}: has listener for event:`,
43
+ this.listeners.has(event)
44
+ );
45
+ return originalEmit.call(this, event, ...args);
46
+ };
47
+
48
+ console.log('Starting await...');
49
+ await cmd;
50
+ console.log('After await:', cmd.listeners.size, 'listeners');
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Listener Timing Debug ===');
6
+
7
+ async function testEarlyListeners() {
8
+ console.log('\n1. Attaching listeners BEFORE await:');
9
+ const cmd = $`echo "test1"`;
10
+
11
+ // Attach listeners immediately after creating command
12
+ const events = [];
13
+ cmd.on('data', () => events.push('data'));
14
+ cmd.on('end', () => events.push('end'));
15
+ cmd.on('exit', () => events.push('exit'));
16
+
17
+ console.log('Events before await:', events);
18
+ await cmd;
19
+ console.log('Events after await:', events);
20
+ }
21
+
22
+ async function testLateListeners() {
23
+ console.log('\n2. Attaching listeners AFTER await:');
24
+ const cmd = $`echo "test2"`;
25
+
26
+ // First await the command
27
+ await cmd;
28
+
29
+ // THEN attach listeners (too late!)
30
+ const events = [];
31
+ cmd.on('data', () => events.push('data'));
32
+ cmd.on('end', () => events.push('end'));
33
+ cmd.on('exit', () => events.push('exit'));
34
+
35
+ console.log('Events after await (should be empty):', events);
36
+ }
37
+
38
+ async function testStreamWithEarlyListeners() {
39
+ console.log('\n3. Testing stream with early listeners:');
40
+ const cmd = $`echo "test3"`;
41
+
42
+ const events = [];
43
+ cmd.on('data', () => events.push('data'));
44
+ cmd.on('end', () => events.push('end'));
45
+ cmd.on('exit', () => events.push('exit'));
46
+
47
+ console.log('Events before stream:', events);
48
+
49
+ // Use stream instead of await
50
+ for await (const chunk of cmd.stream()) {
51
+ console.log('Stream chunk received');
52
+ break; // Just get first chunk
53
+ }
54
+
55
+ console.log('Events after stream:', events);
56
+ }
57
+
58
+ await testEarlyListeners();
59
+ await testLateListeners();
60
+ await testStreamWithEarlyListeners();
61
+
62
+ console.log('\nDebug completed!');
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Listeners Property Debug ===');
6
+
7
+ const cmd = $`echo "test"`;
8
+
9
+ // Override the listeners property to track modifications
10
+ let _listeners = cmd.listeners;
11
+ Object.defineProperty(cmd, 'listeners', {
12
+ get() {
13
+ return _listeners;
14
+ },
15
+ set(newValue) {
16
+ console.log('LISTENERS PROPERTY SET!');
17
+ console.log('Old value size:', _listeners ? _listeners.size : 'undefined');
18
+ console.log('New value size:', newValue ? newValue.size : 'undefined');
19
+
20
+ // Get stack trace to see who's setting the property
21
+ const stack = new Error().stack;
22
+ console.log('Stack trace:', stack.split('\n').slice(1, 5).join('\n'));
23
+
24
+ _listeners = newValue;
25
+ },
26
+ });
27
+
28
+ cmd.on('data', () => console.log('DATA listener called'));
29
+ cmd.on('end', () => console.log('END listener called'));
30
+ cmd.on('exit', () => console.log('EXIT listener called'));
31
+
32
+ console.log('Starting await...');
33
+ await cmd;
34
+ console.log('Completed await');
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Map Methods Debug ===');
6
+
7
+ const cmd = $`echo "test"`;
8
+
9
+ // Override Map methods to track modifications
10
+ const originalClear = cmd.listeners.clear.bind(cmd.listeners);
11
+ const originalDelete = cmd.listeners.delete.bind(cmd.listeners);
12
+ const originalSet = cmd.listeners.set.bind(cmd.listeners);
13
+
14
+ cmd.listeners.clear = function () {
15
+ console.log('LISTENERS MAP CLEARED!');
16
+ const stack = new Error().stack;
17
+ console.log('Stack trace:', stack.split('\n').slice(1, 5).join('\n'));
18
+ return originalClear();
19
+ };
20
+
21
+ cmd.listeners.delete = function (key) {
22
+ console.log('LISTENERS MAP DELETE:', key);
23
+ const stack = new Error().stack;
24
+ console.log('Stack trace:', stack.split('\n').slice(1, 3).join('\n'));
25
+ return originalDelete(key);
26
+ };
27
+
28
+ cmd.listeners.set = function (key, value) {
29
+ console.log('LISTENERS MAP SET:', key, 'with', value.length, 'listeners');
30
+ return originalSet(key, value);
31
+ };
32
+
33
+ cmd.on('data', () => console.log('DATA listener called'));
34
+ cmd.on('end', () => console.log('END listener called'));
35
+ cmd.on('exit', () => console.log('EXIT listener called'));
36
+
37
+ console.log('Starting await...');
38
+ await cmd;
39
+ console.log('Completed await');
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env bun
2
+ // Debug script to test the non-awaited command cleanup issue
3
+
4
+ import { $ } from '../src/$.mjs';
5
+
6
+ // Enable verbose mode
7
+ process.env.COMMAND_STREAM_VERBOSE = 'true';
8
+
9
+ async function testNotAwaitedCleanup() {
10
+ console.log('=== Not Awaited Cleanup Debug ===');
11
+
12
+ console.log('\n1. Initial state:');
13
+ const initialListeners = process.listeners('SIGINT').length;
14
+ console.log('Initial SIGINT listeners:', initialListeners);
15
+
16
+ console.log('\n2. Creating and starting commands without awaiting...');
17
+ const runner1 = $`sleep 0.05`;
18
+ const runner2 = $`echo "not awaited"`;
19
+ const runner3 = $`pwd`;
20
+
21
+ console.log(
22
+ 'After creating runners, SIGINT listeners:',
23
+ process.listeners('SIGINT').length
24
+ );
25
+
26
+ // Start them
27
+ const promise1 = runner1.start();
28
+ console.log(
29
+ 'After starting runner1, SIGINT listeners:',
30
+ process.listeners('SIGINT').length
31
+ );
32
+
33
+ const promise2 = runner2.start();
34
+ console.log(
35
+ 'After starting runner2, SIGINT listeners:',
36
+ process.listeners('SIGINT').length
37
+ );
38
+
39
+ const promise3 = runner3.start();
40
+ console.log(
41
+ 'After starting runner3, SIGINT listeners:',
42
+ process.listeners('SIGINT').length
43
+ );
44
+
45
+ console.log('\n3. Checking after 50ms...');
46
+ await new Promise((resolve) => setTimeout(resolve, 50));
47
+ console.log(
48
+ 'After 50ms, SIGINT listeners:',
49
+ process.listeners('SIGINT').length
50
+ );
51
+
52
+ console.log('\n4. Checking after 100ms total...');
53
+ await new Promise((resolve) => setTimeout(resolve, 50));
54
+ console.log(
55
+ 'After 100ms total, SIGINT listeners:',
56
+ process.listeners('SIGINT').length
57
+ );
58
+
59
+ console.log('\n5. Checking after 200ms total...');
60
+ await new Promise((resolve) => setTimeout(resolve, 100));
61
+ console.log(
62
+ 'After 200ms total, SIGINT listeners:',
63
+ process.listeners('SIGINT').length
64
+ );
65
+
66
+ console.log('\n6. Checking individual promise statuses...');
67
+ console.log(
68
+ 'Promise 1 resolved?',
69
+ await Promise.race([
70
+ promise1.then(() => true),
71
+ new Promise((r) => setTimeout(() => r(false), 0)),
72
+ ])
73
+ );
74
+ console.log(
75
+ 'Promise 2 resolved?',
76
+ await Promise.race([
77
+ promise2.then(() => true),
78
+ new Promise((r) => setTimeout(() => r(false), 0)),
79
+ ])
80
+ );
81
+ console.log(
82
+ 'Promise 3 resolved?',
83
+ await Promise.race([
84
+ promise3.then(() => true),
85
+ new Promise((r) => setTimeout(() => r(false), 0)),
86
+ ])
87
+ );
88
+
89
+ console.log('\n7. Forcing resolution by awaiting all...');
90
+ try {
91
+ const results = await Promise.all([promise1, promise2, promise3]);
92
+ console.log('All promises resolved');
93
+ } catch (e) {
94
+ console.log('Error waiting for promises:', e.message);
95
+ }
96
+
97
+ console.log('\n8. Final state:');
98
+ console.log('Final SIGINT listeners:', process.listeners('SIGINT').length);
99
+ console.log('Expected:', initialListeners);
100
+ console.log(
101
+ 'Match?',
102
+ process.listeners('SIGINT').length === initialListeners
103
+ );
104
+ }
105
+
106
+ testNotAwaitedCleanup().catch(console.error);
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Off Method Debug ===');
6
+
7
+ const cmd = $`echo "test"`;
8
+
9
+ // Override the off method to track when listeners are removed
10
+ const originalOff = cmd.off.bind(cmd);
11
+ cmd.off = function (event, listener) {
12
+ console.log(`OFF called for event: ${event}`);
13
+ console.log(`Listeners before off:`, this.listeners.size);
14
+
15
+ // Get stack trace to see who's calling off
16
+ const stack = new Error().stack;
17
+ console.log('Stack trace:', stack.split('\n').slice(1, 4).join('\n'));
18
+
19
+ const result = originalOff(event, listener);
20
+ console.log(`Listeners after off:`, this.listeners.size);
21
+ return result;
22
+ };
23
+
24
+ cmd.on('data', () => console.log('DATA listener called'));
25
+ cmd.on('end', () => console.log('END listener called'));
26
+ cmd.on('exit', () => console.log('EXIT listener called'));
27
+
28
+ await cmd;