# kanboombo-plugin.mjs

Every command of the plug-in tool and its options, generated from the tool itself. One file for Node 24, with no dependencies and no install.

One file holding the Server's checker, the words for every problem and the
app's day-drawing code. Its first lines name each file it was built from, with
its SHA-256, and its licence, MIT-0. This page is version 1.5.0.

```sh download
curl -O https://kanboombo.com/developers/plugins/kanboombo-plugin.mjs
curl -O https://kanboombo.com/developers/plugins/kanboombo-plugin.mjs.sha256
shasum -a 256 -c kanboombo-plugin.mjs.sha256
```

`node kanboombo-plugin.mjs help <command>` prints any command's usage.

## Commands

### init {#init}

```text
node kanboombo-plugin.mjs init <id> [--kind value|event|item] [--timezone <zone>]
```

Start a plug-in in a new folder named \<id\>: a manifest, a fetcher and fixtures that pass check before you change a line.

| Option | What it does |
|---|---|
| `--kind` | The kind of series to start with: value (numbers on a date; the default), event or item. |
| `--timezone` | The plug-in's IANA time zone, such as Pacific/Auckland. It decides your plug-in's today. Default: this machine's. |

### check {#check}

```text
node kanboombo-plugin.mjs check [<folder>] [--update] [--json]
```

Check a plug-in as the Server will: the manifest, its imports, a run of fetch.mjs on fixtures/sources/ with no network, every record, fixtures/records.jsonl and each fixtures/runs/\<case\>. Prints the digest an approval covers.

| Option | What it does |
|---|---|
| `--update` | Write what fetch.mjs prints to fixtures/records.jsonl instead of comparing. Read the difference before you keep it. |
| `--json` | Print one JSON object instead of text, for your agent: {ok, summary, findings, digest}, each finding with its code, severity, message, fix and docs link, in the words the text uses. It prints it even when check finds problems, and exits 1 then. |

### preview {#preview}

```text
node kanboombo-plugin.mjs preview [<folder>] [--days <from>..<to>] [--language <code>] [--run <case> | --live] [--html <file> | --json]
```

Show the rows your fixture puts on each day, worked out by the code the app draws them with.

| Option | What it does |
|---|---|
| `--days` | The days to show, as YYYY-MM-DD..YYYY-MM-DD, at most 62. Default: three days either side of the fixture's today. |
| `--language` | Show your plug-in's own names (its name, series and fields) in this language, as a reader of it sees them. Dates, figures and the app's own words stay in English, as the app draws them today. Default: en. |
| `--run` | Preview fixtures/runs/\<case\> instead of the folder's own fixtures. |
| `--live` | Preview today's real sources instead of your fixtures: download them once (https, declared hosts only), as probe does. |
| `--html` | Also write the days as an HTML page you can open. |
| `--json` | Run check first, then print one JSON object instead of text: {summary, cache, findings, digest}, what Kanboombo on your Mac draws your days from. It prints it even when check finds problems, and exits 1 then. |

### probe {#probe}

```text
node kanboombo-plugin.mjs probe [<folder>]
```

Download the real sources once (https, declared hosts only) and run fetch.mjs on them. It reaches the real source; it is never part of a check.

### pack {#pack}

```text
node kanboombo-plugin.mjs pack [<folder>] [--out <file>]
```

Check the plug-in, then write the ZIP the publishing portal takes, with .kanboombo-pack.json inside. Refuses unless check passes. The same files give the same bytes.

| Option | What it does |
|---|---|
| `--out` | Where to write it. Default: \<id\>-\<version\>.zip beside the folder, never inside it. |

### digest {#digest}

```text
node kanboombo-plugin.mjs digest [<folder>] [--files]
```

Print the digest an approval covers: SHA-256 over the plug-in's code, without fixtures, listing, README, AGENTS.md or CLAUDE.md.

| Option | What it does |
|---|---|
| `--files` | Also list the files the digest covers, in the order it reads them. |

### login {#login}

```text
node kanboombo-plugin.mjs login [--server <url>] [--name <agent name>]
```

Ask to publish for an organization. It prints a code and an address, and waits while a person who owns or runs the organization approves the code in kanboombo://publish. Approved, it keeps the token in ~/.config/kanboombo/plugin-token.json, readable only by you. Run again within 10 minutes, it waits for the same code.

| Option | What it does |
|---|---|
| `--server` | The Kanboombo API to publish to. Default: https://api.kanboombo.com. |
| `--name` | How the approval screen names this agent. Default: the agent it runs in and this machine, such as Claude Code on build-box. |

### logout {#logout}

```text
node kanboombo-plugin.mjs logout
```

Revoke this agent's token and delete it from this machine.

### upload {#upload}

```text
node kanboombo-plugin.mjs upload [<folder>]
```

Check and pack the plug-in, then upload it to your organization in the publishing portal. Prints the version, its status and what the upload checks found, in the portal's words. The Server then runs it in its locked room.

### status {#status}

```text
node kanboombo-plugin.mjs status [<version>]
```

Show where a version stands: its status, its issues, what the Server's checks found and what to do next. \<version\> is a version id, or a plug-in's folder or id for the last version uploaded from here. Default: the plug-in in the folder you are in, or else your last upload.

### review {#review}

```text
node kanboombo-plugin.mjs review [<version>] --file <review.json> [--attest]
```

