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

@reopt-ai/opt-shell

v1.1.0

Published

Internal-first product harness layer for app shell, page rhythm, and shared state UX.

Readme

@reopt-ai/opt-shell

The runtime product-frame layer for apps built on opt-ui.

Solves problems that theme tokens alone cannot: app shell structure, workspace recipes, page rhythm, empty/error/loading consistency, and shared wrappers for opt-datagrid and opt-editor.

opt-shell is the product frame, not a replacement UI kit. opt-ui owns primitives and visual components; opt-shell owns the frame around them: manifests, policy + theme resolution, workspace recipes, state fallbacks, adapter chrome, and inspect snapshots. Authoring-time helpers (completeness scoring, coverage, rollout audits, scaffold codegen) live behind the ./audit sub-export — tooling, not the production runtime.

Module map

| Area | Source | Public entry | | --------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------- | | Runtime components | src/components, src/provider, src/adapters, src/hooks | @reopt-ai/opt-shell | | Server-safe factory and contracts | src/create-harness-app.ts, src/defaults.ts, src/recipes.ts, src/tokens | @reopt-ai/opt-shell/core | | Managed draft definitions | src/managed-harness.ts | @reopt-ai/opt-shell, @reopt-ai/opt-shell/core | | Authoring & audit toolkit | src/audit (completeness, coverage, patterns, PR/SARIF, rollout, scaffold) | @reopt-ai/opt-shell/audit | | Component doc metadata | src/meta.ts, src/components/_meta-*.ts | @reopt-ai/opt-shell/meta |

Agent skill setup (recommended)

From the consumer project root:

npx skills add reopt-ai/reopt-skills/opt-shell-install

Then ask your agent: Use the opt-shell-install skill to set up @reopt-ai/opt-shell in this project and verify the result. The skill detects legacy @reopt-ai/opt-harness usage, distinguishes a new install from an upgrade, idempotently updates the reopt marker block in AGENTS.md (or CLAUDE.md), reads shell-llms.txt and this README, installs the required opt-palette peer, and verifies recipe, policy, and adapter wiring. The source of truth is reopt-ai/reopt-skills.

Manual fallback:

bun add @reopt-ai/opt-shell @reopt-ai/opt-palette @reopt-ai/opt-ui

Getting Started

1. Define your harness manifest

// lib/harness.ts
import { createShellApp } from "@reopt-ai/opt-shell/core";

export const appHarness = createShellApp({
  id: "my-internal-tool",
  label: "My Tool",
  defaults: {
    density: "comfortable", // "comfortable" | "compact"
    contentWidth: "wide", // "narrow" | "normal" | "wide" | "full"
    navigationMode: "sidebar", // "sidebar" | "stacked"
  },
});

2. Wrap your app with ShellProvider

// app/layout.tsx
import { ShellProvider } from "@reopt-ai/opt-shell";
import { appHarness } from "@/lib/harness";

export default function RootLayout({ children }) {
  return <ShellProvider manifest={appHarness}>{children}</ShellProvider>;
}

3. Build your app shell

import {
  ShellAppShell,
  ShellCollapsibleNav,
  ShellNavGroup,
  ShellNavItem,
} from "@reopt-ai/opt-shell";

export function AppFrame({ children }) {
  return (
    <ShellAppShell
      nav={
        <ShellCollapsibleNav width={260}>
          <ShellNavGroup label="Workspaces">
            <ShellNavItem href="/users" active>
              Users
            </ShellNavItem>
            <ShellNavItem href="/settings">Settings</ShellNavItem>
          </ShellNavGroup>
        </ShellCollapsibleNav>
      }
      mobileHeader={<MobileMenuButton />}
    >
      {children}
    </ShellAppShell>
  );
}

mobileHeader can use useShellNav().open() to toggle the nav — the context is shared with the shell via an internal bridge.

4. Choose a workspace recipe and build your page

import {
  ListWorkspace,
  ShellSection,
  ShellDataGridAdapter,
} from "@reopt-ai/opt-shell";

