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,153 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Example: Using raw() to disable auto-escape for trusted command strings
4
+ // This demonstrates the solution to issue #139
5
+
6
+ import { $, raw } from '../src/$.mjs';
7
+
8
+ console.log('=== raw() Function Examples ===\n');
9
+
10
+ async function demonstrateRaw() {
11
+ console.log('1. Basic raw() usage with trusted commands:');
12
+ console.log('----------------------------------------------');
13
+
14
+ // Example 1: Simple command with shell operators
15
+ console.log('\nExample 1: Command with && operator');
16
+ const cmd1 = 'echo "Step 1" && echo "Step 2"';
17
+ console.log('Input:', cmd1);
18
+ const result1 = await $`${raw(cmd1)}`;
19
+ console.log('Output:', result1.stdout.trim());
20
+ console.log('Expected: Both steps executed\n');
21
+
22
+ // Example 2: Command with pipes
23
+ console.log('Example 2: Command with pipe operator');
24
+ const cmd2 = 'echo "hello world" | wc -w';
25
+ console.log('Input:', cmd2);
26
+ const result2 = await $`${raw(cmd2)}`;
27
+ console.log('Output:', result2.stdout.trim());
28
+ console.log('Expected: Word count = 2\n');
29
+
30
+ // Example 3: Complex command with multiple operators
31
+ console.log('Example 3: Complex command with redirects and pipes');
32
+ const cmd3 = 'seq 1 5 | head -n 3';
33
+ console.log('Input:', cmd3);
34
+ const result3 = await $`${raw(cmd3)}`;
35
+ console.log('Output:', result3.stdout.trim());
36
+ console.log('Expected: Numbers 1, 2, 3\n');
37
+
38
+ console.log('2. Combining raw() with safe interpolation:');
39
+ console.log('----------------------------------------------');
40
+
41
+ // Example 4: Mix raw command with safe user input
42
+ console.log('\nExample 4: Raw command + safe variable');
43
+ const safeInput = 'test file.txt'; // This will be auto-quoted
44
+ const cmd4 = raw('echo "Processing:"');
45
+ const result4 = await $`${cmd4} ${safeInput}`;
46
+ console.log('Command:', `${cmd4.raw} [auto-quoted: ${safeInput}]`);
47
+ console.log('Output:', result4.stdout.trim());
48
+ console.log('Note: File name was safely quoted\n');
49
+
50
+ console.log('3. Configuration-based commands (safe use case):');
51
+ console.log('--------------------------------------------------');
52
+
53
+ // Example 5: Pre-defined commands from configuration
54
+ const config = {
55
+ listHidden: 'ls -la | grep "^\\."',
56
+ countFiles: 'ls -1 | wc -l',
57
+ diskUsage: 'du -sh . 2>/dev/null || echo "N/A"',
58
+ };
59
+
60
+ console.log('\nExample 5: Commands from trusted configuration');
61
+ for (const [name, command] of Object.entries(config)) {
62
+ console.log(`\n${name}:`, command);
63
+ try {
64
+ const result = await $({ mirror: false })`${raw(command)}`;
65
+ console.log(
66
+ 'Output:',
67
+ result.stdout.trim() || result.stderr.trim() || '(no output)'
68
+ );
69
+ console.log('Exit code:', result.code);
70
+ } catch (error) {
71
+ console.log('Error:', error.message);
72
+ }
73
+ }
74
+
75
+ console.log('\n4. Comparison: raw() vs normal interpolation:');
76
+ console.log('-----------------------------------------------');
77
+
78
+ const testString = 'echo "test" && ls';
79
+
80
+ console.log('\nWith raw() - executes as shell command:');
81
+ console.log('Input:', testString);
82
+ const rawResult = await $({ mirror: false })`${raw(testString)}`;
83
+ console.log('Executed:', testString);
84
+ console.log(
85
+ 'Output lines:',
86
+ rawResult.stdout.split('\n').filter((l) => l.trim()).length
87
+ );
88
+
89
+ console.log('\nWithout raw() - treated as literal string:');
90
+ console.log('Input:', testString);
91
+ const normalResult = await $({ mirror: false })`echo ${testString}`;
92
+ console.log('Executed: echo with quoted string');
93
+ console.log('Output:', normalResult.stdout.trim());
94
+ console.log('Note: Special characters were escaped\n');
95
+
96
+ console.log('5. Security demonstration:');
97
+ console.log('---------------------------');
98
+
99
+ console.log('\n⚠️ WARNING: Never use raw() with untrusted input!');
100
+
101
+ // Demonstrate the danger
102
+ const dangerousInput = 'hello; rm -rf /tmp/test-*';
103
+
104
+ console.log('\nDangerous string:', dangerousInput);
105
+ console.log('\n❌ With raw() (DANGEROUS - would execute malicious code):');
106
+ console.log(' Would execute:', dangerousInput);
107
+ console.log(' Status: SKIPPED for safety\n');
108
+
109
+ console.log('✅ Without raw() (SAFE - auto-escaped):');
110
+ const safeResult = await $({ mirror: false })`echo ${dangerousInput}`;
111
+ console.log(' Executed: echo with safely quoted string');
112
+ console.log(' Output:', safeResult.stdout.trim());
113
+ console.log(' Note: Malicious code was neutralized by auto-quoting\n');
114
+
115
+ console.log('6. Practical use cases for raw():');
116
+ console.log('-----------------------------------');
117
+
118
+ console.log('\n✅ GOOD use case: Build scripts');
119
+ const buildSteps = raw('npm run lint && npm run test && npm run build');
120
+ console.log('Build command:', buildSteps.raw);
121
+ console.log('Note: Trusted command from your codebase\n');
122
+
123
+ console.log('✅ GOOD use case: Deployment commands');
124
+ const deployCmd = raw('git pull && npm install && pm2 reload app');
125
+ console.log('Deploy command:', deployCmd.raw);
126
+ console.log('Note: Hardcoded deployment sequence\n');
127
+
128
+ console.log('✅ GOOD use case: Complex shell pipelines');
129
+ const analyzeCmd = raw('cat log.txt | grep ERROR | wc -l');
130
+ console.log('Analysis command:', analyzeCmd.raw);
131
+ console.log('Note: Pre-defined analysis pipeline\n');
132
+
133
+ console.log('❌ BAD use case: User input');
134
+ console.log('const userCmd = getUserInput();');
135
+ console.log('await $`${raw(userCmd)}`; // ❌ DANGEROUS!');
136
+ console.log(
137
+ 'Note: NEVER use raw() with user input - use normal interpolation\n'
138
+ );
139
+
140
+ console.log('Summary:');
141
+ console.log('--------');
142
+ console.log(
143
+ '✅ Use raw() for: Trusted commands, config files, hardcoded strings'
144
+ );
145
+ console.log(
146
+ '❌ Never use raw() for: User input, external data, untrusted sources'
147
+ );
148
+ console.log(
149
+ '💡 Default behavior (auto-escape) is safe and should be used for all user input'
150
+ );
151
+ }
152
+
153
+ demonstrateRaw().catch(console.error);
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Testing Raw Streaming (no jq) ===\n');
6
+
7
+ // Test 1: Simple pipe with cat (should not buffer)
8
+ console.log('Test 1: Streaming through cat (unbuffered):');
9
+ const start = Date.now();
10
+
11
+ const cmd = $`sh -c 'echo "line1"; sleep 0.5; echo "line2"; sleep 0.5; echo "line3"' | cat`;
12
+
13
+ for await (const chunk of cmd.stream()) {
14
+ if (chunk.type === 'stdout') {
15
+ const elapsed = Date.now() - start;
16
+ const data = chunk.data.toString().trim();
17
+ if (data) {
18
+ const lines = data.split('\n').filter((l) => l);
19
+ for (const line of lines) {
20
+ console.log(`[${elapsed}ms] ${line}`);
21
+ }
22
+ }
23
+ }
24
+ }
25
+
26
+ console.log('\n✅ Test complete');
27
+
28
+ // Test 2: grep (line-buffered by default)
29
+ console.log('\nTest 2: Streaming through grep:');
30
+ const start2 = Date.now();
31
+
32
+ const cmd2 = $`sh -c 'echo "match1"; sleep 0.5; echo "skip"; sleep 0.5; echo "match2"' | grep match`;
33
+
34
+ for await (const chunk of cmd2.stream()) {
35
+ if (chunk.type === 'stdout') {
36
+ const elapsed = Date.now() - start2;
37
+ const data = chunk.data.toString().trim();
38
+ if (data) {
39
+ const lines = data.split('\n').filter((l) => l);
40
+ for (const line of lines) {
41
+ console.log(`[${elapsed}ms] ${line}`);
42
+ }
43
+ }
44
+ }
45
+ }
46
+
47
+ console.log('\n✅ Test complete');
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test the README examples to ensure they work correctly
5
+ */
6
+
7
+ import { $ } from '../src/$.mjs';
8
+
9
+ console.log('🧪 Testing README Examples');
10
+ console.log('='.repeat(40));
11
+
12
+ async function testReadmeExamples() {
13
+ try {
14
+ console.log('\n📝 EXAMPLE 1: Send data via streams.stdin with cat');
15
+ console.log('─'.repeat(30));
16
+
17
+ const catCmd = $`cat`;
18
+ const stdin = await catCmd.streams.stdin;
19
+
20
+ if (stdin && stdin.write) {
21
+ console.log('✅ Got writable stdin stream');
22
+ stdin.write('Hello from stdin!\n');
23
+ stdin.write('Multiple lines work!\n');
24
+ stdin.end();
25
+
26
+ const result = await catCmd;
27
+ console.log('✅ Cat output:', JSON.stringify(result.stdout));
28
+ } else {
29
+ console.log('❌ No writable stdin available');
30
+ }
31
+
32
+ console.log('\n🔧 EXAMPLE 2: Filter data with grep');
33
+ console.log('─'.repeat(30));
34
+
35
+ const grepCmd = $`grep "important"`;
36
+ const grepStdin = await grepCmd.streams.stdin;
37
+
38
+ if (grepStdin && grepStdin.write) {
39
+ console.log('✅ Got writable grep stdin stream');
40
+ grepStdin.write('ignore this line\n');
41
+ grepStdin.write('important message 1\n');
42
+ grepStdin.write('skip this too\n');
43
+ grepStdin.write('another important note\n');
44
+ grepStdin.end();
45
+
46
+ const grepResult = await grepCmd;
47
+ console.log(
48
+ '✅ Grep filtered output:',
49
+ JSON.stringify(grepResult.stdout)
50
+ );
51
+ } else {
52
+ console.log('❌ No writable grep stdin available');
53
+ }
54
+
55
+ console.log('\n📊 EXAMPLE 3: Sort data via stdin');
56
+ console.log('─'.repeat(30));
57
+
58
+ const sortCmd = $`sort`;
59
+ const sortStdin = await sortCmd.streams.stdin;
60
+
61
+ if (sortStdin && sortStdin.write) {
62
+ console.log('✅ Got writable sort stdin stream');
63
+ sortStdin.write('zebra\n');
64
+ sortStdin.write('apple\n');
65
+ sortStdin.write('banana\n');
66
+ sortStdin.write('cherry\n');
67
+ sortStdin.end();
68
+
69
+ const sortResult = await sortCmd;
70
+ console.log('✅ Sort result:', JSON.stringify(sortResult.stdout));
71
+ } else {
72
+ console.log('❌ No writable sort stdin available');
73
+ }
74
+
75
+ console.log('\n🧮 EXAMPLE 4: Calculator with bc (if available)');
76
+ console.log('─'.repeat(30));
77
+
78
+ try {
79
+ const calcCmd = $`bc -l`;
80
+ const calcStdin = await calcCmd.streams.stdin;
81
+
82
+ if (calcStdin && calcStdin.write) {
83
+ console.log('✅ Got writable bc stdin stream');
84
+ calcStdin.write('scale=2\n');
85
+ calcStdin.write('10 / 3\n');
86
+ calcStdin.write('sqrt(16)\n');
87
+ calcStdin.write('quit\n');
88
+
89
+ const calcResult = await calcCmd;
90
+ console.log(
91
+ '✅ BC calculation results:',
92
+ JSON.stringify(calcResult.stdout.trim())
93
+ );
94
+ } else {
95
+ console.log('❌ No writable bc stdin available');
96
+ }
97
+ } catch (error) {
98
+ console.log('⚠️ BC not available or failed:', error.message);
99
+ }
100
+
101
+ console.log('\n🔄 EXAMPLE 5: Text transformation with tr');
102
+ console.log('─'.repeat(30));
103
+
104
+ const trCmd = $`tr 'a-z' 'A-Z'`;
105
+ const trStdin = await trCmd.streams.stdin;
106
+
107
+ if (trStdin && trStdin.write) {
108
+ console.log('✅ Got writable tr stdin stream');
109
+ trStdin.write('hello world\n');
110
+ trStdin.write('this is lowercase text\n');
111
+ trStdin.end();
112
+
113
+ const trResult = await trCmd;
114
+ console.log('✅ TR transformed text:', JSON.stringify(trResult.stdout));
115
+ } else {
116
+ console.log('❌ No writable tr stdin available');
117
+ }
118
+
119
+ console.log('\n⚡ EXAMPLE 6: Process control with kill()');
120
+ console.log('─'.repeat(30));
121
+
122
+ const sleepCmd = $`sleep 5`;
123
+
124
+ // Kill after 1 second
125
+ setTimeout(() => {
126
+ console.log('🔪 Using kill() to stop sleep command...');
127
+ sleepCmd.kill();
128
+ }, 1000);
129
+
130
+ const sleepResult = await sleepCmd;
131
+ console.log('✅ Sleep killed with exit code:', sleepResult.code);
132
+
133
+ console.log(`\n${'='.repeat(40)}`);
134
+ console.log('🎉 README EXAMPLES TEST COMPLETED!');
135
+ } catch (error) {
136
+ console.log('\n❌ ERROR:', error.message);
137
+ console.error(error.stack);
138
+ process.exit(1);
139
+ }
140
+ }
141
+
142
+ testReadmeExamples();
@@ -0,0 +1,28 @@
1
+ import { $ } from '../src/$.mjs';
2
+
3
+ async function testRealCat() {
4
+ console.log('Testing real cat (not virtual) with streams.stdin...');
5
+
6
+ // Force bypass of virtual command by using /bin/cat
7
+ const catCmd = $`/bin/cat`;
8
+ const stdin = await catCmd.streams.stdin;
9
+
10
+ console.log('stdin available:', !!stdin);
11
+ console.log('stdin writable:', stdin ? stdin.writable : 'N/A');
12
+
13
+ if (stdin) {
14
+ stdin.write('Hello from streams.stdin!\n');
15
+ stdin.write('Multiple lines work\n');
16
+ stdin.end();
17
+ }
18
+
19
+ const result = await catCmd;
20
+ console.log('Result code:', result.code);
21
+ console.log('Result stdout:', JSON.stringify(result.stdout));
22
+ console.log(
23
+ 'Expected content present:',
24
+ result.stdout.includes('Hello from streams.stdin!')
25
+ );
26
+ }
27
+
28
+ testRealCat().catch(console.error);
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('Test with real commands only (no virtual echo):\n');
6
+
7
+ // Use printf instead of echo to avoid virtual command
8
+ const result = await $`printf '{"test":1}\\n' | jq .`;
9
+ console.log('Result:', result.stdout);
10
+
11
+ console.log('\nTest streaming:');
12
+ const start = Date.now();
13
+ for await (const chunk of $`bun run js/examples/emulate-claude-stream.mjs | jq .`.stream()) {
14
+ if (chunk.type === 'stdout') {
15
+ const elapsed = Date.now() - start;
16
+ const lines = chunk.data.toString().trim().split('\n').slice(0, 2);
17
+ if (lines[0]) {
18
+ console.log(`[${elapsed}ms] ${lines[0]}`);
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ async function testRealShellCommands() {
6
+ console.log('Testing with real shell commands...');
7
+
8
+ // Test with a real shell command (ls should exist on most systems)
9
+ console.log('\n1. Testing real shell command with capture: false:');
10
+ const result1 = await $`ls /tmp`.start({ capture: false });
11
+ console.log('Result stdout:', JSON.stringify(result1.stdout)); // Should be undefined
12
+ console.log('Result code:', result1.code);
13
+
14
+ // Test with a real shell command with capture: true
15
+ console.log('\n2. Testing real shell command with capture: true:');
16
+ const result2 = await $`ls /tmp`.start({ capture: true });
17
+ console.log('Result stdout type:', typeof result2.stdout); // Should be string
18
+ console.log('Result stdout length:', result2.stdout?.length || 0);
19
+ console.log('Result code:', result2.code);
20
+
21
+ // Test with mirror: false to capture but not show output
22
+ console.log('\n3. Testing real shell command with mirror: false:');
23
+ const result3 = await $`ls -la /tmp`.start({ mirror: false, capture: true });
24
+ console.log('Result stdout type:', typeof result3.stdout);
25
+ console.log('Result stdout lines:', result3.stdout?.split('\n').length || 0);
26
+ console.log('Result code:', result3.code);
27
+
28
+ console.log('\nAll tests completed!');
29
+ }
30
+
31
+ testRealShellCommands().catch(console.error);
@@ -0,0 +1,160 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test commands that actually read and respond to stdin
5
+ */
6
+
7
+ import { $ } from '../src/$.mjs';
8
+
9
+ console.log('=== Testing commands that ACTUALLY read stdin ===');
10
+ console.log('');
11
+
12
+ async function testRealStdinCommands() {
13
+ try {
14
+ console.log('TEST 1: cat - classic stdin reader');
15
+
16
+ const catCmd = $`cat`;
17
+ const stdin1 = catCmd.streams.stdin;
18
+
19
+ if (stdin1) {
20
+ stdin1.write('Hello from stdin!\\n');
21
+ stdin1.write('Second line\\n');
22
+ stdin1.end();
23
+ }
24
+
25
+ const result1 = await catCmd;
26
+ console.log('✓ cat result:', JSON.stringify(result1.stdout));
27
+ console.log(' Exit code:', result1.code);
28
+
29
+ console.log('\\nTEST 2: grep - filter input from stdin');
30
+
31
+ const grepCmd = $`grep "hello"`;
32
+ const stdin2 = grepCmd.streams.stdin;
33
+
34
+ if (stdin2) {
35
+ stdin2.write('this line has no match\\n');
36
+ stdin2.write('hello world\\n');
37
+ stdin2.write('another non-match\\n');
38
+ stdin2.write('hello again\\n');
39
+ stdin2.end();
40
+ }
41
+
42
+ const result2 = await grepCmd;
43
+ console.log('✓ grep result:', JSON.stringify(result2.stdout));
44
+ console.log(' Exit code:', result2.code);
45
+
46
+ console.log('\\nTEST 3: sort - sort input from stdin');
47
+
48
+ const sortCmd = $`sort`;
49
+ const stdin3 = sortCmd.streams.stdin;
50
+
51
+ if (stdin3) {
52
+ stdin3.write('zebra\\n');
53
+ stdin3.write('apple\\n');
54
+ stdin3.write('banana\\n');
55
+ stdin3.end();
56
+ }
57
+
58
+ const result3 = await sortCmd;
59
+ console.log('✓ sort result:', JSON.stringify(result3.stdout));
60
+ console.log(' Exit code:', result3.code);
61
+
62
+ console.log('\\nTEST 4: wc - count lines from stdin');
63
+
64
+ const wcCmd = $`wc -l`;
65
+ const stdin4 = wcCmd.streams.stdin;
66
+
67
+ if (stdin4) {
68
+ stdin4.write('line 1\\n');
69
+ stdin4.write('line 2\\n');
70
+ stdin4.write('line 3\\n');
71
+ stdin4.end();
72
+ }
73
+
74
+ const result4 = await wcCmd;
75
+ console.log('✓ wc result:', JSON.stringify(result4.stdout.trim()));
76
+ console.log(' Exit code:', result4.code);
77
+
78
+ console.log('\\nTEST 5: tr - transform text from stdin');
79
+
80
+ const trCmd = $`tr 'a-z' 'A-Z'`; // Convert lowercase to uppercase
81
+ const stdin5 = trCmd.streams.stdin;
82
+
83
+ if (stdin5) {
84
+ stdin5.write('hello world\\n');
85
+ stdin5.write('this is lowercase\\n');
86
+ stdin5.end();
87
+ }
88
+
89
+ const result5 = await trCmd;
90
+ console.log('✓ tr result:', JSON.stringify(result5.stdout));
91
+ console.log(' Exit code:', result5.code);
92
+
93
+ console.log('\\nTEST 6: awk - process stdin with awk');
94
+
95
+ const awkCmd = $`awk '{print NR ": " $0}'`; // Add line numbers
96
+ const stdin6 = awkCmd.streams.stdin;
97
+
98
+ if (stdin6) {
99
+ stdin6.write('first line\\n');
100
+ stdin6.write('second line\\n');
101
+ stdin6.write('third line\\n');
102
+ stdin6.end();
103
+ }
104
+
105
+ const result6 = await awkCmd;
106
+ console.log('✓ awk result:', JSON.stringify(result6.stdout));
107
+ console.log(' Exit code:', result6.code);
108
+
109
+ console.log('\\nTEST 7: head - limit lines from stdin');
110
+
111
+ const headCmd = $`head -n 2`;
112
+ const stdin7 = headCmd.streams.stdin;
113
+
114
+ if (stdin7) {
115
+ stdin7.write('line 1\\n');
116
+ stdin7.write('line 2\\n');
117
+ stdin7.write('line 3\\n');
118
+ stdin7.write('line 4\\n');
119
+ stdin7.end();
120
+ }
121
+
122
+ const result7 = await headCmd;
123
+ console.log('✓ head result:', JSON.stringify(result7.stdout));
124
+ console.log(' Exit code:', result7.code);
125
+
126
+ console.log('\\nTEST 8: Interactive command - bc calculator');
127
+
128
+ const bcCmd = $`bc -l`;
129
+ const stdin8 = bcCmd.streams.stdin;
130
+
131
+ if (stdin8) {
132
+ stdin8.write('2 + 3\\n');
133
+ stdin8.write('10 * 5\\n');
134
+ stdin8.write('sqrt(16)\\n');
135
+ stdin8.write('quit\\n'); // Important: quit to exit bc
136
+ }
137
+
138
+ const result8 = await bcCmd;
139
+ console.log('✓ bc result:', JSON.stringify(result8.stdout));
140
+ console.log(' Exit code:', result8.code);
141
+
142
+ console.log('\\n✅ SUMMARY:');
143
+ console.log(' • All these commands actually READ and PROCESS stdin input');
144
+ console.log(
145
+ ' • They demonstrate real stdin control, not just timing coincidences'
146
+ );
147
+ console.log(
148
+ ' • These are the types of commands where streams.stdin is genuinely useful'
149
+ );
150
+ console.log(
151
+ ' • Commands like ping, top (without quit) ignore stdin - use kill() for those'
152
+ );
153
+ } catch (error) {
154
+ console.log('\\n❌ TEST FAILED:', error.message);
155
+ console.error(error.stack);
156
+ process.exit(1);
157
+ }
158
+ }
159
+
160
+ testRealStdinCommands();
@@ -0,0 +1,98 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Batched test runner that runs tests in smaller groups to avoid interference
5
+ */
6
+
7
+ import { execSync } from 'child_process';
8
+ import { readdirSync } from 'fs';
9
+ import { join } from 'path';
10
+
11
+ const testsDir = join(process.cwd(), 'tests');
12
+ const testFiles = readdirSync(testsDir)
13
+ .filter((f) => f.endsWith('.test.mjs'))
14
+ .sort();
15
+
16
+ // Group tests into batches
17
+ const batchSize = 5;
18
+ const batches = [];
19
+ for (let i = 0; i < testFiles.length; i += batchSize) {
20
+ batches.push(testFiles.slice(i, i + batchSize));
21
+ }
22
+
23
+ console.log(
24
+ `🧪 Running ${testFiles.length} test files in ${batches.length} batches...\n`
25
+ );
26
+
27
+ let totalPass = 0;
28
+ let totalFail = 0;
29
+ const failedFiles = [];
30
+
31
+ batches.forEach((batch, index) => {
32
+ console.log(`\n📦 Batch ${index + 1}/${batches.length}: ${batch.join(', ')}`);
33
+
34
+ const files = batch.map((f) => join(testsDir, f)).join(' ');
35
+
36
+ try {
37
+ // Run batch synchronously and capture output
38
+ const output = execSync(`bun test ${files} 2>&1`, { encoding: 'utf-8' });
39
+
40
+ // Parse the output to find pass/fail counts
41
+ const passMatch = output.match(/(\d+)\s+pass/);
42
+ const failMatch = output.match(/(\d+)\s+fail/);
43
+
44
+ const pass = passMatch ? parseInt(passMatch[1]) : 0;
45
+ const fail = failMatch ? parseInt(failMatch[1]) : 0;
46
+
47
+ totalPass += pass;
48
+ totalFail += fail;
49
+
50
+ if (fail > 0) {
51
+ console.log(` ❌ ${pass} pass, ${fail} fail`);
52
+ failedFiles.push(
53
+ ...batch.filter((f) =>
54
+ // Try to identify which files had failures
55
+ output.includes(f)
56
+ )
57
+ );
58
+ } else {
59
+ console.log(` ✅ ${pass} pass`);
60
+ }
61
+ } catch (error) {
62
+ // Test failed to run or had non-zero exit
63
+ const output = error.stdout || '';
64
+ const passMatch = output.match(/(\d+)\s+pass/);
65
+ const failMatch = output.match(/(\d+)\s+fail/);
66
+
67
+ const pass = passMatch ? parseInt(passMatch[1]) : 0;
68
+ const fail = failMatch ? parseInt(failMatch[1]) : 0;
69
+
70
+ totalPass += pass;
71
+ totalFail += fail;
72
+
73
+ if (fail > 0) {
74
+ console.log(` ❌ ${pass} pass, ${fail} fail`);
75
+ failedFiles.push(...batch);
76
+ } else {
77
+ console.log(` ⚠️ Error running batch`);
78
+ failedFiles.push(...batch);
79
+ }
80
+ }
81
+ });
82
+
83
+ console.log(`\n${'='.repeat(60)}`);
84
+ console.log('📊 Summary:');
85
+ console.log(` Total tests passed: ${totalPass}`);
86
+ console.log(` Total tests failed: ${totalFail}`);
87
+ console.log(
88
+ ` Batches with issues: ${failedFiles.length > 0 ? failedFiles.length : 0}`
89
+ );
90
+
91
+ if (failedFiles.length > 0) {
92
+ console.log('\n❌ Files with potential issues:');
93
+ [...new Set(failedFiles)].forEach((f) => console.log(` - ${f}`));
94
+ process.exit(1);
95
+ } else {
96
+ console.log('\n✅ All batches completed successfully!');
97
+ process.exit(0);
98
+ }