Skip to content

Add hey thread comment for private thread notes - #383

Open
jeissonneira wants to merge 3 commits into
basecamp:mainfrom
jeissonneira:thread-comment
Open

Add hey thread comment for private thread notes#383
jeissonneira wants to merge 3 commits into
basecamp:mainfrom
jeissonneira:thread-comment

Conversation

@jeissonneira

@jeissonneira jeissonneira commented Sep 1, 2026

Copy link
Copy Markdown

The gap

hey reply mails a reply. There is no CLI for the other thing a thread holds: a private internal note. Those notes show up as kind: "comment" in hey thread read, but you could only add them in the web app.

The comments write is not in hey-sdk OpenAPI. Empty or wrong form fields can create a blank comment, so this has to post a specific field.

The change

hey thread comment <thread-id> -m "..." posts a private internal note, not a mailed reply.

  • POST /topics/{topic_id}/comments?account_id={account_id} via Client.PostForm (same redirect-capturing form path as collections, snippets, and publications)
  • Body: comment[content]=<plain text> — sent exactly as typed, not converted from Markdown
  • Success is 302 Location: /imbox; the redirect is not followed
  • Account ID comes from Topics().Get so All Accounts still posts against the thread's mail account
  • After a successful post, hey thread read shows the note as kind: "comment"

--message/-m is required and cannot be blank.

Tests

