Developing Extensions

This guide documents how to scaffold a new extension, structure the folder, and define the manifest configuration.


🏗️ Generating Extension Templates

To create a new extension boilerplate, run the create subcommand:

./nervi app create <extension-id> [flags]

Flags

  • --mode: Specifies the UI interaction type. Either "tool" (command responder, default) or "menu" (text-menu interface).
  • --type: Specifies the process lifecycle. Either "stateless" (spawns and exits, default) or "stateful" (lives in background).

Scaffolding Command Example

./nervi app create calculator --mode=tool --type=stateless

This creates a new folder in %AppData%\Roaming\nervi\extensions\calculator\ containing:

  • manifest.json: Configuration specifications.
  • main.go: Boilerplate entry code reading/writing JSON frames.

📄 Manifest JSON Configuration Schema

Field Definitions

  • name (string, required): Human-readable label.
  • description (string, required): Short functional summary.
  • version (string, required): Semantic version string (e.g. 1.0.0).
  • author (string, optional): Developer contact.
  • executable (string, required): Path to the executable binary file, relative to the folder containing manifest.json.
  • type (string, required): "stateless" or "stateful"
  • mode (string, required): "tool" or "menu"
  • stores_data (boolean, optional): Set to true if your extension uses state storage.
  • tools (array, required in tool mode): Exposes a list of callable tools.

🧰 Tool Definition Object

Each item in the tools array describes a function that users can call:

  • name (string, required): Programmatic name of the tool (must not contain spaces).
  • description (string, required): Short guide displayed during help menus.
  • input_schema (object, required): A JSON Schema object defining required parameters and types.

Example Tool Definition

{
  "name": "multiply",
  "description": "Multiplies two numbers",
  "input_schema": {
    "type": "object",
    "properties": {
      "x": {"type": "number", "description": "First factor"},
      "y": {"type": "number", "description": "Second factor"}
    },
    "required": ["x", "y"]
  }
}