Skip to content

feat!: print markdown to stdout by default, add --comment flag#9

Merged
fank merged 1 commit into
mainfrom
claude/markdown-by-default
Apr 10, 2026
Merged

feat!: print markdown to stdout by default, add --comment flag#9
fank merged 1 commit into
mainfrom
claude/markdown-by-default

Conversation

@fank
Copy link
Copy Markdown
Member

@fank fank commented Apr 10, 2026

Summary

Phase 3 of the gh-attach roadmap: invert the default output behavior. gh attach <N> FILE... no longer posts a PR/issue comment by default — it uploads the files and writes the rendered markdown to stdout, making the tool composable with shell pipelines, PR body edits, clipboards, and any other caller. The pre-v0.3.0 comment-posting behavior is still available via --comment.

Why

The tool was always two independent things welded together: an upload step and a comment-posting step. GitDataClient and CommentClient have been separate since v0.1. Until now, the caller had no way to get the markdown out without also posting a comment — which meant embedding uploads in a PR body, a Slack message, an issue template, or anywhere else required either parsing the Done: URL back out or not using the tool at all.

After this change, the caller owns the output. gh attach produces markdown; what you do with it is your call.

Output contract

Invocation stdout stderr Side-effects
gh attach 123 file.png rendered markdown (bare, no marker, no heading) Uploading... + Uploaded: block with one URL per file upload only
gh attach --comment 123 file.png rendered markdown (same as above) Uploading... + Uploaded: + Commented: <url> upload + upsert comment
  • stdout is always the bare formatSection output (trimmed, no <!-- gh-attach --> marker, no ### Attachments heading). Callers add their own structure if they want.
  • stderr carries the actionable references — one directly-embeddable blob/<sha>/<file>?raw=true URL per uploaded file, so interactive users see copy-pasteable links even when stdout is piped.
  • --comment is additive, not modal: it adds a comment-post side-effect without changing what goes to stdout. gh attach --comment 123 file.png | tee backup.md works exactly as you'd expect.

Migration

# Before (v0.2.x)
gh attach 123 file.png                  # uploaded + commented

# After (v0.3.0)
gh attach 123 file.png                  # uploads + prints markdown to stdout
gh attach --comment 123 file.png        # uploads + comments (old behavior)

New use cases unlocked

# Embed uploads directly in a PR body
MARKDOWN=$(gh attach 123 dist/report.png)
gh pr edit 123 --body "Build passed.

$MARKDOWN"

# Copy to clipboard (Wayland / X11 / macOS)
gh attach 123 screenshot.png | wl-copy
gh attach 123 screenshot.png | pbcopy

# Pipe into gh-cli's own commenter instead of the upsert logic
gh attach 123 file.png | gh pr comment 123 --body-file -

# Save to a file for later
gh attach 123 file.png > upload.md

Scope of changes

  • main.go — adds --comment flag, threads it through run(), replaces the unconditional comment post with: always emit markdown to stdout, always emit URL list to stderr, optional comment post guarded by the flag.
  • README.md — rewrites the Usage section with the new default, adds a "Composing with other tools" subsection, updates the intro and How-it-works list.
  • comment.go — unchanged. The upsert logic works exactly the same; it's just called conditionally now.

~20 logical lines changed in main.go. The architectural separation was already in place — this PR just turns the comment step into an opt-in branch.

Verification

Smoke-tested end-to-end against a throwaway issue (enthus-appdev/gh-attach#8, closed after test).

Default path (no --comment):

$ ./gh-attach 8 banner.png
--- stdout ---
| banner.png |
|---|
| ![banner.png](https://github.com/enthus-appdev/gh-attach/blob/516099d.../banner.png?raw=true) |
--- stderr ---
Uploading 1 file(s) to #8 in enthus-appdev/gh-attach...
Uploaded:
  https://github.com/enthus-appdev/gh-attach/blob/516099d.../banner.png?raw=true

Comments on #8 after this run: 0.

With --comment:

$ ./gh-attach --comment --title "With comment flag" 8 banner.png
--- stdout ---
**With comment flag**

| banner.png |
|---|
| ![banner.png](https://github.com/.../blob/d88aeca.../banner.png?raw=true) |
--- stderr ---
Uploading 1 file(s) to #8 in enthus-appdev/gh-attach...
Uploaded:
  https://github.com/.../blob/d88aeca.../banner.png?raw=true
Commented: https://github.com/enthus-appdev/gh-attach/issues/8#issuecomment-4225794424

Comments on #8 after this run: 1 (body starts with <!-- gh-attach -->\n### Attachments\n\n**With comment flag**\n...).

go build ./... and go vet ./... both clean.

Test plan

  • Review the new stdout/stderr contract — any concerns about the bare (no-heading) stdout format?
  • Review help text — is --comment discoverable enough?
  • Confirm v0.3.0 as the right release tag for this breaking change

BREAKING CHANGE: `gh attach <N> FILE...` no longer posts a PR/issue
comment by default. The rendered markdown is written to stdout instead,
making the tool composable with shell pipelines, PR body edits, and
clipboards. Pass `--comment` for the pre-v0.3.0 upsert behavior.

Output contract after this change:
- stdout: always the bare rendered markdown (trimmed formatSection)
- stderr: progress line + one directly-embeddable URL per file
- with --comment: add a `Commented: <url>` line on stderr

Migration:
- Before (v0.2.x): gh attach 123 file.png            (uploads + comments)
- After  (v0.3.0): gh attach 123 file.png            (uploads + prints md)
                   gh attach --comment 123 file.png  (old behavior)

The architectural separation was already clean in the code —
GitDataClient and CommentClient have always been independent. This
commit makes the comment post opt-in instead of unconditional.

Smoke-tested end-to-end against #8: default
path prints markdown with no comment; --comment path posts the
comment and writes the same markdown to stdout.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request changes the default behavior of gh attach to print rendered markdown to stdout instead of automatically posting a PR comment. A new --comment flag is introduced to opt-in to the previous behavior of upserting a comment. Additionally, raw URLs are now printed to stderr for better visibility when stdout is piped. The README has been updated with new usage examples and an explanation of the revised workflow. I have no feedback to provide.

@fank fank merged commit 0adbc7c into main Apr 10, 2026
@fank fank deleted the claude/markdown-by-default branch April 10, 2026 19:25
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.

1 participant