internal/cmd/thread_comment_test.go checks the POST path and query, form field, Accept: */*, Content-Type: application/x-www-form-urlencoded, that Markdown-looking text is sent verbatim, that missing/empty -m and a bad thread ID make no request, and that /imbox is not followed.

TMPDIR=/tmp/t GOWORK=off make check is green. (Without the short TMPDIR, three pre-existing TUI unix-socket tests fail to bind on this machine; they are unrelated to this change.)


Summary by cubic

Adds hey thread comment <thread-id> -m "..." so private internal thread notes can be posted from the CLI. Previously these notes could be read via hey thread read but only created in the web app.

New Features

  • Posts to /topics/{id}/comments through PostForm since the comments write is not in the SDK OpenAPI.
  • Sends the message exactly as typed rather than converting Markdown, unlike other -m flags.
  • Requires non-blank -m; treats the 302 to /imbox as success and does not follow it.

Written for commit d88a059. Summary will update on new commits.

Review in cubic

Copilot AI balanced review requested due to automatic review settings September 1, 2026 19:28
@jeissonneira
jeissonneira requested a review from a team as a code owner September 1, 2026 19:28

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

Adds hey thread comment for private, non-mailed thread notes.

Changes:

  • Adds and registers the comment command.
  • Posts account-scoped plain-text notes through the SDK.
  • Adds tests and updates documentation/snapshots.

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.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
internal/cmd/thread_comment.go Implements the command.
internal/cmd/thread_comment_test.go Tests requests, validation, and output.
internal/cmd/topic.go Registers the subcommand.
README.md Documents user-facing usage.
skills/hey/SKILL.md Adds agent guidance.
API-COVERAGE.md Records endpoint coverage.
.surface Updates the CLI surface snapshot.

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

Comment thread internal/cmd/thread_comment.go Outdated
Comment on lines +66 to +68
if _, err := rootSDK.PostForm(cmd.Context(), path, values); err != nil {
return apierr.FromSDK(err)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Not changing this yet, because it is the open question on this PR rather than a detail of it. What HEY answers a comment post with — a redirect to /imbox, a redirect to the thread, a 200 — is the endpoint's contract, and pinning Location: /imbox from the outside would make the command fail on a harmless change to HEY's own UI routing. The SDK already surfaces 4xx/5xx as errors, so a 2xx or a redirect is HEY accepting the form. Whether this command should post the form at all, or wait for a JSON endpoint and an SDK operation, is the decision this PR is parked on (see the API-COVERAGE thread); the success check will be shaped by that answer.

Comment thread internal/cmd/topic.go Outdated

@cubic-dev-ai cubic-dev-ai Bot 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.

1 issue found across 7 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="API-COVERAGE.md">

<violation number="1" location="API-COVERAGE.md:74">
P2: The new `/topics/{id}/comments` row posts through `Client.PostForm`, but both this file's header ("API interactions use the HEY SDK") and AGENTS.md ("All API interactions must go through the HEY SDK... add it to the SDK") require SDK-typed operations, and this is the only `PostForm` call in the repo. The cited precedent (Collections, Publications) is the opposite: those form endpoints were added to the SDK as `Collections().Create`/`Publications().Create`. Add a `Comments().Create` operation to hey-sdk/go instead of working around it, matching the repo's rule that missing operations go into the SDK (require operator sign-off) rather than here.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread internal/cmd/thread_comment.go Outdated
Comment thread API-COVERAGE.md
| `/entries/{id}/replies` | POST | SDK `Entries().CreateReply`, `Entries().CreateReplyDraft` | `hey reply <topic-id>`, `hey reply --draft`, `hey compose --thread-id [--draft]` | covered |
| `/topics/{id}.json` | GET | SDK `Topics().Get` | `hey forward <topic-id>`, `hey reply <topic-id>`, TUI `r` | covered |
| `/topics/{id}.json` | GET | SDK `Topics().Get` | `hey forward <topic-id>`, `hey reply <topic-id>`, `hey thread comment <topic-id>`, TUI `r` | covered |
| `/topics/{id}/comments` | POST | `Client.PostForm` (not generated — no OpenAPI operation) | `hey thread comment <topic-id>` | covered |

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.

P2: The new /topics/{id}/comments row posts through Client.PostForm, but both this file's header ("API interactions use the HEY SDK") and AGENTS.md ("All API interactions must go through the HEY SDK... add it to the SDK") require SDK-typed operations, and this is the only PostForm call in the repo. The cited precedent (Collections, Publications) is the opposite: those form endpoints were added to the SDK as Collections().Create/Publications().Create. Add a Comments().Create operation to hey-sdk/go instead of working around it, matching the repo's rule that missing operations go into the SDK (require operator sign-off) rather than here.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At API-COVERAGE.md, line 74:

<comment>The new `/topics/{id}/comments` row posts through `Client.PostForm`, but both this file's header ("API interactions use the HEY SDK") and AGENTS.md ("All API interactions must go through the HEY SDK... add it to the SDK") require SDK-typed operations, and this is the only `PostForm` call in the repo. The cited precedent (Collections, Publications) is the opposite: those form endpoints were added to the SDK as `Collections().Create`/`Publications().Create`. Add a `Comments().Create` operation to hey-sdk/go instead of working around it, matching the repo's rule that missing operations go into the SDK (require operator sign-off) rather than here.</comment>

<file context>
@@ -70,7 +70,8 @@ which is what `Entries().ListDraftsPage` and `hey draft list --page` exist for.
 | `/entries/{id}/replies` | POST | SDK `Entries().CreateReply`, `Entries().CreateReplyDraft` | `hey reply <topic-id>`, `hey reply --draft`, `hey compose --thread-id [--draft]` | covered |
-| `/topics/{id}.json` | GET | SDK `Topics().Get` | `hey forward <topic-id>`, `hey reply <topic-id>`, TUI `r` | covered |
+| `/topics/{id}.json` | GET | SDK `Topics().Get` | `hey forward <topic-id>`, `hey reply <topic-id>`, `hey thread comment <topic-id>`, TUI `r` | covered |
+| `/topics/{id}/comments` | POST | `Client.PostForm` (not generated — no OpenAPI operation) | `hey thread comment <topic-id>` | covered |
 | `/entries/{id}/forwards/new.json` | GET | SDK `Entries().NewForward` | `hey forward <topic-id>` | covered |
 | `/bulk_replies/new.json` | GET | SDK `BulkReplies().Draft` | `hey bulk-reply preview`, `hey bulk-reply send`, TUI `ctrl+b` | covered |
</file context>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is the right reading of the rule, and it is the decision this PR is waiting on: /topics/{id}/comments has no JSON endpoint in HEY today, so a typed Comments().Create in hey-sdk/go would be wrapping the same HTML form post the CLI does here. Whether to accept a form-built operation for thread comments (in the SDK, then here) or wait for HEY to expose comments as JSON first is an operator/API call that is pending alongside the same question for stage threads. Until it lands I have rebased the branch onto main and kept it green rather than moving the call between repos.

Comment thread skills/hey/SKILL.md
Comment thread internal/cmd/topic.go
jeissonneira and others added 3 commits September 10, 2026 14:31
Posts an internal note via PostForm to /topics/{id}/comments, not a mailed reply.
…e Markdown exception

Trimming only decides whether -m is blank; the text itself goes to HEY untouched, as the
command documents. The parent command's listing now says it writes as well as reads, and
the skill's Markdown-by-default sentence names thread comment as the one exception.
@jeremy

jeremy commented Sep 10, 2026

Copy link
Copy Markdown
Member

Rebased onto main at d88a059 (the README additions moved to docs/cli.md, where the manual now lives) and make check is green. Of the seven review threads, four are fixed on the branch (message sent as typed, the parent command's Short, the skill's Markdown exception) and the rest are answered in place.

Where this stands: HEY has no JSON endpoint for thread comments, so this command posts the same HTML form the web app does. Whether to accept a form-built operation for comments — in hey-sdk/go and then here — or wait for HEY to expose comments as JSON first is a pending API decision, and the PR waits on that rather than on anything in the diff.

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.

3 participants