Skip to content

On this page

The file

The manifest of an OmniConflux plugin, host API 1.0. The file is named omniconflux-plugin.json, sits at the top of the plugin folder, is UTF-8 without a byte order mark, holds one JSON object and is at most 16384 bytes long.

This is manifest format 1 for plugin API 1.0. The API is MAJOR.MINOR: a host runs a plugin whose major is its own and whose minor is not greater than its own.

Members

Every member the manifest can hold, nested ones after their parent: commands[].id is the id of each entry of commands.

manifestVersionrequired

1

The version of this file format. Always 1.

apirequired

string

  • matches ^[1-9][0-9]{0,3}\.(?:0|[1-9][0-9]{0,3})$

The host API version the plugin was written for, as MAJOR.MINOR. A host runs the plugin when the major is equal to its own and the minor is not greater than its own.

idrequired

string

  • 3 to 64 characters
  • matches ^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$
  • does not match ^(?:omniconflux(?:-.*)?|omni|kev|aura|arena|daemon|host|app|plugin|plugins|system|operator|approvals|config|connections|core|council|evidence|fleet|handoff|missions|permissions|phone|placement|pty-holder|ratings|registry|review|risk|search|seats|sessions|settings|start|team|usage|verify|worktrees|xp|con|prn|aux|nul|com[0-9]|lpt[0-9])$

The plugin's identity on this machine: its folder name in the host's store, the prefix of its command ids and part of the name of its ledger stream. 3 to 64 characters: lowercase letters, digits and single hyphens, starting with a letter and not ending with a hyphen. Not a name of the product (omniconflux, anything that starts with omniconflux-, omni, kev, aura, arena), not a word for a part of it (daemon, host, app, plugin, plugins, system, operator), not the name of a part of the daemon or of one of its ledger streams (approvals, config, connections, core, council, evidence, fleet, handoff, missions, permissions, phone, placement, pty-holder, ratings, registry, review, risk, search, seats, sessions, settings, start, team, usage, verify, worktrees, xp), and not a device name of Windows (con, prn, aux, nul, com0 to com9, lpt0 to lpt9). At install the host also refuses an id that is a harness id of the registry.

namerequired

string

  • 1 to 48 characters
  • matches ^[!-~](?:[ -~]*[!-~])?$
  • does not match ^[Oo][Mm][Nn][Ii][Cc][Oo][Nn][Ff][Ll][Uu][Xx]

The name the app shows. 1 to 48 printable characters of the basic Latin range (U+0020 to U+007E), no space at either end. It may not start with the letters of OmniConflux in any letter case.

versionrequired

string

  • at most 64 characters
  • matches ^(?:0|[1-9][0-9]{0,5})\.(?:0|[1-9][0-9]{0,5})\.(?:0|[1-9][0-9]{0,5})(?:-[0-9A-Za-z][0-9A-Za-z.-]{0,31})?$

The plugin's own version, MAJOR.MINOR.PATCH with an optional pre-release part. Shown to the operator; the host does not compare versions, it compares files.

descriptionrequired

string

  • 1 to 200 characters
  • matches ^[!-~](?:[ -~]*[!-~])?$

One line that says what the plugin does, shown in the approval prompt. 1 to 200 printable basic Latin characters, no space at either end.

publisheroptional

string

  • 1 to 64 characters
  • matches ^[!-~](?:[ -~]*[!-~])?$

Who wrote the plugin, as the author states it. Never checked by the host and always shown as unverified. 1 to 64 printable basic Latin characters, no space at either end.

mainrequired

string

  • at most 200 characters
  • matches ^[A-Za-z0-9_][A-Za-z0-9._-]*(?:/[A-Za-z0-9_][A-Za-z0-9._-]*)*\.(?:js|mjs|cjs)$

The script the host runs with Node.js, as a path relative to the plugin folder with / between parts. Each part starts with a letter, a digit or an underscore and holds letters, digits, dots, underscores and hyphens; the file ends in .js, .mjs or .cjs.

permissionsrequired

array; each item is one of "events.read", "lists.read", "commands.add", "storage.own", "tasks.create"

  • at most 5 items
  • no item twice

The permissions the plugin asks for. The operator approves this exact list; the host refuses every call whose permission is not in it. May be empty, and may list them in any order: the approval prompt shows them, plugin.approve names them and the host compares them in the order of the permission table.

commandsoptional

array; each item is object

  • at most 8 items

The commands the plugin adds to the app's command list. Needs the commands.add permission. A command exists only here: there is no call that adds one at run time.

commands[].idrequired

string

  • at most 32 characters
  • matches ^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$

