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,94 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Proof that ping cannot be controlled via stdin - you need kill() method
5
+ */
6
+
7
+ import { spawn } from 'child_process';
8
+ import { $ } from '../src/$.mjs';
9
+
10
+ console.log('=== PROOF: ping ignores stdin, needs kill() method ===');
11
+ console.log('');
12
+
13
+ async function proveStdinLimitation() {
14
+ console.log('DEMONSTRATION 1: Native child_process with ping');
15
+ console.log('→ Sending CTRL+C via stdin (will be ignored by ping)');
16
+
17
+ const child = spawn('ping', ['8.8.8.8']);
18
+ let output = '';
19
+
20
+ child.stdout.on('data', (data) => {
21
+ output += data.toString();
22
+ process.stdout.write(` [ping] ${data}`);
23
+ });
24
+
25
+ // Try to send CTRL+C after 1.5 seconds
26
+ setTimeout(() => {
27
+ console.log(' → Sending \\x03 (CTRL+C) to stdin...');
28
+ child.stdin.write('\\x03');
29
+ child.stdin.write('quit\\n');
30
+ child.stdin.write('exit\\n');
31
+ child.stdin.end();
32
+ console.log(' → stdin closed, but ping continues running...');
33
+ }, 1500);
34
+
35
+ // Force kill after 3 seconds to prove stdin didn't work
36
+ setTimeout(() => {
37
+ console.log(' → stdin failed, using kill() to terminate...');
38
+ child.kill('SIGTERM');
39
+ }, 3000);
40
+
41
+ await new Promise((resolve) => child.on('close', resolve));
42
+ console.log(' ✓ Native ping required kill() signal to stop');
43
+ console.log('');
44
+
45
+ console.log('DEMONSTRATION 2: command-stream with proper kill() method');
46
+ const cmd = $`ping 8.8.8.8`;
47
+
48
+ // Start by accessing stdout
49
+ cmd.streams.stdout.on('data', (data) => {
50
+ process.stdout.write(` [stream] ${data}`);
51
+ });
52
+
53
+ // Kill cleanly after 2 seconds
54
+ setTimeout(() => {
55
+ console.log(' → Using command-stream kill() method...');
56
+ cmd.kill();
57
+ }, 2000);
58
+
59
+ const result = await cmd;
60
+ console.log(
61
+ ` ✓ command-stream ping cleanly terminated with code: ${result.code}`
62
+ );
63
+ console.log('');
64
+
65
+ console.log('DEMONSTRATION 3: stdin DOES work for commands that read it');
66
+ console.log('→ Testing with cat command');
67
+
68
+ const catCmd = $`cat`;
69
+ const stdin = catCmd.streams.stdin;
70
+
71
+ if (stdin) {
72
+ stdin.write('This data goes to cat via stdin\\n');
73
+ stdin.write('And cat will output it\\n');
74
+ stdin.end();
75
+ }
76
+
77
+ const catResult = await catCmd;
78
+ console.log(' ✓ cat output:', JSON.stringify(catResult.stdout));
79
+ console.log('');
80
+
81
+ console.log('📋 SUMMARY:');
82
+ console.log(
83
+ ' • ping ignores stdin completely (network utility, not interactive)'
84
+ );
85
+ console.log(' • To interrupt ping, you MUST use kill() method or signals');
86
+ console.log(
87
+ ' • stdin works fine for commands that actually read it (cat, grep, etc.)'
88
+ );
89
+ console.log(
90
+ ' • command-stream provides both: streams.stdin AND kill() method'
91
+ );
92
+ }
93
+
94
+ proveStdinLimitation().catch(console.error);
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $, register } from '../src/$.mjs';
4
+
5
+ // Register a custom virtual command with the new object-based signature
6
+ register('greet', async ({ stdin }) => ({
7
+ stdout: `Hello, ${stdin.trim()}!\n`,
8
+ code: 0,
9
+ }));
10
+
11
+ // Example usage: echo "World" | greet
12
+ console.log('Running: echo "World" | greet');
13
+ const result = await $`echo "World"`.pipe($`greet`);
14
+ console.log('Result:', result.stdout.trim());
15
+
16
+ // Example with args
17
+ register('greet-formal', async ({ args, stdin }) => {
18
+ const title = args[0] || '';
19
+ return { stdout: `Hello, ${title} ${stdin.trim()}!\n`, code: 0 };
20
+ });
21
+
22
+ console.log('\nRunning: echo "Smith" | greet-formal Mr.');
23
+ const result2 = await $`echo "Smith"`.pipe($`greet-formal Mr.`);
24
+ console.log('Result:', result2.stdout.trim());
25
+
26
+ // Example accessing other options
27
+ register('debug', async ({ args, stdin, options }) => {
28
+ const info = {
29
+ args,
30
+ stdinLength: stdin ? stdin.length : 0,
31
+ mirror: options.mirror,
32
+ capture: options.capture,
33
+ };
34
+ return { stdout: `${JSON.stringify(info, null, 2)}\n`, code: 0 };
35
+ });
36
+
37
+ console.log('\nRunning: echo "test input" | debug arg1 arg2');
38
+ const result3 = await $`echo "test input"`.pipe($`debug arg1 arg2`);
39
+ console.log('Result:', result3.stdout.trim());
@@ -0,0 +1,143 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Realtime JSON Streaming Demo ===\n');
6
+ console.log(
7
+ 'This demo shows that jq processes and outputs JSON objects immediately'
8
+ );
9
+ console.log('as they arrive, not waiting for the entire stream to complete.\n');
10
+ console.log(
11
+ 'Watch the timestamps - each JSON object appears immediately after being generated!\n'
12
+ );
13
+ console.log('---\n');
14
+
15
+ // Example 1: Simple realtime streaming with visible delays
16
+ console.log(
17
+ 'Example 1: Streaming with 1-second delays between each JSON object:'
18
+ );
19
+ console.log('Starting at:', new Date().toISOString());
20
+ console.log('');
21
+
22
+ const cmd1 = $`sh -c 'echo "{\\"event\\":\\"start\\",\\"time\\":\\"$(date +%H:%M:%S)\\"}"; sleep 1; echo "{\\"event\\":\\"middle\\",\\"time\\":\\"$(date +%H:%M:%S)\\"}"; sleep 1; echo "{\\"event\\":\\"end\\",\\"time\\":\\"$(date +%H:%M:%S)\\"}"' | jq -c .`;
23
+
24
+ for await (const chunk of cmd1.stream()) {
25
+ if (chunk.type === 'stdout') {
26
+ const timestamp = new Date().toISOString();
27
+ process.stdout.write(`[${timestamp}] Received: ${chunk.data.toString()}`);
28
+ }
29
+ }
30
+
31
+ console.log('\n---\n');
32
+
33
+ // Example 2: Processing server logs in realtime
34
+ console.log('Example 2: Simulating realtime server logs with filtering:');
35
+ console.log('(Only showing ERROR and WARN levels)\n');
36
+
37
+ const serverLogs = $`sh -c '
38
+ echo "{\\"level\\":\\"INFO\\",\\"msg\\":\\"Server starting\\",\\"time\\":\\"$(date +%H:%M:%S)\\"}";
39
+ sleep 0.5;
40
+ echo "{\\"level\\":\\"ERROR\\",\\"msg\\":\\"Database connection failed\\",\\"time\\":\\"$(date +%H:%M:%S)\\"}";
41
+ sleep 0.5;
42
+ echo "{\\"level\\":\\"INFO\\",\\"msg\\":\\"Retrying connection\\",\\"time\\":\\"$(date +%H:%M:%S)\\"}";
43
+ sleep 0.5;
44
+ echo "{\\"level\\":\\"WARN\\",\\"msg\\":\\"High memory usage\\",\\"time\\":\\"$(date +%H:%M:%S)\\"}";
45
+ sleep 0.5;
46
+ echo "{\\"level\\":\\"INFO\\",\\"msg\\":\\"Connection restored\\",\\"time\\":\\"$(date +%H:%M:%S)\\"}";
47
+ ' | jq -c 'select(.level == "ERROR" or .level == "WARN")'`;
48
+
49
+ let buffer = '';
50
+ for await (const chunk of serverLogs.stream()) {
51
+ if (chunk.type === 'stdout') {
52
+ buffer += chunk.data.toString();
53
+ const lines = buffer.split('\n');
54
+ buffer = lines.pop() || ''; // Keep incomplete line in buffer
55
+
56
+ for (const line of lines) {
57
+ if (line.trim()) {
58
+ try {
59
+ const timestamp = new Date().toISOString();
60
+ const log = JSON.parse(line.trim());
61
+ console.log(
62
+ `[${timestamp}] ${log.level}: ${log.msg} (generated at ${log.time})`
63
+ );
64
+ } catch (e) {
65
+ console.log('Failed to parse:', line);
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
71
+
72
+ console.log('\n---\n');
73
+
74
+ // Example 3: Streaming metrics with transformation
75
+ console.log('Example 3: Streaming metrics with realtime transformation:');
76
+ console.log('(Adding status based on CPU value)\n');
77
+
78
+ const metrics = $`sh -c '
79
+ for i in 1 2 3 4 5; do
80
+ cpu=$((45 + RANDOM % 40));
81
+ echo "{\\"metric\\":\\"cpu\\",\\"value\\":$cpu,\\"host\\":\\"server-$i\\",\\"time\\":\\"$(date +%H:%M:%S.%N | cut -b1-12)\\"}";
82
+ sleep 0.3;
83
+ done
84
+ ' | jq -c '{metric, value, host, time, status: (if .value > 70 then "critical" elif .value > 50 then "warning" else "normal" end)}'`;
85
+
86
+ console.log('Monitoring CPU metrics (updates every 0.3 seconds):');
87
+ let metricsBuffer = '';
88
+ for await (const chunk of metrics.stream()) {
89
+ if (chunk.type === 'stdout') {
90
+ metricsBuffer += chunk.data.toString();
91
+ const lines = metricsBuffer.split('\n');
92
+ metricsBuffer = lines.pop() || '';
93
+
94
+ for (const line of lines) {
95
+ if (line.trim()) {
96
+ try {
97
+ const timestamp = new Date().toISOString();
98
+ const metric = JSON.parse(line.trim());
99
+ const statusIcon =
100
+ metric.status === 'critical'
101
+ ? '🔴'
102
+ : metric.status === 'warning'
103
+ ? '🟡'
104
+ : '🟢';
105
+ console.log(
106
+ `[${timestamp}] ${statusIcon} ${metric.host}: CPU ${metric.value}% - ${metric.status}`
107
+ );
108
+ } catch (e) {
109
+ console.log('Failed to parse metric:', line);
110
+ }
111
+ }
112
+ }
113
+ }
114
+ }
115
+
116
+ console.log('\n---\n');
117
+
118
+ // Example 4: Using EventEmitter pattern for realtime processing
119
+ console.log('Example 4: Using EventEmitter pattern for realtime JSON stream:');
120
+ console.log('(Shows different ways to handle streaming)\n');
121
+
122
+ const eventCmd = $`sh -c '
123
+ for i in 1 2 3; do
124
+ echo "{\\"id\\":$i,\\"data\\":\\"Message $i\\",\\"timestamp\\":$(date +%s)}";
125
+ sleep 0.7;
126
+ done
127
+ ' | jq -c .`;
128
+
129
+ let eventCount = 0;
130
+ eventCmd
131
+ .on('data', (chunk) => {
132
+ eventCount++;
133
+ const timestamp = new Date().toISOString();
134
+ console.log(
135
+ `[${timestamp}] Event #${eventCount}: ${chunk.toString().trim()}`
136
+ );
137
+ })
138
+ .on('end', (result) => {
139
+ console.log(`\nStream completed. Total events: ${eventCount}`);
140
+ console.log('Final result code:', result.code);
141
+
142
+ console.log('\n=== Demo Complete ===');
143
+ });
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('=== Most reliable stdin commands ===');
6
+
7
+ async function reliableStdinCommands() {
8
+ try {
9
+ console.log('\\n1️⃣ cat (classic stdin reader)');
10
+ const catCmd = $`cat`;
11
+ const catStdin = await catCmd.streams.stdin;
12
+ console.log(
13
+ ' stdin type:',
14
+ typeof catStdin,
15
+ 'has write?',
16
+ !!(catStdin && catStdin.write)
17
+ );
18
+
19
+ if (catStdin && catStdin.write) {
20
+ catStdin.write('Hello cat!\\n');
21
+ catStdin.write('Second line\\n');
22
+ catStdin.end();
23
+ console.log(' ✅ Wrote data to cat');
24
+ } else {
25
+ console.log(' ❌ No writable stdin');
26
+ }
27
+
28
+ const catResult = await catCmd;
29
+ console.log(' 📤 Result:', JSON.stringify(catResult.stdout));
30
+
31
+ console.log('\\n2️⃣ sort (sorts stdin lines)');
32
+ const sortCmd = $`sort`;
33
+ const sortStdin = await sortCmd.streams.stdin;
34
+ console.log(
35
+ ' stdin type:',
36
+ typeof sortStdin,
37
+ 'has write?',
38
+ !!(sortStdin && sortStdin.write)
39
+ );
40
+
41
+ if (sortStdin && sortStdin.write) {
42
+ sortStdin.write('zebra\\n');
43
+ sortStdin.write('apple\\n');
44
+ sortStdin.write('banana\\n');
45
+ sortStdin.end();
46
+ console.log(' ✅ Wrote data to sort');
47
+ } else {
48
+ console.log(' ❌ No writable stdin');
49
+ }
50
+
51
+ const sortResult = await sortCmd;
52
+ console.log(' 📤 Result:', JSON.stringify(sortResult.stdout));
53
+
54
+ console.log('\\n3️⃣ wc -l (counts lines from stdin)');
55
+ const wcCmd = $`wc -l`;
56
+ const wcStdin = await wcCmd.streams.stdin;
57
+ console.log(
58
+ ' stdin type:',
59
+ typeof wcStdin,
60
+ 'has write?',
61
+ !!(wcStdin && wcStdin.write)
62
+ );
63
+
64
+ if (wcStdin && wcStdin.write) {
65
+ wcStdin.write('line 1\\n');
66
+ wcStdin.write('line 2\\n');
67
+ wcStdin.write('line 3\\n');
68
+ wcStdin.end();
69
+ console.log(' ✅ Wrote data to wc');
70
+ } else {
71
+ console.log(' ❌ No writable stdin');
72
+ }
73
+
74
+ const wcResult = await wcCmd;
75
+ console.log(' 📤 Result:', JSON.stringify(wcResult.stdout.trim()));
76
+
77
+ console.log('\\n4️⃣ tr (transforms text from stdin)');
78
+ const trCmd = $`tr 'a-z' 'A-Z'`;
79
+ const trStdin = await trCmd.streams.stdin;
80
+ console.log(
81
+ ' stdin type:',
82
+ typeof trStdin,
83
+ 'has write?',
84
+ !!(trStdin && trStdin.write)
85
+ );
86
+
87
+ if (trStdin && trStdin.write) {
88
+ trStdin.write('hello world\\n');
89
+ trStdin.write('transform this\\n');
90
+ trStdin.end();
91
+ console.log(' ✅ Wrote data to tr');
92
+ } else {
93
+ console.log(' ❌ No writable stdin');
94
+ }
95
+
96
+ const trResult = await trCmd;
97
+ console.log(' 📤 Result:', JSON.stringify(trResult.stdout));
98
+
99
+ console.log('\\n5️⃣ grep (filters stdin)');
100
+ const grepCmd = $`grep "test"`;
101
+ const grepStdin = await grepCmd.streams.stdin;
102
+ console.log(
103
+ ' stdin type:',
104
+ typeof grepStdin,
105
+ 'has write?',
106
+ !!(grepStdin && grepStdin.write)
107
+ );
108
+
109
+ if (grepStdin && grepStdin.write) {
110
+ grepStdin.write('no match here\\n');
111
+ grepStdin.write('this is a test line\\n');
112
+ grepStdin.write('skip this\\n');
113
+ grepStdin.write('another test\\n');
114
+ grepStdin.end();
115
+ console.log(' ✅ Wrote data to grep');
116
+ } else {
117
+ console.log(' ❌ No writable stdin');
118
+ }
119
+
120
+ const grepResult = await grepCmd;
121
+ console.log(' 📤 Result:', JSON.stringify(grepResult.stdout));
122
+
123
+ console.log('\\n📊 SUMMARY:');
124
+ console.log(' The most reliable commands for stdin testing:');
125
+ console.log(
126
+ ' ✅ cat, sort, wc, tr, grep - all read from stdin by default'
127
+ );
128
+ console.log(' ✅ These never exit until stdin is closed');
129
+ console.log(' ✅ Perfect for demonstrating streams.stdin control');
130
+ } catch (error) {
131
+ console.error('Error:', error.message);
132
+ }
133
+ }
134
+
135
+ reliableStdinCommands();
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ // Reproducing issue #135: Trace logs interfere with output when CI=true
3
+ // This test sets CI=true BEFORE importing the module
4
+
5
+ process.env.CI = 'true';
6
+
7
+ import { $ } from '../src/$.mjs';
8
+
9
+ console.log('=== Test with CI=true set BEFORE import ===');
10
+ const $silent = $({ mirror: false, capture: true });
11
+ const result = await $silent`echo '{"status":"ok"}'`;
12
+ console.log('Output:', result.stdout || result);
13
+ console.log(
14
+ '\n=== Expected: Should be just {"status":"ok"} without trace logs ==='
15
+ );
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ // Reproducing issue #135: Trace logs interfere with output when CI=true
3
+
4
+ import { $ } from '../src/$.mjs';
5
+
6
+ const $silent = $({ mirror: false, capture: true });
7
+
8
+ console.log('=== Test 1: Without CI environment ===');
9
+ const result1 = await $silent`echo '{"status":"ok"}'`;
10
+ console.log('Output:', result1.stdout || result1);
11
+
12
+ console.log('\n=== Test 2: With CI=true environment ===');
13
+ process.env.CI = 'true';
14
+ const result2 = await $silent`echo '{"status":"ok"}'`;
15
+ console.log('Output:', result2.stdout || result2);
16
+
17
+ console.log('\n=== Expected: Both outputs should be just {"status":"ok"} ===');
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+
3
+ // This file documents how cd SHOULD behave to match shell behavior
4
+
5
+ import { $, shell, enableVirtualCommands } from '../src/$.mjs';
6
+
7
+ enableVirtualCommands();
8
+ shell.verbose(false);
9
+
10
+ console.log('=== Expected Shell cd Behavior ===\n');
11
+
12
+ async function testShellBehavior() {
13
+ const originalCwd = process.cwd();
14
+
15
+ console.log(
16
+ '1. cd should persist for subsequent commands in the same session:'
17
+ );
18
+ console.log(' $ cd /tmp');
19
+ console.log(' $ pwd');
20
+ console.log(' Expected: /tmp');
21
+
22
+ // In a real shell, this would work:
23
+ await $`cd /tmp`;
24
+ const pwd1 = await $`pwd`;
25
+ console.log(' Actual:', pwd1.stdout.trim());
26
+ console.log(' Status:', pwd1.stdout.trim() === '/tmp' ? '✓' : '✗');
27
+
28
+ console.log(
29
+ '\n2. cd in command chain should affect all commands in the chain:'
30
+ );
31
+ console.log(' $ cd /usr && pwd');
32
+ console.log(' Expected: /usr');
33
+
34
+ const result2 = await $`cd /usr && pwd`;
35
+ console.log(' Actual:', result2.stdout.trim());
36
+ console.log(' Status:', result2.stdout.trim() === '/usr' ? '✓' : '✗');
37
+
38
+ console.log('\n3. After chain, directory should still be changed:');
39
+ console.log(' $ pwd');
40
+ console.log(' Expected: /usr (from previous cd)');
41
+
42
+ const pwd3 = await $`pwd`;
43
+ console.log(' Actual:', pwd3.stdout.trim());
44
+ console.log(' Status:', pwd3.stdout.trim() === '/usr' ? '✓' : '✗');
45
+
46
+ console.log('\n4. Subshell () should NOT affect parent shell:');
47
+ console.log(' $ (cd /tmp && pwd)');
48
+ console.log(' $ pwd');
49
+ console.log(' Expected: still /usr');
50
+
51
+ await $`(cd /tmp && pwd)`;
52
+ const pwd4 = await $`pwd`;
53
+ console.log(' Actual after subshell:', pwd4.stdout.trim());
54
+ console.log(' Status:', pwd4.stdout.trim() === '/usr' ? '✓' : '✗');
55
+
56
+ console.log('\n5. Multiple cd commands should work sequentially:');
57
+ console.log(' $ cd /var');
58
+ console.log(' $ cd log');
59
+ console.log(' $ pwd');
60
+ console.log(' Expected: /var/log');
61
+
62
+ await $`cd /var`;
63
+ await $`cd log`;
64
+ const pwd5 = await $`pwd`;
65
+ console.log(' Actual:', pwd5.stdout.trim());
66
+ console.log(' Status:', pwd5.stdout.trim() === '/var/log' ? '✓' : '✗');
67
+
68
+ console.log('\n6. cd with relative paths:');
69
+ console.log(' $ cd ..');
70
+ console.log(' $ pwd');
71
+ console.log(' Expected: /var');
72
+
73
+ await $`cd ..`;
74
+ const pwd6 = await $`pwd`;
75
+ console.log(' Actual:', pwd6.stdout.trim());
76
+ console.log(' Status:', pwd6.stdout.trim() === '/var' ? '✓' : '✗');
77
+
78
+ // Return to original directory
79
+ process.chdir(originalCwd);
80
+
81
+ console.log('\n=== Test Complete ===');
82
+ console.log('Note: This shows the expected shell behavior.');
83
+ console.log('The virtual cd command needs to maintain directory state');
84
+ console.log('across commands in the same $ session, but isolate');
85
+ console.log('subshells created with ().');
86
+ }
87
+
88
+ testShellBehavior().catch(console.error);
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env node
2
+ // Test SIGINT forwarding to child processes
3
+ // This runs in a subprocess to avoid killing the test runner
4
+
5
+ import { $ } from '../src/$.mjs';
6
+
7
+ process.env.COMMAND_STREAM_VERBOSE = 'true';
8
+
9
+ console.log('TEST: Starting SIGINT forwarding test');
10
+
11
+ // Test that SIGINT is forwarded to child processes
12
+ console.log('TEST: Starting long-running command');
13
+ const runner = $`sleep 30`;
14
+ const promise = runner.start();
15
+
16
+ // Set up a handler to catch SIGINT but don't let it kill the process
17
+ let sigintReceived = false;
18
+ process.on('SIGINT', () => {
19
+ console.log('RESULT: parent_received_sigint=true');
20
+ sigintReceived = true;
21
+ // Don't exit - we want to continue the test
22
+ });
23
+
24
+ // Wait a bit for command to start
25
+ await new Promise((resolve) => setTimeout(resolve, 100));
26
+
27
+ // Send SIGINT to ourselves
28
+ console.log('TEST: Sending SIGINT');
29
+ process.kill(process.pid, 'SIGINT');
30
+
31
+ // Wait a bit for signal handling
32
+ await new Promise((resolve) => setTimeout(resolve, 200));
33
+
34
+ // Check if process was killed
35
+ let exitCode = null;
36
+ try {
37
+ // Try to wait for the promise with a timeout
38
+ await Promise.race([
39
+ promise.then((result) => {
40
+ exitCode = result.code;
41
+ }),
42
+ new Promise((_, reject) =>
43
+ setTimeout(() => reject(new Error('timeout')), 500)
44
+ ),
45
+ ]);
46
+ } catch (e) {
47
+ if (e.message === 'timeout') {
48
+ console.log('RESULT: command_still_running=true');
49
+ } else {
50
+ console.log(`RESULT: command_exit_code=${exitCode ?? 'error'}`);
51
+ }
52
+ }
53
+
54
+ console.log(`RESULT: sigint_received=${sigintReceived}`);
55
+
56
+ // Clean up
57
+ runner.kill();
58
+
59
+ console.log('TEST: Complete');
60
+ process.exit(0);
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env node
2
+ // Test script to verify SIGINT handler cleanup
3
+ // This runs in a subprocess to avoid interfering with the test runner
4
+
5
+ import { $ } from '../src/$.mjs';
6
+
7
+ process.env.COMMAND_STREAM_VERBOSE = 'true';
8
+
9
+ console.log('TEST: Starting SIGINT handler test');
10
+
11
+ // Test 1: Verify handler is installed when command starts
12
+ console.log('TEST: Check initial state');
13
+ const initialListeners = process.listeners('SIGINT').length;
14
+ console.log(`RESULT: initial_listeners=${initialListeners}`);
15
+
16
+ // Start a command
17
+ console.log('TEST: Starting command');
18
+ const runner = $`sleep 0.1`;
19
+ const promise = runner.start();
20
+
21
+ // Check handler was installed
22
+ const duringListeners = process.listeners('SIGINT').length;
23
+ console.log(`RESULT: during_listeners=${duringListeners}`);
24
+
25
+ // Wait for completion
26
+ await promise;
27
+
28
+ // Check handler was removed
29
+ const afterListeners = process.listeners('SIGINT').length;
30
+ console.log(`RESULT: after_listeners=${afterListeners}`);
31
+
32
+ // Test 2: Multiple concurrent commands share single handler
33
+ console.log('TEST: Starting multiple concurrent commands');
34
+ const promises = [$`sleep 0.05`, $`sleep 0.05`, $`sleep 0.05`];
35
+
36
+ const starts = promises.map((p) => p.start());
37
+ const concurrentListeners = process.listeners('SIGINT').length;
38
+ console.log(`RESULT: concurrent_listeners=${concurrentListeners}`);
39
+
40
+ await Promise.all(starts);
41
+ const afterConcurrentListeners = process.listeners('SIGINT').length;
42
+ console.log(`RESULT: after_concurrent_listeners=${afterConcurrentListeners}`);
43
+
44
+ // Test 3: Handler removed on error
45
+ console.log('TEST: Testing error handling');
46
+ try {
47
+ await $`exit 1`;
48
+ } catch (e) {
49
+ // Expected
50
+ }
51
+
52
+ const afterErrorListeners = process.listeners('SIGINT').length;
53
+ console.log(`RESULT: after_error_listeners=${afterErrorListeners}`);
54
+
55
+ // Test 4: Handler removed when command is killed
56
+ console.log('TEST: Testing kill cleanup');
57
+ const killRunner = $`sleep 10`;
58
+ const killPromise = killRunner.start();
59
+
60
+ setTimeout(() => killRunner.kill(), 10);
61
+
62
+ try {
63
+ await killPromise;
64
+ } catch (e) {
65
+ // Expected
66
+ }
67
+
68
+ const afterKillListeners = process.listeners('SIGINT').length;
69
+ console.log(`RESULT: after_kill_listeners=${afterKillListeners}`);
70
+
71
+ console.log('TEST: Complete');
72
+ process.exit(0);