Fill in a version's review information from a file: example days, the cases that must show nothing or fail, each source's terms and release notes.

| Option | What it does |
|---|---|
| `--file` | The review information, as JSON. Required. |
| `--attest` | Also make the five statements, in your organization's name: you may publish the data, each source is its holder's own, no record names a private person, the fetcher never tries the network, its words inform without selling. Only when they are true and the person you work for agrees. |

### submit {#submit}

```text
node kanboombo-plugin.mjs submit [<version>]
```

Submit a version for review by a person at Kanboombo. Refused, with each reason, until the Server's checks passed, the review information is complete, the five statements are made, and your organization is verified, invited and has accepted the current Developer Agreement.

### publish {#publish}

```text
node kanboombo-plugin.mjs publish [<version>]
```

Publish a version Kanboombo approved. Only an agent approved with publishing allowed may; otherwise a person presses Publish in kanboombo://publish.

### unpublish {#unpublish}

```text
node kanboombo-plugin.mjs unpublish [<plug-in>]
```

Take a published plug-in out of the Plug-in Store: nobody new can install it, it keeps running for readers who have it, and they see it is no longer listed. \<plug-in\> is its id or its folder; default: the folder you are in. Only an agent approved with publishing allowed may.

### relist {#relist}

```text
node kanboombo-plugin.mjs relist [<plug-in>]
```

Put a plug-in you unpublished back in the Plug-in Store. Never one Kanboombo took down or took off the shelf, and never one that is retired. Only an agent approved with publishing allowed may.

### retire {#retire}

```text
node kanboombo-plugin.mjs retire [<plug-in>]
```

Retiring is for good: its runs stop, readers keep the records it wrote, and its id is never used again. So only a person retires, in kanboombo://publish, typing the id; the API refuses an agent, and this says where the person does it.

### help {#help}

```text
node kanboombo-plugin.mjs help [<command>]
```

Show every command, or one command's options.

## Exit codes

| Code | Means |
|---|---|
| `0` | Done: the plug-in passes, or the command did what it says. |
| `1` | The plug-in does not pass (its problems are on standard error), or `probe` could not reach a source. `pack` and `upload` send or write nothing. For the publishing commands, also: you are not logged in, Kanboombo could not be reached, or it refused, with its code and message on standard error. |
| `2` | The command was not understood: an unknown command or option, a missing argument, a refused `--days`, `--server` or `--file`. |

## Where it runs your code {#where-it-runs-your-code}

`check`, `preview`, `pack` and `init` run `fetch.mjs` on your machine, as you,
on your fixtures, behind a [guard](/developers/plugins/build/fixtures/#check):
a seat belt, not a sandbox.

## On your own days {#on-your-days}

Turn on Developer Mode in Settings and choose a folder under **A plug-in folder
on your days**: before any review, its section shows "On this Mac · not
published", with Run again, What check found, Open the folder and Publish… in
its "…" menu. Kanboombo runs `preview --json` on it, with its own Node:

```json norun="its shape: what Kanboombo draws your days from"
{
  "summary": { "id": "dop-economy", "name": { "en": "DOP Economy" }, "source": "Banco Central", "series": [], "freshness": {}, "today": "2026-10-07", "records": 60 },
  "cache": { "series": {}, "covered": {}, "freshness": {}, "unreachable": false },
  "findings": [],
  "digest": "5e34581c…"
}
```

Nothing is stored and nothing leaves your Mac: the `local`
[audience](/developers/plugins/plan/data-rights/#local).

## What reaches Kanboombo, and what it keeps

Only `probe` and `preview --live` (your sources) and the publishing commands,
`login` to `publish`, use the network. Those talk only to the API `login` was
given, send your token nowhere else and follow no redirect
([With your agent](/developers/plugins/publish/#agent)). `login` keeps its
token in `plugin-token.json` and `upload` the last version per plug-in in
`plugins/<id>.json`, in `~/.config/kanboombo/`, readable only by you;
`KANBOOMBO_PLUGIN_HOME` moves it (one per agent on a shared machine), and
`logout` revokes and deletes the token. `KANBOOMBO_PLUGIN_NOW`, an ISO time, is
the moment `init` writes into `fixtures/context.json`; these docs set
`2026-09-30T19:30:00.000Z`.

## Versions {#versions}

- **1.5.0.** `check --json`: one object, each finding with its code, fix and
  docs link.
- **1.4.0.** `check` counts the `runs/<case>` it passed; `pack` warns about
  `init`'s README; `init` keeps acronyms (US).
- **1.3.0.** `preview --json`, which your Mac draws your own days from;
  `preview --live`, on today's real sources; a fetcher in a folder reached
  through a link (`/tmp` on a Mac) may read its own files.
- **1.2.0.** `unpublish`, `relist`, and `retire`, which says where a person
  retires a plug-in, since only a person may; codes `PLG-LISTING-*` and
  `PLG-RETIRE-CONFIRM`.
- **1.1.0.** Publish with your agent: `login`, `logout`, `upload`, `status`,
  `review`, `submit` and `publish`. `init` also writes `AGENTS.md` and
  `CLAUDE.md`.
- **1.0.0.** `init`, `check`, `preview`, `probe`, `pack`, `digest` and `help`.
  Reading outside the folder fails with `PLG-RUN-READ-OUTSIDE`.

Contract 1's own changes are in [the manifest](/developers/plugins/reference/manifest/#changelog).
