Skip to content

fix: quote replies as ADF instead of round-tripping through text - #72

Merged
Hinne1 merged 9 commits into
mainfrom
claude/reply-to-adf-quoting
Aug 6, 2026
Merged

fix: quote replies as ADF instead of round-tripping through text#72
Hinne1 merged 9 commits into
mainfrom
claude/reply-to-adf-quoting

Conversation

@Hinne1

@Hinne1 Hinne1 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Problem

atl jira issue comment add --reply-to built its quote by calling api.ADFToText on the original comment and re-parsing the result as Markdown. ADFToText is a display function that deliberately degrades mention nodes to @Name text and media nodes to [Image: alt] text, so every reply to a comment containing an attachment republished a corrupted copy of it.

Observed in production: the posted comment's ADF contained 0 media nodes and a literal text node reading [Image: image-20260805-135958.png]; the author's => came back as =❭.

Fix

Assemble the reply as ADF directly — attribution paragraph, then a blockquote holding the original's nodes, then the user's body.

  • Legal children pass through verbatim. blockquote accepts exactly paragraph, bulletList, orderedList, codeBlock, mediaGroup, mediaSingle; those are copied untouched, which is what preserves media and mentions.
  • Illegal nodes hoist their legal descendants rather than flattening whole, so an image inside a panel survives. Only a subtree with nothing legal in it degrades to text.
  • Inline content stays together. A containsLegal gate stops the recursion descending into inline-content nodes, which would otherwise split a heading's runs into separate paragraphs.
  • Node attributes round-trip verbatim. ADFContent/ADFMark capture their raw attrs JSON and re-emit it unchanged. Without this the reply is rejected outright: real media nodes carry "collection": "" — empty but mandatory — and the typed ADFAttrs struct dropped it via omitempty, along with localId and widthType.
  • CommentOptions gains BodyADF *ADF for posting a pre-built document, honoured by both AddCommentWithOptions and UpdateComment. No existing caller sets it.

Verification

Unit tests cover pass-through of all six legal child types, mention and inline-mark preservation, node-level mark stripping, hoisting out of illegal containers, inline-run integrity, the empty-document case, and attribute round-trip using a media node copied verbatim from a real production comment.

Verified end-to-end against the sandbox by reading the posted comment's raw ADF back from the REST API: the reply posts, the quoted media node keeps collection: "", and the heading does not fragment. Asserting through atl comment list would prove nothing — it renders a live mention and plain text identically, and prints [Image: …] for both a real media node and a dead placeholder, so it passes on the broken code.

Side benefit: issue edit --description --append also stops dropping collection/localId on fetched media.

Known limitations (ticketed, not fixed here)

Found while building test fixtures, unrelated to this branch: #69, #70.

@Hinne1

Hinne1 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

/gemini review

@Hinne1
Hinne1 marked this pull request as ready for review August 6, 2026 08:15
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Merging this branch will increase overall coverage

Impacted Packages Coverage Δ 🤖
github.com/enthus-appdev/atl-cli/internal/api 38.46% (+2.76%) 👍
github.com/enthus-appdev/atl-cli/internal/cmd/issue/comment 26.82% (+0.73%) 👍

Coverage by file

Changed files (no unit tests)

Changed File Coverage Δ Total Covered Missed 🤖
github.com/enthus-appdev/atl-cli/internal/api/adf_quote.go 96.00% (+96.00%) 25 (+25) 24 (+24) 1 (+1) 🌟
github.com/enthus-appdev/atl-cli/internal/api/jira.go 25.82% (+6.76%) 546 (+53) 141 (+47) 405 (+6) 👍
github.com/enthus-appdev/atl-cli/internal/api/mention_resolve.go 87.50% (+1.14%) 24 (+2) 21 (+2) 3 👍
github.com/enthus-appdev/atl-cli/internal/cmd/issue/comment/add.go 35.38% (+2.53%) 65 (-5) 23 42 (-5) 👍

Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code.

Changed unit test files

  • github.com/enthus-appdev/atl-cli/internal/api/adf_quote_test.go
  • github.com/enthus-appdev/atl-cli/internal/api/adf_rawattrs_test.go
  • github.com/enthus-appdev/atl-cli/internal/api/jira_comment_body_test.go
  • github.com/enthus-appdev/atl-cli/internal/api/mention_resolve_rawattrs_test.go

@Hinne1
Hinne1 merged commit d9646ae into main Aug 6, 2026
15 checks passed
@Hinne1
Hinne1 deleted the claude/reply-to-adf-quoting branch August 6, 2026 08:53
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