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,133 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Test that we can inherit stdout but not stdin
5
+ * This allows parent process to see output, but child doesn't read from parent's stdin
6
+ */
7
+
8
+ import { $ } from '../src/$.mjs';
9
+
10
+ console.log('=== Testing inherit stdout but not stdin ===');
11
+ console.log('');
12
+
13
+ async function testInheritStdoutNotStdin() {
14
+ try {
15
+ console.log('TEST 1: Inherit stdout - output should appear directly');
16
+
17
+ // This should inherit stdout so we see the output directly
18
+ const inheritStdoutCmd = $`echo "This output should appear directly"`;
19
+
20
+ // Set stdout to inherit mode
21
+ const result1 = await inheritStdoutCmd.run({
22
+ stdout: 'inherit',
23
+ stdin: 'pipe',
24
+ });
25
+ console.log('✓ Command completed with inherit stdout');
26
+ console.log(' Exit code:', result1.code);
27
+ console.log(
28
+ ' Captured stdout (should be empty due to inherit):',
29
+ JSON.stringify(result1.stdout)
30
+ );
31
+
32
+ console.log('');
33
+ console.log('TEST 2: Control stdin independently while inheriting stdout');
34
+
35
+ // Create a command that can read from both stdin and produce stdout
36
+ const catCmd = $`cat`;
37
+
38
+ // Access streams to control individually
39
+ const stdin = catCmd.streams.stdin;
40
+
41
+ console.log(' → Sending data to stdin while stdout is inherited...');
42
+ if (stdin) {
43
+ stdin.write('Hello from controlled stdin!\\n');
44
+ stdin.write('This comes from our code, not the parent process stdin\\n');
45
+ stdin.end();
46
+ }
47
+
48
+ const catResult = await catCmd.run({ stdout: 'inherit' });
49
+ console.log('✓ Cat completed with controlled stdin and inherited stdout');
50
+ console.log(' Exit code:', catResult.code);
51
+
52
+ console.log('');
53
+ console.log('TEST 3: Verify different stdio combinations work');
54
+
55
+ console.log(' 3a: Capture stdout, pipe stdin');
56
+ const cmd3a = $`cat`;
57
+ const stdin3a = cmd3a.streams.stdin;
58
+ if (stdin3a) {
59
+ stdin3a.write('Captured output test\\n');
60
+ stdin3a.end();
61
+ }
62
+ const result3a = await cmd3a.run({ stdout: 'pipe', stdin: 'pipe' });
63
+ console.log(' Result:', JSON.stringify(result3a.stdout));
64
+
65
+ console.log(
66
+ " 3b: Inherit stdout, ignore stdin (for commands that don't need stdin)"
67
+ );
68
+ const result3b = await $`echo "Direct output"`.run({
69
+ stdout: 'inherit',
70
+ stdin: 'ignore',
71
+ });
72
+ console.log(' Exit code:', result3b.code);
73
+
74
+ console.log(' 3c: Mixed mode - inherit stdout, controlled stdin');
75
+ const cmd3c = $`grep "hello"`;
76
+ const stdin3c = cmd3c.streams.stdin;
77
+ if (stdin3c) {
78
+ stdin3c.write('hello world\\n');
79
+ stdin3c.write('test line\\n');
80
+ stdin3c.write('hello again\\n');
81
+ stdin3c.end();
82
+ }
83
+ await cmd3c.run({ stdout: 'inherit', stdin: 'pipe' });
84
+ console.log(' ✓ grep completed with inherited stdout');
85
+
86
+ console.log('');
87
+ console.log(
88
+ 'TEST 4: Verify top command with inherited stdout and controlled stdin'
89
+ );
90
+
91
+ console.log(
92
+ ' → Starting top with inherited stdout, sending "q" via stdin...'
93
+ );
94
+ const topCmd = $`top -n 3`; // Limit iterations
95
+ const topStdin = topCmd.streams.stdin;
96
+
97
+ // Send quit command after a brief delay
98
+ setTimeout(() => {
99
+ if (topStdin) {
100
+ console.log(' → Sending "q" to quit top...');
101
+ topStdin.write('q');
102
+ topStdin.end();
103
+ }
104
+ }, 1000);
105
+
106
+ // Fallback kill
107
+ setTimeout(() => {
108
+ console.log(' → Fallback kill...');
109
+ topCmd.kill();
110
+ }, 3000);
111
+
112
+ const topResult = await topCmd.run({ stdout: 'inherit', stdin: 'pipe' });
113
+ console.log(' ✓ Top completed, exit code:', topResult.code);
114
+
115
+ console.log('');
116
+ console.log('✅ CONCLUSIONS:');
117
+ console.log(' • stdout can be inherited (appears directly in terminal)');
118
+ console.log(' • stdin can be controlled independently via streams.stdin');
119
+ console.log(
120
+ ' • This combination allows seeing output while controlling input'
121
+ );
122
+ console.log(
123
+ ' • Perfect for interactive commands that need specific input'
124
+ );
125
+ } catch (error) {
126
+ console.log('');
127
+ console.error('❌ TEST FAILED:', error.message);
128
+ console.error(error.stack);
129
+ process.exit(1);
130
+ }
131
+ }
132
+
133
+ testInheritStdoutNotStdin();
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Test shell injection protection with the smart quoting
4
+ import { $ } from '../src/$.mjs';
5
+
6
+ console.log('=== Shell Injection Protection Test ===\n');
7
+
8
+ async function testInjection() {
9
+ // Test 1: Command chaining attempt
10
+ console.log('1. Command chaining attempt:');
11
+ const evil1 = 'test; echo INJECTED';
12
+ const cmd1 = $({ mirror: false })`echo ${evil1}`;
13
+ console.log('Input:', evil1);
14
+ console.log('Command:', cmd1.spec.command);
15
+ const result1 = await cmd1;
16
+ const output1 = result1.stdout || String(result1);
17
+ console.log('Output:', output1.trim());
18
+ console.log(output1.includes('INJECTED') ? '❌ INJECTION!' : '✅ Protected');
19
+
20
+ // Test 2: Variable expansion attempt
21
+ console.log('\n2. Variable expansion attempt:');
22
+ const evil2 = '$HOME';
23
+ const cmd2 = $({ mirror: false })`echo ${evil2}`;
24
+ console.log('Input:', evil2);
25
+ console.log('Command:', cmd2.spec.command);
26
+ const result2 = await cmd2;
27
+ const output2 = (result2.stdout || String(result2)).trim();
28
+ console.log('Output:', output2);
29
+ console.log(
30
+ output2 === '$HOME'
31
+ ? '✅ Protected (literal $HOME)'
32
+ : '❌ Variable expanded!'
33
+ );
34
+
35
+ // Test 3: Command substitution attempt
36
+ console.log('\n3. Command substitution attempt:');
37
+ const evil3 = '$(whoami)';
38
+ const cmd3 = $({ mirror: false })`echo ${evil3}`;
39
+ console.log('Input:', evil3);
40
+ console.log('Command:', cmd3.spec.command);
41
+ const result3 = await cmd3;
42
+ const output3 = (result3.stdout || String(result3)).trim();
43
+ console.log('Output:', output3);
44
+ console.log(
45
+ output3 === '$(whoami)'
46
+ ? '✅ Protected (literal $(whoami))'
47
+ : '❌ Command executed!'
48
+ );
49
+
50
+ // Test 4: Safe string - no unnecessary quotes
51
+ console.log('\n4. Safe string (no unnecessary quotes):');
52
+ const safe = 'hello';
53
+ const cmd4 = $({ mirror: false })`echo ${safe}`;
54
+ console.log('Input:', safe);
55
+ console.log('Command:', cmd4.spec.command);
56
+ const result4 = await cmd4;
57
+ console.log('Output:', (result4.stdout || String(result4)).trim());
58
+ console.log(
59
+ !cmd4.spec.command.includes("'hello'")
60
+ ? '✅ No unnecessary quotes'
61
+ : '⚠️ Quoted when not needed'
62
+ );
63
+
64
+ // Test 5: Path without spaces - no unnecessary quotes
65
+ console.log('\n5. Safe path (no unnecessary quotes):');
66
+ const safePath = '/usr/bin/echo';
67
+ const cmd5 = $({ mirror: false })`${safePath} test`;
68
+ console.log('Input:', safePath);
69
+ console.log('Command:', cmd5.spec.command);
70
+ console.log(
71
+ !cmd5.spec.command.startsWith("'")
72
+ ? '✅ Path not unnecessarily quoted'
73
+ : '⚠️ Path quoted when not needed'
74
+ );
75
+ }
76
+
77
+ testInjection().catch(console.error);
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ async function testInteractiveStreaming() {
6
+ console.log('Testing Interactive Streaming I/O\n');
7
+ console.log('This test demonstrates real-time bidirectional streaming:');
8
+ console.log('- Send math expressions to stdin');
9
+ console.log('- Receive results from stdout');
10
+ console.log('- Multiple iterations while process is running\n');
11
+
12
+ // Start the interactive math calculator
13
+ // Use relative path that works from any directory
14
+ const calcPath = new URL('./interactive-math-calc.mjs', import.meta.url)
15
+ .pathname;
16
+ const calc = $`node ${calcPath}`;
17
+
18
+ // Get the streams immediately (process auto-starts)
19
+ const stdin = await calc.streams.stdin;
20
+ const stdout = await calc.streams.stdout;
21
+ const stderr = await calc.streams.stderr;
22
+
23
+ console.log('Streams obtained:');
24
+ console.log(' stdin:', stdin ? 'ready' : 'not available');
25
+ console.log(' stdout:', stdout ? 'ready' : 'not available');
26
+ console.log(' stderr:', stderr ? 'ready' : 'not available');
27
+ console.log('');
28
+
29
+ if (!stdin || !stdout) {
30
+ console.error('Failed to get streams!');
31
+ return;
32
+ }
33
+
34
+ // Set up stdout reader
35
+ const results = [];
36
+ let currentResult = '';
37
+
38
+ stdout.on('data', (chunk) => {
39
+ const text = chunk.toString();
40
+ console.log(' <- Received:', text.trim());
41
+ currentResult += text;
42
+
43
+ // Check if we got a complete result
44
+ if (
45
+ text.includes('RESULT:') ||
46
+ text.includes('READY') ||
47
+ text.includes('GOODBYE')
48
+ ) {
49
+ results.push(text.trim());
50
+ currentResult = '';
51
+ }
52
+ });
53
+
54
+ // Set up stderr reader
55
+ stderr.on('data', (chunk) => {
56
+ console.error(' <- Error:', chunk.toString().trim());
57
+ });
58
+
59
+ // Wait for calculator to be ready
60
+ await new Promise((resolve) => {
61
+ const checkReady = () => {
62
+ if (results.some((r) => r.includes('READY'))) {
63
+ resolve();
64
+ } else {
65
+ setTimeout(checkReady, 10);
66
+ }
67
+ };
68
+ checkReady();
69
+ });
70
+
71
+ console.log('\n--- Starting Interactive Math Session ---\n');
72
+
73
+ // Test cases
74
+ const expressions = [
75
+ '1+2',
76
+ '10*5',
77
+ '100/4',
78
+ '7-3',
79
+ '2**8', // Power of 2
80
+ ];
81
+
82
+ for (const expr of expressions) {
83
+ console.log(` -> Sending: ${expr}`);
84
+ stdin.write(`${expr}\n`);
85
+
86
+ // Wait for result
87
+ const startResults = results.length;
88
+ await new Promise((resolve) => {
89
+ const checkResult = () => {
90
+ if (results.length > startResults) {
91
+ resolve();
92
+ } else {
93
+ setTimeout(checkResult, 10);
94
+ }
95
+ };
96
+ setTimeout(checkResult, 10);
97
+ });
98
+
99
+ // Small delay between calculations
100
+ await new Promise((resolve) => setTimeout(resolve, 100));
101
+ }
102
+
103
+ console.log('\n--- Ending Session ---\n');
104
+
105
+ // Send exit command
106
+ console.log(' -> Sending: exit');
107
+ stdin.write('exit\n');
108
+
109
+ // Wait for goodbye message
110
+ await new Promise((resolve) => {
111
+ const checkGoodbye = () => {
112
+ if (results.some((r) => r.includes('GOODBYE'))) {
113
+ resolve();
114
+ } else {
115
+ setTimeout(checkGoodbye, 10);
116
+ }
117
+ };
118
+ setTimeout(checkGoodbye, 10);
119
+ });
120
+
121
+ // Wait for process to complete
122
+ const result = await calc;
123
+
124
+ console.log('\n--- Summary ---');
125
+ console.log('Process exited with code:', result.code);
126
+ console.log(
127
+ 'Total results received:',
128
+ results.filter((r) => r.includes('RESULT:')).length
129
+ );
130
+ console.log('\nAll results:');
131
+ results.forEach((r) => {
132
+ if (r.includes('RESULT:')) {
133
+ console.log(` ${r}`);
134
+ }
135
+ });
136
+
137
+ console.log('\n✅ Interactive streaming test completed successfully!');
138
+ }
139
+
140
+ testInteractiveStreaming().catch(console.error);
@@ -0,0 +1,24 @@
1
+ # Testing Interactive Top Example
2
+
3
+ To test the interactive top example:
4
+
5
+ ```bash
6
+ node js/examples/interactive-top.mjs
7
+ ```
8
+
9
+ **Expected behavior:**
10
+
11
+ - The `top` command starts immediately
12
+ - ANSI colors and formatting are preserved
13
+ - Full interactivity is maintained (you can press keys like 'q' to quit)
14
+ - No time limits - runs until you manually quit
15
+ - Process cleanup happens properly when you exit
16
+
17
+ **Key features demonstrated:**
18
+
19
+ - ✅ ANSI colors preserved (addresses GitHub issue #10)
20
+ - ✅ Interactive I/O not interfered with (addresses GitHub issue #11)
21
+ - ✅ Manual control - no automatic timeouts
22
+ - ✅ Proper process management and cleanup
23
+
24
+ **Note:** Press 'q' to quit top when you're ready. The example will show the exit code when top terminates.
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { $ } from '../src/$.mjs';
4
+
5
+ console.log('Testing interactive command detection...');
6
+
7
+ // Test 1: Check if top is detected as interactive
8
+ const isTop = $`top`;
9
+
10
+ console.log('Created top command process');
11
+
12
+ // Test 2: Check if ls is detected as non-interactive
13
+ const isLs = $`ls`;
14
+
15
+ console.log('Created ls command process');
16
+
17
+ console.log('Interactive command detection test completed');
@@ -0,0 +1,14 @@
1
+ import { $ } from '../src/$.mjs';
2
+
3
+ async function testInterpolation() {
4
+ const name = 'World';
5
+ const $custom = $({ capture: true, mirror: false });
6
+ const result = await $custom`echo Hello, ${name}!`;
7
+
8
+ console.log('Expected:', "Hello, 'World'!");
9
+ console.log('Actual: ', result.stdout.trim());
10
+ console.log('Match:', result.stdout.trim() === "Hello, 'World'!");
11
+ console.log('Code:', result.code);
12
+ }
13
+
14
+ testInterpolation().catch(console.error);
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Automated test for interruption handling
4
+
5
+ import { $ } from '../src/$.mjs';
6
+
7
+ async function test() {
8
+ console.log('Testing interruption of virtual sleep command...');
9
+
10
+ // Start a long sleep
11
+ const runner = $`sleep 10`;
12
+ const promise = runner.start();
13
+
14
+ // Kill it after 500ms
15
+ setTimeout(() => {
16
+ console.log('Sending kill signal...');
17
+ runner.kill();
18
+ }, 500);
19
+
20
+ // Wait for result
21
+ const result = await promise;
22
+
23
+ console.log('Result:', {
24
+ code: result.code,
25
+ stdout: result.stdout,
26
+ stderr: result.stderr,
27
+ });
28
+
29
+ if (result.code === 143) {
30
+ console.log(
31
+ '✓ SUCCESS: Virtual command was properly interrupted with SIGTERM exit code'
32
+ );
33
+ process.exit(0);
34
+ } else {
35
+ console.log('✗ FAIL: Unexpected exit code:', result.code);
36
+ process.exit(1);
37
+ }
38
+ }
39
+
40
+ test().catch(console.error);
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ // Comprehensive test for issue #135: Trace logs interfere with output
3
+
4
+ import { $ } from '../src/$.mjs';
5
+
6
+ console.log(
7
+ '=== Test 1: Default (no env vars, mirror:false, capture:true) ==='
8
+ );
9
+ const $silent = $({ mirror: false, capture: true });
10
+ const result1 = await $silent`echo test1`;
11
+ console.log('Output:', result1.stdout);
12
+ console.log('Expected: just "test1"\n');
13
+
14
+ console.log('=== Test 2: CI=true (should NOT produce trace logs) ===');
15
+ process.env.CI = 'true';
16
+ const $silent2 = $({ mirror: false, capture: true });
17
+ const result2 = await $silent2`echo test2`;
18
+ console.log('Output:', result2.stdout);
19
+ console.log('Expected: just "test2"\n');
20
+
21
+ console.log(
22
+ '=== Test 3: CI=true + COMMAND_STREAM_TRACE=true (should produce trace logs) ==='
23
+ );
24
+ process.env.COMMAND_STREAM_TRACE = 'true';
25
+ const $silent3 = $({ mirror: false, capture: true });
26
+ const result3 = await $silent3`echo test3`;
27
+ console.log('Output:', result3.stdout);
28
+ console.log('Expected: "test3" (trace logs should appear in stderr above)\n');
29
+
30
+ console.log(
31
+ '=== Test 4: COMMAND_STREAM_TRACE=false overrides COMMAND_STREAM_VERBOSE=true ==='
32
+ );
33
+ process.env.COMMAND_STREAM_VERBOSE = 'true';
34
+ process.env.COMMAND_STREAM_TRACE = 'false';
35
+ const result4 = await $silent`echo test4`;
36
+ console.log('Output:', result4.stdout);
37
+ console.log(
38
+ 'Expected: just "test4" (no trace logs even though VERBOSE=true)\n'
39
+ );
40
+
41
+ console.log('=== All tests completed ===');
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Detailed test for issue #12 - checking error messages and command construction
4
+ // Original issue: https://github.com/link-foundation/command-stream/issues/12
5
+ // Original error: ENOENT: no such file or directory, posix_spawn ''/Users/konard/.claude/local/claude''
6
+
7
+ import { $ } from '../src/$.mjs';
8
+
9
+ const claude = process.env.CLAUDE_PATH || '/Users/konard/.claude/local/claude';
10
+
11
+ console.log('=== Detailed Issue #12 Testing ===\n');
12
+ console.log('Testing path:', claude);
13
+
14
+ async function testScenarios() {
15
+ console.log('\n1. Test direct command (no pipe):');
16
+ console.log('-----------------------------------');
17
+ try {
18
+ const cmd = $({ capture: true, mirror: false })`${claude} --version`;
19
+ console.log('Generated command:', cmd.spec.command);
20
+ const result = await cmd;
21
+ console.log('Exit code:', result.code);
22
+ console.log('Stderr:', result.stderr.trim());
23
+
24
+ // Check for double quotes in stderr
25
+ if (result.stderr.includes("''")) {
26
+ console.log('❌ Double quotes found in stderr!');
27
+ } else {
28
+ console.log('✅ No double quotes in error');
29
+ }
30
+ } catch (error) {
31
+ console.log('Exception:', error.message);
32
+ }
33
+
34
+ console.log('\n2. Test with pipe (original issue):');
35
+ console.log('------------------------------------');
36
+ try {
37
+ const cmd = $({
38
+ capture: true,
39
+ mirror: false,
40
+ })`${claude} -p "hi" --output-format stream-json --model sonnet | jq .`;
41
+ console.log('Generated command:', cmd.spec.command);
42
+ const result = await cmd;
43
+ console.log('Exit code:', result.code);
44
+ console.log('Output:', result.stdout || '(empty)');
45
+ } catch (error) {
46
+ console.log('Exception:', error.message);
47
+ }
48
+
49
+ console.log('\n3. Test command construction:');
50
+ console.log('------------------------------');
51
+
52
+ // Check different interpolation positions
53
+ const testCases = [
54
+ {
55
+ desc: 'First position',
56
+ template: (p) => $({ mirror: false })`${p} --test`,
57
+ },
58
+ {
59
+ desc: 'Middle position',
60
+ template: (p) => $({ mirror: false })`echo ${p} test`,
61
+ },
62
+ { desc: 'With pipe', template: (p) => $({ mirror: false })`${p} | cat` },
63
+ ];
64
+
65
+ for (const { desc, template } of testCases) {
66
+ const cmd = template(claude);
67
+ console.log(`${desc}: ${cmd.spec.command}`);
68
+ }
69
+
70
+ console.log('\n4. Check if pre-quoted paths work:');
71
+ console.log('-----------------------------------');
72
+
73
+ // Test if already-quoted paths are handled correctly
74
+ const quotedPath = `'${claude}'`;
75
+ console.log('Input (pre-quoted):', quotedPath);
76
+ const quotedCmd = $({ mirror: false })`${quotedPath} --test`;
77
+ console.log('Generated command:', quotedCmd.spec.command);
78
+
79
+ if (
80
+ quotedCmd.spec.command.includes("'''") ||
81
+ quotedCmd.spec.command.includes("''")
82
+ ) {
83
+ console.log('⚠️ Potential issue with pre-quoted path handling');
84
+ } else {
85
+ console.log('✅ Pre-quoted path handled correctly');
86
+ }
87
+ }
88
+
89
+ testScenarios().catch(console.error);
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Exact test for issue #12 from deep-assistant/hive-mind
4
+ // Original issue: https://github.com/link-foundation/command-stream/issues/12
5
+ // Original error: ENOENT: no such file or directory, posix_spawn ''/Users/konard/.claude/local/claude''
6
+
7
+ import { $ } from '../src/$.mjs';
8
+
9
+ const claude = process.env.CLAUDE_PATH || '/Users/konard/.claude/local/claude';
10
+
11
+ console.log('Testing exact issue #12 scenario:');
12
+ console.log('Path:', claude);
13
+ console.log();
14
+
15
+ // This is the exact failing line from the original issue
16
+ try {
17
+ const result =
18
+ await $`${claude} -p "hi" --output-format stream-json --model sonnet | jq .`;
19
+ console.log('Success! Result:', result.stdout);
20
+ } catch (error) {
21
+ console.log('Error message:', error.message);
22
+ console.log();
23
+
24
+ // Check if the error contains the problematic double quotes
25
+ if (error.message.includes("''") && error.message.includes('posix_spawn')) {
26
+ console.log('❌ BUG STILL PRESENT: Double quotes in posix_spawn error');
27
+ } else if (error.message.includes('posix_spawn')) {
28
+ console.log('⚠️ posix_spawn error but no double quotes - partial fix');
29
+ } else {
30
+ console.log('✅ BUG FIXED: No double quotes in error message');
31
+ console.log(' Error is now properly formatted');
32
+ }
33
+ }
@@ -0,0 +1,57 @@
1
+ import { $ } from '../src/$.mjs';
2
+
3
+ console.log('=== Testing jq Color Output ===\n');
4
+
5
+ async function testJqColors() {
6
+ const testJson =
7
+ '{"message": "hello world", "number": 42, "active": true, "data": null}';
8
+
9
+ console.log(
10
+ '1. Testing jq with default options (should show colors if TTY):'
11
+ );
12
+ console.log('Input JSON:', testJson);
13
+ console.log(
14
+ '\n--- Output with pretty printing (should be colored in TTY) ---'
15
+ );
16
+
17
+ try {
18
+ // Test 1: Default behavior - should show colors in TTY
19
+ const result1 = await $`echo ${testJson} | jq .`;
20
+ console.log('Result code:', result1.code);
21
+ console.log('Stdout length:', result1.stdout.length);
22
+ console.log('Contains ANSI codes:', /\u001b\[/.test(result1.stdout));
23
+ console.log('Raw stdout:', JSON.stringify(result1.stdout));
24
+
25
+ console.log('\n2. Testing jq with explicit color output:');
26
+ const result2 = await $`echo ${testJson} | jq --color-output .`;
27
+ console.log('Result code:', result2.code);
28
+ console.log('Contains ANSI codes:', /\u001b\[/.test(result2.stdout));
29
+ console.log('Raw stdout:', JSON.stringify(result2.stdout));
30
+
31
+ console.log('\n3. Testing jq with no color output:');
32
+ const result3 = await $`echo ${testJson} | jq --color-output=never .`;
33
+ console.log('Result code:', result3.code);
34
+ console.log('Contains ANSI codes:', /\u001b\[/.test(result3.stdout));
35
+ console.log('Raw stdout:', JSON.stringify(result3.stdout));
36
+
37
+ console.log('\n4. Testing jq with capture=false (pure mirror mode):');
38
+ const $mirror = $({ capture: false, mirror: true });
39
+ console.log('About to run jq with pure mirror mode (output below):');
40
+ const result4 = await $mirror`echo ${testJson} | jq .`;
41
+ console.log('Result code (mirror mode):', result4.code);
42
+
43
+ console.log('\n5. Testing individual field extraction:');
44
+ const result5 = await $`echo ${testJson} | jq -r .message`;
45
+ console.log('Extracted message:', JSON.stringify(result5.stdout.trim()));
46
+ } catch (error) {
47
+ console.error('Error testing jq:', error.message);
48
+ }
49
+ }
50
+
51
+ console.log('TTY Status:');
52
+ console.log('- process.stdout.isTTY:', process.stdout.isTTY);
53
+ console.log('- process.stderr.isTTY:', process.stderr.isTTY);
54
+ console.log('- process.stdin.isTTY:', process.stdin.isTTY);
55
+ console.log();
56
+
57
+ testJqColors().catch(console.error);