Skip to content

Linear GraphQL/CLI hardening: non-retryable retries, missing connection precheck, duplicated plumbing, and headless as-any casts #470

Description

@arul28

Summary: With the now user-facing ade linear graphql (PR #451), a malformed query is retried 4× and a disconnected project surfaces a raw exception; the GraphQL/card-publish plumbing is also implemented redundantly three divergent ways, and the headless Linear bootstrap uses as-any/as-never casts that erase compile-time safety. Related to the Linear-CLI expansion (ADE-65).

Runtime bugs:

  • GraphQL request retries non-retryable validation errors up to maxRetries (4 round-trips, ~3.5s wasted, burns quota). The retry guard gates on (isRateLimited || res.status>=500) but the validation throw is caught by the broad catch that sleeps+retries. linearClient.ts:267,:273,:279; cli.ts:8868. Fix: tag the throw {retryable:false} and rethrow immediately; only retry on network/abort/5xx/429.
  • graphql action runs with no connection-status precheck, so a disconnected project throws the raw 'Linear token missing…', indistinguishable from 'bad query'. registry.ts:2476; linearClient.ts:223; headlessLinearServices.ts:1350. Fix: call buildRuntimeLinearConnectionStatus(runtime) first and throw a typed 'not connected' error.

Duplicated plumbing:

  • publishLinearChatLink card-publish/dedup duplicated across main.ts and bootstrap.ts. bootstrap.ts:439; main.ts:1795; linearLaneCardService.ts — extract createLinearChatLinkPublisher(…).
  • GraphQL argument validation duplicated three times with divergent rules/messages (cli.ts no clamp; registry.ts clamps 0..10; TUI ignores maxRetries). cli.ts:2075,:2104; registry.ts:2534; tuiClient/linearCommands.ts:168 — one shared parseLinearGraphQLInput(raw).
  • Redundant runGraphQL action: duplicate override + allowlist entry no caller dispatches (all callers use graphql). registry.ts:2475,:2479,:600,:612 — delete it; update registry.test.ts:390,403.

Headless casts & cli.ts monolith:

  • createHeadlessLinearServices wires real desktop services through as-any/as-never casts, so a new required method isn't caught at compile time (the dispatcher cast is what let the stub-binding defect ship). headlessLinearServices.ts:1739,:1746,:1782,:1812,:1816,:1843 — type stubs against real interfaces + satisfies Partial<X>.
  • cli.ts is a 14,235-line monolith (~245 top-level functions, 34 buildXxxPlan) that PR Expose Linear GraphQL through ADE CLI #451 added Linear helpers to. cli.ts:9431,:8720,:1 — split each builder into commands/<domain>.ts.

Verification confidence: High on the retry bug and all dedup/count claims; medium on the precheck UX and the casts (runtime-only risk).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions