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

@kancode/cruise-control

v0.2.0

Published

Cruise Control: an LLM permission classifier for KanCode. Rates pending tool actions for risk and user intent, then auto-allows or denies with fail-closed safety rails.

Readme

@kancode/cruise-control

An LLM permission classifier for KanCode. It rates each gated tool action for risk and user intent, then auto-allows or denies — so routine work proceeds without prompting while anything unclear still reaches you.

Registers the permission module id cruise_control.

Install

kancode plugin @kancode/cruise-control

Or add it to kancode.json yourself:

{
  "plugin": ["@kancode/cruise-control"],
  "permission": { "bash": "cruise_control", "edit": "cruise_control" },
  "permission_modules": {
    "cruise_control": { "model": "opencode/deepseek-v4-flash" }
  }
}

A model must be configured. Without one the module asks you to approve manually and hints at /cruise-control-model; it never silently allows.

/cruise-control-model

The plugin also registers a TUI command to pick the classifier model, so it appears exactly when the classifier it configures is installed:

/cruise-control-model

It shows the current model, opens KanCode's own provider/model picker, and writes your choice to permission_modules.cruise_control.model in global config. Bind it with the permission_cruise_control_model keybind slot.

How a decision is made

Evaluation short-circuits in this order, so most decisions never reach the model:

  1. Destructive denyrm -rf, DROP DATABASE, TRUNCATE, force-push to main, mkfs, dd of=/dev/…. This is a pattern-matched backstop for common forms, not a sandbox: obfuscated equivalents can slip past it, so the model and your allowlist remain the real controls.
  2. Managed app directoriesexternal_directory inside KanCode's own config/data/cache/state/tmp roots.
  3. Session-scoped todo / rename — session state, not filesystem writes.
  4. Per-prompt cache — decisions learned earlier in the same turn (deny wins over allow).
  5. Explicit approval — you answered a short "ok"/"go ahead" to an assistant permission ask naming this action.
  6. Model classification — structured {risk, intent, reason}, then:
    • risk: low or intent: high → allow
    • risk: medium and intent: medium → allow
    • otherwise → deny
  7. Safety rails — a candidate allow is downgraded unless the permission is on allowlist and absent from never_auto.

Failure always denies. Timeouts, provider errors, and unparseable output fail closed. Only risk: low outcomes are cached, and the cache clears on every new user message.

The classifier sees a filtered view: your messages plus tool names and truncated arguments. It never sees assistant text, reasoning, or tool results. Tool input is wrapped in a delimited block so it cannot be read as instructions.

Options

All under permission_modules.cruise_control:

| Option | Default | Meaning | | --- | --- | --- | | model | (required) | providerID/modelID used to classify | | instructions | built-in | background / allow / conditional / deny string arrays | | allowlist | common tools | Permissions eligible for auto-allow; [] disables auto-allow entirely | | never_auto | [] | Permissions that always escalate, even on allow | | timeout_ms | 8000 | Per-attempt budget for the model call | | retries | 3 | Max attempts including the first | | retry_interval_ms | 2000 | Delay between attempts | | parallel_classify | false | Allow concurrent classification | | classify_gap_ms | 250 | Minimum gap between serialized calls | | dynamic_list | enabled | { enabled, max_size } for the per-prompt cache |

Only sections you set are used; missing ones fall back to built-in defaults. Defaults are applied, never written into your config, so improvements ship with the plugin instead of going stale in a file you never edited.

Disabling

{ "plugin_enabled": { "puetsua.cruise-control": false } }

If the plugin is missing or fails to install, KanCode degrades to asking you normally — it does not deny.

Compatibility

Requires a KanCode host that provides the plugin model capability (input.model) and permission.registerModule. No engines gate is declared: KanCode's compatibility check is skipped entirely for 0.x hosts, so a range there would be inert today and misleading tomorrow. On a host without the capability the module registers but every decision fails closed to deny.

This package has no runtime dependencies. The host contract is mirrored as types in src/host.ts.

Releasing

Tag a semver version with no v prefix; .github/workflows/release.yml builds, tests, verifies both entries load under real Node, and publishes via npm trusted publishing (OIDC — no token stored in the repo).

npm version 0.1.1 --no-git-tag-version
git commit -am "release: 0.1.1" && git tag 0.1.1 && git push --follow-tags

The workflow fails if the tag and package.json version disagree. Use the workflow_dispatch trigger for a dry run.

Previous name

Published as @puetsua/kancode-cruise-control through 0.1.1. That name is deprecated; nothing else changed.

License

MIT