npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

openlinear

v0.1.32

Published

OpenLinear launcher, installer, and validation utilities

Readme

OpenLinear

A kanban board that executes your tasks.

Describe what you want built. Click execute. Get a pull request.

npm version npm downloads License: MIT Node TypeScript

GitHub · Documentation · Architecture · Releases


What is OpenLinear?

OpenLinear is a project management tool that turns your backlog into pull requests. You manage tasks on a Linear-style kanban board. When you're ready, an AI agent — running locally with your own credentials — clones your repo, creates a branch, writes the code, and opens a PR. No copy-pasting prompts, no context switching.

This package is the official launcher and utility library. It does two things:

  1. CLIopenlinear command that launches the pre-built desktop app on macOS or Linux.
  2. Library — TypeScript utilities for execution metadata validation, payload sanitization, and feature flag management used internally by the OpenLinear platform.

Installation

Global — CLI launcher (macOS / Linux x64)

npm install -g openlinear
# or
pnpm add -g openlinear
# or
yarn global add openlinear
# or
curl -fsSL https://raw.githubusercontent.com/kaizen403/openlinear/main/install.sh | bash
# or
paru -S openlinear-bin

The global launcher currently supports macOS (Apple Silicon / Intel) and Linux x64. The npm installer and the curl installer place the desktop app in ~/.openlinear/. Once complete, run:

openlinear

Local GitHub auth

OpenLinear now prefers a browser-based local callback flow instead of a hosted callback on rixie.in.

If GitHub CLI is already authenticated on your machine, openlinear github login reuses that local token first.

If no local GitHub CLI token is available and OPENLINEAR_GITHUB_CLIENT_SECRET is set, openlinear github login starts a temporary callback server on http://localhost:<port>/callback, opens GitHub in your browser, and stores the resulting token locally.

If you do not want the browser flow, or you have not configured a client secret, the CLI falls back to GitHub device flow. You can also force either mode explicitly.

openlinear github login
openlinear github login --browser
openlinear github login --device
openlinear github status
openlinear github whoami
openlinear github logout

Browser mode requires a GitHub OAuth app client secret:

export OPENLINEAR_GITHUB_CLIENT_SECRET=your-client-secret

The GitHub OAuth app tied to your client_id also needs a loopback callback configured in GitHub, such as http://localhost/callback.

Optional callback overrides:

export OPENLINEAR_GITHUB_CALLBACK_HOST=localhost
export OPENLINEAR_GITHUB_CALLBACK_PORT=0
export OPENLINEAR_GITHUB_CALLBACK_PATH=/callback

No hosted callback route is involved. The token is stored locally in ~/.config/openlinear/github-auth.json.

Local — Library API

npm install openlinear

CLI

openlinear [args...]

The CLI launcher resolves the desktop binary from ~/.openlinear/OpenLinear.app/Contents/MacOS/OpenLinear, ~/.openlinear/openlinear, or ~/.openlinear/openlinear.AppImage, applies Linux-specific environment flags for X11/Wayland when needed, and passes all arguments through to the app.

If the binary is not found, it prints installation instructions and exits:

OpenLinear desktop app not found.

Install it from npm:
  npm install -g openlinear

Or download the latest desktop release:
  https://github.com/kaizen403/openlinear/releases/latest

Library API

The package ships four entry points. Import only what you need.

| Entry point | Contents | |---|---| | openlinear | Re-exports everything below | | openlinear/types | Zod schemas, TypeScript types, validation functions | | openlinear/validation | Payload sanitization and forbidden-field utilities | | openlinear/config | Feature flag parsing and execution mode helpers |


openlinear/types

Zod-validated types and validation functions for execution metadata synced between the local agent and the cloud dashboard.

Types

import type { ExecutionMetadataSync } from 'openlinear/types';

// ExecutionStatus — z.enum
type ExecutionStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';

// ErrorCategory — z.enum
type ErrorCategory = 'AUTH' | 'RATE_LIMIT' | 'MERGE_CONFLICT' | 'TIMEOUT' | 'UNKNOWN';