export function UsersPage() {
  return (
    <ListWorkspace
      header={<PageHeader title="Users" />}
      toolbar={<FilterBar />}
    >
      <ShellSection title="Active users">
        <ShellDataGridAdapter
          rows={users}
          columns={columns}
          loading={isLoading}
          empty={{
            title: "No users",
            description: "Create one to get started",
          }}
        />
      </ShellSection>
    </ListWorkspace>
  );
}

Which component do I need?

App frame
└─ ShellAppShell (nav + ShellCollapsibleNav)

Page content — pick ONE workspace per page:
├─ Data list / table     → ListWorkspace + ShellDataGridAdapter
├─ Single resource       → DetailWorkspace
├─ Content editing       → EditorWorkspace + ShellEditorAdapter
├─ Overview / triage     → DashboardWorkspace
├─ Landing / marketing   → LandingWorkspace (or ShellLandingPage)
└─ Full-screen tool      → ShellFullscreenToolSurface

Within a workspace:
├─ Content grouping      → ShellSection
├─ Loading/empty/error   → ShellStateBoundary
├─ Density-aware gaps    → ShellSpacing
├─ Bottom action bar     → ShellBottomBar
└─ Temporary side panel  → ShellFlyoutAside

Recipe selection guide

| Signal | Recipe | Why | | --------------------------------------------- | ------------- | ----------------------------------------- | | Rows of records, DataGrid, filter/sort | list | Collection browsing is the primary action | | Single resource, summary cards, metadata | detail | Inspecting one entity at a time | | Rich content editing, save/draft state | editor | Authoring workflows need state management | | Metrics, charts, activity feed, quick actions | dashboard | Overview and triage | | Public-facing, hero sections, promotional | landing | Engagement and conversion |

Use selectRecipe() from @reopt-ai/opt-shell/core for programmatic selection:

import { selectRecipe } from "@reopt-ai/opt-shell/core";

selectRecipe({ hasDataGrid: true }); // → "list"
selectRecipe({ hasEditor: true }); // → "editor"
selectRecipe({ isPublicFacing: true }); // → "landing"
selectRecipe({ primaryAction: "inspect" }); // → "detail"

Runtime ownership

ShellProvider resolves policy from three layers:

runtime override → manifest defaults → framework defaults

The resolved policy controls:

| Policy field | Effect | Default | | ---------------- | ----------------------------------------------- | ---------------- | | density | page and section spacing rhythm | comfortable | | contentWidth | narrow / normal / wide / full max width | wide | | navigationMode | app-level sidebar or stacked nav framing | sidebar | | motionPolicy | harness-managed motion allowance | reduced | | stateLabels | shared loading, empty, and error fallback copy | English baseline | | panelBehavior | sticky aside / sticky toolbar defaults | sticky aside | | adapters | DataGrid and Editor adapter chrome | card | | theme | inherited, generated, or promoted opt-ui theme | preset default |

The provider also emits inspect snapshots. ShellStateBoundary, ShellDataGridAdapter, ShellEditorAdapter, nav, aside, bottom bar, header stack, and AI runtime state report into that snapshot so @reopt-ai/opt-devtool can show policy, adapter, layout, diff, and staleness state.


Hooks

| Hook | Where | Purpose | | ----------------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | useShell() | Inside ShellProvider | Manifest + resolved policy. Emits a dev warning if no Provider ancestor. | | useShellOptional() | Anywhere | Same return shape as useShell() but silent fallback (no warning) when no Provider. Used by adapters / chrome that may render standalone. | | useShellNav() | Inside ShellAppShell | Nav mode, collapsed, open/close/toggle | | useShellAI() | Inside ShellProvider | AI runtime configuration injected via <ShellProvider ai={…}> | | useShellEditorAI() | Inside ShellProvider | opt-editor AI bridge — auto-wires the AI transport into <Editor> props | | useShellDevtoolController() | Inside ShellProvider | Reports adapter/layout state to the @reopt-ai/opt-devtool inspect panel |

