Skip to main content
charm init scaffolds new agents from a remote manifest — not from files bundled inside the installed charmos wheel. That lets the community add templates without waiting for an SDK release.

How it works

When you run charm init, the CLI fetches:
https://raw.githubusercontent.com/CharmAIOS/charm-community-plugin/main/templates/registry.json
Each manifest entry lists files (as JSON strings) to write into the new project directory. After a PR merges to main, the template is available globally on the next charm init. Offline fallback: if the manifest cannot be fetched, the CLI scaffolds a minimal Python template.

Contributing a template

You do not write Python loader code — only a JSON entry in the manifest.

Step 1: Prepare your template entry

[!TIP] Discoverability: Templates merged into this manifest are automatically displayed in the Charm Store Templates Registry for the whole community to discover and scaffold.
{
  "id": "my-sales-agent",
  "description": "Sales outreach agent starter",
  "author": "Your Name",
  "tags": ["sales", "outreach"],
  "github_url": "https://github.com/YourOrg/your-repo",
  "post_init_message": "  ├── charm.yaml\n  ├── .charmignore\n  └── src/\n      └── main.py\n\nNext: charm push",
  "files": [
    {
      "path": "charm.yaml",
      "content": "version: \"0.4.2\"\n\npersona:\n  name: \"My Sales Agent\"\n  description: \"A sales agent starter.\"\n  version: \"0.1.0\"\n\ninterface:\n  input:\n    type: object\n    required: [message]\n    properties:\n      message: { type: string, title: Message }\n  output:\n    type: string\n\nruntime:\n  adapter:\n    type: custom\n    entry_point: src.main:agent\n  lifecycle: serverless\n"
    },
    {
      "path": ".charmignore",
      "content": ".env\n.venv\n__pycache__/\n*.pyc\n"
    },
    {
      "path": "src/__init__.py",
      "content": ""
    },
    {
      "path": "src/main.py",
      "content": "def agent(inputs):\n    msg = inputs.get('message', 'hello')\n    return f'Sales draft for: {msg}'\n"
    }
  ]
}
Tips:
  • id must be unique kebab-case — used as charm init my-agent --template my-sales-agent
  • author, tags, and github_url help users discover your template in the Store Registry.
  • Include version: "0.4.2" in charm.yaml content (required contract version)
  • Use type: custom (or python, an alias) for standard Python agents — not a fictional adapter name unless you document a required plugin
  • Escape newlines as \n and quotes as \" inside JSON strings
  • Rich templates can include interface.ui for Store widgets — see Input Forms

Step 2: Open a pull request

  1. Fork CharmAIOS/charm-community-plugin
  2. Append your object to the templates array in templates/registry.json
  3. Submit a PR for review
After merge to main, your template appears in charm init (interactive menu or --template <id>).

Templates vs runtime plugins

Community templateAdapter plugin
DeliversStarter files for charm initNew runtime.adapter.type
RegistrationManifest PRcharm.adapters entry point
Custom Docker imageOnly if template’s charm.yaml sets custom_imageRequired on cloud