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,119 @@
1
+ #!/usr/bin/env bun
2
+
3
+ // Test different ways to read from piped processes
4
+
5
+ console.log('=== Testing Direct Pipe Reading Methods ===\n');
6
+
7
+ // Method 1: Two separate processes with manual pipe
8
+ console.log('Method 1: Manual pipe connection with for await:');
9
+ {
10
+ const proc1 = Bun.spawn(
11
+ ['bun', 'run', 'js/examples/emulate-claude-stream.mjs'],
12
+ {
13
+ stdout: 'pipe',
14
+ stderr: 'pipe',
15
+ }
16
+ );
17
+
18
+ const proc2 = Bun.spawn(['jq', '.'], {
19
+ stdin: proc1.stdout,
20
+ stdout: 'pipe',
21
+ stderr: 'pipe',
22
+ });
23
+
24
+ const start = Date.now();
25
+ let chunkCount = 0;
26
+
27
+ // Read using for await
28
+ for await (const chunk of proc2.stdout) {
29
+ chunkCount++;
30
+ const elapsed = Date.now() - start;
31
+ console.log(` [${elapsed}ms] Chunk ${chunkCount}: ${chunk.length} bytes`);
32
+ }
33
+
34
+ await proc1.exited;
35
+ await proc2.exited;
36
+ }
37
+
38
+ // Method 2: Try reading proc1.stdout directly while it's also piped
39
+ console.log('\nMethod 2: Read from first process while piped:');
40
+ {
41
+ const proc1 = Bun.spawn(
42
+ ['bun', 'run', 'js/examples/emulate-claude-stream.mjs'],
43
+ {
44
+ stdout: 'pipe',
45
+ stderr: 'pipe',
46
+ }
47
+ );
48
+
49
+ const start = Date.now();
50
+ let chunkCount = 0;
51
+
52
+ // Try to read proc1 stdout directly (even though it will be piped)
53
+ for await (const chunk of proc1.stdout) {
54
+ chunkCount++;
55
+ const elapsed = Date.now() - start;
56
+ const text = Buffer.from(chunk).toString().trim();
57
+ console.log(` [${elapsed}ms] From proc1: ${text}`);
58
+ }
59
+
60
+ await proc1.exited;
61
+ }
62
+
63
+ // Method 3: Use tee to split the stream
64
+ console.log('\nMethod 3: Using tee() to split stream:');
65
+ {
66
+ const proc1 = Bun.spawn(
67
+ ['bun', 'run', 'js/examples/emulate-claude-stream.mjs'],
68
+ {
69
+ stdout: 'pipe',
70
+ stderr: 'pipe',
71
+ }
72
+ );
73
+
74
+ // Use ReadableStream.tee() to split the stream
75
+ const [stream1, stream2] = proc1.stdout.tee();
76
+
77
+ const proc2 = Bun.spawn(['jq', '.'], {
78
+ stdin: stream2,
79
+ stdout: 'pipe',
80
+ stderr: 'pipe',
81
+ });
82
+
83
+ const start = Date.now();
84
+ let chunkCount = 0;
85
+
86
+ // Read from the tee'd stream
87
+ for await (const chunk of stream1) {
88
+ chunkCount++;
89
+ const elapsed = Date.now() - start;
90
+ const text = Buffer.from(chunk).toString().trim();
91
+ console.log(` [${elapsed}ms] From tee: ${text}`);
92
+ }
93
+
94
+ await proc1.exited;
95
+ await proc2.exited;
96
+ }
97
+
98
+ // Method 4: What if we DON'T pipe and just run the full command?
99
+ console.log('\nMethod 4: Full pipeline as single command:');
100
+ {
101
+ const proc = Bun.spawn(
102
+ ['sh', '-c', 'bun run js/examples/emulate-claude-stream.mjs | jq .'],
103
+ {
104
+ stdout: 'pipe',
105
+ stderr: 'pipe',
106
+ }
107
+ );
108
+
109
+ const start = Date.now();
110
+ let chunkCount = 0;
111
+
112
+ for await (const chunk of proc.stdout) {
113
+ chunkCount++;
114
+ const elapsed = Date.now() - start;
115
+ console.log(` [${elapsed}ms] Chunk ${chunkCount}: ${chunk.length} bytes`);
116
+ }
117
+
118
+ await proc.exited;
119
+ }
@@ -0,0 +1,28 @@
1
+ #!/bin/bash
2
+
3
+ echo "Testing if jq buffers output:"
4
+ echo ""
5
+
6
+ # Create a script that outputs JSON with delays
7
+ cat > /tmp/stream-test.sh << 'EOF'
8
+ #!/bin/bash
9
+ echo '{"n":1}'
10
+ sleep 0.5
11
+ echo '{"n":2}'
12
+ sleep 0.5
13
+ echo '{"n":3}'
14
+ EOF
15
+
16
+ chmod +x /tmp/stream-test.sh
17
+
18
+ echo "Running: /tmp/stream-test.sh | jq . | while read line..."
19
+ echo "If jq doesn't buffer, we should see output every 0.5 seconds"
20
+ echo ""
21
+
22
+ start=$SECONDS
23
+ /tmp/stream-test.sh | jq . | while IFS= read -r line; do
24
+ elapsed=$((SECONDS - start))
25
+ echo "[${elapsed}s] $line"
26
+ done
27
+
28
+ rm /tmp/stream-test.sh
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Test: Prevent double-quoting when user provides quotes on strings that need quoting
4
+ import { $ } from '../src/$.mjs';
5
+
6
+ console.log('=== Double-Quoting Prevention Test ===\n');
7
+
8
+ async function testDoubleQuoting() {
9
+ console.log('Scenario 1: User quotes a path with spaces');
10
+ console.log('-------------------------------------------');
11
+
12
+ // User provides quotes around a path with spaces
13
+ const pathWithSpaces = '/path with spaces/command';
14
+ const userQuoted1 = `'${pathWithSpaces}'`;
15
+ const userQuoted2 = `"${pathWithSpaces}"`;
16
+
17
+ console.log('Original path:', pathWithSpaces);
18
+ console.log('\nUser provides single quotes:', userQuoted1);
19
+ const cmd1 = $({ mirror: false })`${userQuoted1} --test`;
20
+ console.log('Generated:', cmd1.spec.command);
21
+ console.log('Expected: Already quoted, should not double-quote');
22
+
23
+ console.log('\nUser provides double quotes:', userQuoted2);
24
+ const cmd2 = $({ mirror: false })`${userQuoted2} --test`;
25
+ console.log('Generated:', cmd2.spec.command);
26
+ console.log('Expected: Preserve double quotes (wrap in single quotes)');
27
+
28
+ console.log('\n\nScenario 2: User quotes a string with special characters');
29
+ console.log('----------------------------------------------------------');
30
+
31
+ // User provides quotes around dangerous strings
32
+ const dangerous = 'test; echo HACKED';
33
+ const userQuotedDanger1 = `'${dangerous}'`;
34
+ const userQuotedDanger2 = `"${dangerous}"`;
35
+
36
+ console.log('Dangerous string:', dangerous);
37
+ console.log('\nUser provides single quotes:', userQuotedDanger1);
38
+ const cmd3 = $({ mirror: false })`echo ${userQuotedDanger1}`;
39
+ console.log('Generated:', cmd3.spec.command);
40
+ console.log('Expected: Already single-quoted, should not double-quote');
41
+
42
+ console.log('\nUser provides double quotes:', userQuotedDanger2);
43
+ const cmd4 = $({ mirror: false })`echo ${userQuotedDanger2}`;
44
+ console.log('Generated:', cmd4.spec.command);
45
+ console.log('Expected: Preserve double quotes (wrap in single quotes)');
46
+
47
+ console.log('\n\nScenario 3: User quotes safe strings (unnecessary)');
48
+ console.log('----------------------------------------------------');
49
+
50
+ const safe = 'hello';
51
+ const userQuotedSafe1 = `'${safe}'`;
52
+ const userQuotedSafe2 = `"${safe}"`;
53
+
54
+ console.log('Safe string:', safe);
55
+ console.log('\nUser unnecessarily single-quotes:', userQuotedSafe1);
56
+ const cmd5 = $({ mirror: false })`echo ${userQuotedSafe1}`;
57
+ console.log('Generated:', cmd5.spec.command);
58
+ console.log("Expected: Preserve user's quotes even if unnecessary");
59
+
60
+ console.log('\nUser unnecessarily double-quotes:', userQuotedSafe2);
61
+ const cmd6 = $({ mirror: false })`echo ${userQuotedSafe2}`;
62
+ console.log('Generated:', cmd6.spec.command);
63
+ console.log("Expected: Preserve user's quotes (wrap in single quotes)");
64
+
65
+ console.log('\n\nScenario 4: Complex edge cases');
66
+ console.log('--------------------------------');
67
+
68
+ // User quotes a string that contains quotes
69
+ const withQuotes = "it's a test";
70
+ const userQuotedComplex = `"${withQuotes}"`;
71
+
72
+ console.log('String with internal quotes:', withQuotes);
73
+ console.log('User wraps in double quotes:', userQuotedComplex);
74
+ const cmd7 = $({ mirror: false })`echo ${userQuotedComplex}`;
75
+ console.log('Generated:', cmd7.spec.command);
76
+ console.log('Expected: Preserve double quotes, wrap in single quotes');
77
+
78
+ // User provides escaped quotes
79
+ const alreadyEscaped = "\\'test\\'";
80
+ console.log('\nAlready escaped string:', alreadyEscaped);
81
+ const cmd8 = $({ mirror: false })`echo ${alreadyEscaped}`;
82
+ console.log('Generated:', cmd8.spec.command);
83
+ console.log('Expected: Handle escaped quotes properly');
84
+
85
+ console.log('\n\n=== Verification Tests ===\n');
86
+
87
+ // Test that the commands actually work
88
+ console.log('Testing actual execution:');
89
+
90
+ try {
91
+ // Test with user-quoted path with spaces
92
+ const testPath = '"/test path/cmd"';
93
+ const testCmd = $({ capture: true, mirror: false })`echo ${testPath}`;
94
+ const result = await testCmd;
95
+ console.log('\nInput:', testPath);
96
+ console.log('Command:', testCmd.spec.command);
97
+ console.log('Output:', (result.stdout || String(result)).trim());
98
+ console.log(
99
+ 'Verification:',
100
+ (result.stdout || String(result)).trim() === '"/test path/cmd"'
101
+ ? 'āœ… Quotes preserved correctly'
102
+ : 'āŒ Quotes not preserved'
103
+ );
104
+
105
+ // Test with user-quoted dangerous string
106
+ const testDanger = "'test; echo BAD'";
107
+ const dangerCmd = $({ capture: true, mirror: false })`echo ${testDanger}`;
108
+ const dangerResult = await dangerCmd;
109
+ console.log('\nInput:', testDanger);
110
+ console.log('Command:', dangerCmd.spec.command);
111
+ console.log(
112
+ 'Output:',
113
+ (dangerResult.stdout || String(dangerResult)).trim()
114
+ );
115
+ console.log(
116
+ 'Verification:',
117
+ !(dangerResult.stdout || String(dangerResult)).includes('BAD')
118
+ ? 'āœ… No injection occurred'
119
+ : 'āŒ INJECTION!'
120
+ );
121
+ } catch (error) {
122
+ console.error('Execution error:', error.message);
123
+ }
124
+
125
+ console.log('\n\n=== Double-Quote Prevention Rules ===\n');
126
+ console.log(
127
+ '1. If string starts and ends with single quotes: preserve as-is (no double-quoting)'
128
+ );
129
+ console.log(
130
+ '2. If string starts and ends with double quotes: wrap in single quotes to preserve'
131
+ );
132
+ console.log('3. If string has no quotes but needs them: add single quotes');
133
+ console.log(
134
+ "4. If string has no quotes and doesn't need them: leave unquoted"
135
+ );
136
+ }
137
+
138
+ testDoubleQuoting().catch(console.error);
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Test: Edge cases for quote handling
4
+ // Expected: Proper handling of unusual quoting scenarios
5
+
6
+ import { $ } from '../src/$.mjs';
7
+
8
+ console.log('=== Test: Quote Edge Cases ===\n');
9
+
10
+ const edgeCases = [
11
+ {
12
+ desc: 'Single quote character alone',
13
+ input: "'",
14
+ check: (cmd) => cmd.includes("\\'"),
15
+ },
16
+ {
17
+ desc: 'Double quote character alone',
18
+ input: '"',
19
+ check: (cmd) => true,
20
+ },
21
+ {
22
+ desc: 'Empty single quotes',
23
+ input: "''",
24
+ check: (cmd) => cmd === "echo ''",
25
+ },
26
+ {
27
+ desc: 'Empty double quotes',
28
+ input: '""',
29
+ check: (cmd) => cmd === 'echo \'""\'',
30
+ },
31
+ {
32
+ desc: 'Nested quotes (double inside single)',
33
+ input: '\'"test"\'',
34
+ check: (cmd) => true,
35
+ },
36
+ {
37
+ desc: 'Nested quotes (single inside double)',
38
+ input: '"\'test\'"',
39
+ check: (cmd) => true,
40
+ },
41
+ {
42
+ desc: 'Multiple single quotes',
43
+ input: "'''",
44
+ check: (cmd) => true,
45
+ },
46
+ {
47
+ desc: 'Path with internal quotes',
48
+ input: "/path/with'quote/in'it",
49
+ check: (cmd) => cmd.includes("\\'"),
50
+ },
51
+ {
52
+ desc: 'Already escaped quote',
53
+ input: "can\\'t",
54
+ check: (cmd) => true,
55
+ },
56
+ {
57
+ desc: 'Mix of quotes and spaces',
58
+ input: 'it\'s "a test"',
59
+ check: (cmd) => true,
60
+ },
61
+ ];
62
+
63
+ async function testEdgeCases() {
64
+ for (const { desc, input, check } of edgeCases) {
65
+ console.log(`\n${desc}:`);
66
+ console.log('Input:', JSON.stringify(input));
67
+
68
+ const cmd = $({ mirror: false })`echo ${input}`;
69
+ console.log('Generated:', cmd.spec.command);
70
+
71
+ if (check && check(cmd.spec.command)) {
72
+ console.log('āœ… PASS: Handled correctly');
73
+ } else {
74
+ console.log('āš ļø Check the quoting pattern');
75
+ }
76
+
77
+ // Test actual execution for some cases
78
+ if (!input.includes('|') && !input.includes('&') && !input.includes(';')) {
79
+ try {
80
+ const result = await $`echo ${input}`;
81
+ console.log('Execution output:', JSON.stringify(String(result).trim()));
82
+ } catch (error) {
83
+ console.log('Execution error:', error.message);
84
+ }
85
+ }
86
+ }
87
+ }
88
+
89
+ testEdgeCases().catch(console.error);
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Test Event Emissions ===\n');
6
+
7
+ console.log('Test: emulate | cat | jq with event listeners');
8
+ const cmd = $`bun run js/examples/emulate-claude-stream.mjs | cat | jq .`;
9
+
10
+ const start = Date.now();
11
+ let eventCount = 0;
12
+
13
+ // Listen to raw stdout events
14
+ cmd.on('stdout', (data) => {
15
+ eventCount++;
16
+ const elapsed = Date.now() - start;
17
+ const text = data.toString().trim();
18
+ if (eventCount <= 3 || elapsed < 700) {
19
+ console.log(
20
+ `[${elapsed}ms] Event ${eventCount}: ${text.substring(0, 50)}...`
21
+ );
22
+ }
23
+ });
24
+
25
+ // Also run the command
26
+ const result = await cmd;
27
+
28
+ console.log(`\nTotal events: ${eventCount}`);
29
+ console.log(`Final output length: ${result.stdout.length} chars`);
30
+
31
+ if (eventCount >= 5) {
32
+ console.log('āœ… Real-time events are being emitted from source!');
33
+ console.log('The implementation is streaming correctly.');
34
+ console.log('The formatted jq output is available in result.stdout');
35
+ } else {
36
+ console.log('āŒ Not enough events emitted');
37
+ }
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Test with explicit stdio configuration ===');
6
+
7
+ async function testExplicitStdio() {
8
+ console.log('Test 1: Use run() with explicit stdio');
9
+
10
+ const cmd1 = $`cat`;
11
+ const stdin1 = cmd1.streams.stdin;
12
+
13
+ console.log('Stdin before run:', !!stdin1);
14
+
15
+ // Explicitly set stdio to pipe mode
16
+ const runPromise = cmd1.run({
17
+ stdin: 'pipe',
18
+ stdout: 'pipe',
19
+ stderr: 'pipe',
20
+ });
21
+
22
+ console.log('Command started?', cmd1.started);
23
+ console.log('Stdin after start:', !!cmd1.streams.stdin);
24
+
25
+ const actualStdin = cmd1.streams.stdin;
26
+ if (actualStdin) {
27
+ actualStdin.write('Hello explicit stdio\\n');
28
+ actualStdin.end();
29
+ }
30
+
31
+ const result1 = await runPromise;
32
+ console.log('Result:', result1);
33
+
34
+ console.log('\\nTest 2: Start manually with stdio options');
35
+
36
+ const cmd2 = $`cat`;
37
+ cmd2.start({ mode: 'async', stdin: 'pipe', stdout: 'pipe', stderr: 'pipe' });
38
+
39
+ const stdin2 = cmd2.streams.stdin;
40
+ console.log('Manual start stdin available?', !!stdin2);
41
+
42
+ if (stdin2) {
43
+ stdin2.write('Manual start test\\n');
44
+ stdin2.end();
45
+ }
46
+
47
+ const result2 = await cmd2;
48
+ console.log('Manual result:', result2);
49
+ }
50
+
51
+ testExplicitStdio().catch(console.error);
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Final Streaming Test with PTY Workaround ===\n');
6
+
7
+ console.log('Test 1: Direct emulator execution (baseline):');
8
+ {
9
+ const start = Date.now();
10
+ for await (const chunk of $`bun run js/examples/emulate-claude-stream.mjs`.stream()) {
11
+ if (chunk.type === 'stdout') {
12
+ const elapsed = Date.now() - start;
13
+ const lines = chunk.data
14
+ .toString()
15
+ .trim()
16
+ .split('\n')
17
+ .filter((l) => l);
18
+ for (const line of lines) {
19
+ console.log(` [${elapsed}ms] ${line}`);
20
+ }
21
+ }
22
+ }
23
+ }
24
+
25
+ console.log(
26
+ '\nTest 2: Emulator piped through jq (should stream in real-time):'
27
+ );
28
+ {
29
+ const start = Date.now();
30
+ let chunkCount = 0;
31
+
32
+ for await (const chunk of $`bun run js/examples/emulate-claude-stream.mjs | jq .`.stream()) {
33
+ if (chunk.type === 'stdout') {
34
+ chunkCount++;
35
+ const elapsed = Date.now() - start;
36
+ const text = chunk.data.toString();
37
+ const lines = text.split('\n').filter((l) => l.trim());
38
+
39
+ if (lines.length > 0) {
40
+ console.log(` [${elapsed}ms] Chunk ${chunkCount}: ${lines[0]}`);
41
+ if (lines.length > 1) {
42
+ console.log(
43
+ ` ... and ${lines.length - 1} more lines`
44
+ );
45
+ }
46
+ }
47
+ }
48
+ }
49
+ console.log(` Total chunks: ${chunkCount}`);
50
+ }
51
+
52
+ console.log('\nTest 3: Complex pipeline with jq -c:');
53
+ {
54
+ const start = Date.now();
55
+
56
+ for await (const chunk of $`bun run js/examples/emulate-claude-stream.mjs | jq -c .`.stream()) {
57
+ if (chunk.type === 'stdout') {
58
+ const elapsed = Date.now() - start;
59
+ const lines = chunk.data.toString().trim().split('\n');
60
+ for (const line of lines) {
61
+ if (line) {
62
+ console.log(` [${elapsed}ms] ${line}`);
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
68
+
69
+ console.log(
70
+ '\nāœ… If timestamps show incremental times (not all the same), streaming is working!'
71
+ );
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ async function testFix() {
6
+ console.log('🧪 Testing the stdin pipe fix');
7
+
8
+ const sortCmd = $`sort`;
9
+ console.log('1. Created sort command');
10
+
11
+ // Start with pipe stdin
12
+ const startPromise = sortCmd.start({
13
+ mode: 'async',
14
+ stdin: 'pipe',
15
+ stdout: 'pipe',
16
+ stderr: 'pipe',
17
+ });
18
+
19
+ // Add timeout to avoid hanging
20
+ const timeoutPromise = new Promise((_, reject) => {
21
+ setTimeout(() => reject(new Error('Start timed out')), 2000);
22
+ });
23
+
24
+ try {
25
+ await Promise.race([startPromise, timeoutPromise]);
26
+ console.log('2. Started successfully');
27
+ } catch (error) {
28
+ console.log('2. Start timeout (process is waiting - good!)');
29
+ }
30
+
31
+ console.log('3. Checking child status:');
32
+ console.log(' started:', sortCmd.started);
33
+ console.log(' child exists:', !!sortCmd.child);
34
+ console.log(' finished:', sortCmd.finished);
35
+
36
+ if (sortCmd.child) {
37
+ console.log(' child.stdin exists:', !!sortCmd.child.stdin);
38
+ console.log(
39
+ ' child.stdin writable:',
40
+ sortCmd.child.stdin ? sortCmd.child.stdin.writable : 'N/A'
41
+ );
42
+ }
43
+
44
+ // Now test streams access
45
+ const stdinPromise = sortCmd.streams.stdin;
46
+ const stdinTimeout = new Promise((resolve) => {
47
+ setTimeout(() => resolve('TIMEOUT'), 1000);
48
+ });
49
+
50
+ const stdin = await Promise.race([stdinPromise, stdinTimeout]);
51
+ console.log('4. Got stdin:');
52
+ console.log(' result:', stdin === 'TIMEOUT' ? 'TIMEOUT' : typeof stdin);
53
+ console.log(' has write:', stdin && stdin.write ? 'YES' : 'NO');
54
+
55
+ if (stdin && stdin.write) {
56
+ console.log('5. SUCCESS! Writing to stdin...');
57
+ stdin.write('zebra\n');
58
+ stdin.write('apple\n');
59
+ stdin.end();
60
+
61
+ const result = await sortCmd;
62
+ console.log(' Sorted result:', JSON.stringify(result.stdout));
63
+ } else {
64
+ console.log('5. Cleaning up...');
65
+ sortCmd.kill();
66
+ }
67
+
68
+ console.log('Test complete');
69
+ }
70
+
71
+ testFix();
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Testing Incremental Streaming ===\n');
6
+
7
+ // Test: Does output stream incrementally?
8
+ console.log('Each line should appear with 500ms delay between them:\n');
9
+ const start = Date.now();
10
+
11
+ const cmd = $`sh -c 'echo "line1"; sleep 0.5; echo "line2"; sleep 0.5; echo "line3"'`;
12
+
13
+ for await (const chunk of cmd.stream()) {
14
+ if (chunk.type === 'stdout') {
15
+ const elapsed = Date.now() - start;
16
+ const lines = chunk.data
17
+ .toString()
18
+ .trim()
19
+ .split('\n')
20
+ .filter((l) => l);
21
+ for (const line of lines) {
22
+ console.log(`[${elapsed}ms] ${line}`);
23
+ }
24
+ }
25
+ }
26
+
27
+ console.log('\n--- Now testing with pipe ---\n');
28
+
29
+ const start2 = Date.now();
30
+ const cmd2 = $`sh -c 'echo "line1"; sleep 0.5; echo "line2"; sleep 0.5; echo "line3"' | cat`;
31
+
32
+ for await (const chunk of cmd2.stream()) {
33
+ if (chunk.type === 'stdout') {
34
+ const elapsed = Date.now() - start2;
35
+ const lines = chunk.data
36
+ .toString()
37
+ .trim()
38
+ .split('\n')
39
+ .filter((l) => l);
40
+ for (const line of lines) {
41
+ console.log(`[${elapsed}ms] ${line}`);
42
+ }
43
+ }
44
+ }
45
+
46
+ console.log('\nāœ… Test complete');
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env bun
2
+
3
+ // Test spawning processes individually and connecting them
4
+
5
+ const proc1 = Bun.spawn(
6
+ ['bun', 'run', 'js/examples/emulate-claude-stream.mjs'],
7
+ {
8
+ stdout: 'pipe',
9
+ stderr: 'pipe',
10
+ }
11
+ );
12
+
13
+ const proc2 = Bun.spawn(['jq', '.'], {
14
+ stdin: proc1.stdout,
15
+ stdout: 'pipe',
16
+ stderr: 'pipe',
17
+ });
18
+
19
+ console.log('Testing direct process pipe connection:');
20
+ console.log('This SHOULD stream in real-time\n');
21
+
22
+ const start = Date.now();
23
+
24
+ // Read from jq's output
25
+ for await (const chunk of proc2.stdout) {
26
+ const elapsed = Date.now() - start;
27
+ const text = Buffer.from(chunk).toString();
28
+ const lines = text.split('\n').filter((l) => l.trim());
29
+ for (const line of lines) {
30
+ console.log(`[${elapsed}ms] ${line}`);
31
+ }
32
+ }
33
+
34
+ await proc1.exited;
35
+ await proc2.exited;