Skip to content

fix: preserve stderr-only CLI output semantics (#47) - #102

Merged
konard merged 7 commits into
mainfrom
issue-47-b31e0547
Sep 15, 2026
Merged

konard merged 7 commits into
mainfrom
issue-47-b31e0547

Conversation

@konard

@konard konard commented Sep 9, 2025

Copy link
Copy Markdown
Member

Summary

  • Preserve successful stderr-only command output as stderr in both JavaScript and Rust.
  • Extend the shared competitor behavior port and the focused /bin/sh parity suites with stdout-only, stderr-only PR URL, mixed-stream, and explicit 2>&1 cases.
  • Document how to inspect both streams or opt into normal shell merging, with patch release metadata for both packages.

Resolves #47.

Root cause and selected behavior

The issue reported an empty stdout when a gh pr create version wrote its success URL to file descriptor 2. An empty stdout is expected in that case: shells and process libraries preserve the child-selected descriptor, and command-stream exposes the URL through result.stderr.

There was also a historical virtual-command bug: a command such as echo URL >&2 could treat >&2 as literal data instead of shell syntax. The cross-language real-shell routing fix landed on main in #103; this branch now includes that fix and adds the missing stderr assertions that prevent a regression.

The least-surprising default remains shell-compatible separation:

Command behavior result.stdout result.stderr
child writes URL to stderr empty URL
command appends 2>&1 URL empty

No new library setting is needed: standard 2>&1 is the opt-in configuration for callers that want one combined stream, while the default retains information instead of silently relabelling it.

Reproduction and coverage

On the historical 0.7.1 implementation, the minimal shell simulation produced the wrong result:

command: echo https://github.com/octo/example/pull/123 >&2
stdout: "https://github.com/octo/example/pull/123 >&2\n"
stderr: ""

The same case now matches /bin/sh: stdout is empty and stderr contains the URL. An explicit 2>&1 case verifies the inverse capture.

The stdout-stderr-separation behavior port is shared by every selected competitor source in the audited corpora: 12 JavaScript/runtime sources and 14 Rust process libraries/runtime primitives. The focused parity suites also compare exit code, filesystem effects, stdout, and stderr directly with /bin/sh in both implementations.

Verification

  • bun test js/tests/ --timeout 10000 — 1,407 passed, 6 skipped, 0 failed
  • cargo test --manifest-path rust/Cargo.toml --all-features --verbose — passed, including doctests
  • bun run check — ESLint, formatting, and duplication gates passed
  • cargo fmt --all -- --check, Clippy with warnings denied, and rustdoc with warnings denied — passed
  • JavaScript changeset, Rust changelog/version, and language-parity validators — passed
  • Rust release-script tests, release build, package verification, file-size check, and crate-size check — passed
  • Node.js 24 ESM/CommonJS and compatibility tests — passed locally; CI covers all supported Node versions and operating systems
  • 24-case redirection experiment — 0 divergences from /bin/sh

This is not a UI change, so screenshots are not applicable.

Adding CLAUDE.md with task information for AI processing.
This file will be removed when the task is complete.

Issue: #47
@konard konard self-assigned this Sep 9, 2025
konard and others added 2 commits September 9, 2025 19:55
- Add needsRealShell() check to virtual command bypass logic
- Ensure commands with stderr redirection (>&2, 2>&1) use real shell
- Add comprehensive test suite for stderr redirection scenarios
- Fixes issue where gh pr create output wasn't captured properly
- Update version to 0.7.2

This resolves GitHub issue #47 where gh pr create output was not
properly captured because the virtual echo command was being used
instead of falling back to the real shell for stderr redirection.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@konard konard changed the title [WIP] gh pr create output not captured by command-stream Fix stderr redirection handling for gh pr create and similar commands Sep 9, 2025
@konard
konard marked this pull request as ready for review September 9, 2025 17:05
@konard

konard commented Sep 15, 2026

Copy link
Copy Markdown
Member Author

We should double check more cases similar like this, make sure we have test coverage similar to all our competitors, and select behavior closer to how it would behave in sh scripts or with least surprise based on best practices from competitors. If there multiple options we should allow to configure, and use closer to sh behavior by default.

We also must support all our supported language versions.

@konard
konard marked this pull request as draft September 15, 2026 12:27
@konard

konard commented Sep 15, 2026

Copy link
Copy Markdown
Member Author

🤖 AI Work Session Started

Starting automated work session at 2026-09-15T12:27:15.278Z

The PR has been converted to draft mode while work is in progress.

This comment marks the beginning of an AI work session. Please wait for the session to finish, and provide your feedback.

Runtime: solve v2.29.0 · tool codex · model gpt-5.6-sol · task image konard/hive-mind-dind:2.29.0@sha256:11a236d03854cbaea86fdd7ca06265c912cf0b67d1fcc9b3eb60bd84c43ff749

# Conflicts:
#	js/examples/comprehensive-stderr-test.mjs
#	js/examples/debug-2to1.mjs
#	js/examples/debug-stderr-redirection.mjs
#	js/examples/simple-stderr-test.mjs
#	js/examples/test-gh-pr-create-fix.mjs
#	js/examples/test-gh-pr-create-issue.mjs
#	js/tests/stderr-redirection.test.mjs
#	package.json
#	src/$.mjs
#	src/shell-parser.mjs
@konard konard changed the title Fix stderr redirection handling for gh pr create and similar commands fix: preserve stderr-only CLI output semantics (#47) Sep 15, 2026
@konard
konard marked this pull request as ready for review September 15, 2026 13:01
@konard

konard commented Sep 15, 2026

Copy link
Copy Markdown
Member Author

Working session summary

Implemented and finalized PR #102.

  • Added JavaScript and Rust regression coverage for stderr-only URLs, mixed streams, and 2>&1.
  • Verified parity with /bin/sh and all tracked competitor corpora.
  • Documented stderr capture and stream-merging behavior.
  • Added patch release metadata.
  • Merged current main and resolved conflicts.
  • Local suites passed: 1,407 JS tests, full Rust tests/doctests, lint, formatting, packaging, and security checks.
  • All five fresh CI workflows pass at a63c292.
  • PR is clean, mergeable, and ready for review.

This summary was automatically extracted from the AI working session output.

@konard

konard commented Sep 15, 2026

Copy link
Copy Markdown
Member Author

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost estimation:

  • Model: GPT-5.6 Sol
  • Provider: OpenAI
  • Public pricing estimate: $10.362001

📊 Context and tokens usage:

  • 284.6K / 200K (142%) input tokens, 39.5K / 128K (31%) output tokens

Total: (284.6K + 8.6M cached) input tokens, 39.5K output tokens, $10.362001 cost

🤖 Models used:

  • Tool: OpenAI Codex
  • Requested: gpt-5.6-sol
  • Thinking level: xhigh (~31999 tokens)
  • Model: GPT-5.6 Sol (gpt-5.6-sol)

📎 Log file uploaded as Gist (4552KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard

konard commented Sep 15, 2026

Copy link
Copy Markdown
Member Author

✅ Ready to merge

This pull request is now ready to be merged:

  • All CI checks have passed
  • No merge conflicts
  • No pending changes

Monitored by hive-mind with --auto-restart-until-mergeable flag

@konard
konard merged commit 4079669 into main Sep 15, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gh pr create output not captured by command-stream

1 participant