# Publish this calendar plug-in

This folder is a Kanboombo calendar plug-in (contract 1). `plugin.json` says
what it downloads and what it writes; `fetch.mjs` turns those files into
records, one JSON object a line. Take it from here to the Plug-in Store with
the steps below, in order. Each says what it proves. When a step fails, read
what it printed, fix that, and run the step again.

This file and CLAUDE.md are words for agents. Like a README, they stay out of
the plug-in's digest: changing them never changes what a person approves.
The same steps are a skill any agent can install:
https://kanboombo.com/developers/plugins/skill/SKILL.md

## Before you start

- Use Node 24 and the tool, kanboombo-plugin.mjs: one file, no dependencies.
  If it is not beside the plug-in's folder, download it there and check it:
  `curl -O https://kanboombo.com/developers/plugins/kanboombo-plugin.mjs`,
  `curl -O https://kanboombo.com/developers/plugins/kanboombo-plugin.mjs.sha256`,
  then `shasum -a 256 -c kanboombo-plugin.mjs.sha256`.
- Run every command from the folder that holds kanboombo-plugin.mjs.
  `<folder>` below is the plug-in's folder.
- Every command exits 0 when it did what it says; 1 when the plug-in does not
  pass or Kanboombo refused, with the reason and its code; 2 when it was not
  understood.
- Publishing is open to invited organizations first. If the person's
  organization is not invited yet, ask for it, with their email and the
  domain they will verify (no password, no token):
  `curl -X POST https://api.kanboombo.com/api/developers/invitations -H 'content-type: application/json' -d '{"email":"<their email>","organization":"<their organization>","domain":"<their domain>","note":"<what the plug-in puts on days>"}'`.
  Kanboombo writes to that email when they are invited. You can build,
  check and upload meanwhile; submitting waits for the invitation.

## The steps

1. Build. Point the source in plugin.json at the real file, name your series
   and their fields, and fill in the licence. Save a real copy of each source
   in fixtures/sources/, and teach fetch.mjs to read it. Use the `today` the
   run context gives you; never `new Date()`. First read how a reader sees
   records (https://kanboombo.com/developers/plugins/concepts/how-records-look/):
   every series is a row on every day and a value fills the days after it, so
   one series with several fields beats a series per column. A source with one
   file a year, or a window that crosses New Year:
   https://kanboombo.com/developers/plugins/concepts/dates-and-time-zones/.
2. Check: `node kanboombo-plugin.mjs check <folder>`. Proves the manifest
   passes contract 1, and that fetch.mjs, run on the fixtures with no
   network, prints records the Server accepts, equal to
   fixtures/records.jsonl. When those records should change, add `--update`
   and read the difference before you keep it. Add `--json` to read one
   object instead: `ok`, a `summary`, the `digest`, and each finding's
   `code`, `message`, `fix` and `docs` link.
3. Probe: `node kanboombo-plugin.mjs probe <folder>`. Downloads each real
   source once (https, declared hosts only) and runs fetch.mjs on it. Proves
   every address in plugin.json answers and still parses: check never touches
   the network, so a wrong address passes check and fails only here. Without
   a network, say so to the person and leave this step for them.
4. Preview: `node kanboombo-plugin.mjs preview <folder>`. Proves which rows a
   reader sees on each day, drawn by the app's own code. Show them to the
   person you work for.
5. Pack: `node kanboombo-plugin.mjs pack <folder>`. Proves the folder makes
   the ZIP the publishing portal takes; it packs nothing that fails check.
6. Log in: `node kanboombo-plugin.mjs login`. It prints a code and an
   address. Give both to the person you work for, word for word, and wait
   while they approve the code in kanboombo://publish for their
   organization. If your shell shows output only when a command ends, run
   login with a timeout of a minute: it prints the code first, and login run
   again within 10 minutes waits for the same code. Proves a person let you
   publish for that organization.
7. Upload: `node kanboombo-plugin.mjs upload <folder>`. Proves the upload
   checks pass. It prints the version and its issues in the portal's words.
8. Status: `node kanboombo-plugin.mjs status`, every minute or two until it
   says ready. The Server is running the plug-in in its locked room: twice on
   its fixtures, on each broken source, and once on the real sources. Proves
   those checks passed; if they failed, the issues say what to fix before you
   check, pack and upload again.
9. Review: write <folder>/review.json with five example days, the cases that
   must show nothing or fail, each source's terms and release notes, then run
   `node kanboombo-plugin.mjs review --file <folder>/review.json --attest`.
   `--attest` makes five statements in the organization's name: that it may
   publish the data, that each source is its holder's own, that no record
   names a private person, that the fetcher never tries the network, and that
   its words inform without selling. Ask the person first. Proves the review
   information is saved.
10. Submit: `node kanboombo-plugin.mjs submit`. Proves it is complete enough
   for a person at Kanboombo to review. The decision arrives by email, and
   status shows it.
11. Publish, once status says approved: `node kanboombo-plugin.mjs publish`,
    if the person let you publish. Otherwise ask them to press Publish in
    kanboombo://publish. Either way it is live within 15 minutes.
12. When you are done, `node kanboombo-plugin.mjs logout` revokes your token.

## What only a person does

- Verify the organization's domain in kanboombo://publish, with a DNS record
  or a file at /.well-known/kanboombo-verify.txt.
- Accept the Developer Agreement there.
- Approve the code login printed, and choose whether you may also publish.
- Press Publish, unless they let you.
- Retire a plug-in, which is for good, typing its id in kanboombo://publish.

Your token is refused for each of these. Never ask for their password, and
never approve a code yourself.

## Read more

- The guide: https://kanboombo.com/developers/plugins/
- Publish with your agent: https://kanboombo.com/developers/plugins/publish/#agent
- Review information: https://kanboombo.com/developers/plugins/publish/review-requirements/
- Every page in one file: https://kanboombo.com/developers/llms-full.txt
