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.
- package/js/examples/01-basic-streaming.mjs +14 -0
- package/js/examples/02-async-iterator.mjs +9 -0
- package/js/examples/03-file-and-console.mjs +16 -0
- package/js/examples/04-claude-jq-pipe.mjs +16 -0
- package/js/examples/CI-DEBUG-README.md +138 -0
- package/js/examples/README-examples.mjs +111 -0
- package/js/examples/README.md +345 -0
- package/js/examples/STREAMING_INTERFACES_SUMMARY.md +116 -0
- package/js/examples/add-test-timeouts.js +107 -0
- package/js/examples/ansi-default-preserved.mjs +11 -0
- package/js/examples/ansi-global-config.mjs +12 -0
- package/js/examples/ansi-reset-default.mjs +12 -0
- package/js/examples/ansi-strip-utils.mjs +12 -0
- package/js/examples/baseline-child-process.mjs +23 -0
- package/js/examples/baseline-claude-test.mjs +47 -0
- package/js/examples/baseline-working.mjs +34 -0
- package/js/examples/capture-mirror-comparison.mjs +23 -0
- package/js/examples/capture-mirror-default.mjs +11 -0
- package/js/examples/capture-mirror-performance.mjs +16 -0
- package/js/examples/capture-mirror-show-only.mjs +16 -0
- package/js/examples/capture-mirror-silent-processing.mjs +16 -0
- package/js/examples/ci-debug-baseline-vs-library.mjs +265 -0
- package/js/examples/ci-debug-es-module-loading.mjs +184 -0
- package/js/examples/ci-debug-signal-handling.mjs +225 -0
- package/js/examples/ci-debug-stdout-buffering.mjs +94 -0
- package/js/examples/ci-debug-test-timeouts.mjs +259 -0
- package/js/examples/claude-exact-file-output.mjs +20 -0
- package/js/examples/claude-exact-jq.mjs +13 -0
- package/js/examples/claude-exact-streaming.mjs +13 -0
- package/js/examples/claude-jq-pipeline.mjs +13 -0
- package/js/examples/claude-json-stream.mjs +39 -0
- package/js/examples/claude-streaming-basic.mjs +99 -0
- package/js/examples/claude-streaming-demo.mjs +126 -0
- package/js/examples/claude-streaming-final.mjs +20 -0
- package/js/examples/cleanup-verification-test.mjs +115 -0
- package/js/examples/colors-buffer-processing.mjs +14 -0
- package/js/examples/colors-default-preserved.mjs +15 -0
- package/js/examples/colors-per-command-config.mjs +15 -0
- package/js/examples/colors-strip-ansi.mjs +13 -0
- package/js/examples/commandstream-jq.mjs +29 -0
- package/js/examples/commandstream-working.mjs +23 -0
- package/js/examples/comprehensive-streams-demo.mjs +121 -0
- package/js/examples/ctrl-c-concurrent-processes.mjs +20 -0
- package/js/examples/ctrl-c-long-running-command.mjs +20 -0
- package/js/examples/ctrl-c-real-system-command.mjs +17 -0
- package/js/examples/ctrl-c-sleep-command.mjs +17 -0
- package/js/examples/ctrl-c-stdin-forwarding.mjs +20 -0
- package/js/examples/ctrl-c-virtual-command.mjs +17 -0
- package/js/examples/debug-already-started.mjs +20 -0
- package/js/examples/debug-ansi-processing.mjs +42 -0
- package/js/examples/debug-basic-streaming.mjs +44 -0
- package/js/examples/debug-buildshellcommand.mjs +82 -0
- package/js/examples/debug-child-process.mjs +43 -0
- package/js/examples/debug-child-state.mjs +55 -0
- package/js/examples/debug-chunking.mjs +38 -0
- package/js/examples/debug-command-parsing.mjs +61 -0
- package/js/examples/debug-complete-consolidation.mjs +97 -0
- package/js/examples/debug-echo-args.mjs +22 -0
- package/js/examples/debug-emit-timing.mjs +28 -0
- package/js/examples/debug-end-event.mjs +56 -0
- package/js/examples/debug-errexit.mjs +16 -0
- package/js/examples/debug-event-emission.mjs +40 -0
- package/js/examples/debug-event-timing.mjs +67 -0
- package/js/examples/debug-event-vs-result.mjs +30 -0
- package/js/examples/debug-exact-command.mjs +28 -0
- package/js/examples/debug-exact-test-scenario.mjs +44 -0
- package/js/examples/debug-execution-path.mjs +27 -0
- package/js/examples/debug-exit-command.mjs +38 -0
- package/js/examples/debug-exit-virtual.mjs +54 -0
- package/js/examples/debug-finish-consolidation.mjs +44 -0
- package/js/examples/debug-force-cleanup.mjs +47 -0
- package/js/examples/debug-getter-basic.mjs +13 -0
- package/js/examples/debug-getter-direct.mjs +23 -0
- package/js/examples/debug-getter-internals.mjs +61 -0
- package/js/examples/debug-handler-detection.mjs +65 -0
- package/js/examples/debug-idempotent-finish.mjs +54 -0
- package/js/examples/debug-idempotent-kill.mjs +58 -0
- package/js/examples/debug-interpolation-individual.mjs +88 -0
- package/js/examples/debug-interpolation-issue.mjs +101 -0
- package/js/examples/debug-jq-streaming.mjs +57 -0
- package/js/examples/debug-jq-tty-colors.mjs +168 -0
- package/js/examples/debug-kill-cleanup.mjs +56 -0
- package/js/examples/debug-kill-method.mjs +33 -0
- package/js/examples/debug-listener-interference.mjs +38 -0
- package/js/examples/debug-listener-lifecycle.mjs +50 -0
- package/js/examples/debug-listener-timing.mjs +62 -0
- package/js/examples/debug-listeners-property.mjs +34 -0
- package/js/examples/debug-map-methods.mjs +39 -0
- package/js/examples/debug-not-awaited-cleanup.mjs +106 -0
- package/js/examples/debug-off-method.mjs +28 -0
- package/js/examples/debug-option-merging.mjs +17 -0
- package/js/examples/debug-options.mjs +36 -0
- package/js/examples/debug-output.mjs +25 -0
- package/js/examples/debug-pattern-matching.mjs +69 -0
- package/js/examples/debug-pipeline-cat.mjs +28 -0
- package/js/examples/debug-pipeline-cleanup.mjs +71 -0
- package/js/examples/debug-pipeline-error-detailed.mjs +78 -0
- package/js/examples/debug-pipeline-error.mjs +65 -0
- package/js/examples/debug-pipeline-issue.mjs +26 -0
- package/js/examples/debug-pipeline-method.mjs +22 -0
- package/js/examples/debug-pipeline-stream.mjs +66 -0
- package/js/examples/debug-pipeline.mjs +14 -0
- package/js/examples/debug-process-exit-trace.mjs +41 -0
- package/js/examples/debug-process-path.mjs +38 -0
- package/js/examples/debug-property-check.mjs +29 -0
- package/js/examples/debug-resource-cleanup.mjs +83 -0
- package/js/examples/debug-shell-args.mjs +103 -0
- package/js/examples/debug-sigint-child-handler.mjs +44 -0
- package/js/examples/debug-sigint-forwarding.mjs +61 -0
- package/js/examples/debug-sigint-handler-install.mjs +79 -0
- package/js/examples/debug-sigint-handler-order.mjs +85 -0
- package/js/examples/debug-sigint-listeners.mjs +48 -0
- package/js/examples/debug-sigint-start-pattern.mjs +62 -0
- package/js/examples/debug-sigint-timer.mjs +40 -0
- package/js/examples/debug-simple-command.mjs +49 -0
- package/js/examples/debug-simple-getter.mjs +30 -0
- package/js/examples/debug-simple.mjs +39 -0
- package/js/examples/debug-simplified-finished.mjs +102 -0
- package/js/examples/debug-stack-overflow.mjs +25 -0
- package/js/examples/debug-stdin-simple.mjs +28 -0
- package/js/examples/debug-stdin.mjs +28 -0
- package/js/examples/debug-stream-emitter-isolated.mjs +45 -0
- package/js/examples/debug-stream-emitter.mjs +25 -0
- package/js/examples/debug-stream-events.mjs +70 -0
- package/js/examples/debug-stream-generator.mjs +23 -0
- package/js/examples/debug-stream-getter-issue.mjs +37 -0
- package/js/examples/debug-stream-getter.mjs +19 -0
- package/js/examples/debug-stream-internals.mjs +64 -0
- package/js/examples/debug-stream-method.mjs +46 -0
- package/js/examples/debug-stream-object.mjs +58 -0
- package/js/examples/debug-stream-properties.mjs +37 -0
- package/js/examples/debug-stream-timing.mjs +28 -0
- package/js/examples/debug-streaming.mjs +24 -0
- package/js/examples/debug-test-isolation.mjs +54 -0
- package/js/examples/debug-test-state.mjs +27 -0
- package/js/examples/debug-user-sigint.mjs +19 -0
- package/js/examples/debug-virtual-disable.mjs +21 -0
- package/js/examples/debug-virtual-vs-real.mjs +68 -0
- package/js/examples/debug-with-trace.mjs +23 -0
- package/js/examples/debug_parent_stream.mjs +22 -0
- package/js/examples/emulate-claude-stream.mjs +30 -0
- package/js/examples/emulated-streaming-direct.mjs +22 -0
- package/js/examples/emulated-streaming-jq-pipe.mjs +22 -0
- package/js/examples/emulated-streaming-sh-pipe.mjs +23 -0
- package/js/examples/events-build-process.mjs +73 -0
- package/js/examples/events-concurrent-streams.mjs +51 -0
- package/js/examples/events-error-handling.mjs +59 -0
- package/js/examples/events-file-monitoring.mjs +66 -0
- package/js/examples/events-interactive-simulation.mjs +69 -0
- package/js/examples/events-log-processing.mjs +72 -0
- package/js/examples/events-network-monitoring.mjs +68 -0
- package/js/examples/events-ping-basic.mjs +37 -0
- package/js/examples/events-progress-tracking.mjs +55 -0
- package/js/examples/events-stdin-input.mjs +34 -0
- package/js/examples/example-ansi-ls.mjs +39 -0
- package/js/examples/example-top.mjs +27 -0
- package/js/examples/final-ping-stdin-proof.mjs +88 -0
- package/js/examples/final-test-shell-operators.mjs +123 -0
- package/js/examples/final-working-examples.mjs +162 -0
- package/js/examples/gh-auth-test.mjs +103 -0
- package/js/examples/gh-delete-hang-test.mjs +79 -0
- package/js/examples/gh-gist-creation-test.mjs +276 -0
- package/js/examples/gh-gist-minimal-test.mjs +89 -0
- package/js/examples/gh-hang-exact-original.mjs +83 -0
- package/js/examples/gh-hang-reproduction.mjs +151 -0
- package/js/examples/gh-hang-test-with-redirect.mjs +45 -0
- package/js/examples/gh-hang-test-without-redirect.mjs +43 -0
- package/js/examples/gh-minimal-hang-check.mjs +33 -0
- package/js/examples/gh-operations-with-cd.mjs +187 -0
- package/js/examples/gh-output-test.mjs +102 -0
- package/js/examples/gh-reproduce-hang.mjs +41 -0
- package/js/examples/git-operations-with-cd.mjs +186 -0
- package/js/examples/interactive-math-calc.mjs +45 -0
- package/js/examples/interactive-top-fixed.mjs +25 -0
- package/js/examples/interactive-top-improved.mjs +72 -0
- package/js/examples/interactive-top-pty-logging.mjs +69 -0
- package/js/examples/interactive-top-pty.mjs +27 -0
- package/js/examples/interactive-top-with-logging.mjs +56 -0
- package/js/examples/interactive-top.mjs +29 -0
- package/js/examples/jq-color-demo.mjs +53 -0
- package/js/examples/jq-colors-streaming.mjs +42 -0
- package/js/examples/manual-ctrl-c-test.mjs +50 -0
- package/js/examples/methods-multiple-options.mjs +25 -0
- package/js/examples/methods-run-basic.mjs +10 -0
- package/js/examples/methods-start-basic.mjs +10 -0
- package/js/examples/node-compat-data-events.mjs +36 -0
- package/js/examples/node-compat-readable-event.mjs +29 -0
- package/js/examples/node-compat-small-buffer.mjs +33 -0
- package/js/examples/options-capture-false.mjs +12 -0
- package/js/examples/options-combined-settings.mjs +13 -0
- package/js/examples/options-custom-input.mjs +16 -0
- package/js/examples/options-default-behavior.mjs +10 -0
- package/js/examples/options-maximum-performance.mjs +15 -0
- package/js/examples/options-mirror-false.mjs +10 -0
- package/js/examples/options-performance-mode.mjs +13 -0
- package/js/examples/options-performance-optimization.mjs +14 -0
- package/js/examples/options-run-alias-demo.mjs +15 -0
- package/js/examples/options-run-alias.mjs +10 -0
- package/js/examples/options-silent-execution.mjs +14 -0
- package/js/examples/options-streaming-capture.mjs +24 -0
- package/js/examples/options-streaming-multiple.mjs +35 -0
- package/js/examples/options-streaming-silent.mjs +21 -0
- package/js/examples/options-streaming-stdin.mjs +21 -0
- package/js/examples/ping-streaming-filtered.mjs +22 -0
- package/js/examples/ping-streaming-interruptible.mjs +47 -0
- package/js/examples/ping-streaming-silent.mjs +24 -0
- package/js/examples/ping-streaming-simple.mjs +13 -0
- package/js/examples/ping-streaming-statistics.mjs +49 -0
- package/js/examples/ping-streaming-timestamps.mjs +22 -0
- package/js/examples/ping-streaming.mjs +48 -0
- package/js/examples/prove-ping-stdin-limitation.mjs +94 -0
- package/js/examples/readme-example.mjs +39 -0
- package/js/examples/realtime-json-stream.mjs +143 -0
- package/js/examples/reliable-stdin-commands.mjs +135 -0
- package/js/examples/reproduce-issue-135-v2.mjs +15 -0
- package/js/examples/reproduce-issue-135.mjs +17 -0
- package/js/examples/shell-cd-behavior.mjs +88 -0
- package/js/examples/sigint-forwarding-test.mjs +60 -0
- package/js/examples/sigint-handler-test.mjs +72 -0
- package/js/examples/simple-async-test.mjs +49 -0
- package/js/examples/simple-claude-test.mjs +17 -0
- package/js/examples/simple-event-test.mjs +33 -0
- package/js/examples/simple-jq-streaming.mjs +48 -0
- package/js/examples/simple-stream-demo.mjs +35 -0
- package/js/examples/simple-test-sleep.js +30 -0
- package/js/examples/simple-working-stdin.mjs +30 -0
- package/js/examples/streaming-behavior-test.mjs +116 -0
- package/js/examples/streaming-direct-command.mjs +21 -0
- package/js/examples/streaming-filtered-output.mjs +33 -0
- package/js/examples/streaming-grep-pipeline.mjs +21 -0
- package/js/examples/streaming-interactive-stdin.mjs +24 -0
- package/js/examples/streaming-jq-pipeline.mjs +23 -0
- package/js/examples/streaming-multistage-pipeline.mjs +23 -0
- package/js/examples/streaming-pipes-event-pattern.mjs +27 -0
- package/js/examples/streaming-pipes-multistage.mjs +22 -0
- package/js/examples/streaming-pipes-realtime-jq.mjs +23 -0
- package/js/examples/streaming-progress-tracking.mjs +34 -0
- package/js/examples/streaming-reusable-configs.mjs +52 -0
- package/js/examples/streaming-silent-capture.mjs +20 -0
- package/js/examples/streaming-test-simple.mjs +70 -0
- package/js/examples/streaming-virtual-pipeline.mjs +18 -0
- package/js/examples/syntax-basic-comparison.mjs +31 -0
- package/js/examples/syntax-basic-options.mjs +12 -0
- package/js/examples/syntax-combined-options.mjs +19 -0
- package/js/examples/syntax-command-chaining.mjs +12 -0
- package/js/examples/syntax-custom-directory.mjs +10 -0
- package/js/examples/syntax-custom-environment.mjs +13 -0
- package/js/examples/syntax-custom-stdin.mjs +10 -0
- package/js/examples/syntax-mixed-regular.mjs +11 -0
- package/js/examples/syntax-mixed-usage.mjs +15 -0
- package/js/examples/syntax-multiple-listeners.mjs +87 -0
- package/js/examples/syntax-piping-comparison.mjs +32 -0
- package/js/examples/syntax-reusable-config.mjs +16 -0
- package/js/examples/syntax-reusable-configs.mjs +21 -0
- package/js/examples/syntax-silent-operations.mjs +10 -0
- package/js/examples/syntax-stdin-option.mjs +12 -0
- package/js/examples/temp-sigint-test.mjs +21 -0
- package/js/examples/test-actual-buildshell.mjs +44 -0
- package/js/examples/test-async-streams-working.mjs +102 -0
- package/js/examples/test-async-streams.mjs +90 -0
- package/js/examples/test-auth-parse.mjs +74 -0
- package/js/examples/test-auto-quoting.mjs +57 -0
- package/js/examples/test-auto-start-fix.mjs +95 -0
- package/js/examples/test-baseline-sigint.mjs +38 -0
- package/js/examples/test-buffer-behavior.mjs +39 -0
- package/js/examples/test-buffers-simple.mjs +35 -0
- package/js/examples/test-bun-specific-issue.mjs +106 -0
- package/js/examples/test-bun-streaming.mjs +81 -0
- package/js/examples/test-cat-direct.mjs +41 -0
- package/js/examples/test-cat-pipe.mjs +34 -0
- package/js/examples/test-cd-behavior.mjs +42 -0
- package/js/examples/test-child-process-timing.mjs +53 -0
- package/js/examples/test-child-sigint-handler.mjs +62 -0
- package/js/examples/test-cleanup-simple.mjs +21 -0
- package/js/examples/test-comprehensive-tracing.mjs +58 -0
- package/js/examples/test-correct-space-handling.mjs +46 -0
- package/js/examples/test-ctrl-c-debug.mjs +44 -0
- package/js/examples/test-ctrl-c-inherit.mjs +30 -0
- package/js/examples/test-ctrl-c-sleep.mjs +31 -0
- package/js/examples/test-ctrl-c.mjs +17 -0
- package/js/examples/test-debug-new-options.mjs +55 -0
- package/js/examples/test-debug-pty.mjs +49 -0
- package/js/examples/test-debug-tee.mjs +38 -0
- package/js/examples/test-debug.mjs +25 -0
- package/js/examples/test-direct-jq.mjs +47 -0
- package/js/examples/test-direct-pipe-reading.mjs +119 -0
- package/js/examples/test-direct-pipe.sh +28 -0
- package/js/examples/test-double-quoting-prevention.mjs +138 -0
- package/js/examples/test-edge-cases-quoting.mjs +89 -0
- package/js/examples/test-events.mjs +37 -0
- package/js/examples/test-explicit-stdio.mjs +51 -0
- package/js/examples/test-final-streaming.mjs +71 -0
- package/js/examples/test-fix.mjs +71 -0
- package/js/examples/test-incremental-streaming.mjs +46 -0
- package/js/examples/test-individual-spawn.mjs +35 -0
- package/js/examples/test-inherit-stdout-not-stdin.mjs +133 -0
- package/js/examples/test-injection-protection.mjs +77 -0
- package/js/examples/test-interactive-streaming.mjs +140 -0
- package/js/examples/test-interactive-top.md +24 -0
- package/js/examples/test-interactive.mjs +17 -0
- package/js/examples/test-interpolation.mjs +14 -0
- package/js/examples/test-interrupt.mjs +40 -0
- package/js/examples/test-issue-135-comprehensive.mjs +41 -0
- package/js/examples/test-issue12-detailed.mjs +89 -0
- package/js/examples/test-issue12-exact.mjs +33 -0
- package/js/examples/test-jq-color.mjs +57 -0
- package/js/examples/test-jq-colors.mjs +41 -0
- package/js/examples/test-jq-compact.mjs +33 -0
- package/js/examples/test-jq-native.sh +10 -0
- package/js/examples/test-jq-pipeline-behavior.mjs +80 -0
- package/js/examples/test-jq-realtime.mjs +40 -0
- package/js/examples/test-manual-start.mjs +54 -0
- package/js/examples/test-mixed-quoting.mjs +88 -0
- package/js/examples/test-multi-stream.mjs +50 -0
- package/js/examples/test-multistage-debug.mjs +44 -0
- package/js/examples/test-native-spawn-vs-command-stream.mjs +154 -0
- package/js/examples/test-no-parse-pipeline.mjs +33 -0
- package/js/examples/test-non-virtual.mjs +52 -0
- package/js/examples/test-operators.mjs +53 -0
- package/js/examples/test-parent-continues.mjs +44 -0
- package/js/examples/test-path-interpolation.mjs +86 -0
- package/js/examples/test-ping-kill-and-stdin.mjs +98 -0
- package/js/examples/test-ping.mjs +12 -0
- package/js/examples/test-pty-spawn.mjs +101 -0
- package/js/examples/test-pty.mjs +38 -0
- package/js/examples/test-quote-behavior-summary.mjs +110 -0
- package/js/examples/test-quote-edge-cases.mjs +69 -0
- package/js/examples/test-quote-parsing.mjs +23 -0
- package/js/examples/test-raw-function.mjs +153 -0
- package/js/examples/test-raw-streaming.mjs +47 -0
- package/js/examples/test-readme-examples.mjs +142 -0
- package/js/examples/test-real-cat.mjs +28 -0
- package/js/examples/test-real-commands.mjs +21 -0
- package/js/examples/test-real-shell.mjs +31 -0
- package/js/examples/test-real-stdin-commands.mjs +160 -0
- package/js/examples/test-runner-batched.mjs +98 -0
- package/js/examples/test-runner-simple.mjs +80 -0
- package/js/examples/test-runner.mjs +67 -0
- package/js/examples/test-scope-parse.mjs +31 -0
- package/js/examples/test-sh-pipeline.mjs +24 -0
- package/js/examples/test-shell-detection.mjs +71 -0
- package/js/examples/test-shell-parser.mjs +37 -0
- package/js/examples/test-sigint-behavior.mjs +241 -0
- package/js/examples/test-sigint-handling.sh +14 -0
- package/js/examples/test-simple-pipe.mjs +12 -0
- package/js/examples/test-simple-streaming.mjs +32 -0
- package/js/examples/test-sleep-stdin.js +27 -0
- package/js/examples/test-sleep.mjs +56 -0
- package/js/examples/test-smart-quoting.mjs +180 -0
- package/js/examples/test-spaces-in-path.mjs +48 -0
- package/js/examples/test-special-chars-quoting.mjs +54 -0
- package/js/examples/test-stdin-after-start.mjs +39 -0
- package/js/examples/test-stdin-simple.mjs +67 -0
- package/js/examples/test-stdin-timing.mjs +74 -0
- package/js/examples/test-stdio-combinations.mjs +124 -0
- package/js/examples/test-stream-access.mjs +84 -0
- package/js/examples/test-stream-cleanup.mjs +27 -0
- package/js/examples/test-stream-readers.mjs +152 -0
- package/js/examples/test-streaming-final.mjs +57 -0
- package/js/examples/test-streaming-interfaces.mjs +141 -0
- package/js/examples/test-streaming-timing.mjs +27 -0
- package/js/examples/test-streaming.mjs +32 -0
- package/js/examples/test-streams-stdin-comprehensive.mjs +134 -0
- package/js/examples/test-streams-stdin-ctrl-c.mjs +96 -0
- package/js/examples/test-template-literal.mjs +26 -0
- package/js/examples/test-template-vs-interpolation.mjs +49 -0
- package/js/examples/test-timing.mjs +41 -0
- package/js/examples/test-top-inherit-stdout-stdin-control.mjs +123 -0
- package/js/examples/test-top-quit-stdin.mjs +118 -0
- package/js/examples/test-trace-option.mjs +21 -0
- package/js/examples/test-user-double-quotes.mjs +36 -0
- package/js/examples/test-user-single-quotes.mjs +36 -0
- package/js/examples/test-verbose.mjs +18 -0
- package/js/examples/test-verbose2.mjs +32 -0
- package/js/examples/test-virtual-streaming.mjs +125 -0
- package/js/examples/test-waiting-command.mjs +52 -0
- package/js/examples/test-waiting-commands.mjs +83 -0
- package/js/examples/test-watch-mode.mjs +104 -0
- package/js/examples/test-yes-cancellation.mjs +26 -0
- package/js/examples/test-yes-detailed.mjs +58 -0
- package/js/examples/test-yes-trace.mjs +28 -0
- package/js/examples/trace-abort-controller.mjs +30 -0
- package/js/examples/trace-error-handling.mjs +22 -0
- package/js/examples/trace-pipeline-command.mjs +22 -0
- package/js/examples/trace-signal-handling.mjs +35 -0
- package/js/examples/trace-simple-command.mjs +18 -0
- package/js/examples/trace-stderr-output.mjs +22 -0
- package/js/examples/verify-fix-both-runtimes.mjs +73 -0
- package/js/examples/verify-issue12-fixed.mjs +78 -0
- package/js/examples/which-command-common-commands.mjs +19 -0
- package/js/examples/which-command-gh-test.mjs +23 -0
- package/js/examples/which-command-nonexistent.mjs +20 -0
- package/js/examples/which-command-system-comparison.mjs +28 -0
- package/js/examples/working-example.mjs +13 -0
- package/js/examples/working-stdin-examples.mjs +138 -0
- package/js/examples/working-streaming-demo.mjs +49 -0
- package/{src → js/src}/$.mjs +20 -4
- package/{src → js/src}/$.utils.mjs +14 -2
- package/js/tests/$.features.test.mjs +283 -0
- package/js/tests/$.test.mjs +935 -0
- package/js/tests/builtin-commands.test.mjs +387 -0
- package/js/tests/bun-shell-path-fix.test.mjs +115 -0
- package/js/tests/bun.features.test.mjs +189 -0
- package/js/tests/cd-virtual-command.test.mjs +622 -0
- package/js/tests/cleanup-verification.test.mjs +127 -0
- package/js/tests/ctrl-c-baseline.test.mjs +207 -0
- package/js/tests/ctrl-c-basic.test.mjs +220 -0
- package/js/tests/ctrl-c-library.test.mjs +197 -0
- package/js/tests/ctrl-c-signal.test.mjs +915 -0
- package/js/tests/examples.test.mjs +252 -0
- package/js/tests/execa.features.test.mjs +198 -0
- package/js/tests/gh-commands.test.mjs +164 -0
- package/js/tests/gh-gist-operations.test.mjs +221 -0
- package/js/tests/git-gh-cd.test.mjs +466 -0
- package/js/tests/interactive-option.test.mjs +114 -0
- package/js/tests/interactive-streaming.test.mjs +307 -0
- package/js/tests/issue-135-final.test.mjs +58 -0
- package/js/tests/jq-color-behavior.test.mjs +140 -0
- package/js/tests/jq.test.mjs +318 -0
- package/js/tests/options-examples.test.mjs +106 -0
- package/js/tests/options-syntax.test.mjs +112 -0
- package/js/tests/path-interpolation.test.mjs +412 -0
- package/js/tests/pipe.test.mjs +291 -0
- package/js/tests/raw-function.test.mjs +266 -0
- package/js/tests/readme-examples.test.mjs +427 -0
- package/js/tests/resource-cleanup-internals.test.mjs +669 -0
- package/js/tests/shell-settings.test.mjs +279 -0
- package/js/tests/sigint-cleanup-isolated.test.mjs +151 -0
- package/js/tests/sigint-cleanup.test.mjs +118 -0
- package/js/tests/start-run-edge-cases.test.mjs +152 -0
- package/js/tests/start-run-options.test.mjs +181 -0
- package/js/tests/stderr-output-handling.test.mjs +279 -0
- package/js/tests/streaming-interfaces.test.mjs +194 -0
- package/js/tests/sync.test.mjs +297 -0
- package/js/tests/system-pipe.test.mjs +226 -0
- package/js/tests/test-cleanup.mjs +200 -0
- package/js/tests/test-helper-fixed.mjs +148 -0
- package/js/tests/test-helper-v2.mjs +118 -0
- package/js/tests/test-helper.mjs +171 -0
- package/js/tests/test-sigint-child.js +15 -0
- package/js/tests/text-method.test.mjs +225 -0
- package/js/tests/virtual.test.mjs +364 -0
- package/js/tests/yes-command-cleanup.test.mjs +208 -0
- package/js/tests/zx.features.test.mjs +233 -0
- package/package.json +13 -12
- package/rust/Cargo.lock +947 -0
- package/rust/Cargo.toml +47 -0
- package/rust/src/commands/basename.rs +69 -0
- package/rust/src/commands/cat.rs +123 -0
- package/rust/src/commands/cd.rs +67 -0
- package/rust/src/commands/cp.rs +187 -0
- package/rust/src/commands/dirname.rs +57 -0
- package/rust/src/commands/echo.rs +73 -0
- package/rust/src/commands/env.rs +33 -0
- package/rust/src/commands/exit.rs +36 -0
- package/rust/src/commands/false.rs +24 -0
- package/rust/src/commands/ls.rs +182 -0
- package/rust/src/commands/mkdir.rs +98 -0
- package/rust/src/commands/mod.rs +200 -0
- package/rust/src/commands/mv.rs +180 -0
- package/rust/src/commands/pwd.rs +28 -0
- package/rust/src/commands/rm.rs +150 -0
- package/rust/src/commands/seq.rs +179 -0
- package/rust/src/commands/sleep.rs +97 -0
- package/rust/src/commands/test.rs +204 -0
- package/rust/src/commands/touch.rs +99 -0
- package/rust/src/commands/true.rs +24 -0
- package/rust/src/commands/which.rs +87 -0
- package/rust/src/commands/yes.rs +99 -0
- package/rust/src/lib.rs +492 -0
- package/rust/src/main.rs +37 -0
- package/rust/src/shell_parser.rs +565 -0
- package/rust/src/utils.rs +335 -0
- package/rust/tests/builtin_commands.rs +549 -0
- package/rust/tests/process_runner.rs +286 -0
- package/rust/tests/shell_parser.rs +296 -0
- package/rust/tests/utils.rs +282 -0
- package/rust/tests/virtual_commands.rs +199 -0
- /package/{src → js/src}/commands/$.basename.mjs +0 -0
- /package/{src → js/src}/commands/$.cat.mjs +0 -0
- /package/{src → js/src}/commands/$.cd.mjs +0 -0
- /package/{src → js/src}/commands/$.cp.mjs +0 -0
- /package/{src → js/src}/commands/$.dirname.mjs +0 -0
- /package/{src → js/src}/commands/$.echo.mjs +0 -0
- /package/{src → js/src}/commands/$.env.mjs +0 -0
- /package/{src → js/src}/commands/$.exit.mjs +0 -0
- /package/{src → js/src}/commands/$.false.mjs +0 -0
- /package/{src → js/src}/commands/$.ls.mjs +0 -0
- /package/{src → js/src}/commands/$.mkdir.mjs +0 -0
- /package/{src → js/src}/commands/$.mv.mjs +0 -0
- /package/{src → js/src}/commands/$.pwd.mjs +0 -0
- /package/{src → js/src}/commands/$.rm.mjs +0 -0
- /package/{src → js/src}/commands/$.seq.mjs +0 -0
- /package/{src → js/src}/commands/$.sleep.mjs +0 -0
- /package/{src → js/src}/commands/$.test.mjs +0 -0
- /package/{src → js/src}/commands/$.touch.mjs +0 -0
- /package/{src → js/src}/commands/$.true.mjs +0 -0
- /package/{src → js/src}/commands/$.which.mjs +0 -0
- /package/{src → js/src}/commands/$.yes.mjs +0 -0
- /package/{src → js/src}/shell-parser.mjs +0 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
|
|
5
|
+
console.log('=== Test async streams interface ===');
|
|
6
|
+
|
|
7
|
+
async function testAsyncStreams() {
|
|
8
|
+
try {
|
|
9
|
+
console.log('TEST 1: Basic cat with await streams.stdin');
|
|
10
|
+
|
|
11
|
+
const catCmd = $`cat`;
|
|
12
|
+
|
|
13
|
+
console.log('Awaiting stdin...');
|
|
14
|
+
const stdin = await catCmd.streams.stdin;
|
|
15
|
+
console.log('✓ Got stdin:', !!stdin);
|
|
16
|
+
|
|
17
|
+
if (stdin) {
|
|
18
|
+
stdin.write('Hello async stdin!\\n');
|
|
19
|
+
stdin.write('This is much cleaner!\\n');
|
|
20
|
+
stdin.end();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const result = await catCmd;
|
|
24
|
+
console.log('✓ Cat result:', JSON.stringify(result.stdout));
|
|
25
|
+
|
|
26
|
+
console.log('\\nTEST 2: Grep with async streams');
|
|
27
|
+
|
|
28
|
+
const grepCmd = $`grep "test"`;
|
|
29
|
+
const grepStdin = await grepCmd.streams.stdin;
|
|
30
|
+
|
|
31
|
+
if (grepStdin) {
|
|
32
|
+
grepStdin.write('no match\\n');
|
|
33
|
+
grepStdin.write('test line\\n');
|
|
34
|
+
grepStdin.write('another test\\n');
|
|
35
|
+
grepStdin.end();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const grepResult = await grepCmd;
|
|
39
|
+
console.log('✓ Grep result:', JSON.stringify(grepResult.stdout));
|
|
40
|
+
|
|
41
|
+
console.log('\\nTEST 3: Sort with async streams');
|
|
42
|
+
|
|
43
|
+
const sortCmd = $`sort`;
|
|
44
|
+
const sortStdin = await sortCmd.streams.stdin;
|
|
45
|
+
|
|
46
|
+
if (sortStdin) {
|
|
47
|
+
sortStdin.write('zebra\\n');
|
|
48
|
+
sortStdin.write('apple\\n');
|
|
49
|
+
sortStdin.write('banana\\n');
|
|
50
|
+
sortStdin.end();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const sortResult = await sortCmd;
|
|
54
|
+
console.log('✓ Sort result:', JSON.stringify(sortResult.stdout));
|
|
55
|
+
|
|
56
|
+
console.log('\\nTEST 4: Multiple streams access');
|
|
57
|
+
|
|
58
|
+
const mixedCmd = $`sh -c 'cat && echo "stderr message" >&2'`;
|
|
59
|
+
const [mixedStdin, mixedStdout] = await Promise.all([
|
|
60
|
+
mixedCmd.streams.stdin,
|
|
61
|
+
mixedCmd.streams.stdout,
|
|
62
|
+
]);
|
|
63
|
+
|
|
64
|
+
console.log('✓ Got both stdin and stdout streams');
|
|
65
|
+
|
|
66
|
+
if (mixedStdin) {
|
|
67
|
+
mixedStdin.write('Mixed input\\n');
|
|
68
|
+
mixedStdin.end();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const mixedResult = await mixedCmd;
|
|
72
|
+
console.log(
|
|
73
|
+
'✓ Mixed result:',
|
|
74
|
+
JSON.stringify({
|
|
75
|
+
stdout: mixedResult.stdout,
|
|
76
|
+
stderr: mixedResult.stderr,
|
|
77
|
+
})
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
console.log('\\n🎉 SUCCESS:');
|
|
81
|
+
console.log(' ✅ Async streams interface works perfectly!');
|
|
82
|
+
console.log(' ✅ No more manual timing required');
|
|
83
|
+
console.log(' ✅ Clean, intuitive API: await cmd.streams.stdin');
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.log('\\n❌ Error:', error.message);
|
|
86
|
+
console.error(error.stack);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
testAsyncStreams();
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { $ } from '../src/$.mjs';
|
|
2
|
+
|
|
3
|
+
async function getDetailedAuthStatus() {
|
|
4
|
+
try {
|
|
5
|
+
const authResult = await $`gh auth status 2>&1`.run({
|
|
6
|
+
capture: true,
|
|
7
|
+
mirror: false,
|
|
8
|
+
});
|
|
9
|
+
const output = authResult.stdout;
|
|
10
|
+
|
|
11
|
+
// Parse auth status details
|
|
12
|
+
const details = {
|
|
13
|
+
authenticated: authResult.code === 0,
|
|
14
|
+
loggedInAs: null,
|
|
15
|
+
account: null,
|
|
16
|
+
protocol: null,
|
|
17
|
+
token: null,
|
|
18
|
+
scopes: [],
|
|
19
|
+
hasGistScope: false,
|
|
20
|
+
rawOutput: output, // Include raw output for debugging
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Parse logged in account - updated pattern for new format
|
|
24
|
+
const accountMatch = output.match(
|
|
25
|
+
/Logged in to github\.com account (\S+)|Logged in to [\w\.]+ as (\S+)/
|
|
26
|
+
);
|
|
27
|
+
if (accountMatch) {
|
|
28
|
+
details.account = accountMatch[1] || accountMatch[2];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Parse git operations protocol
|
|
32
|
+
const protocolMatch = output.match(/Git operations protocol:\s*(\w+)/);
|
|
33
|
+
if (protocolMatch) {
|
|
34
|
+
details.protocol = protocolMatch[1];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Parse token (masked)
|
|
38
|
+
const tokenMatch = output.match(/Token:\s*(\S+)/);
|
|
39
|
+
if (tokenMatch) {
|
|
40
|
+
details.token = tokenMatch[1];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Parse token scopes - handle both quoted and unquoted formats
|
|
44
|
+
const scopesMatch = output.match(
|
|
45
|
+
/Token scopes:\s*'([^']+)'|Token scopes:\s*([^\n]+)/
|
|
46
|
+
);
|
|
47
|
+
if (scopesMatch) {
|
|
48
|
+
const scopesStr = scopesMatch[1] || scopesMatch[2];
|
|
49
|
+
// Split by comma and/or quotes, clean up
|
|
50
|
+
details.scopes = scopesStr
|
|
51
|
+
.split(/[,']/)
|
|
52
|
+
.map((s) => s.trim())
|
|
53
|
+
.filter((s) => s && s !== '');
|
|
54
|
+
details.hasGistScope = details.scopes.includes('gist');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Check if completely logged out
|
|
58
|
+
if (output.includes('You are not logged into any GitHub hosts')) {
|
|
59
|
+
details.authenticated = false;
|
|
60
|
+
details.account = null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return details;
|
|
64
|
+
} catch (error) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Test it
|
|
70
|
+
const status = await getDetailedAuthStatus();
|
|
71
|
+
console.log('Auth Status Details:');
|
|
72
|
+
console.log(JSON.stringify(status, null, 2));
|
|
73
|
+
console.log('\nParsed scopes:', status?.scopes);
|
|
74
|
+
console.log('Has gist scope:', status?.hasGistScope);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Test: Automatic quoting when user doesn't provide quotes
|
|
4
|
+
// Expected: Smart auto-quoting based on content
|
|
5
|
+
|
|
6
|
+
import { $ } from '../src/$.mjs';
|
|
7
|
+
|
|
8
|
+
console.log('=== Test: Automatic Smart Quoting ===\n');
|
|
9
|
+
|
|
10
|
+
const testCases = [
|
|
11
|
+
{
|
|
12
|
+
name: 'Simple path without spaces',
|
|
13
|
+
value: '/usr/bin/echo',
|
|
14
|
+
shouldQuote: true, // Currently quotes everything
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'Path with spaces',
|
|
18
|
+
value: '/path with spaces/command',
|
|
19
|
+
shouldQuote: true,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'Path with special shell chars ($)',
|
|
23
|
+
value: '/path/with$variable',
|
|
24
|
+
shouldQuote: true,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'Path with special shell chars (&)',
|
|
28
|
+
value: '/path/with&background',
|
|
29
|
+
shouldQuote: true,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'Simple command name',
|
|
33
|
+
value: 'echo',
|
|
34
|
+
shouldQuote: true, // Currently quotes everything
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'Empty string',
|
|
38
|
+
value: '',
|
|
39
|
+
shouldQuote: true,
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
for (const { name, value, shouldQuote } of testCases) {
|
|
44
|
+
console.log(`\nTest: ${name}`);
|
|
45
|
+
console.log('Input:', JSON.stringify(value));
|
|
46
|
+
|
|
47
|
+
const cmd = $({ mirror: false })`${value} --test`;
|
|
48
|
+
console.log('Generated:', cmd.spec.command);
|
|
49
|
+
|
|
50
|
+
const hasQuotes =
|
|
51
|
+
cmd.spec.command.startsWith("'") || cmd.spec.command.startsWith('"');
|
|
52
|
+
console.log('Has quotes:', hasQuotes);
|
|
53
|
+
console.log('Should quote:', shouldQuote);
|
|
54
|
+
console.log(
|
|
55
|
+
hasQuotes === shouldQuote ? '✅ PASS' : '⚠️ Note: Quoting behavior differs'
|
|
56
|
+
);
|
|
57
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test to verify that auto-start only happens on actual stdin/stdout/stderr access,
|
|
5
|
+
* not when accessing the parent objects (streams, buffers, strings).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { $ } from '../src/$.mjs';
|
|
9
|
+
|
|
10
|
+
console.log('=== Testing Auto-Start Behavior Fix ===');
|
|
11
|
+
console.log('');
|
|
12
|
+
|
|
13
|
+
async function testAutoStartBehavior() {
|
|
14
|
+
try {
|
|
15
|
+
console.log('TEST 1: Accessing parent objects should NOT auto-start');
|
|
16
|
+
|
|
17
|
+
const command1 = $`echo "test1"`;
|
|
18
|
+
console.log('✓ Command created');
|
|
19
|
+
console.log(' Started?', command1.started);
|
|
20
|
+
console.log(' Finished?', command1.finished);
|
|
21
|
+
|
|
22
|
+
// These should NOT auto-start the command
|
|
23
|
+
const streams = command1.streams;
|
|
24
|
+
console.log('✓ Accessed .streams');
|
|
25
|
+
console.log(' Started?', command1.started);
|
|
26
|
+
|
|
27
|
+
const buffers = command1.buffers;
|
|
28
|
+
console.log('✓ Accessed .buffers');
|
|
29
|
+
console.log(' Started?', command1.started);
|
|
30
|
+
|
|
31
|
+
const strings = command1.strings;
|
|
32
|
+
console.log('✓ Accessed .strings');
|
|
33
|
+
console.log(' Started?', command1.started);
|
|
34
|
+
|
|
35
|
+
console.log('');
|
|
36
|
+
console.log('TEST 2: Accessing stdin/stdout/stderr SHOULD auto-start');
|
|
37
|
+
|
|
38
|
+
const command2 = $`echo "test2"`;
|
|
39
|
+
console.log('✓ Command2 created');
|
|
40
|
+
console.log(' Started?', command2.started);
|
|
41
|
+
|
|
42
|
+
// This SHOULD auto-start the command
|
|
43
|
+
const stdout = command2.streams.stdout;
|
|
44
|
+
console.log('✓ Accessed .streams.stdout');
|
|
45
|
+
console.log(' Started?', command2.started);
|
|
46
|
+
|
|
47
|
+
// Wait for completion
|
|
48
|
+
const result2 = await command2;
|
|
49
|
+
console.log('✓ Result:', JSON.stringify(result2.stdout.trim()));
|
|
50
|
+
|
|
51
|
+
console.log('');
|
|
52
|
+
console.log('TEST 3: Buffer access should auto-start');
|
|
53
|
+
|
|
54
|
+
const command3 = $`echo "test3"`;
|
|
55
|
+
console.log('✓ Command3 created');
|
|
56
|
+
console.log(' Started?', command3.started);
|
|
57
|
+
|
|
58
|
+
// Access buffer properties - should NOT auto-start yet
|
|
59
|
+
const buffers3 = command3.buffers;
|
|
60
|
+
console.log('✓ Accessed .buffers');
|
|
61
|
+
console.log(' Started?', command3.started);
|
|
62
|
+
|
|
63
|
+
// Now access actual buffer - SHOULD auto-start
|
|
64
|
+
const stdoutBuffer = await command3.buffers.stdout;
|
|
65
|
+
console.log('✓ Accessed .buffers.stdout');
|
|
66
|
+
console.log(' Result:', stdoutBuffer.toString().trim());
|
|
67
|
+
|
|
68
|
+
console.log('');
|
|
69
|
+
console.log('TEST 4: String access should auto-start');
|
|
70
|
+
|
|
71
|
+
const command4 = $`echo "test4"`;
|
|
72
|
+
console.log('✓ Command4 created');
|
|
73
|
+
console.log(' Started?', command4.started);
|
|
74
|
+
|
|
75
|
+
// Access string properties - should NOT auto-start yet
|
|
76
|
+
const strings4 = command4.strings;
|
|
77
|
+
console.log('✓ Accessed .strings');
|
|
78
|
+
console.log(' Started?', command4.started);
|
|
79
|
+
|
|
80
|
+
// Now access actual string - SHOULD auto-start
|
|
81
|
+
const stdoutString = await command4.strings.stdout;
|
|
82
|
+
console.log('✓ Accessed .strings.stdout');
|
|
83
|
+
console.log(' Result:', JSON.stringify(stdoutString.trim()));
|
|
84
|
+
|
|
85
|
+
console.log('');
|
|
86
|
+
console.log('✅ ALL AUTO-START TESTS PASSED!');
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.log('');
|
|
89
|
+
console.error('❌ AUTO-START TEST FAILED:', error.message);
|
|
90
|
+
console.error(error.stack);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
testAutoStartBehavior();
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { spawn } from 'child_process';
|
|
4
|
+
|
|
5
|
+
console.log('Testing baseline SIGINT behavior');
|
|
6
|
+
|
|
7
|
+
const child = spawn('sh', ['-c', 'echo "BASELINE_START" && sleep 30'], {
|
|
8
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
9
|
+
detached: true,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
console.log('Child spawned with PID:', child.pid);
|
|
13
|
+
|
|
14
|
+
let stdout = '';
|
|
15
|
+
child.stdout.on('data', (data) => {
|
|
16
|
+
stdout += data.toString();
|
|
17
|
+
console.log('Received stdout:', JSON.stringify(data.toString()));
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Wait for output
|
|
21
|
+
setTimeout(() => {
|
|
22
|
+
console.log('Sending SIGINT to child...');
|
|
23
|
+
const result = child.kill('SIGINT');
|
|
24
|
+
console.log('Kill result:', result);
|
|
25
|
+
}, 500);
|
|
26
|
+
|
|
27
|
+
// Wait for exit
|
|
28
|
+
child.on('exit', (code, signal) => {
|
|
29
|
+
console.log('Child exited with code:', code, 'signal:', signal);
|
|
30
|
+
console.log('Total stdout:', stdout);
|
|
31
|
+
process.exit(0);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Timeout safety
|
|
35
|
+
setTimeout(() => {
|
|
36
|
+
console.log('Timeout reached, force killing...');
|
|
37
|
+
child.kill('SIGKILL');
|
|
38
|
+
}, 5000);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { $ } from '../src/$.mjs';
|
|
2
|
+
|
|
3
|
+
console.log('Testing buffer behavior in stream()...');
|
|
4
|
+
|
|
5
|
+
const runner = $`yes "test"`;
|
|
6
|
+
let iterations = 0;
|
|
7
|
+
|
|
8
|
+
// Override emit to see when data events are fired
|
|
9
|
+
const originalEmit = runner.emit.bind(runner);
|
|
10
|
+
let dataEventCount = 0;
|
|
11
|
+
runner.emit = function (event, ...args) {
|
|
12
|
+
if (event === 'data') {
|
|
13
|
+
dataEventCount++;
|
|
14
|
+
console.log(` [DATA EVENT ${dataEventCount}] emitted`);
|
|
15
|
+
}
|
|
16
|
+
return originalEmit(event, ...args);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
console.log('\nStarting iteration...');
|
|
20
|
+
for await (const chunk of runner.stream()) {
|
|
21
|
+
iterations++;
|
|
22
|
+
console.log(`Iteration ${iterations}: received chunk`);
|
|
23
|
+
|
|
24
|
+
if (iterations >= 3) {
|
|
25
|
+
console.log('Breaking after iteration 3...');
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log(`\nFinal state:`);
|
|
31
|
+
console.log(` iterations: ${iterations}`);
|
|
32
|
+
console.log(` dataEventCount: ${dataEventCount}`);
|
|
33
|
+
console.log(` runner.finished: ${runner.finished}`);
|
|
34
|
+
|
|
35
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
36
|
+
console.log(`\nAfter 100ms:`);
|
|
37
|
+
console.log(` dataEventCount: ${dataEventCount}`);
|
|
38
|
+
|
|
39
|
+
process.exit(0);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
|
|
5
|
+
console.log('Testing buffer access...');
|
|
6
|
+
|
|
7
|
+
async function testBuffers() {
|
|
8
|
+
const cmd = $`echo "test buffer"`;
|
|
9
|
+
|
|
10
|
+
// First access - should be promise
|
|
11
|
+
console.log('Getting buffer (first access)...');
|
|
12
|
+
const buffer1 = await cmd.buffers.stdout;
|
|
13
|
+
console.log('Buffer 1:', buffer1.toString());
|
|
14
|
+
|
|
15
|
+
// Check if process is finished
|
|
16
|
+
console.log('Process finished?', cmd.finished);
|
|
17
|
+
console.log('Has outChunks?', !!cmd.outChunks);
|
|
18
|
+
console.log(
|
|
19
|
+
'OutChunks length:',
|
|
20
|
+
cmd.outChunks ? cmd.outChunks.length : 'null'
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
// Second access - should be immediate
|
|
24
|
+
console.log('Getting buffer (second access)...');
|
|
25
|
+
const buffer2 = cmd.buffers.stdout;
|
|
26
|
+
console.log('Buffer 2 type:', typeof buffer2);
|
|
27
|
+
console.log('Buffer 2 is Promise?', buffer2 instanceof Promise);
|
|
28
|
+
if (!(buffer2 instanceof Promise)) {
|
|
29
|
+
console.log('Buffer 2 content:', buffer2.toString());
|
|
30
|
+
} else {
|
|
31
|
+
console.log('Buffer 2 resolved:', (await buffer2).toString());
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
testBuffers().catch(console.error);
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// More targeted test to find the real Bun shell path issue
|
|
4
|
+
import { $ } from '../src/$.mjs';
|
|
5
|
+
|
|
6
|
+
const isBun = typeof globalThis.Bun !== 'undefined';
|
|
7
|
+
console.log(`=== Bun Runtime Shell Path Test ===`);
|
|
8
|
+
console.log(`Runtime: ${isBun ? 'Bun' : 'Node.js'}`);
|
|
9
|
+
console.log(`Platform: ${process.platform}`);
|
|
10
|
+
|
|
11
|
+
// Enable verbose mode to see shell detection
|
|
12
|
+
process.env.COMMAND_STREAM_VERBOSE = 'true';
|
|
13
|
+
|
|
14
|
+
console.log('\n=== Simple Commands ===');
|
|
15
|
+
|
|
16
|
+
// Test simple commands
|
|
17
|
+
const simpleCommands = [
|
|
18
|
+
'pwd',
|
|
19
|
+
'echo hello',
|
|
20
|
+
'ls /bin/sh',
|
|
21
|
+
'test -f /bin/sh && echo "sh exists"',
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
for (const cmd of simpleCommands) {
|
|
25
|
+
console.log(`\nTesting: ${cmd}`);
|
|
26
|
+
try {
|
|
27
|
+
const result = await $`${cmd}`;
|
|
28
|
+
console.log(`✓ Success: ${result.stdout.toString().trim()}`);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.log(`✗ Failed: ${error.message}`);
|
|
31
|
+
console.log(` Code: ${error.code}`);
|
|
32
|
+
if (error.stderr) {
|
|
33
|
+
console.log(` Stderr: ${error.stderr.toString().trim()}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log('\n=== Testing Shell Detection Explicitly ===');
|
|
39
|
+
|
|
40
|
+
// Import the findAvailableShell function for direct testing
|
|
41
|
+
import fs from 'fs';
|
|
42
|
+
import cp from 'child_process';
|
|
43
|
+
|
|
44
|
+
// Test the actual shell detection logic that might be failing in Bun
|
|
45
|
+
console.log('\nTesting shell existence:');
|
|
46
|
+
const shellPaths = ['/bin/sh', '/usr/bin/sh', '/bin/bash', '/usr/bin/bash'];
|
|
47
|
+
for (const shellPath of shellPaths) {
|
|
48
|
+
try {
|
|
49
|
+
const exists = fs.existsSync(shellPath);
|
|
50
|
+
console.log(`${shellPath}: ${exists ? '✓' : '✗'}`);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.log(`${shellPath}: error - ${error.message}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
console.log('\nTesting which command:');
|
|
57
|
+
const shells = ['sh', 'bash', 'which'];
|
|
58
|
+
for (const shell of shells) {
|
|
59
|
+
try {
|
|
60
|
+
const result = cp.spawnSync('which', [shell], { encoding: 'utf-8' });
|
|
61
|
+
console.log(
|
|
62
|
+
`which ${shell}: status=${result.status}, stdout="${result.stdout?.trim()}", stderr="${result.stderr?.trim()}"`
|
|
63
|
+
);
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.log(`which ${shell}: error - ${error.message}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
console.log('\n=== Testing Direct Bun Spawn ===');
|
|
70
|
+
if (isBun) {
|
|
71
|
+
// Test Bun.spawn directly to see if that's the issue
|
|
72
|
+
console.log('Testing Bun.spawn with /bin/sh:');
|
|
73
|
+
try {
|
|
74
|
+
const proc = Bun.spawn(['/bin/sh', '-c', 'echo "Bun spawn test"'], {
|
|
75
|
+
stdout: 'pipe',
|
|
76
|
+
stderr: 'pipe',
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const text = await new Response(proc.stdout).text();
|
|
80
|
+
const exitCode = await proc.exited;
|
|
81
|
+
|
|
82
|
+
console.log(
|
|
83
|
+
`✓ Bun.spawn success: exitCode=${exitCode}, output="${text.trim()}"`
|
|
84
|
+
);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.log(`✗ Bun.spawn failed: ${error.message}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
console.log('Testing Bun.spawn with which sh:');
|
|
90
|
+
try {
|
|
91
|
+
const proc = Bun.spawn(['which', 'sh'], {
|
|
92
|
+
stdout: 'pipe',
|
|
93
|
+
stderr: 'pipe',
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const text = await new Response(proc.stdout).text();
|
|
97
|
+
const errorText = await new Response(proc.stderr).text();
|
|
98
|
+
const exitCode = await proc.exited;
|
|
99
|
+
|
|
100
|
+
console.log(
|
|
101
|
+
`Bun.spawn which: exitCode=${exitCode}, stdout="${text.trim()}", stderr="${errorText.trim()}"`
|
|
102
|
+
);
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.log(`✗ Bun.spawn which failed: ${error.message}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
// Test if Bun's process stdout streaming works properly
|
|
4
|
+
|
|
5
|
+
console.log('Test 1: Direct command that outputs with delays');
|
|
6
|
+
const proc1 = Bun.spawn(
|
|
7
|
+
['sh', '-c', 'echo "1"; sleep 0.3; echo "2"; sleep 0.3; echo "3"'],
|
|
8
|
+
{
|
|
9
|
+
stdout: 'pipe',
|
|
10
|
+
stderr: 'pipe',
|
|
11
|
+
}
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const start1 = Date.now();
|
|
15
|
+
for await (const chunk of proc1.stdout) {
|
|
16
|
+
const elapsed = Date.now() - start1;
|
|
17
|
+
console.log(
|
|
18
|
+
`[${elapsed}ms] Got chunk:`,
|
|
19
|
+
Buffer.from(chunk).toString().trim()
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
console.log('\nTest 2: Command with jq pipeline');
|
|
24
|
+
const proc2 = Bun.spawn(
|
|
25
|
+
['sh', '-c', './js/examples/emulate-claude-stream.mjs | jq .'],
|
|
26
|
+
{
|
|
27
|
+
stdout: 'pipe',
|
|
28
|
+
stderr: 'pipe',
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const start2 = Date.now();
|
|
33
|
+
let chunkCount = 0;
|
|
34
|
+
for await (const chunk of proc2.stdout) {
|
|
35
|
+
chunkCount++;
|
|
36
|
+
const elapsed = Date.now() - start2;
|
|
37
|
+
const text = Buffer.from(chunk).toString();
|
|
38
|
+
const lines = text
|
|
39
|
+
.split('\n')
|
|
40
|
+
.filter((l) => l.trim())
|
|
41
|
+
.slice(0, 3); // Show first 3 lines
|
|
42
|
+
console.log(
|
|
43
|
+
`[${elapsed}ms] Chunk ${chunkCount}: ${lines.length} lines, first few:`,
|
|
44
|
+
lines
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
console.log('\nTest 3: Read stdout using different method');
|
|
49
|
+
const proc3 = Bun.spawn(
|
|
50
|
+
['sh', '-c', './js/examples/emulate-claude-stream.mjs | jq .'],
|
|
51
|
+
{
|
|
52
|
+
stdout: 'pipe',
|
|
53
|
+
stderr: 'pipe',
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const start3 = Date.now();
|
|
58
|
+
const reader = proc3.stdout.getReader();
|
|
59
|
+
let chunkCount3 = 0;
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
while (true) {
|
|
63
|
+
const { done, value } = await reader.read();
|
|
64
|
+
if (done) {
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
chunkCount3++;
|
|
68
|
+
const elapsed = Date.now() - start3;
|
|
69
|
+
const text = Buffer.from(value).toString();
|
|
70
|
+
const lines = text
|
|
71
|
+
.split('\n')
|
|
72
|
+
.filter((l) => l.trim())
|
|
73
|
+
.slice(0, 3);
|
|
74
|
+
console.log(
|
|
75
|
+
`[${elapsed}ms] Reader chunk ${chunkCount3}: ${lines.length} lines, first few:`,
|
|
76
|
+
lines
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
} finally {
|
|
80
|
+
reader.releaseLock();
|
|
81
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
console.log('=== Test cat | jq directly ===\n');
|
|
4
|
+
|
|
5
|
+
// Direct Bun test
|
|
6
|
+
const proc1 = Bun.spawn(
|
|
7
|
+
['bun', 'run', 'js/examples/emulate-claude-stream.mjs'],
|
|
8
|
+
{
|
|
9
|
+
stdout: 'pipe',
|
|
10
|
+
stderr: 'pipe',
|
|
11
|
+
}
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const proc2 = Bun.spawn(['cat'], {
|
|
15
|
+
stdin: proc1.stdout,
|
|
16
|
+
stdout: 'pipe',
|
|
17
|
+
stderr: 'pipe',
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const proc3 = Bun.spawn(['jq', '.'], {
|
|
21
|
+
stdin: proc2.stdout,
|
|
22
|
+
stdout: 'pipe',
|
|
23
|
+
stderr: 'pipe',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const start = Date.now();
|
|
27
|
+
let chunkCount = 0;
|
|
28
|
+
|
|
29
|
+
console.log('Reading from jq output:');
|
|
30
|
+
for await (const chunk of proc3.stdout) {
|
|
31
|
+
chunkCount++;
|
|
32
|
+
const elapsed = Date.now() - start;
|
|
33
|
+
console.log(`[${elapsed}ms] Chunk ${chunkCount}: ${chunk.length} bytes`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
await proc1.exited;
|
|
37
|
+
await proc2.exited;
|
|
38
|
+
await proc3.exited;
|
|
39
|
+
|
|
40
|
+
console.log(`\nTotal chunks: ${chunkCount}`);
|
|
41
|
+
console.log(chunkCount === 1 ? '❌ Buffered' : '✅ Streaming');
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
// Test with cat instead of jq
|
|
4
|
+
|
|
5
|
+
console.log('Test: Piping through cat (should not buffer)\n');
|
|
6
|
+
|
|
7
|
+
// First process: emulator
|
|
8
|
+
const proc1 = Bun.spawn(['./js/examples/emulate-claude-stream.mjs'], {
|
|
9
|
+
stdout: 'pipe',
|
|
10
|
+
stderr: 'pipe',
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// Second process: cat (should be unbuffered)
|
|
14
|
+
const proc2 = Bun.spawn(['cat'], {
|
|
15
|
+
stdin: proc1.stdout,
|
|
16
|
+
stdout: 'pipe',
|
|
17
|
+
stderr: 'pipe',
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const start = Date.now();
|
|
21
|
+
let chunkCount = 0;
|
|
22
|
+
|
|
23
|
+
for await (const chunk of proc2.stdout) {
|
|
24
|
+
chunkCount++;
|
|
25
|
+
const elapsed = Date.now() - start;
|
|
26
|
+
const text = Buffer.from(chunk).toString().trim();
|
|
27
|
+
|
|
28
|
+
console.log(`[${elapsed}ms] Chunk ${chunkCount}: ${text}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log(`\nTotal chunks received: ${chunkCount}`);
|
|
32
|
+
|
|
33
|
+
await proc1.exited;
|
|
34
|
+
await proc2.exited;
|