Follow-up to #268: cover external and bot comment authors, validate --id - #270
Merged
Merged
Conversation
#268 adds `user.id` and `editedAt` to `issue comment list --json`, which is the right shape -- the raw connection is passed straight through, so GraphQL field names and nesting are preserved. This fills in the cases it stops short of. `externalUser` did not get the same treatment as `user`, but it has the same problem and the schema is explicit about why: ExternalUser.displayName "can match the display name of an actual user". So a consumer could disambiguate two workspace members from each other and still be unable to tell a member from an external commenter with the same name. It now carries `id` too. Integration-authored comments were the bigger gap. They have `user` and `externalUser` both null, so they arrived in the JSON with no author information at all -- the exact problem #268 sets out to fix, for a whole class of comment it does not reach. Selecting `botActor` gives them `type` (non-null, the reliable key, since ActorBot is not a Node and its `id` is nullable) plus `subType`, `name` and `id`. `userDisplayName` is available but left out: it names a person in an external system and is display-only, so it is not worth the exposure to solve an identity problem the other fields already solve. That also fixes a rendering bug we were one field away from: every GitHub, Slack and workflow comment printed as `@Unknown`, because the query never asked who the bot was. The author fallback was duplicated for root comments and replies; it is now one helper, with botActor checked last so a comment carrying both a user and a bot actor still renders the human, and every existing snapshot stays byte-identical. Finally, `--id` was forwarded to the API unvalidated. The repo already has `isLinearUuid`, and CLAUDE.md asks for an immediate, actionable error when user-supplied input is malformed rather than a raw GraphQL failure, so a non-UUID is now rejected before the request with a message showing the expected shape. The flag stays hidden, with a comment recording why it exists.
schpetbot
force-pushed
the
oss-pr-lander/268
branch
from
August 31, 2026 20:36
733cb72 to
19a031c
Compare
schpetbot
marked this pull request as ready for review
August 31, 2026 20:36
Collaborator
Author
|
Shipped in v2.6.0. Follow-up to #268.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #268. Draft until #268 lands — this branch currently contains @leonardsellem's commits too, and will be rebased down to just the delta once #268 is merged.
#268 adds
user.idandeditedAttoissue comment list --json, and the shape is right: it passes the raw connection straight through, so GraphQL field names and nesting are preserved per CLAUDE.md. This fills in the cases it stops short of.externalUserhas the same problemuserdoesIt didn't get the same treatment, and the schema is explicit about why it needs it —
ExternalUser.displayName"Can match the display name of an actual user". So a consumer could disambiguate two workspace members from each other and still not tell a member from an external commenter with the same name. It now carriesidtoo.Integration-authored comments had no author identity at all
This is the bigger gap. A comment posted by GitHub, Slack, or a workflow has
userandexternalUserbothnull, so it arrived in the JSON with nothing identifying its author — the exact problem #268 sets out to solve, for a whole class of comment it doesn't reach.Selecting
botActorgives those commentstype(non-null, and the reliable key here —ActorBotis not aNodeand itsidis nullable), plussubType,name, andid.botActor.userDisplayNameis available and deliberately left out: it names a person in an external system and is display-only, so it isn't worth the exposure to solve an identity problem the other fields already solve. Easy to add if you disagree.A rendering bug we were one field away from
Because the query never asked who the bot was, every GitHub/Slack/workflow comment printed as
@Unknown. Now that we fetchbotActor, it renders the bot's name (falling back to itstypewhennameis null):The author fallback was duplicated for root comments and replies; it's now one helper, with
botActorchecked last so a comment carrying both a user and a bot actor still renders the human. Every pre-existing snapshot is byte-identical — that's the regression assertion.--idwas forwarded unvalidated--id <uuid:string>is a cliffystring, so a typo reached the API and came back as a raw GraphQL error. CLAUDE.md asks for an immediate, actionable error instead. Linear documentsCommentCreateInput.idas "The identifier in UUID v4 format", so this checks v4 specifically — the sharedisLinearUuid()is deliberately lax (it's used to tell UUIDs apart from names elsewhere, a different job), so this validation is local:The flag stays hidden, now with a comment recording why it exists (caller-supplied ids make retries idempotent).
Verification
565 tests pass;
deno task check,deno lint,deno fmt --checkclean;deno task codegenproduces no further diff. Manually exercised:--idabsent fromcomment add --help, invalid and non-v4 values rejected with exit 1 and no stack trace, a valid v4 passing validation through to the issue lookup.