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

@volter/twin-linear

v2.0.35

Published

Local Linear twin — GraphQL (SDL-derived); your real `@linear/sdk` talks to it unmodified. Mirror, simulate, and fork. Built on @volter/world-core.

Readme

@volter/twin-linear

Protocol 1: the pull observes through the kernel (observeResources), and the pack still serves and pushes on the protocol-1 paths. Check the generated index for protocol standing and use the shared model for current state semantics.

The Linear twin — a local replica of Linear's GraphQL API on the shared @volter/world-core kernel. The real @linear/sdk works against it unmodified. This is the reference twin (every R1–R18 row passes).

Surface

  • GraphQL API (linear-twin.ts): the pack's ONE served schema, derived from Linear's real GraphQL SDL, so the strict SDK type-checks pass by construction. Issues + teams, projects, cycles, users, labels, workflowStates, comments, roadmaps, documents, initiatives, customers and the rest, with issue→team/project/cycle/comment links and project→roadmap grouping.
  • State + behaviour (linear-state.ts): the vendor field mapping, identifier assignment, workflow-state resolution, filtering/search/pagination and every resolve* write path — the ONE implementation the derived schema binds its root fields to. A second, hand-written SUBSET schema used to live beside it behind world-linear serve --subset; it was deleted on 2026-09-03 (no consumer, no verify, no saboteur, and demonstrably divergent from the vendor — it typed Notification as a concrete type where the SDL makes it an interface, metadata as String where the vendor has JSONObject!, and invented input fields real Linear rejects).
  • HTTP surface (linear-server.ts): the schema's fetch closure and the pack's only Bun.serve call — createLinearTwinFetch/createDerivedLinearTwinServer. The closure is on the kernel's one HTTP adaptation, so it serves the real GET /twin manifest door and the GET /twin/store/<name> door; off the doors a GET answers a service blurb. The server factory is nothing but Bun.serve around the closure, so standalone and hosted lanes serve the same bytes.
  • Connector (linear-connector.ts): full-workspace pull from real Linear (issues + teams/projects/cycles/labels/workflowStates) and push of pending local actions, confirmed back into observed events (auth injected).
  • Webhooks (linear-webhooks.ts): issueCreate/issueUpdate fire Linear-shaped webhooks on write.
  • Conformance (linear-conformance.ts): operation-acceptance + vendor-SDL drift + recorded-diff vs a real captured Linear response (standing gate).
  • UI mirror (linear-mirror-ui.ts): a Linear-style issue board (React), a pure frontend of the twin (R3) — the console reads its state through the store door (GET /twin/store/mirror, the ONE projection linear-mirror-state.ts declares on the pack's fetch adapter) and writes through the GraphQL API (issueCreate POSTed to /).

CLI

world-linear serve [--read-only] [--port N] [--root DIR]
world-linear mirror [--port N] [--root DIR]
world-linear conformance [--root DIR]

Point the real @linear/sdk LinearClient at it via apiUrl.

Interaction surfaces

  1. SDK/API — zero edits (preferred): LINEAR_TWIN_URL=http://127.0.0.1:PORT node --require @volter/world-core/inject your-app redirects the real @linear/sdk from api.linear.app to the twin. Or override directly: new LinearClient({ apiKey: 'twin', apiUrl: 'http://127.0.0.1:PORT/' }).
  2. API + CLI — run the twin in a World and inspect it with volter world log and diff. Use the deployment guide for changeset review and deployment.
  3. Read-only — world-linear serve --read-only: unlimited local reads, no rate limits; writes refuse like Linear (GraphQL error).
  4. UI mirror — world-linear mirror renders a Linear-style view of the twin's state.

(See Getting Started → "Twin interaction surfaces", and cookbook/zero-edit-inject.)

Stable on the twin rubric: fidelity, read/write/fork, sync, observability, event emission, and conformance are tracked with explicit coverage gaps.

Coverage

Goal: honest, explicitly tracked coverage of Linear's core feature surface. Every capability is either done or todo; anything not done is a gap to close.

Done — issues (create/update/get/list) with rich IssueFilter (state/title/identifier/ priority/estimate/assignee/labels + and/or compounds) and opaque cursor pagination; workflow states + transitions (server-assigned stateId, default per-team workflow, name/type stored on move); comments; teams; projects + depth (state/progress/startDate/targetDate/lead); project milestones; cycles; estimates; issue relations (blocks/duplicate/related/similar); labels + assignees; attachments (title/subtitle/url/JSON metadata); notifications (generated from comment/assignment activity, mark-read + archive); project updates (body/health); favorites (issue/project, create + idempotent delete); server-side identifier assignment (TEAM-N); roadmaps (create + list/get, projects linked to a roadmap — modeled on Linear's real Roadmap/RoadmapCreateInput SDL types and exercised through the real @linear/sdk's createRoadmap/roadmaps/roadmap); documents (rich-text docs with title/markdown content, create + update + list/get, linked to a project or initiative — modeled on Linear's real Document/DocumentCreateInput/DocumentUpdateInput/ DocumentPayload SDL types, deterministic doc-N ids, exercised through the real @linear/sdk's createDocument/updateDocument/documents/document plus Project.documents/Initiative.documents) and initiatives (workspace themes grouping projects/documents, initiativeCreate/initiatives/ initiative). SDL-derived schema built from Linear's real published GraphQL SDL so the real @linear/sdk type-checks and runs unmodified — and, since 2026-09-03, the pack's ONLY schema; webhooks on issue create/update; UI mirror (rung-5 ✅ — every board/detail surface rendered, plus a Documents view: docs list with title/content-preview/linked-parent + initiatives); conformance (vendor-SDL drift + recorded-diff + canonical ops validated against the real SDL); connector — full-workspace pull from real Linear (issues AND teams/projects/cycles/labels/workflowStates/initiatives/documents, each via its real collection query, mapped to twin subjects and observed through the kernel's observeResources, which appends only what changed) + deep push: issue fields with name→id resolution for state/assignee/labels, comments, relations, attachments, project updates, favorites, notification update/archive, documents (create/update), initiatives — each confirmed back into observed events). Niche admin/workflow surfaces: organization settings (organizationUpdate + workspace policy fields: name/urlKey/ allowMembersToInvite/roadmapEnabled/gitBranchFormat/fiscalYearStartMonth); members + invites (users/user reading the real User type with role/active/admin/guest, userUpdate/userSuspend/ userUnsuspend, organizationInvites/organizationInvite/organizationInviteCreate/organizationInviteDelete); issue + project templates (templates/template/templateCreate/templateUpdate/templateDelete, type-discriminated issue vs project); snooze (Issue.snoozedUntilAt/snoozedBy via issueUpdate); triage (Team.triageIssueState, untriaged queue via Team.issues, server-stamped Issue.triagedAt on triage exit); audit log (auditEntries AuditEntry feed, appended on admin mutations); email intake (emailIntakeAddress/emailIntakeAddressCreate, minted per-team address); git automation states (Team.gitAutomationStates/gitAutomationStateCreate, branch/PR → workflow-state rules). All modeled on Linear's real published SDL and exercised through the twin's one GraphQL surface (which is that SDL, by construction). UI mirror gained four screens: Timeline (project Gantt over a month axis), Roadmap (initiative columns rolling up projects + progress bars), Settings (Workspace/ Teams/Members tabs), and a Command menu (Cmd-K palette with keyboard nav) — all rung-5 structural-DOM verified.

Planned (known-missing, will do) — saved views / custom views / filters, SLAs / automations rules (beyond git-automation states), sub-team hierarchy, deeper webhooks (only issueCreate/issueUpdate today), OAuth scopes, third-party integrations, the issue import mutations with their async import-job record moving through its status states, and GraphQL subscriptions — serving the realtime websocket transport and pushing the same state changes the twin already emits to its webhook surface.

Rate budget — the fail-closed backstop on live calls

liveLinearExecute is the one place this pack issues a live request, so every call it makes is charged against a persistent, fail-closed spend ledger before the request goes out. Past the ceiling, or while a Retry-After/429 cooldown is armed, it throws instead of calling. The ledger is keyed by vendor and a hash of the credential (limits are per credential, so it is deliberately not cwd-scoped) and persists across processes, so a fresh process does not get a fresh allowance; a corrupt ledger counts as a full window rather than zero spend. There is no option to disable it, and no value you can pass for budget that yields an unguarded client — an injected budget is validated by method identity, so a subclass or a Proxy that replaces checkBudget is refused.

The declared numbers: 600 requests / hour — 12% of Linear's documented 5,000/hour for API-key auth. Priced by GraphQL operation (query PullTeams, mutation PushComment), since Linear has one endpoint; an unreadable document is keyed mutation, because mispricing a write as a read is the direction that costs something. Mutations cost 2 (a judgement call: a runaway push creates issues and notifications a human must clean up). It does not model Linear's complexity axis — that is a function of document shape, not request count — and says so.

The mechanism is shared and vendor-agnostic — it lives in the kernel (@volter/world-core → packages/world-core/src/rateBudget.ts); what lives here in src/linear-budget.ts is this vendor's declaration (window, ceiling, per-endpoint weights, and a reason citing the limits above) plus the vendor-bound LinearBudget. The rule is ratified as ../../../docs/contributing/architecture.md D8, and the kernel module's header documents what the guard does not guarantee — read that before trusting it.