Skip to content

Linear

The Linear integration installs hlix as an agent in your Linear workspace. Assign it an issue or mention it, and it opens an agent session — a thread in which it reports what it is doing and what it decided, and in which you can steer or stop it.

This is the only integration that both receives work and reports progress on the same surface.

  • Agency owner or admin in the hlix workspace
  • Permission to authorize an OAuth application in the target Linear workspace
  • At least one hlix project the issue can be resolved to — see what it needs to key on
  1. Start the install. From the dashboard’s integrations screen, or directly:

    Terminal window
    curl -sS -i "$HLIX_BASE_URL/v1/api/integrations/linear/install" \
    -H "x-api-key: $HLIX_API_KEY" \
    -H "X-Organization-Id: $HLIX_WORKSPACE_ID"

    Expected result: a 302 to linear.app/oauth/authorize, carrying an HMAC-signed state that binds the install to your workspace and user.

  2. Authorize in Linear. hlix requests read, write, app:assignable, and app:mentionable, and installs with actor=app — so it becomes a workspace-level app user rather than acting as you. The two app: scopes are what make it assignable and mentionable at all.

  3. Land back on hlix. The callback exchanges the code, reads the app user and workspace identity, and stores the installation with its refresh token and expiry.

    Expected result: a redirect to …/integrations/linear?installed=1.

  4. Verify.

    Terminal window
    curl -sS "$HLIX_BASE_URL/v1/api/integrations/linear" \
    -H "x-api-key: $HLIX_API_KEY" \
    -H "X-Organization-Id: $HLIX_WORKSPACE_ID"

    Then, in Linear, assign the hlix agent to a test issue. A thought activity — “Received — gathering context…” — should appear in the session within seconds.

Everything hlix says lands as an agent activity on the Linear session, not as an issue comment. Five kinds:

Activity Meaning
thought intermediate reasoning. The immediate acknowledgement is one of these, and is ephemeral
action a concrete step it took, with its parameter and result
response its answer for this turn — a plan summary, a status, or the outcome
elicitation a question for you. With options attached, Linear renders them as choices
error the run failed, with the message

The session’s own status moves alongside: awaitingInput when it needs an answer, complete when the turn is finished, error when it is not. A session stays open only while something is actually going to report back.

hlix has to decide which project — and, for a multi-repository project, which repository — an issue belongs to. When it cannot, it does not guess. It sets the session to awaitingInput and asks once, listing the candidates, because running an agent against the wrong repository is worse than a question.

Two cases produce that question:

  • Nothing to key a project on. The issue has no signal tying it to a hlix project.
  • The project has several repositories and the issue never said which.

Answer in the thread and the session continues.

  • Prompt it again by replying in the session. The agent reads the prior activity history, so the reply is a continuation rather than a fresh start.
  • Stop it with Linear’s stop signal. hlix honours it immediately, records the stop, replies “Stopped as requested.”, and closes the session.

When hlix queues a cycle proposal it cannot hand to a live orchestrator, it says so and closes the turn rather than leaving the thread showing “Working…” indefinitely.

  • The install uses actor=app, so the agent is its own workspace user. Actions are attributable to hlix, not to whoever installed it.
  • Access tokens last 24 hours. hlix refreshes proactively within five minutes of expiry — but only after a webhook’s signature has been verified, so a forged payload cannot trigger a token refresh or any database write.
  • Every webhook is HMAC-verified against the OAuth app’s signing secret before any side effect.
  • A PermissionChange or unrecognised event type is acknowledged and ignored rather than processed on a guess.
  • An OAuthApp revocation from Linear’s side marks the installation revoked in hlix.
Terminal window
curl -sS -X POST "$HLIX_BASE_URL/v1/api/integrations/linear/$INSTALL_ID/revoke" \
-H "x-api-key: $HLIX_API_KEY" \
-H "X-Organization-Id: $HLIX_WORKSPACE_ID"

owner or admin only. Revoke the OAuth application in Linear as well — that is the half that removes hlix’s access.

  • 500Linear OAuth not configured. The deployment has no Linear OAuth credentials. Operator fix.
  • Redirect with error=missing_code_or_state — the callback was opened without Linear’s parameters. Restart from /install.
  • Redirect with error=invalid_state_… — the signed state failed verification or expired. Restart the install.
  • Redirect with error=token_exchange_failed — Linear refused the authorization code. Usually a redirect-URI mismatch in the OAuth app configuration.
  • Redirect with error=viewer_lookup_failed — the token worked but the app user could not be read. Check the granted scopes include read.
  • 401 on the webhook — unauthorized. hlix answers this both when the signature does not verify AND when no installation matches the payload’s app user, deliberately: the endpoint is unauthenticated, so a distinct “unknown installation” reply would let anyone probe which Linear workspaces hlix is installed in. To tell the two apart, read the backend log — it records unknown appUserId or signature invalid with the reason. Confirm the configured signing secret matches the OAuth app’s Webhooks tab, and that you are pointing Linear at the right deployment; Linear disables a webhook that keeps failing.
  • Nothing appears in the session thread — assignment and mention need the app:assignable and app:mentionable scopes. Reinstall if the original authorization predates them.
  • The thread asks which project or repository — that is the design, not a failure. Answer in the thread.