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,41 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Testing jq color output in pipelines ===\n');
6
+
7
+ // Test 1: Direct jq with color output
8
+ console.log('1. Direct jq command with --color-output:');
9
+ const directResult =
10
+ await $`echo '{"name": "test", "value": 42, "active": true}' | jq --color-output .`;
11
+ console.log('Raw output:');
12
+ process.stdout.write(directResult.stdout);
13
+ console.log('\nRaw bytes (first 100):');
14
+ console.log(Buffer.from(directResult.stdout.slice(0, 100)));
15
+
16
+ console.log('\n2. Pipeline with jq --color-output:');
17
+ const pipeResult =
18
+ await $`echo '{"users": [{"name": "Alice", "age": 30}, {"name": "Bob", "age": 25}]}' | jq --color-output '.users[]'`;
19
+ console.log('Raw output:');
20
+ process.stdout.write(pipeResult.stdout);
21
+
22
+ console.log('\n3. Testing if jq auto-detects color capability:');
23
+ const autoResult = await $`echo '{"test": "data"}' | jq .`;
24
+ console.log('Raw output (should have colors if terminal supports it):');
25
+ process.stdout.write(autoResult.stdout);
26
+
27
+ console.log('\n4. Testing streaming behavior:');
28
+ const streamProc = $`printf '{"a":1}\\n{"b":2}\\n{"c":3}\\n' | jq --color-output -c .`;
29
+
30
+ console.log('Streaming output:');
31
+ streamProc.on('stdout', (chunk) => {
32
+ process.stdout.write('CHUNK: ');
33
+ process.stdout.write(chunk);
34
+ });
35
+
36
+ await streamProc;
37
+
38
+ console.log('\n=== Analysis ===');
39
+ console.log('- Direct jq should show colors if --color-output is used');
40
+ console.log('- Pipeline should preserve ANSI codes in streaming');
41
+ console.log('- Check raw bytes to see ANSI escape sequences (\\x1b[...)');
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env bun
2
+
3
+ // Test jq with compact output mode
4
+
5
+ console.log('Test: jq with -c (compact) flag\n');
6
+
7
+ const proc1 = Bun.spawn(['./js/examples/emulate-claude-stream.mjs'], {
8
+ stdout: 'pipe',
9
+ stderr: 'pipe',
10
+ });
11
+
12
+ // Use jq -c for compact output (one line per JSON object)
13
+ const proc2 = Bun.spawn(['jq', '-c', '.'], {
14
+ stdin: proc1.stdout,
15
+ stdout: 'pipe',
16
+ stderr: 'pipe',
17
+ });
18
+
19
+ const start = Date.now();
20
+ let chunkCount = 0;
21
+
22
+ for await (const chunk of proc2.stdout) {
23
+ chunkCount++;
24
+ const elapsed = Date.now() - start;
25
+ const text = Buffer.from(chunk).toString().trim();
26
+
27
+ console.log(`[${elapsed}ms] Chunk ${chunkCount}: ${text}`);
28
+ }
29
+
30
+ console.log(`\nTotal chunks received: ${chunkCount}`);
31
+
32
+ await proc1.exited;
33
+ await proc2.exited;
@@ -0,0 +1,10 @@
1
+ #!/bin/bash
2
+
3
+ echo "Testing native jq streaming (without our library):"
4
+ echo "Each JSON object should appear immediately, not all at once"
5
+ echo ""
6
+
7
+ # Test with delays - jq should output each line as it arrives
8
+ (echo '{"n":1}'; sleep 0.5; echo '{"n":2}'; sleep 0.5; echo '{"n":3}') | jq . | while read line; do
9
+ echo "[$(date +%s%3N)] $line"
10
+ done
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test to demonstrate jq's color behavior in different contexts
5
+ */
6
+
7
+ import { $ } from '../src/$.mjs';
8
+ import { execSync } from 'child_process';
9
+
10
+ const testJson = '{"message": "hello", "number": 42}';
11
+
12
+ console.log('='.repeat(60));
13
+ console.log('JQ COLOR BEHAVIOR IN DIFFERENT CONTEXTS');
14
+ console.log('='.repeat(60));
15
+
16
+ console.log('\nEnvironment:', {
17
+ 'process.stdout.isTTY': process.stdout.isTTY,
18
+ TERM: process.env.TERM,
19
+ });
20
+
21
+ console.log('\n1. JQ IN A PIPELINE (through command-stream):');
22
+ console.log('-'.repeat(40));
23
+ // When jq is part of a pipeline, it detects it's not writing to a TTY
24
+ const pipeResult = await $`echo ${testJson} | jq .`;
25
+ console.log('Command: echo ... | jq .');
26
+ console.log('Has colors:', /\u001b\[\d+/.test(pipeResult.stdout));
27
+ console.log("Reason: jq detects it's in a pipeline, not direct TTY output\n");
28
+
29
+ console.log('2. JQ DIRECTLY TO TTY (if possible):');
30
+ console.log('-'.repeat(40));
31
+ try {
32
+ // Try to run jq directly without a pipe
33
+ const directResult = await $`jq . <<< '${testJson}'`;
34
+ console.log('Command: jq . <<< ...');
35
+ console.log('Has colors:', /\u001b\[\d+/.test(directResult.stdout));
36
+ console.log('Output sample:', directResult.stdout.substring(0, 50));
37
+ } catch (e) {
38
+ console.log('Could not test direct jq (bash syntax not supported)');
39
+ }
40
+
41
+ console.log('\n3. JQ WITH EXPLICIT COLOR FLAGS:');
42
+ console.log('-'.repeat(40));
43
+ const colorResult = await $`echo ${testJson} | jq -C .`;
44
+ console.log('Command: echo ... | jq -C .');
45
+ console.log(
46
+ 'Has colors:',
47
+ /\u001b\[\d+/.test(colorResult.stdout),
48
+ '(forced with -C)'
49
+ );
50
+
51
+ const noColorResult = await $`echo ${testJson} | jq -M .`;
52
+ console.log('Command: echo ... | jq -M .');
53
+ console.log(
54
+ 'Has colors:',
55
+ /\u001b\[\d+/.test(noColorResult.stdout),
56
+ '(disabled with -M)'
57
+ );
58
+
59
+ console.log('\n4. DIRECT SHELL EXECUTION (for comparison):');
60
+ console.log('-'.repeat(40));
61
+ try {
62
+ // Using execSync to run directly in shell
63
+ const shellOutput = execSync(`echo '${testJson}' | jq .`, {
64
+ encoding: 'utf8',
65
+ shell: '/bin/sh',
66
+ });
67
+ console.log('Via execSync with shell:');
68
+ console.log('Has colors:', /\u001b\[\d+/.test(shellOutput));
69
+ } catch (e) {
70
+ console.log('Error:', e.message);
71
+ }
72
+
73
+ console.log(`\n${'='.repeat(60)}`);
74
+ console.log('SUMMARY:');
75
+ console.log("- jq auto-detects when it's in a pipeline vs direct TTY");
76
+ console.log('- In pipelines, jq disables colors by default (smart behavior)');
77
+ console.log('- This is why the test sees no colors even with isTTY=true');
78
+ console.log('- The -C flag forces colors even in pipelines');
79
+ console.log('- The -M flag disables colors even with TTY');
80
+ console.log('='.repeat(60));
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Testing Real-Time jq Streaming ===\n');
6
+
7
+ console.log('Test: Emulated Claude stream with jq formatting');
8
+ const start = Date.now();
9
+ let lastTime = start;
10
+ let chunkCount = 0;
11
+
12
+ for await (const chunk of $`bun run js/examples/emulate-claude-stream.mjs | jq .`.stream()) {
13
+ if (chunk.type === 'stdout') {
14
+ chunkCount++;
15
+ const now = Date.now();
16
+ const elapsed = now - start;
17
+ const delta = now - lastTime;
18
+ lastTime = now;
19
+
20
+ const text = chunk.data.toString().trim();
21
+ if (text) {
22
+ console.log(`[${elapsed}ms, +${delta}ms] Chunk ${chunkCount}:`);
23
+ console.log(text);
24
+ console.log('---');
25
+ }
26
+ }
27
+ }
28
+
29
+ console.log(`\nTotal chunks received: ${chunkCount}`);
30
+ console.log(`Total time: ${Date.now() - start}ms`);
31
+
32
+ if (chunkCount >= 5) {
33
+ console.log(
34
+ '✅ SUCCESS: Real-time streaming is working! We received multiple chunks over time.'
35
+ );
36
+ } else if (chunkCount === 1) {
37
+ console.log('❌ FAIL: All output was buffered into a single chunk.');
38
+ } else {
39
+ console.log('⚠️ WARNING: Received fewer chunks than expected.');
40
+ }
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ async function testManualStart() {
6
+ console.log('🧪 Testing manual start with pipe stdin');
7
+
8
+ // Start manually with correct options
9
+ const sortCmd = $`sort`;
10
+ console.log('1. Created sort command');
11
+
12
+ // Manual start with correct stdio
13
+ await sortCmd.start({
14
+ mode: 'async',
15
+ stdin: 'pipe',
16
+ stdout: 'pipe',
17
+ stderr: 'pipe',
18
+ });
19
+ console.log('2. Manually started with pipe stdio');
20
+
21
+ console.log('3. After manual start:');
22
+ console.log(' started:', sortCmd.started);
23
+ console.log(' child exists:', !!sortCmd.child);
24
+
25
+ if (sortCmd.child) {
26
+ console.log(' child.stdin exists:', !!sortCmd.child.stdin);
27
+ console.log(
28
+ ' child.stdin writable:',
29
+ sortCmd.child.stdin ? sortCmd.child.stdin.writable : 'N/A'
30
+ );
31
+ console.log(' child.stdin type:', typeof sortCmd.child.stdin);
32
+ }
33
+
34
+ // Now try to get stdin through streams
35
+ const stdin = await sortCmd.streams.stdin;
36
+ console.log('4. Got stdin through streams:');
37
+ console.log(' type:', typeof stdin);
38
+ console.log(' has write:', !!(stdin && stdin.write));
39
+
40
+ if (stdin && stdin.write) {
41
+ console.log('5. Writing to stdin...');
42
+ stdin.write('zebra\n');
43
+ stdin.write('apple\n');
44
+ stdin.end();
45
+
46
+ const result = await sortCmd;
47
+ console.log(' Result:', JSON.stringify(result.stdout));
48
+ } else {
49
+ console.log('5. No writable stdin, killing...');
50
+ sortCmd.kill();
51
+ }
52
+ }
53
+
54
+ testManualStart();
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Test: Mixed quoted and unquoted arguments
4
+ // Expected: Each argument properly handled based on its content
5
+
6
+ import { $ } from '../src/$.mjs';
7
+
8
+ console.log('=== Test: Mixed Quoting Scenarios ===\n');
9
+
10
+ async function testMixedQuoting() {
11
+ console.log('1. Multiple interpolations in one command:');
12
+ console.log('------------------------------------------');
13
+
14
+ const cmd = 'echo';
15
+ const arg1 = 'hello';
16
+ const arg2 = 'world';
17
+ const arg3 = '$USER';
18
+
19
+ const command = $({ mirror: false })`${cmd} ${arg1} ${arg2} ${arg3}`;
20
+ console.log('Inputs:', { cmd, arg1, arg2, arg3 });
21
+ console.log('Generated:', command.spec.command);
22
+
23
+ try {
24
+ const result = await command;
25
+ console.log('Output:', String(result).trim());
26
+ } catch (error) {
27
+ console.log('Error:', error.message);
28
+ }
29
+
30
+ console.log('\n2. Mix of pre-quoted and unquoted:');
31
+ console.log('-----------------------------------');
32
+
33
+ const quotedPath = '"/path with spaces/file.txt"';
34
+ const unquotedPath = 'output.log';
35
+
36
+ const mixedCmd = $({ mirror: false })`cat ${quotedPath} > ${unquotedPath}`;
37
+ console.log('Quoted input:', quotedPath);
38
+ console.log('Unquoted input:', unquotedPath);
39
+ console.log('Generated:', mixedCmd.spec.command);
40
+
41
+ console.log('\n3. Command construction with various types:');
42
+ console.log('--------------------------------------------');
43
+
44
+ const executable = '/usr/bin/env';
45
+ const program = 'node';
46
+ const flag = '--version';
47
+ const envVar = 'NODE_ENV=production';
48
+
49
+ const complexCmd = $({
50
+ mirror: false,
51
+ })`${envVar} ${executable} ${program} ${flag}`;
52
+ console.log('Components:', { envVar, executable, program, flag });
53
+ console.log('Generated:', complexCmd.spec.command);
54
+
55
+ console.log('\n4. User mixes single and double quotes:');
56
+ console.log('----------------------------------------');
57
+
58
+ const singleQuotedArg = "'my-file.txt'";
59
+ const doubleQuotedArg = '"another file.txt"';
60
+ const unquotedArg = 'regular.txt';
61
+
62
+ const userMixedCmd = $({
63
+ mirror: false,
64
+ })`ls ${singleQuotedArg} ${doubleQuotedArg} ${unquotedArg}`;
65
+ console.log('Single quoted:', singleQuotedArg);
66
+ console.log('Double quoted:', doubleQuotedArg);
67
+ console.log('Unquoted:', unquotedArg);
68
+ console.log('Generated:', userMixedCmd.spec.command);
69
+
70
+ console.log('\n5. Path interpolation positions:');
71
+ console.log('---------------------------------');
72
+
73
+ const testPath = '/Users/konard/.claude/local/claude';
74
+
75
+ // First position (command)
76
+ const firstPos = $({ mirror: false })`${testPath} --version`;
77
+ console.log('First position:', firstPos.spec.command);
78
+
79
+ // Middle position
80
+ const middlePos = $({ mirror: false })`echo ${testPath} done`;
81
+ console.log('Middle position:', middlePos.spec.command);
82
+
83
+ // Last position
84
+ const lastPos = $({ mirror: false })`file ${testPath}`;
85
+ console.log('Last position:', lastPos.spec.command);
86
+ }
87
+
88
+ testMixedQuoting().catch(console.error);
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env bun
2
+
3
+ // Test reading from multiple processes in pipeline simultaneously
4
+
5
+ console.log('=== Testing Multi-Stream Pipeline Reading ===\n');
6
+
7
+ const proc1 = Bun.spawn(
8
+ ['bun', 'run', 'js/examples/emulate-claude-stream.mjs'],
9
+ {
10
+ stdout: 'pipe',
11
+ stderr: 'pipe',
12
+ }
13
+ );
14
+
15
+ // Use tee to split the stream so we can both pipe it and read it
16
+ const [readStream, pipeStream] = proc1.stdout.tee();
17
+
18
+ const proc2 = Bun.spawn(['jq', '.'], {
19
+ stdin: pipeStream,
20
+ stdout: 'pipe',
21
+ stderr: 'pipe',
22
+ });
23
+
24
+ const start = Date.now();
25
+
26
+ // Read from proc1's tee'd stream for real-time updates
27
+ console.log('Reading from source (proc1):');
28
+ (async () => {
29
+ for await (const chunk of readStream) {
30
+ const elapsed = Date.now() - start;
31
+ const text = Buffer.from(chunk).toString().trim();
32
+ console.log(` [${elapsed}ms] Source: ${text}`);
33
+ }
34
+ })();
35
+
36
+ // Also read from proc2 to get the final jq output
37
+ console.log('\nReading from jq output (proc2):');
38
+ let jqOutput = '';
39
+ for await (const chunk of proc2.stdout) {
40
+ const elapsed = Date.now() - start;
41
+ const text = Buffer.from(chunk).toString();
42
+ jqOutput += text;
43
+ console.log(` [${elapsed}ms] jq completed, ${chunk.length} bytes`);
44
+ }
45
+
46
+ console.log('\nFinal jq output:');
47
+ console.log(jqOutput);
48
+
49
+ await proc1.exited;
50
+ await proc2.exited;
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Debug Multi-Stage Pipeline ===\n');
6
+
7
+ console.log('Testing: emulate | cat | jq');
8
+ const start = Date.now();
9
+ let chunkCount = 0;
10
+ let firstChunkTime = null;
11
+ let lastChunkTime = null;
12
+
13
+ for await (const chunk of $`bun run js/examples/emulate-claude-stream.mjs | cat | jq .`.stream()) {
14
+ if (chunk.type === 'stdout') {
15
+ chunkCount++;
16
+ const elapsed = Date.now() - start;
17
+
18
+ if (!firstChunkTime) {
19
+ firstChunkTime = elapsed;
20
+ }
21
+ lastChunkTime = elapsed;
22
+
23
+ console.log(
24
+ `[${elapsed}ms] Chunk ${chunkCount}: ${chunk.data.length} bytes`
25
+ );
26
+ }
27
+ }
28
+
29
+ console.log(`\nSummary:`);
30
+ console.log(`- Total chunks: ${chunkCount}`);
31
+ console.log(`- First chunk at: ${firstChunkTime}ms`);
32
+ console.log(`- Last chunk at: ${lastChunkTime}ms`);
33
+ console.log(`- Time span: ${lastChunkTime - firstChunkTime}ms`);
34
+
35
+ if (chunkCount === 1) {
36
+ console.log('\n❌ All output was buffered into a single chunk');
37
+ console.log('This means jq collected all input before producing output');
38
+ } else if (lastChunkTime - firstChunkTime < 100) {
39
+ console.log('\n⚠️ Chunks arrived very close together (< 100ms span)');
40
+ console.log('This suggests partial buffering');
41
+ } else {
42
+ console.log('\n✅ Real-time streaming is working!');
43
+ console.log('Chunks arrived over time as expected');
44
+ }
@@ -0,0 +1,154 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test to prove that native spawn/child_process cannot kill ping via stdin,
5
+ * but our command-stream library can kill it properly with the kill() method.
6
+ */
7
+
8
+ import { spawn } from 'child_process';
9
+ import { $ } from '../src/$.mjs';
10
+
11
+ console.log('=== Testing Native spawn vs command-stream kill capabilities ===');
12
+ console.log('');
13
+
14
+ async function testNativeSpawnVsCommandStream() {
15
+ try {
16
+ console.log(
17
+ 'TEST 1: Native spawn - try to kill ping via stdin (will fail)'
18
+ );
19
+
20
+ const nativeProcess = spawn('ping', ['8.8.8.8']);
21
+ console.log('✓ Native ping process started, PID:', nativeProcess.pid);
22
+
23
+ // Try to send CTRL+C via stdin (this won't work for ping)
24
+ setTimeout(() => {
25
+ console.log(' Attempting to send CTRL+C via stdin to native ping...');
26
+ nativeProcess.stdin.write('\x03'); // CTRL+C
27
+ nativeProcess.stdin.end();
28
+ }, 2000);
29
+
30
+ // Set up a timeout to kill the process since stdin won't work
31
+ const killTimeout = setTimeout(() => {
32
+ console.log(' stdin CTRL+C failed (as expected), using SIGTERM...');
33
+ nativeProcess.kill('SIGTERM');
34
+ }, 4000);
35
+
36
+ const nativeResult = await new Promise((resolve) => {
37
+ let stdout = '';
38
+ let stderr = '';
39
+
40
+ nativeProcess.stdout.on('data', (data) => {
41
+ stdout += data.toString();
42
+ process.stdout.write(`[NATIVE] ${data}`);
43
+ });
44
+
45
+ nativeProcess.stderr.on('data', (data) => {
46
+ stderr += data.toString();
47
+ });
48
+
49
+ nativeProcess.on('close', (code, signal) => {
50
+ clearTimeout(killTimeout);
51
+ resolve({ code, signal, stdout, stderr });
52
+ });
53
+ });
54
+
55
+ console.log(
56
+ ' Native ping terminated with code:',
57
+ nativeResult.code,
58
+ 'signal:',
59
+ nativeResult.signal
60
+ );
61
+ console.log(' Output length:', nativeResult.stdout.length);
62
+
63
+ console.log('');
64
+ console.log(
65
+ 'TEST 2: command-stream - kill ping using kill() method (will work)'
66
+ );
67
+
68
+ const streamCommand = $`ping 8.8.8.8`;
69
+
70
+ // Access stdout to start the process
71
+ const stdout = streamCommand.streams.stdout;
72
+ console.log('✓ command-stream ping started');
73
+
74
+ // Set up data listener to see output
75
+ if (stdout) {
76
+ stdout.on('data', (data) => {
77
+ process.stdout.write(`[STREAM] ${data}`);
78
+ });
79
+ }
80
+
81
+ // Kill after 2 seconds using our kill() method
82
+ setTimeout(() => {
83
+ console.log(' Killing command-stream ping using kill() method...');
84
+ streamCommand.kill();
85
+ }, 2000);
86
+
87
+ const streamResult = await streamCommand;
88
+ console.log(
89
+ ' command-stream ping terminated with code:',
90
+ streamResult.code
91
+ );
92
+ console.log(' Output length:', streamResult.stdout.length);
93
+
94
+ console.log('');
95
+ console.log(
96
+ 'TEST 3: Show stdin works for commands that actually read stdin'
97
+ );
98
+
99
+ console.log(' Testing native spawn with cat (stdin should work)...');
100
+ const nativeCat = spawn('cat');
101
+
102
+ nativeCat.stdin.write('Hello from native cat\n');
103
+ nativeCat.stdin.end();
104
+
105
+ const catResult = await new Promise((resolve) => {
106
+ let output = '';
107
+ nativeCat.stdout.on('data', (data) => {
108
+ output += data.toString();
109
+ });
110
+ nativeCat.on('close', (code) => {
111
+ resolve({ code, output });
112
+ });
113
+ });
114
+
115
+ console.log(' Native cat result:', JSON.stringify(catResult.output));
116
+
117
+ console.log(' Testing command-stream with cat...');
118
+ const streamCat = $`cat`;
119
+ const catStdin = streamCat.streams.stdin;
120
+
121
+ if (catStdin) {
122
+ catStdin.write('Hello from command-stream cat\n');
123
+ catStdin.end();
124
+ }
125
+
126
+ const streamCatResult = await streamCat;
127
+ console.log(
128
+ ' command-stream cat result:',
129
+ JSON.stringify(streamCatResult.stdout)
130
+ );
131
+
132
+ console.log('');
133
+ console.log('✅ CONCLUSIONS:');
134
+ console.log(
135
+ ' 1. Native spawn cannot kill ping via stdin CTRL+C (ping ignores stdin)'
136
+ );
137
+ console.log(
138
+ ' 2. command-stream kill() method properly terminates ping with signals'
139
+ );
140
+ console.log(
141
+ ' 3. Both native spawn and command-stream work fine with stdin for commands that read it (like cat)'
142
+ );
143
+ console.log(
144
+ ' 4. For ping specifically, you need kill() method, not stdin manipulation'
145
+ );
146
+ } catch (error) {
147
+ console.log('');
148
+ console.error('❌ TEST FAILED:', error.message);
149
+ console.error(error.stack);
150
+ process.exit(1);
151
+ }
152
+ }
153
+
154
+ testNativeSpawnVsCommandStream();
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('Testing: Disable pipeline parsing, let sh handle it\n');
6
+
7
+ // Temporarily disable pipeline parsing to test
8
+ const originalParse = $.prototype._parseCommand;
9
+ $.prototype._parseCommand = function (command) {
10
+ // Skip pipeline parsing
11
+ return null;
12
+ };
13
+
14
+ const start = Date.now();
15
+
16
+ // This will now be executed as a single sh command
17
+ const cmd = $`bun run js/examples/emulate-claude-stream.mjs | jq .`;
18
+
19
+ for await (const chunk of cmd.stream()) {
20
+ if (chunk.type === 'stdout') {
21
+ const elapsed = Date.now() - start;
22
+ const lines = chunk.data
23
+ .toString()
24
+ .split('\n')
25
+ .filter((l) => l.trim());
26
+ for (const line of lines) {
27
+ console.log(`[${elapsed}ms] ${line}`);
28
+ }
29
+ }
30
+ }
31
+
32
+ // Restore original parsing
33
+ $.prototype._parseCommand = originalParse;
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ async function testNonVirtual() {
6
+ console.log('🧪 Testing with definitely non-virtual command');
7
+
8
+ // Use wc which should not be virtual
9
+ const wcCmd = $`wc -l`;
10
+ console.log('1. Created wc command');
11
+
12
+ // Check if process spawns properly with regular async execution
13
+ console.log('2. Testing normal execution first...');
14
+ const testCmd = $`wc -l`;
15
+ const testResult = await testCmd.start({ stdin: 'test\nline2\n' });
16
+ console.log(' Normal execution result:', testResult.stdout.trim());
17
+
18
+ // Now test streams
19
+ console.log('3. Testing streams...');
20
+ await wcCmd.start({
21
+ mode: 'async',
22
+ stdin: 'pipe',
23
+ stdout: 'pipe',
24
+ stderr: 'pipe',
25
+ });
26
+
27
+ console.log('4. After start:');
28
+ console.log(' started:', wcCmd.started);
29
+ console.log(' child exists:', !!wcCmd.child);
30
+ console.log(' finished:', wcCmd.finished);
31
+
32
+ if (wcCmd.child) {
33
+ console.log(' child.pid:', wcCmd.child.pid);
34
+ console.log(' child.stdin:', typeof wcCmd.child.stdin);
35
+ }
36
+
37
+ // Try direct access to child stdin if available
38
+ if (wcCmd.child && wcCmd.child.stdin) {
39
+ console.log('5. Direct child.stdin access works!');
40
+ wcCmd.child.stdin.write('line1\n');
41
+ wcCmd.child.stdin.write('line2\n');
42
+ wcCmd.child.stdin.end();
43
+
44
+ const result = await wcCmd;
45
+ console.log(' Direct access result:', result.stdout.trim());
46
+ } else {
47
+ console.log('5. No child.stdin available');
48
+ wcCmd.kill();
49
+ }
50
+ }
51
+
52
+ testNonVirtual();