0.2.0 note: useShellLayout, useShellBreakpoint, useShellPageContext, useResizable, useShellCssVar, useShellDensity are removed. They had zero documented consumers; if you need any of them, please open an issue describing the use case.


z-index scale

All overlay/sticky elements use a documented scale (tokens/z-index.ts):

| z-index | Constant | Element | | ------- | --------------- | ------------------------------------------ | | 10 | stackedHeader | Sticky page headers (ShellStackedHeader) | | 20 | bottomBar | Fixed/sticky bottom bar (ShellBottomBar) | | 40 | backdrop | Overlay backdrops (nav + flyout) | | 50 | navOverlay | Collapsible nav overlay panel | | 51 | flyoutOverlay | Flyout aside overlay (above nav) |


Theme configuration

Two modes via ShellThemeConfig (discriminated union):

Preset mode — uses a static opt-ui theme:

{ mode: "preset", preset: "default" }

Generated mode — produces tokens via the opt-palette engine:

{
  mode: "generated",
  palette: {
    seed: "#0ea5e9",
    harmony: "analogous",
    radiusScale: "medium",
    shadowIntensity: "subtle",
    neutralTemperature: "cool",
  },
}

Theme scope controls where the resolved theme lands:

| Scope | Behavior | | ---------------- | ---------------------------------------------------------------------- | | inherit | no harness CSS is emitted; descendants inherit the global opt-ui theme | | override | generated tokens are scoped under <div data-harness="..."> | | promote-global | the harness pushes its theme into the global OptThemeProvider stack |


Prerequisites

Components rely on CSS custom properties from @reopt-ai/opt-ui themes:

| Variable | Purpose | | ---------------------- | -------------------- | | --opt-bg | Page background | | --opt-surface | Card / panel surface | | --opt-border | Border color | | --opt-text | Primary text | | --opt-text-secondary | Secondary text | | --opt-text-tertiary | Muted text | | --opt-radius | Border radius token |

Peer dependencies

| Package | Required | Notes | | ------------------------ | ------------------ | -------------------------- | | react / react-dom | Yes | ^19.0.0 | | @reopt-ai/opt-palette | Yes | OKLCH color engine | | @reopt-ai/opt-datagrid | With adapters only | For ShellDataGridAdapter | | @reopt-ai/opt-editor | With adapters only | For ShellEditorAdapter |

Entry points

| Import path | Use case | | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | @reopt-ai/opt-shell | Client-side React components, hooks, adapters, managed shell helpers, runtime types | | @reopt-ai/opt-shell/core | Server-safe factory, policy resolution, recipe metadata, selectRecipe, DTCG token import/export, contract types | | @reopt-ai/opt-shell/audit | Authoring & audit toolkit: completeness scoring, coverage, pattern search, PR review/SARIF, rollout contract registry. Not part of the production runtime. | | @reopt-ai/opt-shell/meta | Component doc metadata for the docs registry |


Slot contract

Workspaces are the primary contract:

  • DashboardWorkspace, ListWorkspace, DetailWorkspace, EditorWorkspace, and LandingWorkspace are the primary wrappers around ShellPage.
  • Workspace wrappers require header plus children or content at the TypeScript level. The canonical landing recipe itself only requires content in src/recipes.ts, but the current LandingWorkspace wrapper keeps a header prop for API consistency.
  • filters belongs to the list recipe. Other recipes should avoid filter chrome even if the current base prop type does not fully prevent it.
  • LandingWorkspace omits filters and aside; use ShellLandingPage when you need hero / CTA / stacked public-page chrome instead of workspace slots.
  • Recipe defaults (width, gap, sticky aside, slot contract) live in src/recipes.ts

| Recipe | Wrapper | Required recipe slots | Optional recipe slots | Defaults | | ----------- | -------------------- | --------------------- | --------------------------------------- | ------------------------------------------------ | | list | ListWorkspace | header, content | toolbar, filters, aside, footer | wide, sticky aside, drawer mobile aside | | detail | DetailWorkspace | header, content | toolbar, aside, footer | normal, sticky aside, stacked mobile aside | | editor | EditorWorkspace | header, content | toolbar, aside, footer | wide, non-sticky aside, collapsed mobile aside | | dashboard | DashboardWorkspace | header, content | toolbar, aside, footer | full, non-sticky aside | | landing | LandingWorkspace | content | header, footer | full, no aside, no filters |

