Skip to content

fix: preserve complex Markdown in GitHub CLI bodies - #108

Merged
konard merged 7 commits into
mainfrom
issue-40-b1e760e6
Sep 14, 2026
Merged

konard merged 7 commits into
mainfrom
issue-40-b1e760e6

Conversation

@konard

@konard konard commented Sep 9, 2025

Copy link
Copy Markdown
Member

Closes #40.

Problem and reproduction

Interpolating a multiline Markdown value into gh issue create --body must send one exact argument even when the body contains fenced code, inline backticks, ${...} text, $HOME, command-substitution syntax, mixed quotes, operators, globs, backslashes, significant whitespace, or Unicode.

The original issue used author-written quotes around the interpolation:

await $`gh issue create --title "${title}" --body "${body}"`;

Running the new regression against the pre-context-aware implementation (360b71a) reproduced the bug: unquoted interpolation passed, while the double-quoted, single-quoted, and injection-safety cases failed with shell syntax errors. The same six cases pass on this branch.

Solution

  • Add an exact-argv regression that simulates the complete gh issue create invocation without creating a real issue.
  • Cover direct interpolation, author-written double and single quotes, injection-shaped Markdown, the existing legacy quote-context option, fenced code, multiline/trailing whitespace, Windows-style paths, and Unicode.
  • Run the regression in the Bun OS matrix and under every supported Node.js major in CI (20, 22, and 24).
  • Add the complex body to the audited JavaScript and Rust competitor-compatibility behaviors, covering both direct argv and safe shell interpolation.
  • Document the default direct --body ${body} form, context-aware --body "${body}", and GitHub CLI's native --body-file - stdin alternative.
  • Add a guarded real-world example and a reusable shell/Bun/zx/Execa comparison experiment.
  • Add JavaScript and Rust patch release fragments.

Behavior decision

The default follows the least-surprising shell contract: an interpolated value is data and arrives as one argument, like "$BODY" in sh. The recommended form is simply:

await $`gh issue create --repo ${repository} --title ${title} --body ${body}`;

No GitHub-specific escaping helper is needed. Author-written quotes remain supported by the existing context-aware quoting behavior. Users who intentionally opt into legacy COMMAND_STREAM_QUOTE_CONTEXT=0 behavior can continue to use the unquoted interpolation form. When a file or stdin is the natural source, gh --body-file remains available as a transport choice rather than a required workaround.

The live experiment matched sh "$BODY" for command-stream's automatic and author-quoted forms, Bun Shell, and zx. Execa is optional locally; its reviewed interpolation behavior remains represented by the repository's pinned competitor corpus. That corpus accounts for 12 JavaScript projects and 14 Rust projects at immutable revisions.

Verification

  • node --test js/tests/github-cli-body.test.mjs — 6 passed
  • bun test js/tests/ --timeout 10000 — 1,394 passed, 6 skipped, 0 failed
  • JavaScript lint, Prettier, duplication, and changeset validation — passed
  • cargo fmt --all -- --check — passed
  • cargo clippy --all-targets --all-features -- -D warnings — passed
  • cargo doc --no-deps --all-features — passed
  • cargo test --all-features --verbose and doc tests — passed
  • Rust changelog/version checks, release-script tests, and file-size checks — passed
  • Fresh merge simulation against main — passed

The GitHub CLI itself documents both --body string and --body-file file; --body-file - reads standard input.

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

Issue: #40
@konard konard self-assigned this Sep 9, 2025
konard and others added 2 commits September 9, 2025 20:48
Add comprehensive solution for safely passing complex markdown content with special characters to GitHub CLI commands.

## Changes

### Core Implementation
- Add `githubCli` helper object with methods for safe GitHub CLI operations
- Implement `createIssue()`, `createPullRequest()`, and `withBodyFile()` functions
- Use temporary file approach with `--body-file` parameter to avoid shell escaping issues
- Automatic cleanup of temporary files with proper error handling

### New Features
- Safe handling of backticks, variables (${var}), quotes, and special characters
- Support for all GitHub CLI options (assignee, labels, milestone, etc.)
- Production-ready error handling and file cleanup
- Memory-efficient temporary file management

### Testing & Examples
- Comprehensive test suite covering edge cases and error scenarios
- Demonstration script showing the problem and solution
- Documentation with usage examples for CI/CD workflows

### Version Bump
- Update package.json from 0.7.1 to 0.7.2

## Solves
- Issue #40: GitHub CLI with complex markdown body fails due to shell escaping
- Provides production-ready alternative to direct `--body` parameter usage
- Maintains compatibility with all existing functionality

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

Co-Authored-By: Claude <noreply@anthropic.com>
@konard
konard marked this pull request as ready for review September 9, 2025 17:57
@konard

konard commented Sep 14, 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 14, 2026 21:05
@konard

konard commented Sep 14, 2026

Copy link
Copy Markdown
Member Author

🤖 AI Work Session Started

Starting automated work session at 2026-09-14T21:05:29.924Z

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/github-cli-complex-body-solution.mjs
#	js/examples/test-gh-cli-body-issue.mjs
#	js/tests/github-cli-body.test.mjs
#	package.json
#	src/$.mjs
@konard konard changed the title [WIP] GitHub CLI with complex markdown body fix: preserve complex Markdown in GitHub CLI bodies Sep 14, 2026
@konard
konard marked this pull request as ready for review September 14, 2026 21:41
@konard

konard commented Sep 14, 2026

Copy link
Copy Markdown
Member Author

Working session summary

Implemented and finalized PR #108.

  • Added exact GitHub CLI Markdown-body regression coverage.
  • Covered quotes, code fences, shell syntax, whitespace, backslashes, Unicode, and injection safety.
  • Extended JavaScript and Rust competitor corpora.
  • Added documentation, example, experiment, and release fragments.
  • Resolved conflicts with main.
  • All CI workflows pass across Node 20/22/24, Bun, Rust, Windows, macOS, and Linux.
  • Working tree is clean; PR is mergeable and ready for review.

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

@konard

konard commented Sep 14, 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: $15.524431

📊 Context and tokens usage:

  • 413.2K / 200K (207%) input tokens, 53.6K / 128K (42%) output tokens

Total: (413.2K + 13.3M cached) input tokens, 53.6K output tokens, $15.524431 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 (5512KB)


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

@konard
konard merged commit d6242e1 into main Sep 14, 2026
36 checks passed
@konard

konard commented Sep 14, 2026

Copy link
Copy Markdown
Member Author

🎉 Auto-merged

This pull request has been automatically merged by hive-mind.

  • All CI checks have passed

Auto-merged by hive-mind with --auto-merge flag

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.

GitHub CLI with complex markdown body

1 participant