Skip to content

better-slop/orbit

Repository files navigation

Orbit

Highly experimental linear backend clone written entirely by GPT-5.4 and now GPT-5.5.

Linear-compatible backend foundation.

Current stack:

  • Nix flakes
  • Phoenix
  • Absinthe GraphQL
  • Ecto + Postgres
  • Oban

Current runtime slice:

  • /up health endpoint
  • /graphql endpoint
  • /oauth/token and /oauth/revoke token endpoints
  • API-key auth via Authorization header
  • bearer auth via minted access tokens
  • viewer, teams, projects, issues, webhooks queries
  • issueCreate, issueUpdate, webhookCreate mutations
  • issueCreated, issueUpdated subscriptions
  • webhook delivery job + delivery history

Demo app:

  • demos/linearlite is a Typescript/TanStack Start SSR frontend adapted from ElectricSQL's example
  • uses Orbit GraphQL directly for issues, projects, cycles, comments, notifications
  • uses /socket for live inbox updates when subscriptions are available

Boot

Preferred:

nix --extra-experimental-features 'nix-command flakes' develop
scripts/bootstrap.sh
mix phx.server

Without entering the shell manually:

nix --extra-experimental-features 'nix-command flakes' develop -c scripts/bootstrap.sh
nix --extra-experimental-features 'nix-command flakes' develop -c mix phx.server

Default local database:

  • host: 127.0.0.1
  • port: 55432
  • user: postgres
  • password: postgres

Seeded Dev Auth

priv/repo/seeds.exs creates:

  • user: zero@orbit.local
  • API key: orbit_dev_key
  • teammate: teammate@orbit.local
  • teammate API key: orbit_teammate_key
  • observer: observer@orbit.local
  • observer API key: orbit_observer_key
  • OAuth client id: orbit_dev_client
  • OAuth client secret: orbit_dev_secret

Use it like:

curl -s http://127.0.0.1:4000/graphql \
  -H 'content-type: application/json' \
  -H 'authorization: orbit_dev_key' \
  -d '{"query":"{ viewer { id name email } }"}'

Storage config:

  • default: filesystem
  • S3-compatible adapters supported via ORBIT_STORAGE_PROVIDER=tigris|r2|aws|minio
  • S3 provider requests are now signed/performed through official aws-elixir primitives plus hackney
  • supporting env vars: ORBIT_STORAGE_ACCESS_KEY_ID, ORBIT_STORAGE_SECRET_ACCESS_KEY, ORBIT_STORAGE_BUCKET, ORBIT_STORAGE_ENDPOINT, ORBIT_STORAGE_REGION, ORBIT_UPLOAD_ROOT

Token exchange example:

curl -s http://127.0.0.1:4000/oauth/token \
  -H 'content-type: application/json' \
  -d '{
    "grant_type":"api_key",
    "client_id":"orbit_dev_client",
    "client_secret":"orbit_dev_secret",
    "api_key":"orbit_dev_key"
  }'

Example Mutation

mutation CreateIssue($input: IssueCreateInput!) {
  issueCreate(input: $input) {
    success
    issue {
      id
      identifier
      title
    }
  }
}

Variables:

{
  "input": {
    "title": "Ship Orbit",
    "description": "Make Linear clients happy",
    "teamId": "TEAM_ID",
    "projectId": "PROJECT_ID",
    "priority": 1
  }
}

Status

This is not full Linear parity yet.

It is the working backend foundation:

  • schema/runtime shell in place
  • local reproducible dev env in place
  • database boot/migrations in place
  • GraphQL vertical slice in place
  • reactive hooks/subscriptions/webhook jobs in place

Next work is breadth:

  • larger schema coverage
  • richer filtering/pagination
  • more webhook payload parity
  • SDK/client compatibility testing against real Linear consumers

About

Linear SDK / GraphQL compatible/ WebSocket compatible issue tracking in Elixir using Electric SQL, Absinthe, Ecto, and Phoenix.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors