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,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Test sleep example for CI reliability (no network dependencies)
|
|
4
|
+
console.error('[test-sleep.mjs] Process started, PID:', process.pid);
|
|
5
|
+
console.error('[test-sleep.mjs] Node version:', process.version);
|
|
6
|
+
console.error('[test-sleep.mjs] Current directory:', process.cwd());
|
|
7
|
+
console.error('[test-sleep.mjs] Script path:', import.meta.url);
|
|
8
|
+
|
|
9
|
+
let $;
|
|
10
|
+
try {
|
|
11
|
+
const module = await import('../src/$.mjs');
|
|
12
|
+
$ = module.$;
|
|
13
|
+
console.error('[test-sleep.mjs] Module imported successfully');
|
|
14
|
+
} catch (error) {
|
|
15
|
+
console.error('[test-sleep.mjs] Failed to import module:', error.message);
|
|
16
|
+
console.error('[test-sleep.mjs] Error stack:', error.stack);
|
|
17
|
+
// Exit early if we can't import the module
|
|
18
|
+
console.log('STARTING_SLEEP'); // Still output for test
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
console.error('[test-sleep.mjs] Is TTY:', process.stdout.isTTY);
|
|
23
|
+
console.log('STARTING_SLEEP');
|
|
24
|
+
console.error('[test-sleep.mjs] Wrote STARTING_SLEEP to stdout');
|
|
25
|
+
|
|
26
|
+
// Ensure stdout is flushed immediately for CI environments
|
|
27
|
+
await new Promise((resolve) => {
|
|
28
|
+
if (process.stdout.isTTY === false) {
|
|
29
|
+
console.error(
|
|
30
|
+
'[test-sleep.mjs] Non-TTY environment detected, forcing flush'
|
|
31
|
+
);
|
|
32
|
+
// Force flush in non-TTY environments (CI)
|
|
33
|
+
process.stdout.write('', () => {
|
|
34
|
+
console.error('[test-sleep.mjs] Stdout flush completed');
|
|
35
|
+
resolve();
|
|
36
|
+
});
|
|
37
|
+
} else {
|
|
38
|
+
console.error('[test-sleep.mjs] TTY environment, no flush needed');
|
|
39
|
+
resolve();
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
console.error('[test-sleep.mjs] About to run sleep command');
|
|
44
|
+
try {
|
|
45
|
+
const result = await $`sleep 30`; // Long enough to be interrupted, but timeout safe
|
|
46
|
+
console.log('SLEEP_COMPLETED');
|
|
47
|
+
console.error('[test-sleep.mjs] Sleep completed with code:', result.code);
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error(
|
|
50
|
+
'[test-sleep.mjs] Sleep interrupted:',
|
|
51
|
+
error.message,
|
|
52
|
+
'code:',
|
|
53
|
+
error.code
|
|
54
|
+
);
|
|
55
|
+
process.exit(error.code || 1);
|
|
56
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Test smart quoting behavior for interpolated strings
|
|
4
|
+
// We need to preserve user-provided quotes while still auto-quoting when necessary
|
|
5
|
+
|
|
6
|
+
import { $ } from '../src/$.mjs';
|
|
7
|
+
|
|
8
|
+
console.log('=== Smart Quoting Tests ===\n');
|
|
9
|
+
|
|
10
|
+
async function testSmartQuoting() {
|
|
11
|
+
const claude = '/Users/konard/.claude/local/claude';
|
|
12
|
+
|
|
13
|
+
console.log('1. Testing user-provided quotes preservation:');
|
|
14
|
+
console.log('----------------------------------------------');
|
|
15
|
+
|
|
16
|
+
// Case 1: User provides single quotes
|
|
17
|
+
console.log('\nCase 1: User wraps in single quotes');
|
|
18
|
+
const singleQuoted = `'${claude}'`;
|
|
19
|
+
console.log('Input:', singleQuoted);
|
|
20
|
+
const cmd1 = $({ mirror: false })`${singleQuoted} --version`;
|
|
21
|
+
console.log('Generated:', cmd1.spec.command);
|
|
22
|
+
console.log(
|
|
23
|
+
'Expected: Should preserve single quotes without double-escaping'
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
// Case 2: User provides double quotes
|
|
27
|
+
console.log('\nCase 2: User wraps in double quotes');
|
|
28
|
+
const doubleQuoted = `"${claude}"`;
|
|
29
|
+
console.log('Input:', doubleQuoted);
|
|
30
|
+
const cmd2 = $({ mirror: false })`${doubleQuoted} --version`;
|
|
31
|
+
console.log('Generated:', cmd2.spec.command);
|
|
32
|
+
console.log(
|
|
33
|
+
'Expected: Should preserve double quotes (wrapped in single quotes for shell)'
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
// Case 3: No quotes from user - auto-quote
|
|
37
|
+
console.log('\nCase 3: No quotes from user');
|
|
38
|
+
console.log('Input:', claude);
|
|
39
|
+
const cmd3 = $({ mirror: false })`${claude} --version`;
|
|
40
|
+
console.log('Generated:', cmd3.spec.command);
|
|
41
|
+
console.log('Expected: Should auto-quote the path');
|
|
42
|
+
|
|
43
|
+
console.log('\n2. Testing smart auto-quoting (only when needed):');
|
|
44
|
+
console.log('--------------------------------------------------');
|
|
45
|
+
|
|
46
|
+
// Test various strings that need/don't need escaping
|
|
47
|
+
const testCases = [
|
|
48
|
+
{
|
|
49
|
+
desc: 'Simple command (no special chars)',
|
|
50
|
+
value: 'echo',
|
|
51
|
+
needsQuoting: false,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
desc: 'Path with spaces',
|
|
55
|
+
value: '/path with spaces/command',
|
|
56
|
+
needsQuoting: true,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
desc: 'Path with special chars',
|
|
60
|
+
value: '/path/with$special&chars',
|
|
61
|
+
needsQuoting: true,
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
desc: 'Simple path (no special chars)',
|
|
65
|
+
value: '/usr/bin/echo',
|
|
66
|
+
needsQuoting: false, // Ideally shouldn't need quotes
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
desc: 'String with single quote',
|
|
70
|
+
value: "can't",
|
|
71
|
+
needsQuoting: true,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
desc: 'Empty string',
|
|
75
|
+
value: '',
|
|
76
|
+
needsQuoting: true, // Empty needs quotes
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
for (const { desc, value, needsQuoting } of testCases) {
|
|
81
|
+
console.log(`\n${desc}:`);
|
|
82
|
+
console.log('Input:', JSON.stringify(value));
|
|
83
|
+
const cmd = $({ mirror: false })`echo ${value}`;
|
|
84
|
+
console.log('Generated:', cmd.spec.command);
|
|
85
|
+
console.log('Needs quoting:', needsQuoting);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
console.log('\n3. Testing complex scenarios:');
|
|
89
|
+
console.log('------------------------------');
|
|
90
|
+
|
|
91
|
+
// Scenario 1: Mixed quoted and unquoted
|
|
92
|
+
console.log('\nScenario 1: Mixed arguments');
|
|
93
|
+
const path = '/usr/bin/env';
|
|
94
|
+
const arg1 = 'node';
|
|
95
|
+
const arg2 = '--version';
|
|
96
|
+
const mixedCmd = $({ mirror: false })`${path} ${arg1} ${arg2}`;
|
|
97
|
+
console.log('Generated:', mixedCmd.spec.command);
|
|
98
|
+
|
|
99
|
+
// Scenario 2: User pre-quotes some args
|
|
100
|
+
console.log('\nScenario 2: Some args pre-quoted by user');
|
|
101
|
+
const quotedArg = '"my file.txt"';
|
|
102
|
+
const unquotedArg = 'output.log';
|
|
103
|
+
const partialCmd = $({ mirror: false })`cat ${quotedArg} > ${unquotedArg}`;
|
|
104
|
+
console.log('Generated:', partialCmd.spec.command);
|
|
105
|
+
|
|
106
|
+
// Scenario 3: Command with already-escaped characters
|
|
107
|
+
console.log('\nScenario 3: Already-escaped characters');
|
|
108
|
+
const escaped = "can\\'t";
|
|
109
|
+
const escapedCmd = $({ mirror: false })`echo ${escaped}`;
|
|
110
|
+
console.log('Input (escaped):', escaped);
|
|
111
|
+
console.log('Generated:', escapedCmd.spec.command);
|
|
112
|
+
|
|
113
|
+
console.log('\n4. Testing actual execution with quotes:');
|
|
114
|
+
console.log('-----------------------------------------');
|
|
115
|
+
|
|
116
|
+
// Test that quotes work correctly in practice
|
|
117
|
+
try {
|
|
118
|
+
// Test with spaces in argument
|
|
119
|
+
const result1 = await $`echo ${'hello world'}`;
|
|
120
|
+
console.log('Spaces test output:', String(result1).trim());
|
|
121
|
+
|
|
122
|
+
// Test with special characters
|
|
123
|
+
const result2 = await $`echo ${'$HOME'}`;
|
|
124
|
+
console.log('Special char test output:', String(result2).trim());
|
|
125
|
+
console.log('(Should print literal $HOME, not expanded)');
|
|
126
|
+
|
|
127
|
+
// Test with single quotes in content
|
|
128
|
+
const result3 = await $`echo ${"it's working"}`;
|
|
129
|
+
console.log('Single quote test output:', String(result3).trim());
|
|
130
|
+
} catch (error) {
|
|
131
|
+
console.error('Execution error:', error.message);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
console.log('\n5. Edge cases for quote handling:');
|
|
135
|
+
console.log('----------------------------------');
|
|
136
|
+
|
|
137
|
+
// Test various edge cases
|
|
138
|
+
const edgeCases = [
|
|
139
|
+
{
|
|
140
|
+
desc: 'Just single quote',
|
|
141
|
+
input: "'",
|
|
142
|
+
expected: 'Should escape properly',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
desc: 'Just double quote',
|
|
146
|
+
input: '"',
|
|
147
|
+
expected: 'Should escape properly',
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
desc: 'Empty single quotes',
|
|
151
|
+
input: "''",
|
|
152
|
+
expected: 'Should preserve as-is',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
desc: 'Empty double quotes',
|
|
156
|
+
input: '""',
|
|
157
|
+
expected: 'Should wrap in single quotes',
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
desc: 'Nested quotes',
|
|
161
|
+
input: '"\'nested\'"',
|
|
162
|
+
expected: 'Should handle nested quotes',
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
desc: 'Triple quotes',
|
|
166
|
+
input: "'''",
|
|
167
|
+
expected: 'Should escape all quotes',
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
for (const { desc, input, expected } of edgeCases) {
|
|
172
|
+
console.log(`\n${desc}:`);
|
|
173
|
+
console.log('Input:', JSON.stringify(input));
|
|
174
|
+
const cmd = $({ mirror: false })`echo ${input}`;
|
|
175
|
+
console.log('Generated:', cmd.spec.command);
|
|
176
|
+
console.log('Expected:', expected);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
testSmartQuoting().catch(console.error);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $, shell, enableVirtualCommands } from '../src/$.mjs';
|
|
4
|
+
import { mkdtempSync, rmSync, mkdirSync } from 'fs';
|
|
5
|
+
import { tmpdir } from 'os';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
|
|
8
|
+
enableVirtualCommands();
|
|
9
|
+
shell.verbose(true);
|
|
10
|
+
|
|
11
|
+
console.log('=== Testing paths with spaces ===\n');
|
|
12
|
+
|
|
13
|
+
const baseDir = mkdtempSync(join(tmpdir(), 'space-test-'));
|
|
14
|
+
const dirWithSpaces = join(baseDir, 'my test directory');
|
|
15
|
+
mkdirSync(dirWithSpaces);
|
|
16
|
+
const originalCwd = process.cwd();
|
|
17
|
+
|
|
18
|
+
console.log('Directory created:', dirWithSpaces);
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
console.log('\nTest 1: cd with quoted path');
|
|
22
|
+
const result1 = await $`cd "${dirWithSpaces}"`;
|
|
23
|
+
console.log('Exit code:', result1.code);
|
|
24
|
+
console.log('Stdout:', result1.stdout);
|
|
25
|
+
console.log('Stderr:', result1.stderr);
|
|
26
|
+
|
|
27
|
+
const pwd1 = await $`pwd`;
|
|
28
|
+
console.log('Current dir:', pwd1.stdout.trim());
|
|
29
|
+
console.log('Expected:', dirWithSpaces);
|
|
30
|
+
console.log('Match:', pwd1.stdout.trim() === dirWithSpaces);
|
|
31
|
+
|
|
32
|
+
await $`cd ${originalCwd}`;
|
|
33
|
+
|
|
34
|
+
console.log('\nTest 2: cd with escaped spaces');
|
|
35
|
+
const escaped = dirWithSpaces.replace(/ /g, '\\ ');
|
|
36
|
+
const result2 = await $`cd ${escaped}`;
|
|
37
|
+
console.log('Exit code:', result2.code);
|
|
38
|
+
|
|
39
|
+
const pwd2 = await $`pwd`;
|
|
40
|
+
console.log('Current dir:', pwd2.stdout.trim());
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error('Error:', error.message);
|
|
43
|
+
} finally {
|
|
44
|
+
process.chdir(originalCwd);
|
|
45
|
+
rmSync(baseDir, { recursive: true, force: true });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
console.log('\n=== Test Complete ===');
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Test: Quoting strings with special characters
|
|
4
|
+
// Expected: Proper escaping and quoting for shell safety
|
|
5
|
+
|
|
6
|
+
import { $ } from '../src/$.mjs';
|
|
7
|
+
|
|
8
|
+
console.log('=== Test: Special Characters Quoting ===\n');
|
|
9
|
+
|
|
10
|
+
async function testSpecialChars() {
|
|
11
|
+
const tests = [
|
|
12
|
+
{ desc: 'Single quote in string', input: "can't", testExec: true },
|
|
13
|
+
{ desc: 'Double quote in string', input: 'say "hello"', testExec: true },
|
|
14
|
+
{ desc: 'Dollar sign (variable)', input: '$HOME', testExec: true },
|
|
15
|
+
{ desc: 'Backtick (command sub)', input: '`date`', testExec: true },
|
|
16
|
+
{ desc: 'Semicolon (command sep)', input: 'first; second', testExec: true },
|
|
17
|
+
{ desc: 'Ampersand (background)', input: 'cmd &', testExec: false },
|
|
18
|
+
{ desc: 'Pipe character', input: 'a | b', testExec: false },
|
|
19
|
+
{ desc: 'Backslash', input: 'path\\to\\file', testExec: true },
|
|
20
|
+
{ desc: 'Newline', input: 'line1\nline2', testExec: true },
|
|
21
|
+
{ desc: 'Tab', input: 'col1\tcol2', testExec: true },
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
for (const { desc, input, testExec } of tests) {
|
|
25
|
+
console.log(`\n${desc}:`);
|
|
26
|
+
console.log('Input:', JSON.stringify(input));
|
|
27
|
+
|
|
28
|
+
const cmd = $({ mirror: false })`echo ${input}`;
|
|
29
|
+
console.log('Generated:', cmd.spec.command);
|
|
30
|
+
|
|
31
|
+
if (testExec) {
|
|
32
|
+
try {
|
|
33
|
+
const result = await $`echo ${input}`;
|
|
34
|
+
const output = String(result).trim();
|
|
35
|
+
console.log('Output:', JSON.stringify(output));
|
|
36
|
+
|
|
37
|
+
// Check if special chars were properly escaped
|
|
38
|
+
if (input === '$HOME' && output === '$HOME') {
|
|
39
|
+
console.log('✅ Variable not expanded (properly escaped)');
|
|
40
|
+
} else if (input === '`date`' && output === '`date`') {
|
|
41
|
+
console.log('✅ Command substitution prevented (properly escaped)');
|
|
42
|
+
} else if (output === input) {
|
|
43
|
+
console.log('✅ Output matches input (properly escaped)');
|
|
44
|
+
} else {
|
|
45
|
+
console.log('⚠️ Output differs from input');
|
|
46
|
+
}
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.log('Execution error:', error.message);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
testSpecialChars().catch(console.error);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
|
|
5
|
+
console.log('=== Test stdin access after process starts ===');
|
|
6
|
+
|
|
7
|
+
async function testStdinAfterStart() {
|
|
8
|
+
const cmd = $`cat`;
|
|
9
|
+
|
|
10
|
+
// First, start the process explicitly
|
|
11
|
+
cmd.start({ mode: 'async', stdin: 'pipe', stdout: 'pipe', stderr: 'pipe' });
|
|
12
|
+
|
|
13
|
+
// Wait a moment for the process to actually start
|
|
14
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
15
|
+
|
|
16
|
+
console.log('Process started?', cmd.started);
|
|
17
|
+
console.log('Child exists?', !!cmd.child);
|
|
18
|
+
console.log('Child stdin exists?', !!(cmd.child && cmd.child.stdin));
|
|
19
|
+
|
|
20
|
+
// Now try to access stdin
|
|
21
|
+
const stdin = cmd.streams.stdin;
|
|
22
|
+
console.log('Stdin from streams?', !!stdin);
|
|
23
|
+
|
|
24
|
+
if (stdin) {
|
|
25
|
+
console.log('Writing to stdin...');
|
|
26
|
+
stdin.write('Hello after start!\\n');
|
|
27
|
+
stdin.end();
|
|
28
|
+
} else {
|
|
29
|
+
console.log('No stdin available, ending without input');
|
|
30
|
+
// End the process some other way
|
|
31
|
+
setTimeout(() => cmd.kill(), 100);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const result = await cmd;
|
|
35
|
+
console.log('Final result stdout:', JSON.stringify(result.stdout));
|
|
36
|
+
console.log('Exit code:', result.code);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
testStdinAfterStart().catch(console.error);
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Simple focused test for streams.stdin functionality
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { $ } from '../src/$.mjs';
|
|
8
|
+
|
|
9
|
+
console.log('=== Testing streams.stdin simple functionality ===');
|
|
10
|
+
|
|
11
|
+
async function testStdinSimple() {
|
|
12
|
+
try {
|
|
13
|
+
// Test 1: Basic stdin with cat
|
|
14
|
+
console.log('TEST 1: Send data to cat via stdin');
|
|
15
|
+
const cmd1 = $`cat`;
|
|
16
|
+
|
|
17
|
+
const stdin1 = cmd1.streams.stdin;
|
|
18
|
+
console.log(' Process started?', cmd1.started);
|
|
19
|
+
|
|
20
|
+
if (stdin1) {
|
|
21
|
+
stdin1.write('Hello World\\n');
|
|
22
|
+
stdin1.end();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const result1 = await cmd1;
|
|
26
|
+
console.log(' Exit code:', result1.code);
|
|
27
|
+
console.log(' Output:', JSON.stringify(result1.stdout));
|
|
28
|
+
|
|
29
|
+
// Test 2: stdin with echo command using Node.js
|
|
30
|
+
console.log('\\nTEST 2: Node.js script reading stdin');
|
|
31
|
+
const cmd2 = $`node -e "process.stdin.on('data', d => process.stdout.write(d)); process.stdin.on('end', () => process.exit(0));"`;
|
|
32
|
+
|
|
33
|
+
const stdin2 = cmd2.streams.stdin;
|
|
34
|
+
if (stdin2) {
|
|
35
|
+
stdin2.write('Node stdin test\\n');
|
|
36
|
+
stdin2.end();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const result2 = await cmd2;
|
|
40
|
+
console.log(' Exit code:', result2.code);
|
|
41
|
+
console.log(' Output:', JSON.stringify(result2.stdout));
|
|
42
|
+
|
|
43
|
+
// Test 3: Test kill method on sleep
|
|
44
|
+
console.log('\\nTEST 3: Kill sleep command');
|
|
45
|
+
const cmd3 = $`sleep 5`;
|
|
46
|
+
|
|
47
|
+
// Start the process
|
|
48
|
+
cmd3.streams.stdout; // Access to start
|
|
49
|
+
console.log(' Process started?', cmd3.started);
|
|
50
|
+
|
|
51
|
+
// Wait a bit then kill
|
|
52
|
+
setTimeout(() => {
|
|
53
|
+
console.log(' Killing sleep...');
|
|
54
|
+
cmd3.kill();
|
|
55
|
+
}, 500);
|
|
56
|
+
|
|
57
|
+
const result3 = await cmd3;
|
|
58
|
+
console.log(' Exit code:', result3.code);
|
|
59
|
+
|
|
60
|
+
console.log('\\n✅ All stdin tests completed!');
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.error('❌ Error:', error.message);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
testStdinSimple();
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
|
|
5
|
+
console.log('=== Test stdin timing with proper flow ===');
|
|
6
|
+
|
|
7
|
+
async function testStdinTiming() {
|
|
8
|
+
console.log('Test 1: Access stdin immediately and write quickly');
|
|
9
|
+
|
|
10
|
+
const cmd1 = $`cat`;
|
|
11
|
+
|
|
12
|
+
// Get stdin immediately, which should auto-start the process
|
|
13
|
+
const stdin1 = cmd1.streams.stdin;
|
|
14
|
+
console.log('Stdin available immediately?', !!stdin1);
|
|
15
|
+
console.log('Command started?', cmd1.started);
|
|
16
|
+
|
|
17
|
+
if (stdin1) {
|
|
18
|
+
// Write immediately before the process might finish
|
|
19
|
+
stdin1.write('Quick input\\n');
|
|
20
|
+
stdin1.end();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const result1 = await cmd1;
|
|
24
|
+
console.log('Result 1:', JSON.stringify(result1.stdout));
|
|
25
|
+
console.log('Exit code 1:', result1.code);
|
|
26
|
+
|
|
27
|
+
console.log(
|
|
28
|
+
'\\nTest 2: Create test with Node.js script that definitely reads stdin'
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const nodeScript = `
|
|
32
|
+
process.stdin.setEncoding('utf8');
|
|
33
|
+
let input = '';
|
|
34
|
+
process.stdin.on('data', (chunk) => {
|
|
35
|
+
input += chunk;
|
|
36
|
+
});
|
|
37
|
+
process.stdin.on('end', () => {
|
|
38
|
+
process.stdout.write('Received: ' + input);
|
|
39
|
+
});
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
const cmd2 = $`node -e "${nodeScript}"`;
|
|
43
|
+
const stdin2 = cmd2.streams.stdin;
|
|
44
|
+
|
|
45
|
+
console.log('Node script stdin available?', !!stdin2);
|
|
46
|
+
|
|
47
|
+
if (stdin2) {
|
|
48
|
+
stdin2.write('Node.js input test\\n');
|
|
49
|
+
stdin2.end();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const result2 = await cmd2;
|
|
53
|
+
console.log('Node result:', JSON.stringify(result2.stdout));
|
|
54
|
+
console.log('Exit code 2:', result2.code);
|
|
55
|
+
|
|
56
|
+
console.log('\\nTest 3: Test with sleep to ensure process stays alive');
|
|
57
|
+
|
|
58
|
+
const cmd3 = $`sh -c 'cat && echo "Done"'`;
|
|
59
|
+
const stdin3 = cmd3.streams.stdin;
|
|
60
|
+
|
|
61
|
+
console.log('Shell cat stdin available?', !!stdin3);
|
|
62
|
+
|
|
63
|
+
if (stdin3) {
|
|
64
|
+
// Send data and then close stdin
|
|
65
|
+
stdin3.write('Shell script input\\n');
|
|
66
|
+
stdin3.end();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const result3 = await cmd3;
|
|
70
|
+
console.log('Shell result:', JSON.stringify(result3.stdout));
|
|
71
|
+
console.log('Exit code 3:', result3.code);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
testStdinTiming().catch(console.error);
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test different stdio combinations with streams interface
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { $ } from '../src/$.mjs';
|
|
8
|
+
|
|
9
|
+
console.log('=== Testing stdio combinations with streams interface ===');
|
|
10
|
+
console.log('');
|
|
11
|
+
|
|
12
|
+
async function testStdioCombinations() {
|
|
13
|
+
try {
|
|
14
|
+
console.log('TEST 1: Default behavior - streams.stdin works for input');
|
|
15
|
+
|
|
16
|
+
const cmd1 = $`cat`;
|
|
17
|
+
const stdin1 = cmd1.streams.stdin;
|
|
18
|
+
|
|
19
|
+
if (stdin1) {
|
|
20
|
+
stdin1.write('Hello from streams.stdin!\\n');
|
|
21
|
+
stdin1.write('This demonstrates stdin control\\n');
|
|
22
|
+
stdin1.end();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const result1 = await cmd1;
|
|
26
|
+
console.log('✓ Default cat result:', JSON.stringify(result1.stdout));
|
|
27
|
+
console.log(' Exit code:', result1.code);
|
|
28
|
+
|
|
29
|
+
console.log('');
|
|
30
|
+
console.log('TEST 2: Demonstrate top quit with streams.stdin');
|
|
31
|
+
|
|
32
|
+
console.log(' → Starting limited top command...');
|
|
33
|
+
const topCmd = $`top -l 2`; // Limited to 2 iterations on macOS
|
|
34
|
+
const topStdin = topCmd.streams.stdin;
|
|
35
|
+
|
|
36
|
+
// Try to quit early with 'q'
|
|
37
|
+
setTimeout(() => {
|
|
38
|
+
console.log(' → Sending "q" to quit top early...');
|
|
39
|
+
if (topStdin && !topStdin.destroyed) {
|
|
40
|
+
topStdin.write('q');
|
|
41
|
+
}
|
|
42
|
+
}, 500);
|
|
43
|
+
|
|
44
|
+
// Backup kill after reasonable time
|
|
45
|
+
setTimeout(() => {
|
|
46
|
+
if (!topCmd.finished) {
|
|
47
|
+
console.log(' → Backup kill...');
|
|
48
|
+
topCmd.kill();
|
|
49
|
+
}
|
|
50
|
+
}, 3000);
|
|
51
|
+
|
|
52
|
+
const topResult = await topCmd;
|
|
53
|
+
console.log(' ✓ Top completed with exit code:', topResult.code);
|
|
54
|
+
console.log(' ✓ Output length:', topResult.stdout.length, 'characters');
|
|
55
|
+
|
|
56
|
+
console.log('');
|
|
57
|
+
console.log('TEST 3: Compare with native behavior - ping ignores stdin');
|
|
58
|
+
|
|
59
|
+
const pingCmd = $`ping -c 3 127.0.0.1`; // Limited ping
|
|
60
|
+
const pingStdin = pingCmd.streams.stdin;
|
|
61
|
+
|
|
62
|
+
// Try to send data to ping stdin (will be ignored)
|
|
63
|
+
if (pingStdin) {
|
|
64
|
+
pingStdin.write('q\\n');
|
|
65
|
+
pingStdin.write('quit\\n');
|
|
66
|
+
pingStdin.write('\\x03'); // CTRL+C
|
|
67
|
+
pingStdin.end();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const pingResult = await pingCmd;
|
|
71
|
+
console.log(' ✓ Ping completed (stdin ignored, ran full 3 pings)');
|
|
72
|
+
console.log(' ✓ Exit code:', pingResult.code);
|
|
73
|
+
console.log(
|
|
74
|
+
' ✓ Contains ping statistics?',
|
|
75
|
+
pingResult.stdout.includes('packets transmitted')
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
console.log('');
|
|
79
|
+
console.log('TEST 4: Interactive command that responds to stdin - more');
|
|
80
|
+
|
|
81
|
+
// Create a temporary file for 'more' command
|
|
82
|
+
const setupCmd = $`echo "Line 1\\nLine 2\\nLine 3\\nLine 4\\nLine 5\\nLine 6" > /tmp/test-more.txt`;
|
|
83
|
+
await setupCmd;
|
|
84
|
+
|
|
85
|
+
const moreCmd = $`more /tmp/test-more.txt`;
|
|
86
|
+
const moreStdin = moreCmd.streams.stdin;
|
|
87
|
+
|
|
88
|
+
// Send space (next page) and q (quit) to more
|
|
89
|
+
setTimeout(() => {
|
|
90
|
+
if (moreStdin && !moreStdin.destroyed) {
|
|
91
|
+
console.log(' → Sending commands to more...');
|
|
92
|
+
moreStdin.write(' '); // space for next page
|
|
93
|
+
setTimeout(() => moreStdin.write('q'), 100); // quit
|
|
94
|
+
}
|
|
95
|
+
}, 100);
|
|
96
|
+
|
|
97
|
+
const moreResult = await moreCmd;
|
|
98
|
+
console.log(' ✓ More command completed with exit code:', moreResult.code);
|
|
99
|
+
|
|
100
|
+
// Cleanup
|
|
101
|
+
await $`rm -f /tmp/test-more.txt`;
|
|
102
|
+
|
|
103
|
+
console.log('');
|
|
104
|
+
console.log('✅ SUMMARY:');
|
|
105
|
+
console.log(' • streams.stdin allows sending data to any process');
|
|
106
|
+
console.log(
|
|
107
|
+
' • Interactive commands (cat, top, more) can be controlled via stdin'
|
|
108
|
+
);
|
|
109
|
+
console.log(
|
|
110
|
+
' • Network commands (ping) ignore stdin input (expected behavior)'
|
|
111
|
+
);
|
|
112
|
+
console.log(' • kill() method works for forceful termination when needed');
|
|
113
|
+
console.log(
|
|
114
|
+
' • Our library provides both input control AND process control'
|
|
115
|
+
);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.log('');
|
|
118
|
+
console.error('❌ TEST FAILED:', error.message);
|
|
119
|
+
console.error(error.stack);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
testStdioCombinations();
|