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,83 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// Debug script to test resource cleanup behavior
|
|
3
|
+
|
|
4
|
+
import { $ } from '../src/$.mjs';
|
|
5
|
+
|
|
6
|
+
// Enable verbose mode
|
|
7
|
+
process.env.COMMAND_STREAM_VERBOSE = 'true';
|
|
8
|
+
|
|
9
|
+
// Function to access internal state for debugging
|
|
10
|
+
function getInternalDebugInfo() {
|
|
11
|
+
try {
|
|
12
|
+
// This is a hack to access module internals for debugging
|
|
13
|
+
// We'll try to get the activeProcessRunners set
|
|
14
|
+
const moduleText = Bun.file(import.meta.resolve('../src/$.mjs')).text();
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
sigintListeners: process.listeners('SIGINT').length,
|
|
18
|
+
timestamp: new Date().toISOString(),
|
|
19
|
+
};
|
|
20
|
+
} catch (e) {
|
|
21
|
+
return {
|
|
22
|
+
sigintListeners: process.listeners('SIGINT').length,
|
|
23
|
+
timestamp: new Date().toISOString(),
|
|
24
|
+
error: e.message,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function testResourceCleanup() {
|
|
30
|
+
console.log('=== Resource Cleanup Debug ===');
|
|
31
|
+
|
|
32
|
+
console.log('\n1. Initial state:', getInternalDebugInfo());
|
|
33
|
+
|
|
34
|
+
console.log('\n2. Creating and running multiple commands sequentially...');
|
|
35
|
+
|
|
36
|
+
// Test 1: Single command
|
|
37
|
+
console.log('\nTest 1: Single command');
|
|
38
|
+
console.log('Before:', getInternalDebugInfo());
|
|
39
|
+
const result1 = await $`echo "test1"`;
|
|
40
|
+
console.log('After single command:', getInternalDebugInfo());
|
|
41
|
+
console.log('Result:', result1.stdout);
|
|
42
|
+
|
|
43
|
+
// Test 2: Multiple concurrent commands
|
|
44
|
+
console.log('\nTest 2: Multiple concurrent commands');
|
|
45
|
+
console.log('Before:', getInternalDebugInfo());
|
|
46
|
+
|
|
47
|
+
const runners = [$`sleep 0.05`, $`sleep 0.05`, $`sleep 0.05`];
|
|
48
|
+
|
|
49
|
+
const promises = runners.map((r) => r.start());
|
|
50
|
+
console.log('During concurrent execution:', getInternalDebugInfo());
|
|
51
|
+
|
|
52
|
+
await Promise.all(promises);
|
|
53
|
+
console.log('After concurrent commands:', getInternalDebugInfo());
|
|
54
|
+
|
|
55
|
+
// Test 3: Virtual commands (built-in commands)
|
|
56
|
+
console.log('\nTest 3: Virtual commands');
|
|
57
|
+
console.log('Before:', getInternalDebugInfo());
|
|
58
|
+
|
|
59
|
+
const virtualResult = await $`ls /tmp`;
|
|
60
|
+
console.log('After virtual command:', getInternalDebugInfo());
|
|
61
|
+
console.log('Virtual result length:', virtualResult.stdout.length);
|
|
62
|
+
|
|
63
|
+
// Test 4: Mixed real and virtual commands
|
|
64
|
+
console.log('\nTest 4: Mixed commands');
|
|
65
|
+
console.log('Before:', getInternalDebugInfo());
|
|
66
|
+
|
|
67
|
+
const mixedPromises = [
|
|
68
|
+
$`echo "real1"`.start(),
|
|
69
|
+
$`pwd`.start(),
|
|
70
|
+
$`echo "real2"`.start(),
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
console.log('During mixed execution:', getInternalDebugInfo());
|
|
74
|
+
const mixedResults = await Promise.all(mixedPromises);
|
|
75
|
+
console.log('After mixed commands:', getInternalDebugInfo());
|
|
76
|
+
|
|
77
|
+
console.log('\n5. Final cleanup verification');
|
|
78
|
+
// Give a small delay for any async cleanup
|
|
79
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
80
|
+
console.log('Final state:', getInternalDebugInfo());
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
testResourceCleanup().catch(console.error);
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Debug shell argument construction
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
|
|
6
|
+
// Recreate the findAvailableShell logic
|
|
7
|
+
function findAvailableShell() {
|
|
8
|
+
const shellsToTry = [
|
|
9
|
+
{ cmd: '/bin/sh', args: ['-l', '-c'], checkPath: true },
|
|
10
|
+
{ cmd: '/usr/bin/sh', args: ['-l', '-c'], checkPath: true },
|
|
11
|
+
{ cmd: '/bin/bash', args: ['-l', '-c'], checkPath: true },
|
|
12
|
+
{ cmd: '/usr/bin/bash', args: ['-l', '-c'], checkPath: true },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
for (const shell of shellsToTry) {
|
|
16
|
+
if (shell.checkPath) {
|
|
17
|
+
if (fs.existsSync(shell.cmd)) {
|
|
18
|
+
console.log(`Found shell at absolute path: ${shell.cmd}`);
|
|
19
|
+
return { cmd: shell.cmd, args: shell.args };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return { cmd: '/bin/sh', args: ['-l', '-c'] };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const shell = findAvailableShell();
|
|
28
|
+
const commandStr = 'echo hello';
|
|
29
|
+
|
|
30
|
+
console.log('Shell detection result:');
|
|
31
|
+
console.log(` cmd: ${shell.cmd}`);
|
|
32
|
+
console.log(` args: ${JSON.stringify(shell.args)}`);
|
|
33
|
+
|
|
34
|
+
console.log('\nOriginal spawn args:');
|
|
35
|
+
const spawnArgs1 = [
|
|
36
|
+
shell.cmd,
|
|
37
|
+
...shell.args.filter((arg) => arg !== '-l'),
|
|
38
|
+
commandStr,
|
|
39
|
+
];
|
|
40
|
+
console.log(` ${JSON.stringify(spawnArgs1)}`);
|
|
41
|
+
|
|
42
|
+
console.log('\nCorrected spawn args (should include -c):');
|
|
43
|
+
const spawnArgs2 = [shell.cmd, '-c', commandStr];
|
|
44
|
+
console.log(` ${JSON.stringify(spawnArgs2)}`);
|
|
45
|
+
|
|
46
|
+
console.log('\nTesting both approaches:');
|
|
47
|
+
|
|
48
|
+
const isBun = typeof globalThis.Bun !== 'undefined';
|
|
49
|
+
console.log(`Runtime: ${isBun ? 'Bun' : 'Node.js'}`);
|
|
50
|
+
|
|
51
|
+
if (isBun) {
|
|
52
|
+
console.log('\nTesting with original args:');
|
|
53
|
+
try {
|
|
54
|
+
const proc1 = Bun.spawn(spawnArgs1, { stdout: 'pipe', stderr: 'pipe' });
|
|
55
|
+
const stdout1 = await new Response(proc1.stdout).text();
|
|
56
|
+
const stderr1 = await new Response(proc1.stderr).text();
|
|
57
|
+
const code1 = await proc1.exited;
|
|
58
|
+
console.log(` Exit code: ${code1}`);
|
|
59
|
+
console.log(` Stdout: "${stdout1.trim()}"`);
|
|
60
|
+
console.log(` Stderr: "${stderr1.trim()}"`);
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.log(` Error: ${error.message}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.log('\nTesting with corrected args:');
|
|
66
|
+
try {
|
|
67
|
+
const proc2 = Bun.spawn(spawnArgs2, { stdout: 'pipe', stderr: 'pipe' });
|
|
68
|
+
const stdout2 = await new Response(proc2.stdout).text();
|
|
69
|
+
const stderr2 = await new Response(proc2.stderr).text();
|
|
70
|
+
const code2 = await proc2.exited;
|
|
71
|
+
console.log(` Exit code: ${code2}`);
|
|
72
|
+
console.log(` Stdout: "${stdout2.trim()}"`);
|
|
73
|
+
console.log(` Stderr: "${stderr2.trim()}"`);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.log(` Error: ${error.message}`);
|
|
76
|
+
}
|
|
77
|
+
} else {
|
|
78
|
+
const cp = await import('child_process');
|
|
79
|
+
|
|
80
|
+
console.log('\nTesting with original args:');
|
|
81
|
+
try {
|
|
82
|
+
const result1 = cp.spawnSync(spawnArgs1[0], spawnArgs1.slice(1), {
|
|
83
|
+
encoding: 'utf-8',
|
|
84
|
+
});
|
|
85
|
+
console.log(` Exit code: ${result1.status}`);
|
|
86
|
+
console.log(` Stdout: "${result1.stdout?.trim() || ''}"`);
|
|
87
|
+
console.log(` Stderr: "${result1.stderr?.trim() || ''}"`);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.log(` Error: ${error.message}`);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
console.log('\nTesting with corrected args:');
|
|
93
|
+
try {
|
|
94
|
+
const result2 = cp.spawnSync(spawnArgs2[0], spawnArgs2.slice(1), {
|
|
95
|
+
encoding: 'utf-8',
|
|
96
|
+
});
|
|
97
|
+
console.log(` Exit code: ${result2.status}`);
|
|
98
|
+
console.log(` Stdout: "${result2.stdout?.trim() || ''}"`);
|
|
99
|
+
console.log(` Stderr: "${result2.stderr?.trim() || ''}"`);
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.log(` Error: ${error.message}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// Debug script to test SIGINT handler interaction
|
|
3
|
+
|
|
4
|
+
import { $ } from '../src/$.mjs';
|
|
5
|
+
|
|
6
|
+
// Enable verbose mode
|
|
7
|
+
process.env.COMMAND_STREAM_VERBOSE = 'true';
|
|
8
|
+
|
|
9
|
+
// Simulate the child process scenario from the failing test
|
|
10
|
+
let cleanupDone = false;
|
|
11
|
+
|
|
12
|
+
// Add user SIGINT handler FIRST (like the test does)
|
|
13
|
+
process.on('SIGINT', async () => {
|
|
14
|
+
console.log('USER_SIGINT_HANDLER_START');
|
|
15
|
+
// Simulate cleanup work
|
|
16
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
17
|
+
cleanupDone = true;
|
|
18
|
+
console.log('USER_SIGINT_HANDLER_DONE');
|
|
19
|
+
process.exit(0); // Exit cleanly after cleanup
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
console.log('CHILD_READY');
|
|
23
|
+
console.log('Initial SIGINT handlers:', process.listeners('SIGINT').length);
|
|
24
|
+
|
|
25
|
+
// Now start a command that will cause the command-stream SIGINT handler to be installed
|
|
26
|
+
console.log('Starting sleep command...');
|
|
27
|
+
const sleepPromise = $`sleep 2`.start();
|
|
28
|
+
|
|
29
|
+
console.log(
|
|
30
|
+
'After starting command, SIGINT handlers:',
|
|
31
|
+
process.listeners('SIGINT').length
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
// Simulate SIGINT being sent after a short delay
|
|
35
|
+
setTimeout(() => {
|
|
36
|
+
console.log('Sending SIGINT to self...');
|
|
37
|
+
process.kill(process.pid, 'SIGINT');
|
|
38
|
+
}, 100);
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
await sleepPromise;
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.log('Sleep interrupted:', error.message);
|
|
44
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// Debug script to test SIGINT forwarding behavior
|
|
3
|
+
|
|
4
|
+
import { $ } from '../src/$.mjs';
|
|
5
|
+
|
|
6
|
+
// Enable verbose mode
|
|
7
|
+
process.env.COMMAND_STREAM_VERBOSE = 'true';
|
|
8
|
+
|
|
9
|
+
async function testSigintForwarding() {
|
|
10
|
+
console.log('=== SIGINT Forwarding Debug ===');
|
|
11
|
+
|
|
12
|
+
console.log(
|
|
13
|
+
'\n1. Initial SIGINT listeners:',
|
|
14
|
+
process.listeners('SIGINT').length
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
console.log('\n2. Starting a long-running command...');
|
|
18
|
+
const runner = $`sleep 5`;
|
|
19
|
+
const promise = runner.start();
|
|
20
|
+
|
|
21
|
+
console.log(
|
|
22
|
+
'SIGINT listeners after starting:',
|
|
23
|
+
process.listeners('SIGINT').length
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
// Send SIGINT after a short delay
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
console.log('\n3. Sending SIGINT to parent process...');
|
|
29
|
+
console.log(
|
|
30
|
+
'Active listeners before SIGINT:',
|
|
31
|
+
process.listeners('SIGINT').length
|
|
32
|
+
);
|
|
33
|
+
process.kill(process.pid, 'SIGINT');
|
|
34
|
+
}, 100);
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
const result = await promise;
|
|
38
|
+
console.log('\n4. Command completed with result:', result);
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.log('\n4. Command failed with error:', error.message);
|
|
41
|
+
console.log('Exit code:', error.code);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
console.log('\nFinal SIGINT listeners:', process.listeners('SIGINT').length);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Install a test SIGINT handler to see if it gets called
|
|
48
|
+
let parentSigintReceived = false;
|
|
49
|
+
const testHandler = () => {
|
|
50
|
+
parentSigintReceived = true;
|
|
51
|
+
console.log('TEST: Parent SIGINT handler called');
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
process.on('SIGINT', testHandler);
|
|
55
|
+
|
|
56
|
+
testSigintForwarding()
|
|
57
|
+
.then(() => {
|
|
58
|
+
console.log('TEST: Parent received SIGINT:', parentSigintReceived);
|
|
59
|
+
process.removeListener('SIGINT', testHandler);
|
|
60
|
+
})
|
|
61
|
+
.catch(console.error);
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// Debug script to trace SIGINT handler installation and removal
|
|
3
|
+
|
|
4
|
+
import { $ } from '../src/$.mjs';
|
|
5
|
+
|
|
6
|
+
// Enable verbose mode
|
|
7
|
+
process.env.COMMAND_STREAM_VERBOSE = 'true';
|
|
8
|
+
|
|
9
|
+
function getSigintListenerCount() {
|
|
10
|
+
return process.listeners('SIGINT').length;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getInternalState() {
|
|
14
|
+
// Access internal state for debugging
|
|
15
|
+
const activeProcessRunners = eval(`
|
|
16
|
+
import('../src/$.mjs').then(m => {
|
|
17
|
+
// Get internal state from the module
|
|
18
|
+
const moduleScope = m;
|
|
19
|
+
// This is a hack to access internal variables - only for debugging
|
|
20
|
+
return {
|
|
21
|
+
activeProcessRunners: globalThis.__activeProcessRunners || null,
|
|
22
|
+
sigintHandlerInstalled: globalThis.__sigintHandlerInstalled || null
|
|
23
|
+
};
|
|
24
|
+
})
|
|
25
|
+
`);
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
sigintHandlerCount: getSigintListenerCount(),
|
|
29
|
+
activeProcessRunners,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function testSigintHandlerInstall() {
|
|
34
|
+
console.log('=== SIGINT Handler Installation Debug ===');
|
|
35
|
+
|
|
36
|
+
console.log('\n1. Initial state:');
|
|
37
|
+
console.log('Initial SIGINT listeners:', getSigintListenerCount());
|
|
38
|
+
|
|
39
|
+
console.log('\n2. Creating first command runner...');
|
|
40
|
+
const runner1 = $`sleep 0.01`;
|
|
41
|
+
console.log(
|
|
42
|
+
'After creating runner1, SIGINT listeners:',
|
|
43
|
+
getSigintListenerCount()
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
console.log('\n3. Starting first command...');
|
|
47
|
+
const promise1 = runner1.start();
|
|
48
|
+
console.log(
|
|
49
|
+
'After starting runner1, SIGINT listeners:',
|
|
50
|
+
getSigintListenerCount()
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
console.log('\n4. Creating second command runner while first is running...');
|
|
54
|
+
const runner2 = $`sleep 0.01`;
|
|
55
|
+
const promise2 = runner2.start();
|
|
56
|
+
console.log(
|
|
57
|
+
'After starting runner2, SIGINT listeners:',
|
|
58
|
+
getSigintListenerCount()
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
console.log('\n5. Waiting for both commands to finish...');
|
|
62
|
+
await Promise.all([promise1, promise2]);
|
|
63
|
+
|
|
64
|
+
console.log('\n6. Final state after both commands finished:');
|
|
65
|
+
console.log('Final SIGINT listeners:', getSigintListenerCount());
|
|
66
|
+
|
|
67
|
+
console.log(
|
|
68
|
+
'\n7. Testing cleanup - creating and finishing another command...'
|
|
69
|
+
);
|
|
70
|
+
const runner3 = $`echo "test"`;
|
|
71
|
+
await runner3;
|
|
72
|
+
console.log(
|
|
73
|
+
'After third command finished, SIGINT listeners:',
|
|
74
|
+
getSigintListenerCount()
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Run the test
|
|
79
|
+
testSigintHandlerInstall().catch(console.error);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// Debug script to test SIGINT handler order and execution
|
|
3
|
+
|
|
4
|
+
import { $ } from '../src/$.mjs';
|
|
5
|
+
|
|
6
|
+
// Enable verbose mode
|
|
7
|
+
process.env.COMMAND_STREAM_VERBOSE = 'true';
|
|
8
|
+
|
|
9
|
+
let userHandlerCalled = false;
|
|
10
|
+
let userHandlerFinished = false;
|
|
11
|
+
|
|
12
|
+
// Add user SIGINT handler FIRST
|
|
13
|
+
process.on('SIGINT', async () => {
|
|
14
|
+
userHandlerCalled = true;
|
|
15
|
+
console.log('🔥 USER_HANDLER_START');
|
|
16
|
+
console.log(
|
|
17
|
+
'🔥 Current SIGINT handlers when user handler runs:',
|
|
18
|
+
process.listeners('SIGINT').length
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
// Simulate cleanup work
|
|
22
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
23
|
+
|
|
24
|
+
userHandlerFinished = true;
|
|
25
|
+
console.log('🔥 USER_HANDLER_DONE');
|
|
26
|
+
console.log('🔥 About to call process.exit(0)');
|
|
27
|
+
process.exit(0); // Exit cleanly after cleanup
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
console.log('CHILD_READY');
|
|
31
|
+
console.log('Initial SIGINT handlers:', process.listeners('SIGINT').length);
|
|
32
|
+
|
|
33
|
+
// Show all handlers
|
|
34
|
+
const initialHandlers = process.listeners('SIGINT');
|
|
35
|
+
initialHandlers.forEach((handler, i) => {
|
|
36
|
+
console.log(`Handler ${i}:`, `${handler.toString().substring(0, 100)}...`);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Start a command to install command-stream handler
|
|
40
|
+
console.log('Starting sleep command...');
|
|
41
|
+
const sleepPromise = $`sleep 3`.start();
|
|
42
|
+
|
|
43
|
+
console.log(
|
|
44
|
+
'After starting command, SIGINT handlers:',
|
|
45
|
+
process.listeners('SIGINT').length
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
// Show all handlers again
|
|
49
|
+
const afterHandlers = process.listeners('SIGINT');
|
|
50
|
+
afterHandlers.forEach((handler, i) => {
|
|
51
|
+
const str = handler.toString();
|
|
52
|
+
const isCommandStream =
|
|
53
|
+
str.includes('activeProcessRunners') || str.includes('ProcessRunner');
|
|
54
|
+
console.log(
|
|
55
|
+
`Handler ${i} (${isCommandStream ? 'COMMAND-STREAM' : 'USER'}):`,
|
|
56
|
+
`${str.substring(0, 80)}...`
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Send SIGINT after delay
|
|
61
|
+
setTimeout(() => {
|
|
62
|
+
console.log('\n=== SENDING SIGINT ===');
|
|
63
|
+
console.log('User handler called before SIGINT?', userHandlerCalled);
|
|
64
|
+
console.log(
|
|
65
|
+
'Handlers at time of SIGINT:',
|
|
66
|
+
process.listeners('SIGINT').length
|
|
67
|
+
);
|
|
68
|
+
process.kill(process.pid, 'SIGINT');
|
|
69
|
+
}, 200);
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
await sleepPromise;
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.log('Sleep interrupted:', error.message);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// This should never be reached if handlers work correctly
|
|
78
|
+
console.log(
|
|
79
|
+
'This should not print - handlers should have called process.exit()'
|
|
80
|
+
);
|
|
81
|
+
setTimeout(() => {
|
|
82
|
+
console.log('Final state:');
|
|
83
|
+
console.log('User handler called:', userHandlerCalled);
|
|
84
|
+
console.log('User handler finished:', userHandlerFinished);
|
|
85
|
+
}, 500);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
|
|
5
|
+
console.log('=== SIGINT Listeners Debug ===');
|
|
6
|
+
|
|
7
|
+
function logSigintListeners(label) {
|
|
8
|
+
const listeners = process.listeners('SIGINT');
|
|
9
|
+
console.log(`\n--- ${label} ---`);
|
|
10
|
+
console.log('Total SIGINT listeners:', listeners.length);
|
|
11
|
+
|
|
12
|
+
listeners.forEach((listener, i) => {
|
|
13
|
+
const str = listener.toString();
|
|
14
|
+
const isCommandStream =
|
|
15
|
+
str.includes('activeProcessRunners') ||
|
|
16
|
+
str.includes('ProcessRunner') ||
|
|
17
|
+
str.includes('activeChildren');
|
|
18
|
+
console.log(
|
|
19
|
+
`Listener ${i}: ${isCommandStream ? 'COMMAND-STREAM' : 'OTHER'}`
|
|
20
|
+
);
|
|
21
|
+
if (isCommandStream) {
|
|
22
|
+
console.log(` Source preview: ${str.substring(0, 200)}...`);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
logSigintListeners('Initial state');
|
|
28
|
+
|
|
29
|
+
console.log('\nRunning a simple command...');
|
|
30
|
+
const cmd1 = $`echo "test1"`;
|
|
31
|
+
await cmd1;
|
|
32
|
+
|
|
33
|
+
logSigintListeners('After first command');
|
|
34
|
+
|
|
35
|
+
console.log('\nRunning another command...');
|
|
36
|
+
const cmd2 = $`echo "test2"`;
|
|
37
|
+
await cmd2;
|
|
38
|
+
|
|
39
|
+
logSigintListeners('After second command');
|
|
40
|
+
|
|
41
|
+
console.log('\nRunning a concurrent command...');
|
|
42
|
+
const cmd3 = $`sleep 0.1`;
|
|
43
|
+
const cmd4 = $`echo "test3"`;
|
|
44
|
+
await Promise.all([cmd3, cmd4]);
|
|
45
|
+
|
|
46
|
+
logSigintListeners('After concurrent commands');
|
|
47
|
+
|
|
48
|
+
console.log('\nTest completed.');
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
|
|
5
|
+
console.log('=== SIGINT Listeners Start Pattern Debug ===');
|
|
6
|
+
|
|
7
|
+
function getInternalState() {
|
|
8
|
+
const sigintListeners = process.listeners('SIGINT');
|
|
9
|
+
const commandStreamListeners = sigintListeners.filter((l) => {
|
|
10
|
+
const str = l.toString();
|
|
11
|
+
return (
|
|
12
|
+
str.includes('activeProcessRunners') ||
|
|
13
|
+
str.includes('ProcessRunner') ||
|
|
14
|
+
str.includes('activeChildren')
|
|
15
|
+
);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
sigintHandlerCount: commandStreamListeners.length,
|
|
20
|
+
totalSigintListeners: sigintListeners.length,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function logState(label) {
|
|
25
|
+
const state = getInternalState();
|
|
26
|
+
console.log(
|
|
27
|
+
`${label}: sigintHandlerCount=${state.sigintHandlerCount}, total=${state.totalSigintListeners}`
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
logState('Initial state');
|
|
32
|
+
|
|
33
|
+
console.log('\nTesting start() pattern like failing test...');
|
|
34
|
+
const runner = $`sleep 0.01`;
|
|
35
|
+
const promise = runner.start();
|
|
36
|
+
|
|
37
|
+
logState('After calling start() but before await');
|
|
38
|
+
|
|
39
|
+
await promise;
|
|
40
|
+
|
|
41
|
+
logState('After awaiting promise');
|
|
42
|
+
|
|
43
|
+
console.log('\nTesting direct await pattern...');
|
|
44
|
+
const runner2 = $`sleep 0.01`;
|
|
45
|
+
|
|
46
|
+
logState('Before direct await');
|
|
47
|
+
|
|
48
|
+
await runner2;
|
|
49
|
+
|
|
50
|
+
logState('After direct await');
|
|
51
|
+
|
|
52
|
+
console.log('\nTesting multiple start() calls...');
|
|
53
|
+
const runner3 = $`sleep 0.01`;
|
|
54
|
+
const runner4 = $`sleep 0.01`;
|
|
55
|
+
const promise3 = runner3.start();
|
|
56
|
+
const promise4 = runner4.start();
|
|
57
|
+
|
|
58
|
+
logState('After multiple start() calls');
|
|
59
|
+
|
|
60
|
+
await Promise.all([promise3, promise4]);
|
|
61
|
+
|
|
62
|
+
logState('After awaiting all promises');
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
// Debug script to see if our timer fix is working
|
|
3
|
+
|
|
4
|
+
import { $ } from '../src/$.mjs';
|
|
5
|
+
|
|
6
|
+
// Enable verbose mode
|
|
7
|
+
process.env.COMMAND_STREAM_VERBOSE = 'true';
|
|
8
|
+
|
|
9
|
+
let userHandlerCalled = false;
|
|
10
|
+
|
|
11
|
+
// Add user SIGINT handler FIRST
|
|
12
|
+
process.on('SIGINT', () => {
|
|
13
|
+
userHandlerCalled = true;
|
|
14
|
+
console.log('🔥 USER_HANDLER_START (sync)');
|
|
15
|
+
|
|
16
|
+
// Use synchronous delay to see if that changes anything
|
|
17
|
+
const start = Date.now();
|
|
18
|
+
while (Date.now() - start < 50) {
|
|
19
|
+
// Busy wait for 50ms
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
console.log('🔥 USER_HANDLER_DONE (sync)');
|
|
23
|
+
console.log('🔥 About to call process.exit(0)');
|
|
24
|
+
process.exit(0); // Exit cleanly after cleanup
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
console.log('Starting sleep command...');
|
|
28
|
+
const sleepPromise = $`sleep 3`.start();
|
|
29
|
+
|
|
30
|
+
// Send SIGINT after delay
|
|
31
|
+
setTimeout(() => {
|
|
32
|
+
console.log('\n=== SENDING SIGINT ===');
|
|
33
|
+
process.kill(process.pid, 'SIGINT');
|
|
34
|
+
}, 200);
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
await sleepPromise;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.log('Sleep interrupted:', error.message);
|
|
40
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
|
|
5
|
+
async function debugSimpleCommand() {
|
|
6
|
+
console.log('🐛 Testing with a simple non-builtin command');
|
|
7
|
+
|
|
8
|
+
// Use sort instead of cat
|
|
9
|
+
const sortCmd = $`sort`;
|
|
10
|
+
console.log('1. Created sort command');
|
|
11
|
+
|
|
12
|
+
const stdinPromise = sortCmd.streams.stdin;
|
|
13
|
+
console.log('2. Accessed streams.stdin');
|
|
14
|
+
|
|
15
|
+
// Wait longer
|
|
16
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
17
|
+
|
|
18
|
+
console.log('3. After 500ms wait:');
|
|
19
|
+
console.log(' started:', sortCmd.started);
|
|
20
|
+
console.log(' child exists:', !!sortCmd.child);
|
|
21
|
+
|
|
22
|
+
if (sortCmd.child) {
|
|
23
|
+
console.log(' child.stdin exists:', !!sortCmd.child.stdin);
|
|
24
|
+
console.log(
|
|
25
|
+
' child.stdin writable:',
|
|
26
|
+
sortCmd.child.stdin ? sortCmd.child.stdin.writable : 'N/A'
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const stdin = await stdinPromise;
|
|
31
|
+
console.log('4. Awaited stdin:');
|
|
32
|
+
console.log(' type:', typeof stdin);
|
|
33
|
+
console.log(' is null:', stdin === null);
|
|
34
|
+
console.log(' has write:', !!(stdin && stdin.write));
|
|
35
|
+
|
|
36
|
+
// Try to write if we have a real stream
|
|
37
|
+
if (stdin && stdin.write) {
|
|
38
|
+
console.log('5. Trying to write...');
|
|
39
|
+
stdin.write('test\n');
|
|
40
|
+
stdin.end();
|
|
41
|
+
|
|
42
|
+
const result = await sortCmd;
|
|
43
|
+
console.log(' Result:', JSON.stringify(result.stdout));
|
|
44
|
+
} else {
|
|
45
|
+
sortCmd.kill();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
debugSimpleCommand();
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Test if the ProcessRunner class is working correctly
|
|
4
|
+
class TestClass {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.child = null;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
get stdout() {
|
|
10
|
+
return this.child ? this.child.stdout : null;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const test = new TestClass();
|
|
15
|
+
console.log('TestClass stdout:', test.stdout);
|
|
16
|
+
console.log('Should be null:', test.stdout === null);
|
|
17
|
+
|
|
18
|
+
// Now test with actual ProcessRunner
|
|
19
|
+
import { $ } from '../src/$.mjs';
|
|
20
|
+
|
|
21
|
+
const cmd = $`echo "test"`;
|
|
22
|
+
console.log('ProcessRunner stdout:', cmd.stdout);
|
|
23
|
+
console.log('Should be null:', cmd.stdout === null);
|
|
24
|
+
|
|
25
|
+
// Check if the object is really a ProcessRunner
|
|
26
|
+
console.log('cmd constructor name:', cmd.constructor.name);
|
|
27
|
+
console.log(
|
|
28
|
+
'cmd instanceof ProcessRunner:',
|
|
29
|
+
cmd.constructor.name === 'ProcessRunner'
|
|
30
|
+
);
|