// ExecutionMetadataSync — the full sync payload shape
interface ExecutionMetadataSync {
  version?: '1.0';
  taskId: string;
  runId: string;
  status: ExecutionStatus;
  startedAt?: string;       // ISO 8601 datetime
  completedAt?: string;     // ISO 8601 datetime
  durationMs?: number;      // non-negative integer
  branch?: string;
  commitSha?: string;
  prUrl?: string;           // valid URL
  prNumber?: number;        // positive integer
  outcome?: string;         // max 500 chars
  errorCategory?: ErrorCategory;
}

validateExecutionMetadataSync(payload)

Parses and returns the payload as ExecutionMetadataSync. Throws a ZodError if validation fails. Use this when an invalid payload should be a hard error.

import { validateExecutionMetadataSync } from 'openlinear/types';

const metadata = validateExecutionMetadataSync({
  taskId: 'tsk_123',
  runId: 'run_456',
  status: 'completed',
  durationMs: 45000,
  branch: 'feature/add-login',
  prUrl: 'https://github.com/org/repo/pull/42',
  prNumber: 42,
});

safeValidateExecutionMetadataSync(payload)

Safe variant. Returns a discriminated union — never throws.

import { safeValidateExecutionMetadataSync } from 'openlinear/types';

const result = safeValidateExecutionMetadataSync(payload);

if (result.success) {
  console.log('Ready to sync:', result.data);
} else {
  console.error('Validation failed:', result.error.errors);
}

checkExecutionMetadataSync(payload)

Returns a plain { valid: boolean; issues?: string[] } report. Useful for surfacing human-readable errors in logs or UIs without dealing with ZodError.

import { checkExecutionMetadataSync } from 'openlinear/types';

const { valid, issues } = checkExecutionMetadataSync(payload);
if (!valid) {
  issues?.forEach(issue => console.warn(issue));
  // e.g. "prUrl: Invalid url"
}

validateExecutionMetadataMiddleware()

Express middleware factory. Validates req.body against ExecutionMetadataSyncSchema, sets req.validatedMetadata on success, or responds 400 with a structured error on failure.

import express from 'express';
import { validateExecutionMetadataMiddleware } from 'openlinear/types';

const app = express();
app.use(express.json());

app.post('/sync', validateExecutionMetadataMiddleware(), (req, res) => {
  // req.validatedMetadata is typed as ExecutionMetadataSync
  res.json({ received: req.validatedMetadata.taskId });
});

Error response shape (400):

{
  "error": "Invalid sync payload",
  "code": "FORBIDDEN_FIELDS | VALIDATION_ERROR",
  "details": [{ "field": "prUrl", "message": "Invalid url" }]
}

openlinear/validation

Utilities that enforce the trust boundary between local execution and the cloud dashboard. Sensitive fields are never allowed through the sync pipeline.

FORBIDDEN_SYNC_FIELDS

A readonly array of field names that are blocked from cloud sync:

prompt, logs, toolLogs, executionLogs, repoPath, accessToken, apiKey,
passwordHash, jwt, client, timeoutId, rawOutput, diff, fileContents,
env, environment, processEnv

isForbiddenField(field)

Returns true if the field name is in FORBIDDEN_SYNC_FIELDS.

import { isForbiddenField } from 'openlinear/validation';

isForbiddenField('accessToken'); // true
isForbiddenField('taskId');      // false

sanitizePayload(payload)

Strips all forbidden fields from an arbitrary object and returns the sanitized result alongside a list of removed keys.

import { sanitizePayload } from 'openlinear/validation';

const { sanitized, removed } = sanitizePayload({
  taskId: 'tsk_123',
  status: 'completed',
  accessToken: 'ghp_...',   // forbidden
  logs: '[tool output...]', // forbidden
});

// sanitized → { taskId: 'tsk_123', status: 'completed' }
// removed   → ['accessToken', 'logs']

openlinear/config

Feature flag utilities for managing the gradual rollout of local execution mode.

parseFeatureFlags(env?)

Parses feature flags from process.env (or any key/value map you pass). All flags have safe defaults so this never throws in production.