The command's id inside the plugin. The app and the host name the command <plugin id>.<command id>. 1 to 32 characters: lowercase letters, digits and single hyphens, starting with a letter and not ending with a hyphen.

commands[].titlerequired

string

  • 1 to 48 characters
  • matches ^[!-~](?:[ -~]*[!-~])?$

What the command list shows, always next to the plugin's display name. 1 to 48 printable basic Latin characters, no space at either end.

commands[].descriptionoptional

string

  • 1 to 120 characters
  • matches ^[!-~](?:[ -~]*[!-~])?$

One more line for the command list. 1 to 120 printable basic Latin characters, no space at either end.

commands[].inputoptional

one of "none", "text"

  • default "none"

none: the command runs as soon as it is chosen. text: the app first asks the operator for one line of text and passes it to the plugin.

No other members are allowed.

  • When commands has at least 1 item, permissions must contain "commands.add".

What else makes it invalid

Some rules are more than a schema can state. OmniConflux runs the folder checks first, then the manifest checks in this order, and stops at the first that fails. omniconfluxd plugin check runs them on your folder without installing anything and reports every failed folder check and the first failed manifest check, each with its problem code.

The manifest

M1

omniconflux-plugin.json is at the top of the folder, is a regular file of at most 16,384 bytes, and is UTF-8 without a byte order mark.

manifest-missing, manifest-too-large, manifest-not-text

M2

The file parses as JSON and holds one object. No object in it has the same member name twice, and none has a member named __proto__, constructor or prototype.

manifest-not-json, manifest-duplicate-member, manifest-member-name

M3

manifestVersion is the number 1, and api has the form MAJOR.MINOR and names a version this host runs. This comes before the full schema, so a manifest written for a newer host is reported as that.

manifest-version, manifest-invalid, api-unsupported, api-too-new

M4

The object is valid against the manifest schema: the members on this page and nothing else, with commands.add in permissions when there is a command. Every text the operator reads is checked once more to be printable basic Latin.

manifest-invalid

M5

No two commands share an id.

command-id-repeated

M6

main names a regular file inside the folder.

main-missing

M7

At install and again at approval: the name does not read like another plugin's name or like the product's. Two names read alike when they are equal after lowercasing, dropping everything but letters and digits, and reading 0 as o, 1 and i as l, rn as m and vv as w.

name-taken

M8

At install and again at approval: the id is not the id of a harness OmniConflux knows.

id-taken

The plugin folder

F0

At install, on the folder you give: nobody but you can change it. The folder, everything in it and the folders above it may not be writable by a group or by others, and a shared folder such as /tmp is refused.

source-writable

F1

The path is a folder itself, not a link to one.

not-a-folder

F2

Everything in it is a regular file or a folder: no symbolic link, junction, device, FIFO or socket, and no file with more than one hard link.

file-kind

F3

Each part of each path is 1 to 100 letters, digits, dots, underscores and hyphens of basic Latin, after a first character that is a letter, a digit, an underscore or @. It does not end with a dot and is not a Windows device name.

file-name

F4

No two paths are equal after lowercasing.

file-case

F5

At most 10,000 files.

too-many-files

F6

At most 64 MiB (67,108,864 bytes) in all files together.

too-large

F7

Each path inside the folder is at most 200 characters and at most 16 parts deep.

path-too-long

Examples

The schema's own examples. Both are valid manifests.

omniconflux-plugin.json for hello-desk
{
  "manifestVersion": 1,
  "api": "1.0",
  "id": "hello-desk",
  "name": "Hello Desk",
  "version": "0.1.0",
  "description": "Counts finished turns and shows the count.",
  "main": "main.mjs",
  "permissions": []
}
omniconflux-plugin.json for night-shift
{
  "manifestVersion": 1,
  "api": "1.0",
  "id": "night-shift",
  "name": "Night Shift",
  "version": "1.2.0",
  "description": "Starts a follow-up task when a lane is verified.",
  "publisher": "Example Works",
  "main": "dist/main.mjs",
  "permissions": [
    "events.read",
    "lists.read",
    "commands.add",
    "storage.own",
    "tasks.create"
  ],
  "commands": [
    {
      "id": "summary",
      "title": "Show tonight's summary",
      "description": "Lists the lanes verified since the last run."
    },
    {
      "id": "note",
      "title": "Add a note",
      "input": "text"
    }
  ]
}

Plugins ship inside the app

OmniConflux 0.3.0 is released for Omarchy, macOS on Apple silicon and Windows, in a closed beta with a waitlist. Plugins and the SDK ship inside the app from 0.3.0, and the SDK is not on a package registry.