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,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test to verify that streams.stdin can be used to send CTRL+C to interrupt commands
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { $ } from '../src/$.mjs';
|
|
8
|
+
|
|
9
|
+
console.log('=== Testing streams.stdin CTRL+C functionality ===');
|
|
10
|
+
console.log('');
|
|
11
|
+
|
|
12
|
+
async function testStreamsStdinCtrlC() {
|
|
13
|
+
try {
|
|
14
|
+
console.log('TEST 1: Send CTRL+C via streams.stdin to ping command');
|
|
15
|
+
|
|
16
|
+
const command = $`ping 8.8.8.8`;
|
|
17
|
+
console.log('✓ Command created');
|
|
18
|
+
|
|
19
|
+
// Access stdin stream - this should auto-start the command
|
|
20
|
+
const stdin = command.streams.stdin;
|
|
21
|
+
console.log('✓ Accessed streams.stdin - command should be started');
|
|
22
|
+
console.log(' Started?', command.started);
|
|
23
|
+
|
|
24
|
+
// Wait a moment for ping to start
|
|
25
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
26
|
+
|
|
27
|
+
// Send CTRL+C (ASCII code 3)
|
|
28
|
+
console.log('✓ Sending CTRL+C via stdin...');
|
|
29
|
+
if (stdin) {
|
|
30
|
+
stdin.write('\x03'); // CTRL+C
|
|
31
|
+
stdin.end();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Wait for the command to complete
|
|
35
|
+
const result = await command;
|
|
36
|
+
console.log('✓ Command completed with exit code:', result.code);
|
|
37
|
+
console.log('✓ Stdout length:', result.stdout.length);
|
|
38
|
+
console.log(
|
|
39
|
+
'✓ First 200 chars of stdout:',
|
|
40
|
+
JSON.stringify(result.stdout.slice(0, 200))
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
console.log('');
|
|
44
|
+
console.log('TEST 2: Test with a different long-running command');
|
|
45
|
+
|
|
46
|
+
const command2 = $`sleep 10`;
|
|
47
|
+
console.log('✓ Sleep command created');
|
|
48
|
+
|
|
49
|
+
const stdin2 = command2.streams.stdin;
|
|
50
|
+
console.log('✓ Accessed streams.stdin for sleep command');
|
|
51
|
+
|
|
52
|
+
// Wait a moment
|
|
53
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
54
|
+
|
|
55
|
+
// Send CTRL+C
|
|
56
|
+
console.log('✓ Sending CTRL+C to sleep command...');
|
|
57
|
+
if (stdin2) {
|
|
58
|
+
stdin2.write('\x03');
|
|
59
|
+
stdin2.end();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const result2 = await command2;
|
|
63
|
+
console.log('✓ Sleep command completed with exit code:', result2.code);
|
|
64
|
+
|
|
65
|
+
console.log('');
|
|
66
|
+
console.log('TEST 3: Test stdin with echo command');
|
|
67
|
+
|
|
68
|
+
const command3 = $`cat`;
|
|
69
|
+
console.log('✓ Cat command created');
|
|
70
|
+
|
|
71
|
+
const stdin3 = command3.streams.stdin;
|
|
72
|
+
console.log('✓ Accessed streams.stdin for cat command');
|
|
73
|
+
|
|
74
|
+
// Send some data first, then CTRL+C
|
|
75
|
+
if (stdin3) {
|
|
76
|
+
stdin3.write('Hello from stdin!\n');
|
|
77
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
78
|
+
stdin3.write('\x03'); // CTRL+C
|
|
79
|
+
stdin3.end();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const result3 = await command3;
|
|
83
|
+
console.log('✓ Cat command completed with exit code:', result3.code);
|
|
84
|
+
console.log('✓ Output:', JSON.stringify(result3.stdout));
|
|
85
|
+
|
|
86
|
+
console.log('');
|
|
87
|
+
console.log('✅ ALL STREAMS.STDIN CTRL+C TESTS COMPLETED!');
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.log('');
|
|
90
|
+
console.error('❌ STREAMS.STDIN CTRL+C TEST FAILED:', error.message);
|
|
91
|
+
console.error(error.stack);
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
testStreamsStdinCtrlC();
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $, shell, enableVirtualCommands } from '../src/$.mjs';
|
|
4
|
+
|
|
5
|
+
enableVirtualCommands();
|
|
6
|
+
shell.verbose(true);
|
|
7
|
+
|
|
8
|
+
console.log('=== Testing template literal with spaces ===\n');
|
|
9
|
+
|
|
10
|
+
const pathWithSpaces = '/tmp/my test dir';
|
|
11
|
+
|
|
12
|
+
console.log('Variable value:', pathWithSpaces);
|
|
13
|
+
|
|
14
|
+
// Test 1: Direct template literal
|
|
15
|
+
console.log('\nTest 1: Template literal interpolation');
|
|
16
|
+
console.log('Command will be: cd', pathWithSpaces);
|
|
17
|
+
|
|
18
|
+
// Capture what command is actually generated
|
|
19
|
+
const originalCwd = process.cwd();
|
|
20
|
+
|
|
21
|
+
// Try manually constructing the command
|
|
22
|
+
console.log('\nTest 2: Manual command string');
|
|
23
|
+
const cmdString = `cd "${pathWithSpaces}"`;
|
|
24
|
+
console.log('Manual command string:', cmdString);
|
|
25
|
+
const result = await $([cmdString]);
|
|
26
|
+
console.log('Result code:', result.code);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Test the difference between template literals and string interpolation
|
|
4
|
+
import { $ } from '../src/$.mjs';
|
|
5
|
+
|
|
6
|
+
// Enable verbose mode
|
|
7
|
+
process.env.COMMAND_STREAM_VERBOSE = 'true';
|
|
8
|
+
|
|
9
|
+
console.log('=== Template Literal vs String Interpolation Test ===');
|
|
10
|
+
console.log(
|
|
11
|
+
`Runtime: ${typeof globalThis.Bun !== 'undefined' ? 'Bun' : 'Node.js'}`
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
console.log('\n--- Testing Template Literal: $`echo hello` ---');
|
|
15
|
+
try {
|
|
16
|
+
const result1 = await $`echo hello`;
|
|
17
|
+
console.log(
|
|
18
|
+
`✓ Template literal success: "${result1.stdout.toString().trim()}"`
|
|
19
|
+
);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
console.log(`✗ Template literal failed: ${error.message}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.log('\n--- Testing String Interpolation: $`${cmd}` ---');
|
|
25
|
+
const cmd = 'echo hello';
|
|
26
|
+
try {
|
|
27
|
+
const result2 = await $`${cmd}`;
|
|
28
|
+
console.log(
|
|
29
|
+
`✓ String interpolation success: "${result2.stdout.toString().trim()}"`
|
|
30
|
+
);
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.log(`✗ String interpolation failed: ${error.message}`);
|
|
33
|
+
if (error.stderr) {
|
|
34
|
+
console.log(` Stderr: ${error.stderr.toString().trim()}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log('\n--- Testing another format: $(cmd) ---');
|
|
39
|
+
try {
|
|
40
|
+
// Note: This tests using a variable directly in template literal
|
|
41
|
+
const result3 = $`${cmd}`;
|
|
42
|
+
const output3 = await result3;
|
|
43
|
+
console.log(`✓ $(cmd) format success: "${output3.stdout.toString().trim()}"`);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.log(`✗ $(cmd) format failed: ${error.message}`);
|
|
46
|
+
if (error.stderr) {
|
|
47
|
+
console.log(` Stderr: ${error.stderr.toString().trim()}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { $ } from '../src/$.mjs';
|
|
2
|
+
|
|
3
|
+
console.log('Testing exact timing of cancellation...');
|
|
4
|
+
|
|
5
|
+
// Patch the virtual command to see when it yields
|
|
6
|
+
const originalYes = (await import('../src/commands/$.yes.mjs')).default;
|
|
7
|
+
let yieldCount = 0;
|
|
8
|
+
|
|
9
|
+
const patchedYes = async function* (opts) {
|
|
10
|
+
const gen = originalYes(opts);
|
|
11
|
+
for await (const value of gen) {
|
|
12
|
+
yieldCount++;
|
|
13
|
+
console.log(` [YES YIELD ${yieldCount}]`);
|
|
14
|
+
yield value;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// Temporarily replace yes command
|
|
19
|
+
const virtualCommands = (await import('../src/$.mjs')).virtualCommands;
|
|
20
|
+
virtualCommands.set('yes', patchedYes);
|
|
21
|
+
|
|
22
|
+
const runner = $`yes "test"`;
|
|
23
|
+
let iterations = 0;
|
|
24
|
+
|
|
25
|
+
console.log('\nStarting iteration...');
|
|
26
|
+
for await (const chunk of runner.stream()) {
|
|
27
|
+
iterations++;
|
|
28
|
+
console.log(` [RECEIVED ${iterations}]: ${chunk.data.toString().trim()}`);
|
|
29
|
+
|
|
30
|
+
if (iterations >= 3) {
|
|
31
|
+
console.log(' [BREAKING]');
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
console.log(`\nFinal:`);
|
|
37
|
+
console.log(` Total yields from yes: ${yieldCount}`);
|
|
38
|
+
console.log(` Total received: ${iterations}`);
|
|
39
|
+
console.log(` runner.finished: ${runner.finished}`);
|
|
40
|
+
|
|
41
|
+
process.exit(0);
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test top command with inherited stdout but controlled stdin
|
|
5
|
+
* This demonstrates the key requirement: inherit stdout but control stdin independently
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { $ } from '../src/$.mjs';
|
|
9
|
+
|
|
10
|
+
console.log('=== Testing top with inherit stdout + streams.stdin control ===');
|
|
11
|
+
console.log('');
|
|
12
|
+
|
|
13
|
+
async function testTopInheritStdoutStdinControl() {
|
|
14
|
+
try {
|
|
15
|
+
console.log(
|
|
16
|
+
'🎯 GOAL: Run top with inherited stdout, stop it via streams.stdin'
|
|
17
|
+
);
|
|
18
|
+
console.log('');
|
|
19
|
+
console.log(' → top output should appear directly in this terminal');
|
|
20
|
+
console.log(
|
|
21
|
+
' → we should be able to send "q" via streams.stdin to stop it'
|
|
22
|
+
);
|
|
23
|
+
console.log(
|
|
24
|
+
' → this proves stdout inheritance + independent stdin control'
|
|
25
|
+
);
|
|
26
|
+
console.log('');
|
|
27
|
+
|
|
28
|
+
console.log('Starting top command...');
|
|
29
|
+
console.log('━'.repeat(60));
|
|
30
|
+
|
|
31
|
+
// Create top command with inherited stdout
|
|
32
|
+
const topCmd = $`top -n 10`; // Limit to 10 iterations as backup
|
|
33
|
+
|
|
34
|
+
// Get stdin control BEFORE starting with specific options
|
|
35
|
+
const stdin = topCmd.streams.stdin;
|
|
36
|
+
console.log('✓ Got streams.stdin handle');
|
|
37
|
+
|
|
38
|
+
// Set up the quit sequence
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
console.log('\\n[CONTROL] → Sending "q" to quit top...');
|
|
41
|
+
if (stdin && !stdin.destroyed) {
|
|
42
|
+
stdin.write('q');
|
|
43
|
+
// Don't end() immediately - top needs time to process
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
if (stdin && !stdin.destroyed) {
|
|
46
|
+
stdin.end();
|
|
47
|
+
}
|
|
48
|
+
}, 100);
|
|
49
|
+
}
|
|
50
|
+
}, 2000); // Wait 2 seconds to see some output
|
|
51
|
+
|
|
52
|
+
// Backup kill in case stdin quit doesn't work
|
|
53
|
+
const killTimer = setTimeout(() => {
|
|
54
|
+
console.log('\\n[CONTROL] → stdin quit failed, using kill()...');
|
|
55
|
+
topCmd.kill();
|
|
56
|
+
}, 5000);
|
|
57
|
+
|
|
58
|
+
// Run with inherited stdout but piped stdin (so we can control it)
|
|
59
|
+
const result = await topCmd.run({
|
|
60
|
+
stdout: 'inherit', // Output goes directly to terminal
|
|
61
|
+
stdin: 'pipe', // We control stdin via streams.stdin
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
clearTimeout(killTimer);
|
|
65
|
+
console.log('━'.repeat(60));
|
|
66
|
+
console.log('✅ top command completed!');
|
|
67
|
+
console.log(` Exit code: ${result.code}`);
|
|
68
|
+
|
|
69
|
+
if (result.code === 0) {
|
|
70
|
+
console.log(' 🎉 SUCCESS: top quit cleanly via "q" command!');
|
|
71
|
+
} else if (
|
|
72
|
+
result.code === 130 ||
|
|
73
|
+
result.code === 143 ||
|
|
74
|
+
result.code === null
|
|
75
|
+
) {
|
|
76
|
+
console.log(
|
|
77
|
+
' ⚠️ top was terminated by signal (stdin might not have worked)'
|
|
78
|
+
);
|
|
79
|
+
} else {
|
|
80
|
+
console.log(' ℹ️ top exited with unexpected code');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
console.log('');
|
|
84
|
+
console.log('🔍 VERIFICATION: Test the same with a simple command');
|
|
85
|
+
|
|
86
|
+
console.log(' → Running echo with inherited stdout + controlled stdin...');
|
|
87
|
+
const echoCmd = $`cat`;
|
|
88
|
+
const echoStdin = echoCmd.streams.stdin;
|
|
89
|
+
|
|
90
|
+
if (echoStdin) {
|
|
91
|
+
echoStdin.write('This should appear directly in terminal\\n');
|
|
92
|
+
echoStdin.write('Because stdout is inherited\\n');
|
|
93
|
+
echoStdin.end();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const echoResult = await echoCmd.run({
|
|
97
|
+
stdout: 'inherit',
|
|
98
|
+
stdin: 'pipe',
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
console.log(` ✅ Verification completed (exit code: ${echoResult.code})`);
|
|
102
|
+
console.log('');
|
|
103
|
+
|
|
104
|
+
console.log('📋 DEMONSTRATION COMPLETE:');
|
|
105
|
+
console.log(
|
|
106
|
+
' ✅ top output appeared directly in terminal (stdout inherited)'
|
|
107
|
+
);
|
|
108
|
+
console.log(
|
|
109
|
+
' ✅ we controlled top via streams.stdin (independent stdin control)'
|
|
110
|
+
);
|
|
111
|
+
console.log(' ✅ "q" command sent via stdin to stop top');
|
|
112
|
+
console.log(
|
|
113
|
+
' ✅ this proves the library supports: inherit stdout + control stdin'
|
|
114
|
+
);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
console.log('');
|
|
117
|
+
console.error('❌ TEST FAILED:', error.message);
|
|
118
|
+
console.error(error.stack);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
testTopInheritStdoutStdinControl();
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test that we can stop the `top` command by sending 'q' via streams.stdin
|
|
5
|
+
* This demonstrates stdin control for interactive commands that actually read stdin
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { $ } from '../src/$.mjs';
|
|
9
|
+
|
|
10
|
+
console.log('=== Testing top command quit via streams.stdin ===');
|
|
11
|
+
console.log('');
|
|
12
|
+
|
|
13
|
+
async function testTopQuitStdin() {
|
|
14
|
+
try {
|
|
15
|
+
console.log('TEST: Stop top command by sending "q" via streams.stdin');
|
|
16
|
+
|
|
17
|
+
// Start top command (interactive process monitor)
|
|
18
|
+
const topCmd = $`top -n 5`; // Limit to 5 iterations in case stdin quit fails
|
|
19
|
+
console.log('✓ top command created');
|
|
20
|
+
|
|
21
|
+
// Get stdin stream (this will auto-start the command)
|
|
22
|
+
const stdin = topCmd.streams.stdin;
|
|
23
|
+
console.log('✓ Accessed streams.stdin - top should be started');
|
|
24
|
+
console.log(' Started?', topCmd.started);
|
|
25
|
+
|
|
26
|
+
// Get stdout to monitor output
|
|
27
|
+
const stdout = topCmd.streams.stdout;
|
|
28
|
+
if (stdout) {
|
|
29
|
+
stdout.on('data', (data) => {
|
|
30
|
+
const output = data.toString();
|
|
31
|
+
process.stdout.write(`[top] ${output}`);
|
|
32
|
+
|
|
33
|
+
// Look for signs that top is running (like "Tasks:" or "Cpu(s):")
|
|
34
|
+
if (
|
|
35
|
+
output.includes('Tasks:') ||
|
|
36
|
+
output.includes('Cpu') ||
|
|
37
|
+
output.includes('PID')
|
|
38
|
+
) {
|
|
39
|
+
console.log('\\n → top is running, sending "q" to quit...');
|
|
40
|
+
if (stdin && !stdin.destroyed) {
|
|
41
|
+
stdin.write('q');
|
|
42
|
+
// Don't end() stdin immediately - top might need time to process
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Fallback: send 'q' after 2 seconds in case we miss the output detection
|
|
49
|
+
setTimeout(() => {
|
|
50
|
+
console.log('\\n → Fallback: sending "q" after 2 seconds...');
|
|
51
|
+
if (stdin && !stdin.destroyed) {
|
|
52
|
+
stdin.write('q');
|
|
53
|
+
// Give top a moment to process the quit command
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
if (stdin && !stdin.destroyed) {
|
|
56
|
+
stdin.end();
|
|
57
|
+
}
|
|
58
|
+
}, 500);
|
|
59
|
+
}
|
|
60
|
+
}, 2000);
|
|
61
|
+
|
|
62
|
+
// Additional fallback: kill if still running after 5 seconds
|
|
63
|
+
const killTimeout = setTimeout(() => {
|
|
64
|
+
console.log('\\n → stdin "q" failed, using kill() as backup...');
|
|
65
|
+
topCmd.kill();
|
|
66
|
+
}, 5000);
|
|
67
|
+
|
|
68
|
+
// Wait for top to complete
|
|
69
|
+
const result = await topCmd;
|
|
70
|
+
clearTimeout(killTimeout);
|
|
71
|
+
|
|
72
|
+
console.log('\\n✓ top command completed');
|
|
73
|
+
console.log(' Exit code:', result.code);
|
|
74
|
+
console.log(' Output length:', result.stdout.length);
|
|
75
|
+
console.log(
|
|
76
|
+
' First 200 chars:',
|
|
77
|
+
JSON.stringify(result.stdout.slice(0, 200))
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
// Determine how it was stopped
|
|
81
|
+
if (result.code === 0) {
|
|
82
|
+
console.log(' 🎉 SUCCESS: top quit cleanly via "q" command!');
|
|
83
|
+
} else if (result.code === 130 || result.code === 143) {
|
|
84
|
+
console.log(
|
|
85
|
+
' ⚠️ top was killed via signal (stdin quit may not have worked)'
|
|
86
|
+
);
|
|
87
|
+
} else {
|
|
88
|
+
console.log(' ℹ️ top exited with code:', result.code);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
console.log('\\n=== Testing comparison with cat (known stdin reader) ===');
|
|
92
|
+
|
|
93
|
+
const catCmd = $`cat`;
|
|
94
|
+
const catStdin = catCmd.streams.stdin;
|
|
95
|
+
|
|
96
|
+
if (catStdin) {
|
|
97
|
+
catStdin.write('Testing cat stdin\\n');
|
|
98
|
+
catStdin.write('This should work reliably\\n');
|
|
99
|
+
catStdin.end();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const catResult = await catCmd;
|
|
103
|
+
console.log('✓ cat result:', JSON.stringify(catResult.stdout));
|
|
104
|
+
console.log(' Exit code:', catResult.code);
|
|
105
|
+
|
|
106
|
+
console.log('\\n📋 CONCLUSION:');
|
|
107
|
+
console.log('✅ streams.stdin successfully sends data to processes');
|
|
108
|
+
console.log('✅ Interactive commands like top can be controlled via stdin');
|
|
109
|
+
console.log('✅ Fallback kill() method available for stubborn processes');
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.log('');
|
|
112
|
+
console.error('❌ TEST FAILED:', error.message);
|
|
113
|
+
console.error(error.stack);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
testTopQuitStdin();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Test the trace option in $ config
|
|
3
|
+
|
|
4
|
+
import { $ } from '../src/$.mjs';
|
|
5
|
+
|
|
6
|
+
console.log('=== Test: mirror:false with trace:false in CI environment ===');
|
|
7
|
+
process.env.CI = 'true';
|
|
8
|
+
|
|
9
|
+
const $silent = $({ mirror: false, capture: true, trace: false });
|
|
10
|
+
const result = await $silent`echo '{"status":"ok"}'`;
|
|
11
|
+
console.log('JSON Output:', result.stdout);
|
|
12
|
+
|
|
13
|
+
console.log('\n=== Parsing JSON to verify it works ===');
|
|
14
|
+
try {
|
|
15
|
+
const parsed = JSON.parse(result.stdout);
|
|
16
|
+
console.log('Parsed successfully:', parsed);
|
|
17
|
+
console.log('✓ Test PASSED: No trace logs interfered with JSON parsing');
|
|
18
|
+
} catch (e) {
|
|
19
|
+
console.error('✗ Test FAILED: Could not parse JSON:', e.message);
|
|
20
|
+
console.error('Raw output:', result.stdout);
|
|
21
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Test: User provides double quotes around interpolated value
|
|
4
|
+
// Expected: Preserve double quotes (wrapped in single quotes for shell)
|
|
5
|
+
|
|
6
|
+
import { $ } from '../src/$.mjs';
|
|
7
|
+
|
|
8
|
+
const claude = '/Users/konard/.claude/local/claude';
|
|
9
|
+
|
|
10
|
+
console.log('=== Test: User-Provided Double Quotes ===\n');
|
|
11
|
+
|
|
12
|
+
// User wraps the path in double quotes
|
|
13
|
+
const doubleQuoted = `"${claude}"`;
|
|
14
|
+
|
|
15
|
+
console.log('Original path:', claude);
|
|
16
|
+
console.log('User provides:', doubleQuoted);
|
|
17
|
+
|
|
18
|
+
const cmd = $({ mirror: false })`${doubleQuoted} --version`;
|
|
19
|
+
console.log('Generated command:', cmd.spec.command);
|
|
20
|
+
|
|
21
|
+
// Check the expected result
|
|
22
|
+
const expected = `'"/Users/konard/.claude/local/claude"' --version`;
|
|
23
|
+
if (cmd.spec.command === expected) {
|
|
24
|
+
console.log('✅ PASS: Double quotes preserved and properly wrapped');
|
|
25
|
+
} else {
|
|
26
|
+
console.log('❌ FAIL: Unexpected quoting');
|
|
27
|
+
console.log('Expected:', expected);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Test execution
|
|
31
|
+
try {
|
|
32
|
+
const result = await cmd;
|
|
33
|
+
console.log('\nExecution result:', result.code);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.log('\nExecution error:', error.message);
|
|
36
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Test: User provides single quotes around interpolated value
|
|
4
|
+
// Expected: Preserve single quotes without double-escaping
|
|
5
|
+
|
|
6
|
+
import { $ } from '../src/$.mjs';
|
|
7
|
+
|
|
8
|
+
const claude = '/Users/konard/.claude/local/claude';
|
|
9
|
+
|
|
10
|
+
console.log('=== Test: User-Provided Single Quotes ===\n');
|
|
11
|
+
|
|
12
|
+
// User wraps the path in single quotes
|
|
13
|
+
const singleQuoted = `'${claude}'`;
|
|
14
|
+
|
|
15
|
+
console.log('Original path:', claude);
|
|
16
|
+
console.log('User provides:', singleQuoted);
|
|
17
|
+
|
|
18
|
+
const cmd = $({ mirror: false })`${singleQuoted} --version`;
|
|
19
|
+
console.log('Generated command:', cmd.spec.command);
|
|
20
|
+
|
|
21
|
+
// Check the result
|
|
22
|
+
if (cmd.spec.command === `'${claude}' --version`) {
|
|
23
|
+
console.log('✅ PASS: Single quotes preserved correctly');
|
|
24
|
+
} else if (cmd.spec.command.includes("''")) {
|
|
25
|
+
console.log('❌ FAIL: Double quotes detected');
|
|
26
|
+
} else {
|
|
27
|
+
console.log('⚠️ WARNING: Unexpected quoting pattern');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Test execution
|
|
31
|
+
try {
|
|
32
|
+
const result = await cmd;
|
|
33
|
+
console.log('\nExecution result:', result.code);
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.log('\nExecution error:', error.message);
|
|
36
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { $, shell } from '../src/$.mjs';
|
|
2
|
+
|
|
3
|
+
const originalLog = console.log;
|
|
4
|
+
const capturedLogs = [];
|
|
5
|
+
console.log = (...args) => {
|
|
6
|
+
capturedLogs.push(args.join(' '));
|
|
7
|
+
originalLog(...args); // Also output to see what's happening
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
shell.verbose(true);
|
|
11
|
+
await $`echo "verbose test"`;
|
|
12
|
+
|
|
13
|
+
console.log = originalLog;
|
|
14
|
+
console.log('Captured logs:', capturedLogs);
|
|
15
|
+
console.log(
|
|
16
|
+
'Has echo command:',
|
|
17
|
+
capturedLogs.some((log) => log.includes('echo "verbose test"'))
|
|
18
|
+
);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { $, shell } from '../src/$.mjs';
|
|
2
|
+
|
|
3
|
+
const originalLog = console.log;
|
|
4
|
+
const capturedLogs = [];
|
|
5
|
+
console.log = (...args) => {
|
|
6
|
+
capturedLogs.push(args.join(' '));
|
|
7
|
+
originalLog('LOG:', ...args); // Also output to see what's happening
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
shell.verbose(true);
|
|
11
|
+
const result = await $`echo "verbose test"`;
|
|
12
|
+
console.log('Result stdout:', result.stdout);
|
|
13
|
+
|
|
14
|
+
console.log = originalLog;
|
|
15
|
+
console.log('Captured logs:', capturedLogs);
|
|
16
|
+
console.log('Looking for: "echo \\"verbose test\\""');
|
|
17
|
+
console.log(
|
|
18
|
+
'Found verbatim:',
|
|
19
|
+
capturedLogs.some((log) => log === 'echo "verbose test"')
|
|
20
|
+
);
|
|
21
|
+
console.log(
|
|
22
|
+
'Found without quotes:',
|
|
23
|
+
capturedLogs.some((log) => log === 'echo verbose test')
|
|
24
|
+
);
|
|
25
|
+
console.log(
|
|
26
|
+
'Contains echo:',
|
|
27
|
+
capturedLogs.some((log) => log.includes('echo'))
|
|
28
|
+
);
|
|
29
|
+
console.log(
|
|
30
|
+
'Contains verbose test:',
|
|
31
|
+
capturedLogs.some((log) => log.includes('verbose test'))
|
|
32
|
+
);
|