import { parseFeatureFlags } from 'openlinear/config';

const flags = parseFeatureFlags();
// or override for testing:
const flags = parseFeatureFlags({
  LOCAL_EXECUTION_ENABLED: 'true',
  CANARY_PERCENTAGE: '25',
});

| Flag | Type | Default | Description | |---|---|---|---| | LOCAL_EXECUTION_ENABLED | boolean | false | Master switch for local execution | | SERVER_EXECUTION_ENABLED | boolean | true | Master switch for server execution | | CANARY_PERCENTAGE | number (0–100) | 0 | % of users routed to local execution | | FORCE_LOCAL_EXECUTION | boolean | false | Force local for all users (overrides canary) | | KILL_SWITCH_LOCAL_EXECUTION | boolean | false | Disable local for all users immediately |

getFeatureFlags()

Shorthand for parseFeatureFlags(process.env).

isLocalExecutionEnabled(userId, flags?)

Determines whether local execution is active for a specific user, respecting the kill switch, force flag, and canary percentage in that order.

import { isLocalExecutionEnabled, getFeatureFlags } from 'openlinear/config';

const flags = getFeatureFlags();
const useLocal = isLocalExecutionEnabled('user_abc123', flags);

isServerExecutionEnabled(flags?)

Returns flags.SERVER_EXECUTION_ENABLED.

validateFlagConfiguration(flags)

Checks for invalid flag combinations and returns a { valid: boolean; errors: string[] } report.

import { validateFlagConfiguration, getFeatureFlags } from 'openlinear/config';

const { valid, errors } = validateFlagConfiguration(getFeatureFlags());
if (!valid) {
  errors.forEach(e => console.error('[config]', e));
}

Catches:

  • FORCE_LOCAL_EXECUTION and KILL_SWITCH_LOCAL_EXECUTION both enabled simultaneously.
  • Both LOCAL_EXECUTION_ENABLED and SERVER_EXECUTION_ENABLED disabled (no execution mode active).

getMigrationPhase(flags?)

Returns the current rollout phase as a readable string. Useful for observability and dashboards.

import { getMigrationPhase } from 'openlinear/config';

getMigrationPhase(); // 'shadow' | 'canary' | 'cutover' | 'rollback' | 'unknown'

| Phase | Condition | |---|---| | rollback | Kill switch is active | | cutover | Server execution disabled, local is primary | | canary | Local enabled with CANARY_PERCENTAGE > 0 | | shadow | Local enabled but CANARY_PERCENTAGE === 0 | | unknown | No recognizable state |


Security & Trust Boundaries

The sync pipeline enforces a strict boundary to ensure sensitive data never leaves your machine.

| Category | Examples | Synced to cloud? | |---|---|---| | Safe metadata | taskId, status, durationMs, branch, prUrl | Yes | | Local-only paths | repoPath, env, environment | No — stripped | | Credentials | accessToken, apiKey, passwordHash, jwt | No — stripped | | Raw agent output | prompt, logs, toolLogs, diff, rawOutput | No — stripped |

Any payload passing through sanitizePayload or safeValidateExecutionMetadataSync has forbidden fields automatically removed or rejected before they can reach the network.


Repository status

The hosted OpenLinear product has been reduced to a static Vercel landing site plus installer surface. This npm package remains available for launcher and utility use.


Building from Source

git clone https://github.com/kaizen403/openlinear.git
cd openlinear
pnpm install

# Build the npm package
pnpm --filter openlinear build

# Run the landing site from the repo root
pnpm --filter @openlinear/landing dev

Distribution

| Format | Platform | Install | |---|---|---| | npm | macOS, Linux x64 | npm install -g openlinear | | curl | macOS, Linux x64 | curl -fsSL https://raw.githubusercontent.com/kaizen403/openlinear/main/install.sh | bash | | GitHub Releases | macOS, Linux x64 | https://github.com/kaizen403/openlinear/releases/latest |


Contributing

Contributions are welcome. Please open an issue first to discuss what you'd like to change.

The npm package lives at packages/openlinear in the monorepo.

cd packages/openlinear
pnpm build

License

MIT