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

create-ailk

v0.6.1

Published

Scaffolder for AI Launch Kit — `pnpm create ailk@latest <dir>` produces a starter repo consuming @working-theory/* from npm (per ADR 0007).

Readme

create-ailk

Scaffolder for AI Launch Kit. Produces a working starter repo that consumes versioned @working-theory/* packages from npm — the canonical install path per ADR 0007.

Usage

pnpm create ailk@latest my-site
cd my-site
pnpm install
pnpm dev

Compose the site from modules with --modules. The recognized vocabulary is RECOGNIZED_MODULES in src/parse-args.ts — marketing, docs-blog, multi-tenant, workspace, scheduling, signal-collectors, commerce — and the default when the flag is absent is marketing (DEFAULT_MODULES, same file):

pnpm create ailk@latest my-site --modules marketing,docs-blog

Every recognized module except marketing is a paid module, delivered under a license key rather than shipped inside this package — see Paid modules require AILK_LICENSE_KEY.

Sync architecture.yaml after adding a module

When a module is added to an already-scaffolded repo, regenerate its architecture.yaml in place with --sync-architecture <csv> (recognized modules are the same set as --modules):

# in an already-scaffolded repo (default target: cwd)
create-ailk --sync-architecture marketing,docs-blog
# or point at the repo explicitly
create-ailk --sync-architecture marketing,docs-blog ./my-site

Sync mode is data-only and non-destructive: it rewrites only architecture.yaml from the module set, re-copies no template tree, and runs no install. Because deriveArchitecture is byte-deterministic, the synced file is identical to a fresh scaffold's for the same module set — the idempotency the deferred-sync signal contract depends on.

Sync template routes into an existing site

The template is copied once, at scaffold time. When a later release adds a route directory (0.14.0 added /thanks/{slug} and the flow results page, for example), a site scaffolded earlier does not pick it up on its own. sync-routes reports the route directories a site is missing and, with --apply, copies exactly those in:

# check — exit 1 if any template route is missing, 0 otherwise (default target: cwd)
create-ailk sync-routes ./my-site
# copy the missing route directories in
create-ailk sync-routes ./my-site --apply

Check mode lists each missing route with the surface that owns it and the release it was added in (thanks/[slug] (surface: core, added in 0.14.0)). It also lists routes modified locally — a route directory the site has, whose files differ from what the template would write (an edited, added, or deleted file). Modified routes are your edits: they are reported and left as-is, they never fail the check, and --apply never overwrites them.

--apply only creates route directories that are absent, through the same copier a fresh scaffold uses (so the copied files are byte-identical to a fresh scaffold's). It never rewrites or deletes an existing file, never writes outside apps/web/app/[locale]/, runs no install, and a second run is a no-op. --apply exits 0 on success.

Scope. Every core route (about, contact, faq, thanks/[slug], sign-in) is always checked, and so is the (authed) route GROUP — layout.tsx + sign-in-gate.tsx, account/, and waitlist/ — even though it is not itself a --modules-gated surface (#5014): a fresh scaffold ships it unconditionally, the same as core, so sync-routes checks it unconditionally too. It is reported under its own authed identity rather than lumped in with core, so sync-routes's output distinguishes "always present, and this is the sign-in/account shell" from "always present, and this is the marketing core." A gateable surface's routes (blog, docs, flows, …) are checked only when the site carries that surface; a surface gated off at scaffold time is listed as skipped, not missing — its absence is deliberate, not drift. Add a surface with --sync-architecture and the scaffold-page skill, not with sync-routes.

The lib-and-messages dependency contract (#5014). Some routes import files OUTSIDE their own route directory — sign-in/page.tsx imports apps/web/lib/auth-env.ts and lib/site-brand.tsx; the (authed) group's layout.tsx imports apps/web/auth.ts; (authed)/account/page.tsx imports lib/account-config.ts, lib/server-api.ts, and two files from its (authed)/waitlist sibling (components/ForbiddenState.tsx, format.ts). Copying a route's directory alone would leave those imports dangling in an older consumer that never had them. ROUTE_DEPENDENCIES in src/surfaces.ts declares them per route; sync-routes copies each one --apply finds missing (never overwriting — the same rule routes themselves follow) and reports it in check mode under an Also required heading. ROUTE_MESSAGE_NAMESPACES does the same for the i18n namespaces a route's copy needs (signIn, account, waitlistDashboard.gate) — but CHECK-ONLY: a consumer's apps/web/messages/<locale>.json already exists and may carry hand-authored translations, so sync-routes reports a missing namespace rather than attempting to merge JSON keys into it. Adding it is a manual step, same as reading any other reported gap.

The manifest. ROUTE_SINCE in src/surfaces.ts maps every template route directory (relative to apps/web/app/[locale]) to the @working-theory/* fixed-group release line that first shipped it — the version a site pins, so the report can say "added in 0.14.0". create-ailk's own version is not the axis. 0.0.0 means the route predates the manifest and its first release is not recoverable. Surface membership is not in the manifest: it is derived from the route-surface registry in the same file.

Maintainer rule: adding a route directory to the template MUST add a ROUTE_SINCE entry — __tests__/sync-routes.test.ts fails otherwise (and it fails on a stale entry for a route the template no longer ships).

Paid modules require AILK_LICENSE_KEY

src/lib/module-tier.ts splits a requested module set into its free and paid subsets. FREE_MODULES is the one hand-authored list — today marketing alone — and PAID_MODULES is derived from it as every other RECOGNIZED_MODULES entry, so the paid set is currently docs-blog, multi-tenant, workspace, scheduling, signal-collectors and commerce. A module added to the vocabulary is paid until someone deliberately adds it to FREE_MODULES.

Paid modules are not published inside this npm package: their bundles are fetched at scaffold time. resolvePaidModules in src/lib/module-license-gate.ts reads AILK_LICENSE_KEY from the environment (or an injected licenseKey option) and refuses the run when it is unset or empty, naming the paid modules requested and pointing at https://ailaunchkit.ai/pricing. An invalid or lapsed key is refused the same way, from the module distribution's own 401/403 (src/lib/fetch-module.ts). The gate runs before anything is copied (scaffold() in src/programmatic.ts), so a refused run leaves no partial scaffold behind.

AILK_MODULE_REGISTRY_URL is optional: fetchModule uses an explicitly passed registryUrl, then that variable, then the built-in DEFAULT_AILK_MODULE_REGISTRY_URL (src/lib/fetch-module.ts).

# free-only — no key read, no network call
pnpm create ailk@latest my-site --modules marketing

# paid — the key is read from the environment
AILK_LICENSE_KEY=... pnpm create ailk@latest my-site --modules marketing,docs-blog

A request that names no paid module never reaches the key check at all: resolvePaidModules returns an empty map on its first branch, before touching process.env or the network, so a free-only --modules request reads no env var and makes no network call (src/lib/module-license-gate.ts).

What it does

  1. Validates the target directory does not exist OR is empty.
  2. Copies the curated template tree (apps/{web,api,mcp} + database/ + content/ + root config files) from the package's templates/ directory.
  3. Substitutes workspace:* references in every package.json with the matching @working-theory/* semver from npm — versions are pinned at npm-publish time.
  4. Substitutes {{PROJECT_NAME}}, {{COMPANY_NAME}}, {{COMPANY_DOMAIN}} markers in templates/README.md from the target directory name (and CLI flags / interactive prompts in future versions).
  5. Derives and writes architecture.yaml (the site's code-boundary config) from the selected module set — see below.
  6. Prints next steps: cd <dir> && pnpm install && pnpm dev.

architecture.yaml is derived from the module set

The scaffolded site's architecture.yaml (the apps/packages/namespaces the architecture linter walks + the import rules it enforces) is derived from the selected --modules, not copied from a fixed template. The module set is the single source of truth for the site's code-architecture boundaries:

  • A module → architecture-slice registry (src/module-architecture.ts) maps each recognized module to the boundary fragment it contributes.
  • deriveArchitecture(modules) (src/derive-architecture.ts, also exported from the package index) composes a module-independent base with the selected slices into one deterministic document. Same module set → byte-identical output.
  • The scaffolder writes the derived file at the target root, satisfying the scaffolded project.yaml's architecture_rules: architecture.yaml reference.

Sync on module-add is the same derivation re-run over the current module set — idempotent (re-deriving an unchanged set is a no-op), so adding a module later and re-deriving updates architecture.yaml to match. deriveArchitecture is exported for that re-derivation. MODULE_SLICES in src/module-architecture.ts declares a slice for every recognized module.

Templates are snapshotted at build time

The prepublishOnly script (scripts/build-templates.mjs) reads the canonical sources from this monorepo (apps/, database/, content/, root config) and populates templates/. The npm tarball ships the populated templates via the files field. A free-only scaffold performs no network access at scaffold time; only pnpm install (run by the user after scaffolding) hits the npm registry. A run naming a paid module fetches that module's bundle — see Paid modules require AILK_LICENSE_KEY.

Repository

Source: https://github.com/working-theory-labs/ai-launch-kit

Issues: https://github.com/working-theory-labs/ai-launch-kit/issues

License

Apache-2.0. See LICENSE.