Skip to content

Carry the reply prefill's subject onto every reply - #370

Merged
jeremy merged 6 commits into
mainfrom
fix/reply-subject
Sep 1, 2026
Merged

Carry the reply prefill's subject onto every reply#370
jeremy merged 6 commits into
mainfrom
fix/reply-subject

Conversation

@jeremy

@jeremy jeremy commented Aug 31, 2026

Copy link
Copy Markdown
Member

hey reply read the reply prefill (GET /entries/{id}/replies/new.json) but kept only the recipients — and the SDK's ReplyMessagePayload had nowhere to put a subject anyway. HEY never derives a reply's subject server-side, so every reply draft saved as "No subject" in HEY's Drafts. This is the subject leg (part 1 of 3) of #341.

Built on basecamp/hey-sdk#134 (merged), which models subject on ReplyMessagePayload and takes it in CreateReply/CreateReplyDraft. go.mod pins the merge commit's pseudo-version (v0.28.2-0.20260831223614-ed5cf6fadf55); the pin flips to the release tag when one is cut. The vendored MCP model snapshot and its provenance are synced to the same commit, per TestCatalogModelProvenance.

Change

  • resolveThreadReply keeps the prefill's "Re: …" subject on the target (replyPrefillFromServer, formerly replyRecipientsFromServer). The local fallback derives one from the entry's subject the way HEY does in Entry::Replyable#reply_subject — a "Re: " prefix without doubling one already there, in any casing.
  • hey reply and hey compose --thread-id send it on both the draft and delivery paths.
  • The TUI reply form carries it invisibly — the form still shows no subject field, matching HEY's own reply composer.
  • Reply content is untouched: the server appends the quoted original at delivery (auto_quoting defaults on), so the prefill's quoted body still must not be echoed back — sending it would double-quote.

Tests

  • resolveThreadReply asserts the subject on the target from both the prefill and the fallback; the reply-draft test asserts the wire carries message[subject] (the bug's exact symptom); replySubject derivation table incl. Re: normalization.
  • TUI: reply context load asserts the derived subject; the reply-form send asserts it on the wire.
  • make check green.

Basecamp: A reply can't carry a subject — every reply draft saves as "No subject"


Summary by cubic

Carries the reply prefill's "Re: …" subject onto every reply — hey reply, hey compose --thread-id, and the TUI reply form — so reply drafts no longer save as "No subject" in HEY's Drafts (part 1 of 3 for #341). The TUI reply form now also reads its recipients from the prefill, like the CLI already did, and the subject survives even when the prefill answers no recipients.

  • The prefill's subject survives even when it answers no recipients (a thread with yourself); only the recipients fall back to the local computation, in both the CLI and the TUI.
  • Bumps github.com/basecamp/hey-sdk/go to a pseudo-version on merged mainline, syncing the vendored MCP model snapshot; flips to the release tag once one is cut.
  • The local fallback derives the subject from the entry's subject the way HEY does, and the TUI form still shows no subject field.
  • Reply content is untouched — the server appends the quoted original at delivery.

Written for commit 3b0e8a9. Summary will update on new commits.

Review in cubic

@jeremy
jeremy requested a review from a team as a code owner August 31, 2026 22:20
Copilot AI balanced review requested due to automatic review settings August 31, 2026 22:20
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-01T01:05:58.711153Z 3b0e8a9 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Carries reply subjects through CLI and TUI reply paths, preventing drafts from appearing as “No subject.”

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Changes:

  • Preserves server-prefilled subjects with local fallback derivation.
  • Sends subjects for replies and reply drafts across CLI and TUI.
  • Updates the SDK dependency, MCP model snapshot, and tests.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated no comments.

Show a summary per file
File Description
go.mod Pins the subject-capable SDK revision.
go.sum Updates SDK checksums.
nix/package.nix Updates the vendored dependency hash.
internal/cmd/thread_reply.go Resolves and derives reply subjects.
internal/cmd/thread_reply_test.go Tests prefilled, derived, and transmitted subjects.
internal/cmd/reply.go Sends subjects through reply operations.
internal/cmd/compose.go Sends subjects for thread replies.
internal/tui/compose.go Carries hidden reply subjects through TUI forms.
internal/tui/compose_test.go Verifies TUI subject loading and transmission.
internal/mcpserver/model/openapi.json Adds reply subjects to the vendored API model.
internal/mcpserver/model/PROVENANCE.json Records the corresponding SDK revision.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated no new comments.

@jeremy

jeremy commented Aug 31, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2c5fa27fc2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/tui/compose.go Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5dca3e7062

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/cmd/thread_reply.go Outdated
@jeremy

jeremy commented Aug 31, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1a6ea8eba3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/cmd/thread_reply.go
Comment thread internal/tui/compose.go
Comment thread internal/mcpserver/model/openapi.json
@github-actions github-actions Bot added the docs label Aug 31, 2026
@jeremy

jeremy commented Aug 31, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

Reviewed commit: 4c7d65d1bb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

jeremy added 6 commits August 31, 2026 18:03
hey reply read the prefill from GET /entries/{id}/replies/new.json but
kept only the recipients, and the SDK's ReplyMessagePayload had nowhere
to put a subject anyway — so every reply draft saved as "No subject" in
HEY's Drafts (hey-cli#341, part 1 of 3). HEY never derives a reply's
subject server-side.

Bump hey-sdk to the release that models subject on ReplyMessagePayload,
and pass it through everywhere a reply goes out:

- resolveThreadReply keeps the prefill's "Re: …" subject on the target,
  and the local fallback derives one from the entry's subject the way
  HEY does in Entry::Replyable#reply_subject — a "Re: " prefix without
  doubling one already there.
- hey reply and hey compose --thread-id send it on both the draft and
  the delivery paths.
- The TUI reply form carries it invisibly: the form still shows no
  subject field, matching HEY's own reply composer.

Reply content is untouched: the server appends the quoted original at
delivery via auto_quoting, so the prefill's quoted body still must not
be echoed back.
The reply-subject branch moved (README example and an apidiff
acknowledgment), so the pseudo-version, the vendored model provenance,
and the vendorHash all follow.
hey-sdk#134 landed, so the pin moves from the branch pseudo-version to
the merge commit's; provenance and vendorHash follow. Flips to the
release tag when one is cut.
The TUI synthesized a reply's subject and recipients locally from the
entry, so it never saw what only HEY knows: the acting user's own
addresses, aliases and catch-alls to leave off the recipient lines, and
the prefilled "Re: …" subject itself. Ask the reply prefill first and
keep the local computation as the fallback for a failed read or the
empty answer a thread with yourself produces — the same contract
resolveThreadReply already holds.
A recipientless prefill — a thread with yourself — still carries the
subject HEY computed, and both reply paths were discarding it to
re-derive one from the message, whose subject is optional and can be
absent. Only the recipients needed the local computation; the subject
survives the fallback, in resolveThreadReply and the TUI's reply
context alike.
The recipients bullet still described the local-only computation and an
SDK without NewReply; both reply paths now start from HEY's prefill with
the local computation as fallback.
@jeremy
jeremy merged commit e7ff200 into main Sep 1, 2026
33 checks passed
@jeremy
jeremy deleted the fix/reply-subject branch September 1, 2026 01:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants