Appearance
Packages
kernl has four packages under the @kernl scope, not yet published to npm (see Install). Three are pure contracts and engines with zero framework dependencies; one composes them with kehto and applesauce. The shell app at apps/web is not published.
| Package | Version | Role | Dependencies | Peer dependencies |
|---|---|---|---|---|
@kernl/guard | 0.1.0 | Ingress flood control, visibility gate, focus-aware firewall, CSP profile, nested-frame lock, mitigation descriptions. | @kehto/firewall | @napplet/core |
@kernl/messaging | 0.1.0 | Messaging provider contract, registry, composite direct-message adapter, in-memory backend. | none | @napplet/core (the Dm* wire types) |
@kernl/bridges | 0.1.0 | Locator parsing, bridge contract, registry, HTTP bridge with SSRF policy. | none | none |
@kernl/core | 0.1.0 | Composition root over kehto and applesauce: adapters, applet resolution, mount plan, consent summaries, layouts, persistence. | the three above, @kehto/*, applesauce-*, rxjs | @napplet/core, @napplet/nap, @napplet/shim, nostr-tools (required by kehto and applesauce; never imported) |
Shared rules
- ESM only, TypeScript strict,
verbatimModuleSyntax. Each package shipsdist/index.jsanddist/index.d.tswithsideEffects: false. - Every public export has JSDoc with
@param,@returnsand@example, and appears in the API reference. - Streams in
@kernl/coreare rxjsObservables (session$,guard.events$,grants.changes$,relays.changes$,AppletHandle.status$); unsubscribe theSubscriptionthey return.MessagingBackend.subscribereturns{ subscriptionId }, which you pass tounsubscribe. Thrown errors carry a stable prefixed reason:denied:,invalid:,unavailable:; the full list is in Error reasons. - No published package imports
nostr-toolsdirectly, and no published package depends on a UI framework.pnpm check:depsenforces both. - Behaviour is specified in Gherkin under each package's
features/and run by vitest with 100% coverage oversrc.
Versioning
All packages are 0.x. A breaking change is a minor bump; everything else is a patch. Releases are managed with changesets: one changeset per package whose shipped output changed. @kernl/core depends on the other three with workspace:^, so a release of a leaf package produces a patch of core.
Install
The @kernl/* packages are not yet published to npm; pnpm add @kernl/core fails with a not-found error. During the alpha the source repository is private, and the packages are used from a clone of it:
bash
# in a clone of the kernl source repository
pnpm install && pnpm buildpnpm build writes each package's dist/, which is what main, types and exports point at. Then add your code as a workspace package (under packages/ or apps/, the globs in pnpm-workspace.yaml) and depend on what you need with the workspace protocol, as apps/web does:
json
{
"dependencies": {
"@kernl/core": "workspace:^",
"@kernl/guard": "workspace:^"
}
}Run pnpm install again after editing the manifest so pnpm links the workspace packages. @kernl/core pulls the other three in. Install a leaf package alone when you want its contract without kehto and applesauce, for example @kernl/guard to test an applet against the limits, or @kernl/messaging to write a provider.