Fullscreen tools

Tools like theme editors or page builders that don't fit a recipe layout should use ShellFullscreenToolSurface.

Managed harness definitions

Builder stores user-editable harness drafts as ManagedShellDefinition. Those definitions normalize:

  • policy: density, width, motion, state labels, adapter chrome, and theme.
  • recipes: preview slot toggles for all five recipes.
  • fullscreenTool: header/footer toggles for fullscreen tools.

Use normalizeManagedShellDefinition() before persisting arbitrary input, and resolveManagedShellManifest(baseManifest, definition) to merge an approved definition back into the runtime manifest. Builder activation still happens outside this package; opt-shell only provides the normalization and merge boundary.

Scaffold

bun run --filter @reopt-ai/opt-shell scaffold -- \
  --kind workspace --workspace list \
  --target app/orders/page.tsx \
  --title "Orders" --toolbar --filters --aside --footer

The scaffold command writes the route entry plus .harness-contract.ts, .harness-preview.fixture.ts, .harness-doc.md, .harness.test.ts, and .harness-guard-matrix.md. Workspace scaffolding currently accepts list, detail, editor, and dashboard; landing is a runtime recipe but is not yet exposed by the scaffold CLI.


AI Agent Protocol

Phase-aware context

generateShellContext(manifest, { phase }) controls what agents see:

| Phase | Shows | Hides | | ----------- | ------------------------------- | ----------------------- | | scaffold | Recipe selection, heuristics | Slots, adapters, policy | | implement | Locked recipe's slots, adapters | Other recipes, policy | | polish | Policy options, state labels | Recipes, adapters | | audit | Contract rules, anti-patterns | All creation actions | | full | Everything | Nothing |

Completeness scoring

import { computeCompletenessScore } from "@reopt-ai/opt-shell/audit";
const score = computeCompletenessScore(findings, totalChecks);
// score.score: 0-100, score.categories: per-category breakdown

Categories (weights): layout (20%), recipe-contract (25%), adapter-ownership (15%), state-ux (10%), design-document (10%), scaffold-bundle (10%), accessibility (10%).

MCP Handlers

9 handlers from @reopt-ai/opt-shell/core: listShellManifests, getShellRecipes, resolveShellPolicyMCP, getShellRecipeDetail, getShellContractRegistry, getShellCompletenessScore, getShellCoverage, searchShellPatternsHandler, exportTokensDTCGHandler.

0.2.0 note: getStructuredShellContext, recordShellDecision, requestShellApproval, registerShellAgent, detectShellConflicts 등 unproven 핸들러는 컨슈머 사용 0건으로 제거됨. 필요하면 issue로 신고.

Pattern search (50+ patterns)

import { searchShellPatterns } from "@reopt-ai/opt-shell/audit";
const result = searchShellPatterns("datagrid list", 5);

W3C DTCG token export

import { exportShellTokensDTCG } from "@reopt-ai/opt-shell/core";
const dtcg = exportShellTokensDTCG(resolvedTheme);

PR Review & SARIF

import {
  findingsToSARIF,
  generatePRReviewComments,
} from "@reopt-ai/opt-shell/audit";
const sarif = findingsToSARIF(findings); // SARIF 2.1.0
const comments = generatePRReviewComments(findings); // PR inline comments

ESLint Plugin

Enable @reopt/eslint-config/opt-shell-rules:

| Rule | Severity | Description | | ------------------------- | -------- | ----------------------------------------- | | no-raw-engine-in-recipe | error | Must use adapter, not raw DataGrid/Editor | | require-state-boundary | warn | Workspace files need ShellStateBoundary | | no-hardcoded-width | warn | Use policy.contentWidth, not max-w-* |