Arvexa OS
Get API key
Loading API Reference from OpenAPI…
Guide

Plugin Project Structure

The exact package layout, and why packing is reproducible

A plugin project directory contains at most five top-level entries. Two files are required, two directories are required, and one directory is optional:

  • manifest.json — required, plugin-package-1.0
  • README.md — required
  • src/ — required; entrypoint sources, plain .js
  • tests/ — required; harness test files, plain .js
  • assets/ — optional static files

Everything else is excluded. The rule is an allowlist over a denylist, which is the point: a stray .env, a node_modules/ tree, a private key, or an editor backup in your project directory cannot be swept into an uploaded archive because it was not on the list, not because someone remembered to name it. Symlinks are never followed. arvexa plugin validate prints everything it excluded, so nothing is silently dropped.

No build step, no transpilation, no dependencies. The runtime loads the exact bytes in src/. It denies module loading, so a handler cannot require a library, a sibling file, or anything else. Write plain CommonJS that runs as-is; TypeScript sources, bundles, and node_modules have no meaning inside a package.

Packing is reproducible, and that is a security property. arvexa plugin pack writes a .arvexa-plugin archive with stored (uncompressed) entries, a fixed 1980-01-01 timestamp, lexicographically sorted paths, and fixed 0644 attributes. Identical inputs therefore produce byte-identical output on every machine, and the printed sha256 content hash is stable.

That hash is the identity every piece of evidence binds to. A security scan verdict and a test report apply to one exact content hash; the install gate re-checks it. If packing were not reproducible, an author could pass a scan on one archive and install a different one, and the platform's "exact-package scan Pass" guarantee would be unenforceable.

Nested archives are rejected, paths may not traverse, and the packed size is capped at 25,000,000 bytes.

A first project, from an empty directory:

  1. 1Create manifest.json, README.md, src/, and tests/.
  2. 2Run arvexa plugin validate . — it reports every problem at once, not the first.
  3. 3Run arvexa plugin pack . and note the content hash.
  4. 4Run arvexa plugin test . --preflight-only for the offline harness checks.
  5. 5Only then obtain a Developer API key and upload.

A complete, validating example ships in the repository at examples/plugins/call-outcome-observer.