JSPM

@nikip0/colorless

1.0.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 7
  • Score
    100M100P100Q74314F
  • License MIT

Authorize, gate, and prove every action your AI agent takes — tamper-evident, zero-dependency.

Package Exports

  • @nikip0/colorless

Readme

colorless (JavaScript / TypeScript)

Authorize, gate, and prove every action your AI agent takes. Tamper-evident. Zero dependencies. First-class TypeScript types. The JS/TS port of colorless.

npm install @nikip0/colorless   # zero dependencies (uses only Node built-ins; Node >= 18)
import { Colorless } from "@nikip0/colorless";

const cl = new Colorless({ ledger: "agent.jsonl", onApproval: pingSlack });

cl.deny("delete_database");                                   // never
cl.requireApproval("refund", (a) => a.args.amount > 100);     // big ones need a human

const refund = cl.guard(async ({ amount, to }) => pay(amount, to), { name: "refund" });

await refund({ amount: 80, to: "cust_12" });    // runs — sealed in the chain
await refund({ amount: 5000, to: "cust_12" });  // throws ApprovalRequired until a human says yes

cl.verify();   // { ok: true, length: 412, head: "9f3c…" } — proof nothing was altered

Tool calls (OpenAI / Anthropic / MCP)

import { Colorless, ToolGuard, PolicyDenied } from "@nikip0/colorless";

const cl = new Colorless({ ledger: "agent.jsonl" });
cl.deny("delete_repo");

const tg = new ToolGuard(cl);
tg.add("search_web", searchWeb);
tg.add("send_invoice", sendInvoice);

for (const call of llmResponse.toolCalls) {
  try {
    const result = await tg.call(call.name, call.arguments);   // gated + sealed
  } catch (e) {
    if (e instanceof PolicyDenied) /* hand the refusal back to the model */;
  }
}

Same ledger, any language

This SDK writes the exact same JSONL hash-chain format as the Python engine, so a ledger an agent writes in Node can be verified from the terminal with the Python CLI:

colorless verify agent.jsonl    # ✓ verifies a Node-written ledger (any JSON value; see note below)

Cross-language verify covers strings (incl. non-ASCII/emoji), integers, booleans, null, and ordinary decimals. The one edge: floats that serialize in scientific notation (e.g. 1e-7, very small/large) format differently in Python vs JS — avoid those in payloads you verify across languages.

API

  • new Colorless({ ledger, policy, onApproval, redact })redact defaults to "auto" (secrets masked); pass null to disable.
  • .deny / .allow / .requireApproval(name?, when?, reason?) — ordered rules, first match wins.
  • .guard(fn, { name }) — wrap a tool (sync or async). .run(name, args, fn) — gate a call directly.
  • .verify() · .head() · .entries(ref?) · .anchor(path) · .verifyAgainstAnchor(path).
  • .subscribe(cb) — fire cb(entry) after every sealed action (build alerts/exporters). onApproval may return { approved, approver } to seal who authorized it.
  • ToolGuard(cl).add(name, fn).call(name, args) — gate + seal one tool call.

MIT © 2026 Niki Petrov