Repository navigation
Plugin Manifest
plugin.json with "manifest_version": 2 is the one authored plugin schema. It is generated from the Go types in internal/plugin/manifestv2 and published as schemas/plugin-manifest.v2.schema.json (JSON Schema draft 2020-12). A file without manifest_version (or with 1) is v1: the CLI still reads it through one normalizer and prints a one-line deprecation notice per process in v1.5 mode (Compat-V15).
Released 1.4.x CLIs decode plugin.json permissively, so v2 never reuses a v1 key with a different JSON type or a narrower enum. The CLI block is commands (v1 cli is a string), the runtime block is service (v1 runtime is a string), and the lifecycle enum is maturity (v1 status has a fixed enum).
{
"manifest_version": 2,
"name": "tenant",
"version": "1.0.0",
"description": "Multi-tenant operations",
"category": "infrastructure",
"license": "free",
"maturity": "implemented",
"service": {"kind": "cli"},
"commands": {"command": "tenant", "binary": "nself-tenant", "summary": "Manage tenants"}
}Add the generated compatibility keys with manifestv2migrate -compat -write (below).
Command binaries share ~/.nself/plugins/bin/. Publication refuses a binary
claimed by another installed plugin with E141 before replacing any target.
Removal skips binaries another installed plugin also claims, preserving that
plugin's command even if the removed plugin's manifest was edited. Ownership
comes from readable installed manifests; upgrades may replace their own binaries.
Three groups share one flat object:
-
Canonical v2 keys:
manifest_version,license,maturity,installable,requires,service,commands,schema,migrations,seed,env,routes,docs_url. -
Shared v1 keys: authored with the v1 name and JSON type and read natively (for example
port,dependencies,optionalDependencies,visibility,tables,permissions,envVars,deprecation,requiredEntitlements). The list is the set of keys a v1.4.12 reader decodes, committed astools/manifestv2migrate/testdata/v1412-readers.txt. Polymorphic v1 shapes (groupeddependencies, object-formwebhooks) are written in their one canonical shape. - Compatibility keys: generated, never authored (below).
Bundle membership is not a manifest field: bundles.json is the membership source. bundles, tier_pair, author_public_key, signature and checksum are rejected in a v2 file (E111).
| Key | Type | Required | Rule |
|---|---|---|---|
apiEndpoints |
array or null | no | |
arch_support |
array or null | no | |
author |
string | no | |
binaryName |
string | no | |
capabilities |
array or null | no | What the plugin offers, as a list of names. Same key and type as v1; read from the installed plugin.json by the MCP plugin. |
category |
string | yes | |
cli |
string | no | |
cliCommands |
array or null | no | |
commands |
object or null | no | CLI surface mounted as nself <command>; null when the plugin adds no command. |
compat |
object or null | no | |
consumes |
array or null | no | |
dependencies |
array or null | no | |
deprecation |
object or null | no | |
description |
string | yes | |
docs_url |
string | no | pattern ^https://
|
entryPoint |
string | no | |
env |
object or null | no | |
envVars |
array or null | no | |
framework |
string | no | |
graphql |
object or null | no | |
health_endpoint |
string | no | |
homepage |
string | no | |
installable |
boolean or null | no | Defaults to true when absent. |
isCommercial |
boolean | no | |
language |
string | no | |
license |
string | yes | free or licensed. Bundle membership is not a manifest field (ADR 0008).; one of free, licensed |
licenseType |
string | no | |
license_spdx |
string | no | Licence text carried from a v1 file (an SPDX identifier or Source-Available); shown by plugin info. |
manifest_version |
integer | yes | Always 2.; always 2 |
maturity |
string | yes | Lifecycle. deferred requires deprecation.state.; one of implemented, experimental, scaffolded, planned, deferred |
maxNselfVersion |
string | no | |
migrations |
object or null | no | |
minNodeVersion |
string | no | |
minNselfVersion |
string | no | |
multiApp |
object or null | no | |
name |
string | yes | Plugin slug, unique per tier.; pattern ^[a-z][a-z0-9-]*$
|
optionalDependencies |
array or null | no | |
packageManager |
string | no | |
permissions |
array or object | no | Same key and shape as v1: canonical permission strings, or categories mapped to actions. |
platform_checksums |
object | no | |
pluginType |
string | no | |
port |
integer | no | |
provides |
array or null | no | |
repository |
string | no | |
requiredEntitlements |
array or null | no | |
requires |
object or null | no | |
requires_license |
boolean | no | |
rest_routes |
array or null | no | |
routes |
array or null | no | |
runtime |
string | no | |
schema |
string or null | no | np_<name with - replaced by _>. |
seed |
object or null | no | |
service |
object | yes | How the plugin runs. kind compose requires compose and healthcheck. |
status |
string | no | |
systemDependencies |
object or null | no | |
tables |
array or null | no | |
tags |
array or null | no | |
tier |
string | no | |
updated_at |
string | no | |
version |
string | yes | Plugin version (semver).; pattern ^v?[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?(\+[a-zA-Z0-9.]+)?$
|
views |
array or null | no | |
visibility |
string | no | |
webhooks |
array or null | no |
commands is {command, binary, summary?, side_effect?, output?, json?, confirm?, surface?, subcommands: [...]} or null. command and every space-separated segment of a subcommand name match ^[a-z][a-z0-9-]*$; binary matches ^nself-[a-z][a-z0-9-]*$. command must not be one of the core command verbs (E113). A subcommand has name, summary, side_effect, output, json, args, flags, and optional confirm and surface.
-
confirm: {flags: [...], plan?: {flag, id_flag}}names the bool flags that confirm a destructive run. An emptyflagslist is valid (a nonce-only round trip). Every named flag must be a declared bool flag of the same command, andplan.id_flaga declared string flag (E106 names the field, for examplecommands.subcommands[0].confirm.flags[0]). The root declares no flags, so only an empty list is valid there. -
surface: all | cli-only(defaultall). - An arg takes
secret: bool; a flag takessecret: boolandcli_only: bool.
v1 status
|
v2 maturity
|
compatibility status
|
|---|---|---|
stable, beta, absent |
implemented |
stable |
experimental, alpha
|
experimental |
experimental |
planned |
planned |
planned |
deprecated |
deferred + deprecation.state: deprecated
|
deprecated |
eol |
deferred + deprecation.state: eol
|
eol |
| none | scaffolded |
experimental |
deferred requires deprecation.state. State deprecated also requires announcedDate, eolDate and migrationGuide, because released CLIs reject a deprecated plugin without them.
These keys exist only so released 1.4.x CLIs keep decoding a v2 file. manifestv2migrate -compat writes them; loading a file whose derived keys differ from the v2 fields fails with E112. E112 checks the derived keys only: the carried keys (entryPoint, runtime, cli, cliCommands entries other than the canonical command, and a licensed plugin's tier and licenseType) are trusted as written, so a hand edit there passes the gate.
| Key | Derived from |
|---|---|
pluginType, binaryName
|
commands (cli and commands.binary; empty when commands is null) |
minNselfVersion |
lower bound of requires.nself
|
status |
maturity and deprecation.state (table above) |
isCommercial, licenseType, requires_license, tier
|
license: free gives false, free, false, free; licensed gives true, <licenseType>, true, <tier>, where the licensed plugin's own licenseType and tier (max, cloud, internal) are carried and pro is used when it states none |
cliCommands |
the entry named like commands.command takes commands.summary as its description; other entries are carried |
entryPoint, runtime, cli
|
carried verbatim from v1: no v2 field defines them |
The v1 license text (an SPDX identifier or Source-Available) is kept in license_spdx; nself plugin info shows it as before. Released CLIs read the v2 license value (free or licensed) as the text.
v1 reading and all compatibility keys are removed at v1.6.0.
| Code | Meaning |
|---|---|
| E106 | invalid manifest; the message names the field |
| E111 | a forbidden key in a v2 file |
| E112 | compatibility keys drifted from the v2 fields |
| E113 |
commands.command is a core command verb |
| E114 | unsupported manifest_version
|
go run github.com/nself-org/cli/tools/manifestv2migrate -in plugin.json # print canonical v2
go run github.com/nself-org/cli/tools/manifestv2migrate -in plugin.json -write # convert in place
go run github.com/nself-org/cli/tools/manifestv2migrate -in plugin.json -compat -write # regenerate compatibility keys
go run github.com/nself-org/cli/tools/manifestv2migrate -in plugin.json -check # exit 1 unless canonical v2
go run github.com/nself-org/cli/tools/manifestv2migrate -in plugin.json -targets # binary and command pairsOutput has sorted keys, 2-space indent and a trailing newline; running it on its own output changes nothing. The converter maps v1 binaryName to commands.binary, the cliCommands entry named like it to commands.command (other binaries such as sentry-server or billing stay compatibility-only), and binaryName: null to commands: null. It derives service (a port means compose, a binary without a port means cli, otherwise library).
The converter never drops data silently. Every non-empty v1 key with no v2 home (for example actions, config, binary_name, download_url, tarball) is listed on stderr with its value path, and the run exits 1 with nothing written and nothing on stdout. This holds for the default run, -write and -check, and the lists are identical. Empty values (null, "", [], {}) carry nothing and are ignored. Registry-owned keys (bundles, checksum, tier_pair, author_public_key, signature) are removed on purpose (ADR 0008) and reported as a note. A v1 file that v1.4.12 accepts without a category loads, but the converter will not write an invalid v2 file: add the category first.
Some v1 keys convert when their value converts without loss:
-
routes(the plugin's own API:method,path,auth, optionaldescriptionandhmac) becomesrest_routes(descriptionbecomessummary;authandhmacare optional additions). It never becomes the v2routeskey, which is nginx exposure (path,upstream_port). An entry with any other key, or a file that already hasrest_routes, stays refused. -
capabilities(a list of names) is an optional v2 key with the same name and type. -
replacedBy,replacementanddeprecated: truemap intodeprecationwhen the plugin is deprecated (they repeat or filldeprecation.replacedByandstate);docker_imagebecomesservice.imageon a compose service;internalPortandhealth_check_pathmap when they equal the derivedservice.portandservice.healthcheck;depends_onbecomesrequires.plugins;migrationsmaps only as{dir: "migrations", apply: "boot"}. A value that conflicts with what is derived, or whose shape does not fit (a migration file list, acommandslist ofnself <name> <sub>entries, adockerobject with volumes), stays refused, as dodeprecatedSince,deprecated_in,removal_target,serviceTypeandschema_version, which have no v2 field. -
envorenv_varsbecomesenv {required, optional}only as{required: [name], optional: [name]}. Defaults, descriptions, per-variable flags and bare name lists have no place inenv, so they stay refused.
-drop <file> is the one way to discard data. The file lists dead v1 keys, one per line with a # evidence comment; tools/manifestv2migrate/dead-keys.txt is the reviewed list (keys no code reads, not even a dev tool or build script). Only listed keys are dropped: a default or -check run reports what would be dropped, -write reports what was, and any key that is neither mapped nor listed still refuses. A mapped key cannot be listed.
Getting Started
Commands
- Commands, Overview
- Lifecycle: cmd-init · cmd-build · cmd-start · cmd-stop · cmd-restart · cmd-dev
- Monitoring: cmd-status · cmd-logs · cmd-health · cmd-urls · cmd-doctor · cmd-monitor · cmd-alerts · cmd-sentry · cmd-watchdog
- Data: cmd-db · cmd-backup · cmd-dr · cmd-queue · cmd-webhooks
- Config: cmd-config · cmd-service · cmd-env · cmd-promote
- Networking: cmd-ssl · cmd-trust · cmd-dns-setup
- Security: cmd-access · cmd-security · cmd-secrets
- Tenancy: cmd-tenant · cmd-billing
- Plugins: cmd-plugin · cmd-license · cmd-dogfood (extracted, CLI-R11) · cmd-k8s (extracted, CLI-R11) · cmd-encryption (extracted, CLI-R11) · cmd-waf (extracted, CLI-R11) · cmd-federation (extracted, CLI-R11) · cmd-mail (extracted, CLI-R11) · cmd-dlq (extracted, CLI-R11)
- AI: cmd-ai · cmd-claw · cmd-model
- Templates: cmd-template
- Utilities: cmd-exec · cmd-clean · cmd-reset · cmd-update · cmd-upgrade · cmd-version · cmd-admin · cmd-migrate · cmd-migrate-firebase · cmd-migrate-supabase · cmd-completion
Features
- Features, Overview
- Feature-Auth
- Feature-Storage
- Feature-Search
- Feature-Functions
- Feature-Email
- Feature-Monitoring
- Feature-Plugins
- Feature-nClaw, AI Assistant
- Feature-nChat, Messaging
- Feature-nFamily, Family Social
- Feature-nCloud, Managed Hosting
- Feature-Memory-Rooms, Knowledge Organization
- Feature-Agent-Dashboard, Agent Metrics
- Feature-Image-Generation, AI Image Generation
Configuration
- Configuration, Overview
- Config-Env-Vars
- Config-Postgres
- Config-Hasura
- Config-Auth
- Config-Nginx
- Shared-Proxy
- Config-Optional-Services
- Config-Custom-Services
- Config-System
Plugins (87 + 10 monitoring)
- Plugin-Overview
- Plugin-Catalog
- Plugin-Install
- Plugin-Licensing
- Plugin-Architecture
- Plugin-Dev-Guide
- Plugin-Migrations-Contract
Free (25)
- plugin-backup
- plugin-content-acquisition
- plugin-content-progress
- plugin-cron
- plugin-donorbox
- plugin-feature-flags
- plugin-github
- plugin-github-runner
- plugin-invitations
- plugin-jobs
- plugin-link-preview
- plugin-mdns
- plugin-mlflow
- plugin-monitoring
- plugin-notifications
- plugin-notify
- plugin-paypal
- plugin-search
- plugin-shopify
- plugin-stripe
- plugin-subtitle-manager
- plugin-tokens
- plugin-torrent-manager
- plugin-vpn
- plugin-webhooks
Pro (62)
- plugin-access-controls
- plugin-activity-feed
- plugin-admin-api
- plugin-analytics
- plugin-auth
- plugin-bots
- plugin-browser
- plugin-calendar
- plugin-cdn
- plugin-chat
- plugin-claw
- plugin-claw-budget
- plugin-claw-news
- plugin-claw-web
- plugin-cloudflare
- plugin-cms
- plugin-compliance
- plugin-ddns
- plugin-devices
- plugin-documents
- plugin-entitlements
- plugin-file-processing
- plugin-game-metadata
- plugin-geocoding
- plugin-geolocation
- plugin-google
- plugin-home
- plugin-idme
- plugin-knowledge-base
- plugin-linkedin
- plugin-livekit
- plugin-media-processing
- plugin-meetings
- plugin-moderation
- plugin-mux
- plugin-object-storage
- plugin-observability
- plugin-photos
- plugin-podcast
- plugin-post
- plugin-realtime
- plugin-retro-gaming
- plugin-rom-discovery
- plugin-social
- plugin-sports
- plugin-support
- plugin-tmdb
- plugin-voice
- plugin-web3
- plugin-workflows
Planned (26)
plugin-auditplugin-blogplugin-checkoutplugin-commerceplugin-drmplugin-exportplugin-flowplugin-importplugin-ldapplugin-mailgunplugin-mediaplugin-oauth-providersplugin-pagesplugin-postmarkplugin-rate-limitplugin-reportsplugin-samlplugin-schedulerplugin-sendgridplugin-ssoplugin-subscriptionplugin-thumbplugin-transcoderplugin-twilioplugin-wafplugin-watermark
Guides
- Guide-Production-Deployment
- Guide-SSL-Setup
- Guide-Multi-Tenancy
- Guide-Security-Hardening
- Guide-Monitoring-Setup
- Guide-Backup-Restore
- Guide-Custom-Services
- Guide-Migration-from-v1
Architecture
- Architecture
- Architecture-Guardrails
- Service-Graph
- Compose-Generation
- Nginx-Generation
- Plugin-Architecture
Reference
Machine interface
-
JSON-Output,
--jsonenvelope -
Command-Registry,
nself help --json - Exit-Codes
- error-codes, Error Codes
-
Compat-V15,
NSELF_V15gate
Licensing
Security
Brand
Operations
- operations/release-cascade, Release Cascade
- operations/self-healing, Self-Healing Schema
- operations/redis-tuning, Redis Pool Tuning
- operations/meilisearch-warmup, MeiliSearch Warm-Up
- operations/jwt-rotation, JWT Key Rotation
- operations/windows-wsl2-setup, Windows / WSL2 Setup
- operations/gemini-oauth-reauth, Gemini OAuth Reauth
Contributing
Admin
- USER-ACTION-QUEUE, Pending Admin Actions
All commands (21)
- A: cmd-add · cmd-admin
- B: cmd-backup · cmd-build
- C: cmd-clean · cmd-config
- D: cmd-db · cmd-deploy · cmd-doctor
- E: cmd-exec
- I: cmd-init
- L: cmd-license · cmd-logs
- M: cmd-mcp
- R: cmd-remove · cmd-reset · cmd-restart
- S: cmd-start · cmd-status · cmd-stop
- U: cmd-update