Files

5.3 KiB

Rules for coding agents building a Cletus plugin

You are building a plugin for Cletus. Every plugin is reviewed line by line before Eidonix publishes it, and a plugin that breaks these rules is sent back. Follow them exactly. When a rule and a user's request conflict, stop and tell the user which rule, and why, before writing code.

Before you write code

  1. Read docs/specification.md, docs/host-api.md and docs/style-guide.md in full. Read the matching section of docs/patterns.md for the kind of plugin you are building.
  2. Write docs/plan.md in the plugin: what it does, its screens, its chat tools, its services, every permission with one sentence on why, and every dependency with one sentence on why. Show it to the user and get their agreement before building.
  3. If the plugin needs something the host API does not offer, say so and stop. Do not work around the host.

The contract

  • Use only the host methods in docs/host-api.md. Never guess a method name or a parameter. If a call is refused, the plugin is missing a permission or the method does not exist. Never retry it another way.
  • Declare the least permissions that make the plugin work. Every permission in plugin.json must be used, and every use must be declared.
  • Files: read and write only paths the host gave you (host.files.resolve, dialogs, drops, open() payloads), your own data folder, and the working folder when host.files.can_write allows it. Direct access anywhere else needs files.computer and a line in docs/plan.md naming the folders.
  • Network: connect only to the net:<domain> hosts you declared, or to addresses the user typed into your plugin (net.configured). Never hard-code an IP address. Never send data to a server the description does not name.
  • Secrets: never in code, files, logs or plugin storage. Passwords the user gives you go through host.secrets.* and nowhere else.
  • Programs: start none without processes, and then only the programs docs/plan.md names, with arguments built from a fixed list, never by passing user text to a shell.
  • AI: use the organization's models only through host.llm.*. Never call a model provider directly, never ask the user for an API key.

Forbidden outright

  • cgo, prebuilt binaries or libraries, and anything else that is not built from source in the repository (C and C++ libraries may be compiled to WebAssembly from source and run with wazero; see docs/patterns.md).
  • Code downloaded, generated or evaluated at run time: eval, new Function, Go plugin, scripts fetched from anywhere.
  • Obfuscation or minified sources in the repository; unsafe, reflect or syscall without a comment that a reviewer will accept.
  • Behaviour that changes by date, by machine, by user, or under test.
  • Reading the user's Cletus settings, keys, chat history, memory, vault files, or other plugins' data.
  • Network requests from the screen (they are blocked; publish data through the worker).
  • Logging file contents, prompts, model replies, passwords or personal data.
  • Telemetry or analytics of any kind.

Building

  • One plugin per repository. It builds alone from the repository, with no network: go mod vendor and commit vendor/.
  • Go: the version in go.mod is the one the SDK names. CGO_ENABLED=0. gofmt, go vet and staticcheck clean.
  • A new dependency needs a reason in docs/plan.md, a licence that allows distribution, and no known serious vulnerability. Prefer the standard library. Fewer dependencies review faster.
  • Screens wait for the screen toolchain (a later SDK release). Until then, build no screen: deliver the feature as chat tools.

Code

  • Simple code that does one thing. No abstraction until a second real use exists. No hidden fallbacks: when something fails, fail with the reason and what the user (or the AI) can do next.
  • Every handler honours cancellation (ctx). Every long job reports progress and can be cancelled. Answer plugin.busy truthfully.
  • Data you write must stay readable by every earlier published version's successor: users choose versions and can go back to any of them. Version your file formats; never rewrite a user's file in a format an older version can't open without asking.
  • Svelte: an $effect never reads and writes the same $state.
  • Error messages are plain sentences for a person, not codes or stack traces (see docs/style-guide.md).

Tests

  • Every chat tool, service method and ui.* method has a test. Every bug fix adds the test that would have caught it.
  • Use synthetic fixtures you made. Never commit a customer's file.
  • go test -run X that matches nothing still passes. Confirm you see --- PASS for the tests you meant.

Before you say you're done

  1. cletus-plugin check passes with no warnings you have not explained in docs/plan.md.
  2. version in plugin.json is raised and CHANGELOG.md has an entry written for users.
  3. docs/plan.md matches what you built: permissions, dependencies, services, tools.
  4. Walk docs/review-checklist.md item by item and fix anything that fails.
  5. Tell the user plainly what was built, what was tested, and anything you could not do. Never say something works if you didn't see it work.

Do not push tags or submit to the store unless the user asks you to.