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