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 node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import os from 'os';
|
|
7
|
+
|
|
8
|
+
console.log('=== Testing EXACT original hanging scenario ===\n');
|
|
9
|
+
console.log('Using: --secret flag, no 2>&1, capture: true, mirror: false\n');
|
|
10
|
+
|
|
11
|
+
const tempFile = path.join(os.tmpdir(), 'original-hang-test.md');
|
|
12
|
+
await fs.writeFile(
|
|
13
|
+
tempFile,
|
|
14
|
+
'# Test\nThis tests the exact original scenario\n'
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
console.log('Running command that originally hung...');
|
|
19
|
+
const startTime = Date.now();
|
|
20
|
+
|
|
21
|
+
// EXACT original command that hung
|
|
22
|
+
const result =
|
|
23
|
+
await $`gh gist create ${tempFile} --desc "original-hang-test" --secret`.run(
|
|
24
|
+
{
|
|
25
|
+
capture: true,
|
|
26
|
+
mirror: false,
|
|
27
|
+
// No timeout in original
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
const duration = Date.now() - startTime;
|
|
32
|
+
|
|
33
|
+
console.log(`\n✅ Completed in ${duration}ms`);
|
|
34
|
+
console.log('Exit code:', result.code);
|
|
35
|
+
console.log('Stdout:', result.stdout?.trim());
|
|
36
|
+
console.log('Stderr:', result.stderr?.trim());
|
|
37
|
+
|
|
38
|
+
// Cleanup
|
|
39
|
+
if (result.stdout?.includes('gist.github.com')) {
|
|
40
|
+
const gistId = result.stdout.trim().split('/').pop();
|
|
41
|
+
await $`gh gist delete ${gistId} --yes`.run({
|
|
42
|
+
capture: true,
|
|
43
|
+
mirror: false,
|
|
44
|
+
});
|
|
45
|
+
console.log('Cleaned up gist:', gistId);
|
|
46
|
+
}
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.log('\n❌ FAILED');
|
|
49
|
+
console.log('Error:', error.message);
|
|
50
|
+
console.log('This reproduces the original hanging issue!');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
await fs.unlink(tempFile).catch(() => {});
|
|
54
|
+
|
|
55
|
+
console.log('\n=== Testing with variations ===\n');
|
|
56
|
+
|
|
57
|
+
// Test if --secret vs --public=false makes a difference
|
|
58
|
+
console.log('Test with --public=false instead of --secret:');
|
|
59
|
+
await fs.writeFile(tempFile, 'Test content\n');
|
|
60
|
+
|
|
61
|
+
try {
|
|
62
|
+
const result =
|
|
63
|
+
await $`gh gist create ${tempFile} --desc "public-false-test" --public=false`.run(
|
|
64
|
+
{
|
|
65
|
+
capture: true,
|
|
66
|
+
mirror: false,
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
console.log('✅ --public=false works');
|
|
71
|
+
|
|
72
|
+
if (result.stdout?.includes('gist.github.com')) {
|
|
73
|
+
const gistId = result.stdout.trim().split('/').pop();
|
|
74
|
+
await $`gh gist delete ${gistId} --yes`.run({
|
|
75
|
+
capture: true,
|
|
76
|
+
mirror: false,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.log('❌ --public=false also fails:', error.message);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
await fs.unlink(tempFile).catch(() => {});
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import os from 'os';
|
|
7
|
+
|
|
8
|
+
console.log('=== Reproducing gh gist create hanging issue ===\n');
|
|
9
|
+
|
|
10
|
+
// Create test file
|
|
11
|
+
const testFile = path.join(os.tmpdir(), 'hang-test.txt');
|
|
12
|
+
await fs.writeFile(testFile, 'Test content\n');
|
|
13
|
+
|
|
14
|
+
console.log('Test 1: WITHOUT 2>&1 redirection (potential hang)');
|
|
15
|
+
console.log('Running gh gist create WITHOUT stderr redirection...');
|
|
16
|
+
console.log("(This might hang if there's an issue)\n");
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const startTime = Date.now();
|
|
20
|
+
|
|
21
|
+
// This was the problematic case
|
|
22
|
+
const result =
|
|
23
|
+
await $`gh gist create ${testFile} --desc "hang-test" --public=false`.run({
|
|
24
|
+
capture: true,
|
|
25
|
+
mirror: false, // Not mirroring - just capturing
|
|
26
|
+
timeout: 5000, // 5 second safety timeout
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const duration = Date.now() - startTime;
|
|
30
|
+
|
|
31
|
+
console.log('✅ Completed in', duration, 'ms');
|
|
32
|
+
console.log('Exit code:', result.code);
|
|
33
|
+
console.log('Stdout length:', result.stdout?.length);
|
|
34
|
+
console.log('Stderr length:', result.stderr?.length);
|
|
35
|
+
console.log('Stdout content:', result.stdout?.trim());
|
|
36
|
+
console.log('Stderr content:', result.stderr?.trim());
|
|
37
|
+
|
|
38
|
+
// Clean up gist if created
|
|
39
|
+
if (result.stdout && result.stdout.includes('gist.github.com')) {
|
|
40
|
+
const gistId = result.stdout.trim().split('/').pop();
|
|
41
|
+
await $`gh gist delete ${gistId} --yes`.run({
|
|
42
|
+
capture: true,
|
|
43
|
+
mirror: false,
|
|
44
|
+
});
|
|
45
|
+
console.log('Cleaned up gist:', gistId);
|
|
46
|
+
}
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.log('❌ Failed or timed out');
|
|
49
|
+
console.log('Error:', error.message);
|
|
50
|
+
if (error.killed) {
|
|
51
|
+
console.log('Process was killed (likely timeout)');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
console.log('\n---\n');
|
|
56
|
+
|
|
57
|
+
console.log('Test 2: WITH 2>&1 redirection (should work)');
|
|
58
|
+
console.log('Running gh gist create WITH stderr redirection...\n');
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const startTime = Date.now();
|
|
62
|
+
|
|
63
|
+
// This is the workaround
|
|
64
|
+
const result =
|
|
65
|
+
await $`gh gist create ${testFile} --desc "hang-test-2" --public=false 2>&1`.run(
|
|
66
|
+
{
|
|
67
|
+
capture: true,
|
|
68
|
+
mirror: false,
|
|
69
|
+
timeout: 5000,
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const duration = Date.now() - startTime;
|
|
74
|
+
|
|
75
|
+
console.log('✅ Completed in', duration, 'ms');
|
|
76
|
+
console.log('Exit code:', result.code);
|
|
77
|
+
console.log('Stdout length:', result.stdout?.length);
|
|
78
|
+
console.log('Stderr length:', result.stderr?.length);
|
|
79
|
+
console.log(
|
|
80
|
+
'Stdout content (first 200 chars):',
|
|
81
|
+
result.stdout?.slice(0, 200)
|
|
82
|
+
);
|
|
83
|
+
console.log('Stderr content:', result.stderr?.trim());
|
|
84
|
+
|
|
85
|
+
// Extract URL from output
|
|
86
|
+
const lines = result.stdout.trim().split('\n');
|
|
87
|
+
const gistUrl = lines.find((line) => line.includes('gist.github.com'));
|
|
88
|
+
|
|
89
|
+
if (gistUrl) {
|
|
90
|
+
const gistId = gistUrl.split('/').pop();
|
|
91
|
+
await $`gh gist delete ${gistId} --yes`.run({
|
|
92
|
+
capture: true,
|
|
93
|
+
mirror: false,
|
|
94
|
+
});
|
|
95
|
+
console.log('Cleaned up gist:', gistId);
|
|
96
|
+
}
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.log('❌ Failed');
|
|
99
|
+
console.log('Error:', error.message);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
console.log('\n---\n');
|
|
103
|
+
|
|
104
|
+
console.log('Test 3: WITH mirror: true (should also work)');
|
|
105
|
+
console.log('Running gh gist create WITH output mirroring...\n');
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
const startTime = Date.now();
|
|
109
|
+
|
|
110
|
+
// Test with mirror enabled
|
|
111
|
+
const result =
|
|
112
|
+
await $`gh gist create ${testFile} --desc "hang-test-3" --public=false`.run(
|
|
113
|
+
{
|
|
114
|
+
capture: true,
|
|
115
|
+
mirror: true, // This time we mirror output
|
|
116
|
+
timeout: 5000,
|
|
117
|
+
}
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
const duration = Date.now() - startTime;
|
|
121
|
+
|
|
122
|
+
console.log('\n✅ Completed in', duration, 'ms');
|
|
123
|
+
console.log('Exit code:', result.code);
|
|
124
|
+
console.log('Stdout captured:', result.stdout?.trim());
|
|
125
|
+
|
|
126
|
+
// Clean up
|
|
127
|
+
if (result.stdout && result.stdout.includes('gist.github.com')) {
|
|
128
|
+
const gistId = result.stdout.trim().split('/').pop();
|
|
129
|
+
await $`gh gist delete ${gistId} --yes`.run({
|
|
130
|
+
capture: true,
|
|
131
|
+
mirror: false,
|
|
132
|
+
});
|
|
133
|
+
console.log('Cleaned up gist:', gistId);
|
|
134
|
+
}
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.log('❌ Failed');
|
|
137
|
+
console.log('Error:', error.message);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Clean up test file
|
|
141
|
+
await fs.unlink(testFile).catch(() => {});
|
|
142
|
+
|
|
143
|
+
console.log('\n=== Summary ===');
|
|
144
|
+
console.log('If Test 1 hangs/times out but Tests 2 and 3 work, then:');
|
|
145
|
+
console.log(
|
|
146
|
+
'- Issue: gh outputs progress to stderr, and $.mjs might not handle it well'
|
|
147
|
+
);
|
|
148
|
+
console.log('- Workaround 1: Use 2>&1 to redirect stderr to stdout');
|
|
149
|
+
console.log(
|
|
150
|
+
'- Workaround 2: Use mirror: true to display output while capturing'
|
|
151
|
+
);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
5
|
+
|
|
6
|
+
console.log('Testing gh gist create WITH 2>&1 (should work)');
|
|
7
|
+
console.log('This test will timeout after 10 seconds if it hangs\n');
|
|
8
|
+
|
|
9
|
+
const testFile = '/tmp/hang-test-with-redirect.txt';
|
|
10
|
+
await fs.writeFile(testFile, 'Test content\n');
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
const startTime = Date.now();
|
|
14
|
+
|
|
15
|
+
// WITH 2>&1 - should work
|
|
16
|
+
const result =
|
|
17
|
+
await $`gh gist create ${testFile} --desc "test-no-hang" --public=false 2>&1`.run(
|
|
18
|
+
{
|
|
19
|
+
capture: true,
|
|
20
|
+
mirror: false,
|
|
21
|
+
timeout: 10000,
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
const duration = Date.now() - startTime;
|
|
26
|
+
console.log(`✅ SUCCESS - Completed in ${duration}ms`);
|
|
27
|
+
console.log('Exit code:', result.code);
|
|
28
|
+
console.log('Output:', result.stdout?.trim());
|
|
29
|
+
|
|
30
|
+
// Cleanup
|
|
31
|
+
const lines = result.stdout?.trim().split('\n') || [];
|
|
32
|
+
const gistUrl = lines.find((line) => line.includes('gist.github.com'));
|
|
33
|
+
if (gistUrl) {
|
|
34
|
+
const gistId = gistUrl.split('/').pop();
|
|
35
|
+
await $`gh gist delete ${gistId} --yes`.run({
|
|
36
|
+
capture: true,
|
|
37
|
+
mirror: false,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.log('❌ FAILED');
|
|
42
|
+
console.log('Error:', error.message);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
await fs.unlink(testFile).catch(() => {});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
5
|
+
|
|
6
|
+
console.log('Testing gh gist create WITHOUT 2>&1 (potential hang)');
|
|
7
|
+
console.log('This test will timeout after 10 seconds if it hangs\n');
|
|
8
|
+
|
|
9
|
+
const testFile = '/tmp/hang-test-no-redirect.txt';
|
|
10
|
+
await fs.writeFile(testFile, 'Test content\n');
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
const startTime = Date.now();
|
|
14
|
+
|
|
15
|
+
// WITHOUT 2>&1 - might hang
|
|
16
|
+
const result =
|
|
17
|
+
await $`gh gist create ${testFile} --desc "test-hang" --public=false`.run({
|
|
18
|
+
capture: true,
|
|
19
|
+
mirror: false,
|
|
20
|
+
timeout: 10000,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const duration = Date.now() - startTime;
|
|
24
|
+
console.log(`✅ SUCCESS - Completed in ${duration}ms`);
|
|
25
|
+
console.log('Exit code:', result.code);
|
|
26
|
+
console.log('Stdout:', result.stdout?.trim());
|
|
27
|
+
console.log('Stderr:', result.stderr?.trim());
|
|
28
|
+
|
|
29
|
+
// Cleanup
|
|
30
|
+
if (result.stdout?.includes('gist.github.com')) {
|
|
31
|
+
const gistId = result.stdout.trim().split('/').pop();
|
|
32
|
+
await $`gh gist delete ${gistId} --yes`.run({
|
|
33
|
+
capture: true,
|
|
34
|
+
mirror: false,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.log('❌ FAILED or TIMED OUT');
|
|
39
|
+
console.log('Error:', error.message);
|
|
40
|
+
console.log('This confirms the hanging issue!');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
await fs.unlink(testFile).catch(() => {});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
|
|
5
|
+
console.log('=== Minimal test for hanging ===\n');
|
|
6
|
+
|
|
7
|
+
// Test 1: Simple command without any options
|
|
8
|
+
console.log('Test 1: Most basic gh command');
|
|
9
|
+
const result1 = await $`gh --version`;
|
|
10
|
+
console.log('✅ Basic command works\n');
|
|
11
|
+
|
|
12
|
+
// Test 2: Command with capture but no mirror
|
|
13
|
+
console.log('Test 2: With capture: true, mirror: false');
|
|
14
|
+
const result2 = await $`gh --version`.run({ capture: true, mirror: false });
|
|
15
|
+
console.log('Exit code:', result2.code);
|
|
16
|
+
console.log('✅ Capture works\n');
|
|
17
|
+
|
|
18
|
+
// Test 3: Command that fails
|
|
19
|
+
console.log('Test 3: Command that should fail');
|
|
20
|
+
try {
|
|
21
|
+
const result3 = await $`gh gist view nonexistent-id`.run({
|
|
22
|
+
capture: true,
|
|
23
|
+
mirror: false,
|
|
24
|
+
});
|
|
25
|
+
console.log('Exit code:', result3.code);
|
|
26
|
+
console.log('Stdout:', result3.stdout);
|
|
27
|
+
console.log('Stderr:', result3.stderr);
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.log('Caught error:', error.message);
|
|
30
|
+
console.log('Exit code:', error.code);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
console.log('\n=== All tests completed ===');
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $, shell, enableVirtualCommands } from '../src/$.mjs';
|
|
4
|
+
import { mkdtempSync, rmSync } from 'fs';
|
|
5
|
+
import { tmpdir } from 'os';
|
|
6
|
+
import { join } from 'path';
|
|
7
|
+
|
|
8
|
+
// Enable virtual commands including cd
|
|
9
|
+
enableVirtualCommands();
|
|
10
|
+
shell.verbose(true);
|
|
11
|
+
|
|
12
|
+
console.log('=== GitHub CLI Operations with cd Virtual Command Examples ===\n');
|
|
13
|
+
|
|
14
|
+
async function example1_CheckGHAuth() {
|
|
15
|
+
console.log('Example 1: Check GitHub CLI Authentication\n');
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
// Check auth status
|
|
19
|
+
const authStatus = await $`gh auth status 2>&1 || echo "Not authenticated"`;
|
|
20
|
+
|
|
21
|
+
// Try to get current user
|
|
22
|
+
const user =
|
|
23
|
+
await $`gh api user --jq .login 2>/dev/null || echo "anonymous"`;
|
|
24
|
+
console.log(`Current user: ${user.stdout.trim()}`);
|
|
25
|
+
|
|
26
|
+
// Check gh version
|
|
27
|
+
const version = await $`gh --version`;
|
|
28
|
+
console.log(`GitHub CLI version: ${version.stdout.split('\n')[0]}`);
|
|
29
|
+
|
|
30
|
+
console.log('✓ GitHub CLI check completed\n');
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error('Error:', error.message);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function example2_SimulateRepoClone() {
|
|
37
|
+
console.log('Example 2: Simulate Repository Clone Pattern\n');
|
|
38
|
+
|
|
39
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'gh-clone-'));
|
|
40
|
+
const originalCwd = process.cwd();
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
// This simulates the pattern from solve.mjs
|
|
44
|
+
const owner = 'octocat';
|
|
45
|
+
const repo = 'Hello-World';
|
|
46
|
+
|
|
47
|
+
console.log(`Simulating clone of ${owner}/${repo} to ${tempDir}`);
|
|
48
|
+
|
|
49
|
+
// Navigate to temp directory
|
|
50
|
+
await $`cd ${tempDir}`;
|
|
51
|
+
|
|
52
|
+
// In real scenario, this would clone the repo
|
|
53
|
+
// For example purposes, we'll create a mock structure
|
|
54
|
+
await $`git init`;
|
|
55
|
+
await $`git config user.email "bot@example.com"`;
|
|
56
|
+
await $`git config user.name "Bot"`;
|
|
57
|
+
await $`echo "# ${repo}" > README.md`;
|
|
58
|
+
await $`git add . && git commit -m "Initial commit"`;
|
|
59
|
+
|
|
60
|
+
// Simulate gh commands that would work in a cloned repo
|
|
61
|
+
console.log('\nSimulating gh pr list (would fail without remote):');
|
|
62
|
+
await $`gh pr list --limit 1 2>&1 || echo "No remote repository"`;
|
|
63
|
+
|
|
64
|
+
// Return to original directory
|
|
65
|
+
await $`cd ${originalCwd}`;
|
|
66
|
+
|
|
67
|
+
console.log('✓ Clone pattern simulation completed\n');
|
|
68
|
+
} catch (error) {
|
|
69
|
+
console.error('Error:', error.message);
|
|
70
|
+
} finally {
|
|
71
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function example3_WorkflowWithTempDir() {
|
|
76
|
+
console.log('Example 3: Complete Workflow in Temp Directory\n');
|
|
77
|
+
|
|
78
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'workflow-'));
|
|
79
|
+
const originalCwd = process.cwd();
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
// Step 1: Setup repository
|
|
83
|
+
console.log('Step 1: Initialize repository');
|
|
84
|
+
await $`cd ${tempDir} && git init`;
|
|
85
|
+
await $`cd ${tempDir} && git config user.email "workflow@example.com"`;
|
|
86
|
+
await $`cd ${tempDir} && git config user.name "Workflow Bot"`;
|
|
87
|
+
|
|
88
|
+
// Step 2: Create initial structure
|
|
89
|
+
console.log('\nStep 2: Create project structure');
|
|
90
|
+
await $`cd ${tempDir} && mkdir -p src tests docs`;
|
|
91
|
+
await $`cd ${tempDir} && echo "# Project" > README.md`;
|
|
92
|
+
await $`cd ${tempDir} && echo "console.log('Hello');" > src/index.js`;
|
|
93
|
+
await $`cd ${tempDir} && echo "test('example', () => {});" > tests/test.js`;
|
|
94
|
+
|
|
95
|
+
// Step 3: Initial commit
|
|
96
|
+
console.log('\nStep 3: Create initial commit');
|
|
97
|
+
await $`cd ${tempDir} && git add .`;
|
|
98
|
+
await $`cd ${tempDir} && git commit -m "Initial project structure"`;
|
|
99
|
+
|
|
100
|
+
// Step 4: Create feature branch
|
|
101
|
+
console.log('\nStep 4: Create feature branch');
|
|
102
|
+
const branchName = `feature-${Date.now()}`;
|
|
103
|
+
await $`cd ${tempDir} && git checkout -b ${branchName}`;
|
|
104
|
+
|
|
105
|
+
// Step 5: Make feature changes
|
|
106
|
+
console.log('\nStep 5: Implement feature');
|
|
107
|
+
await $`cd ${tempDir} && echo "export const feature = () => 'new feature';" > src/feature.js`;
|
|
108
|
+
await $`cd ${tempDir} && git add .`;
|
|
109
|
+
await $`cd ${tempDir} && git commit -m "Add new feature"`;
|
|
110
|
+
|
|
111
|
+
// Step 6: Show repository state
|
|
112
|
+
console.log('\nStep 6: Show repository state');
|
|
113
|
+
await $`cd ${tempDir} && git log --oneline --graph --all`;
|
|
114
|
+
await $`cd ${tempDir} && git status`;
|
|
115
|
+
|
|
116
|
+
// Return to original directory
|
|
117
|
+
await $`cd ${originalCwd}`;
|
|
118
|
+
|
|
119
|
+
console.log('\n✓ Workflow completed successfully\n');
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error('Error:', error.message);
|
|
122
|
+
} finally {
|
|
123
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async function example4_MultipleDirectoryOperations() {
|
|
128
|
+
console.log('Example 4: Multiple Directory Operations\n');
|
|
129
|
+
|
|
130
|
+
const baseDir = mkdtempSync(join(tmpdir(), 'multi-'));
|
|
131
|
+
const project1 = join(baseDir, 'project1');
|
|
132
|
+
const project2 = join(baseDir, 'project2');
|
|
133
|
+
const originalCwd = process.cwd();
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
// Create project directories
|
|
137
|
+
await $`mkdir -p ${project1} ${project2}`;
|
|
138
|
+
|
|
139
|
+
// Initialize project 1
|
|
140
|
+
console.log('Setting up project1:');
|
|
141
|
+
await $`cd ${project1} && git init && echo "Project 1" > README.md`;
|
|
142
|
+
await $`cd ${project1} && git add . && git config user.email "p1@test.com"`;
|
|
143
|
+
await $`cd ${project1} && git commit -m "Project 1 init" 2>/dev/null || echo "Commit created"`;
|
|
144
|
+
|
|
145
|
+
// Initialize project 2
|
|
146
|
+
console.log('\nSetting up project2:');
|
|
147
|
+
await $`cd ${project2} && git init && echo "Project 2" > README.md`;
|
|
148
|
+
await $`cd ${project2} && git add . && git config user.email "p2@test.com"`;
|
|
149
|
+
await $`cd ${project2} && git commit -m "Project 2 init" 2>/dev/null || echo "Commit created"`;
|
|
150
|
+
|
|
151
|
+
// Show both project states
|
|
152
|
+
console.log('\nProject 1 status:');
|
|
153
|
+
await $`cd ${project1} && git log --oneline`;
|
|
154
|
+
|
|
155
|
+
console.log('\nProject 2 status:');
|
|
156
|
+
await $`cd ${project2} && git log --oneline`;
|
|
157
|
+
|
|
158
|
+
// Demonstrate that cd doesn't affect parent shell
|
|
159
|
+
const pwdResult = await $`pwd`;
|
|
160
|
+
console.log(`\nCurrent directory (unchanged): ${pwdResult.stdout.trim()}`);
|
|
161
|
+
|
|
162
|
+
await $`cd ${originalCwd}`;
|
|
163
|
+
|
|
164
|
+
console.log('\n✓ Multiple directory operations completed\n');
|
|
165
|
+
} catch (error) {
|
|
166
|
+
console.error('Error:', error.message);
|
|
167
|
+
} finally {
|
|
168
|
+
rmSync(baseDir, { recursive: true, force: true });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Run all examples
|
|
173
|
+
async function runExamples() {
|
|
174
|
+
try {
|
|
175
|
+
await example1_CheckGHAuth();
|
|
176
|
+
await example2_SimulateRepoClone();
|
|
177
|
+
await example3_WorkflowWithTempDir();
|
|
178
|
+
await example4_MultipleDirectoryOperations();
|
|
179
|
+
|
|
180
|
+
console.log('=== All GitHub CLI Examples Completed ===');
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.error('Failed to run examples:', error);
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
runExamples();
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
|
|
5
|
+
console.log('=== Testing where gh auth status outputs go ===\n');
|
|
6
|
+
|
|
7
|
+
// Test 1: Capture stdout and stderr separately
|
|
8
|
+
console.log('Test 1: Capture stdout and stderr separately');
|
|
9
|
+
try {
|
|
10
|
+
const result = await $`gh auth status`.run({ capture: true, mirror: false });
|
|
11
|
+
console.log('Exit code:', result.code);
|
|
12
|
+
console.log(
|
|
13
|
+
'Stdout content:',
|
|
14
|
+
result.stdout ? `"${result.stdout.slice(0, 50)}..."` : '(empty)'
|
|
15
|
+
);
|
|
16
|
+
console.log('Stdout length:', result.stdout?.length || 0);
|
|
17
|
+
console.log(
|
|
18
|
+
'Stderr content:',
|
|
19
|
+
result.stderr ? `"${result.stderr.slice(0, 50)}..."` : '(empty)'
|
|
20
|
+
);
|
|
21
|
+
console.log('Stderr length:', result.stderr?.length || 0);
|
|
22
|
+
|
|
23
|
+
// Check where the actual output is
|
|
24
|
+
if (result.stdout && result.stdout.includes('Logged in')) {
|
|
25
|
+
console.log('✅ Output is in STDOUT');
|
|
26
|
+
} else if (result.stderr && result.stderr.includes('Logged in')) {
|
|
27
|
+
console.log('⚠️ Output is in STDERR (need 2>&1 redirection)');
|
|
28
|
+
} else {
|
|
29
|
+
console.log('❌ Output not found in either stdout or stderr');
|
|
30
|
+
}
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.log('Error:', error.message);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
console.log('\n---\n');
|
|
36
|
+
|
|
37
|
+
// Test 2: With 2>&1 redirection
|
|
38
|
+
console.log('Test 2: With 2>&1 redirection to capture all output');
|
|
39
|
+
try {
|
|
40
|
+
const result = await $`gh auth status 2>&1`.run({
|
|
41
|
+
capture: true,
|
|
42
|
+
mirror: false,
|
|
43
|
+
});
|
|
44
|
+
console.log('Exit code:', result.code);
|
|
45
|
+
console.log(
|
|
46
|
+
'Combined stdout content:',
|
|
47
|
+
result.stdout ? `"${result.stdout.slice(0, 50)}..."` : '(empty)'
|
|
48
|
+
);
|
|
49
|
+
console.log('Combined stdout length:', result.stdout?.length || 0);
|
|
50
|
+
console.log(
|
|
51
|
+
'Stderr after redirect:',
|
|
52
|
+
result.stderr ? `"${result.stderr.slice(0, 50)}..."` : '(empty)'
|
|
53
|
+
);
|
|
54
|
+
console.log('Stderr length:', result.stderr?.length || 0);
|
|
55
|
+
|
|
56
|
+
if (result.stdout && result.stdout.includes('Logged in')) {
|
|
57
|
+
console.log('✅ Output captured successfully with 2>&1');
|
|
58
|
+
}
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.log('Error:', error.message);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
console.log('\n---\n');
|
|
64
|
+
|
|
65
|
+
// Test 3: Test if we're authenticated
|
|
66
|
+
console.log('Test 3: Authentication check');
|
|
67
|
+
try {
|
|
68
|
+
// First try without redirection
|
|
69
|
+
const result1 = await $`gh auth status`.run({ capture: true, mirror: false });
|
|
70
|
+
const output1 = (result1.stdout || '') + (result1.stderr || '');
|
|
71
|
+
|
|
72
|
+
// Then try with redirection
|
|
73
|
+
const result2 = await $`gh auth status 2>&1`.run({
|
|
74
|
+
capture: true,
|
|
75
|
+
mirror: false,
|
|
76
|
+
});
|
|
77
|
+
const output2 = result2.stdout || '';
|
|
78
|
+
|
|
79
|
+
// Use whichever has content
|
|
80
|
+
const output = output1.length > output2.length ? output1 : output2;
|
|
81
|
+
|
|
82
|
+
if (output.includes('✓') && output.includes('Logged in to')) {
|
|
83
|
+
console.log('✅ Authenticated to GitHub');
|
|
84
|
+
const userMatch = output.match(/account\s+(\S+)/);
|
|
85
|
+
if (userMatch) {
|
|
86
|
+
console.log(' User:', userMatch[1]);
|
|
87
|
+
}
|
|
88
|
+
const scopeMatch = output.match(/Token scopes:\s*'([^']+)'/);
|
|
89
|
+
if (scopeMatch) {
|
|
90
|
+
console.log(' Scopes:', scopeMatch[1]);
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
console.log('❌ Not authenticated or unable to parse status');
|
|
94
|
+
}
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.log('Error checking auth:', error.message);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
console.log('\n=== Summary ===');
|
|
100
|
+
console.log('gh auth status outputs to STDOUT (not STDERR) when successful');
|
|
101
|
+
console.log('Use `.run({ capture: true })` to capture the output');
|
|
102
|
+
console.log('Exit code 0 = authenticated, 1 = not authenticated');
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { $ } from '../src/$.mjs';
|
|
4
|
+
import { promises as fs } from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import os from 'os';
|
|
7
|
+
|
|
8
|
+
console.log('=== Attempting to reproduce the hanging issue ===\n');
|
|
9
|
+
console.log('Using invalid --secret flag without timeout or error handling');
|
|
10
|
+
console.log('This should demonstrate the hanging behavior\n');
|
|
11
|
+
|
|
12
|
+
const tempFile = path.join(os.tmpdir(), 'hang-reproduce.md');
|
|
13
|
+
await fs.writeFile(tempFile, '# Test Gist\nTrying to reproduce hanging\n');
|
|
14
|
+
|
|
15
|
+
console.log('Starting command that should hang...');
|
|
16
|
+
console.log('If this hangs, press Ctrl+C to stop\n');
|
|
17
|
+
|
|
18
|
+
// This is the problematic combination:
|
|
19
|
+
// 1. Invalid --secret flag
|
|
20
|
+
// 2. No timeout
|
|
21
|
+
// 3. No 2>&1 redirect
|
|
22
|
+
// 4. capture: true, mirror: false
|
|
23
|
+
// 5. No error handling to catch the exit code
|
|
24
|
+
|
|
25
|
+
const startTime = Date.now();
|
|
26
|
+
|
|
27
|
+
const result =
|
|
28
|
+
await $`gh gist create ${tempFile} --desc "hang-test" --secret`.run({
|
|
29
|
+
capture: true,
|
|
30
|
+
mirror: false,
|
|
31
|
+
// No timeout - let it hang if it will
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// If we get here, it didn't hang
|
|
35
|
+
const duration = Date.now() - startTime;
|
|
36
|
+
console.log(`\nCompleted in ${duration}ms (did not hang)`);
|
|
37
|
+
console.log('Exit code:', result.code);
|
|
38
|
+
console.log('Stdout:', result.stdout);
|
|
39
|
+
console.log('Stderr:', result.stderr);
|
|
40
|
+
|
|
41
|
+
await fs.unlink(tempFile).catch(() => {});
|