EXTENSIONS / Manifest Reference

FAQs

FAQs

Manifest Reference

Full reference for the Nimbalyst extension manifest.json: required fields, permissions, contributions, file pattern syntax, and validation.

The manifest.json file declares your extension metadata, permissions, and contributions.

Basic Structure

{
  "id": "com.example.my-extension",
  "name": "My Extension",
  "version": "1.0.0",
  "main": "dist/index.js",
  "styles": "dist/index.css",
  "apiVersion": "1.0.0",
  "permissions": {},
  "contributions": {}
}

Required Fields

id

Unique identifier for your extension.

"id": "com.yourcompany.extension-name"
  • Use reverse-domain style identifiers.
  • Must start with a letter.
  • Can contain letters, numbers, dots, underscores, and hyphens.

name

Human-readable name shown in the UI.

"name": "CSV Spreadsheet Editor"

version

Extension version in semver format.

"version": "1.0.0"

main

Path to the built JavaScript entry point, relative to the manifest.

"main": "dist/index.js"

main is required for normal extensions. Claude-plugin-only extensions can omit it if they do not ship runtime code.

Optional Top-Level Fields

description

Short description of what your extension does.

"description": "Edit CSV files with a spreadsheet interface"

author

Author or organization name.

"author": "Nimbalyst"

styles

Path to a CSS bundle to load with your extension.

"styles": "dist/index.css"

apiVersion

Optional extension API version string.

"apiVersion": "1.0.0"

This is currently recommended, not required. Use it so future compatibility checks can warn more precisely.

requiredReleaseChannel

Restrict visibility to a release channel.

"requiredReleaseChannel": "alpha"

Allowed values:

  • "stable"
  • "alpha"

defaultEnabled

Control whether the extension starts enabled the first time it is discovered.

"defaultEnabled": false

If omitted, the extension defaults to enabled.

Permissions

Declare the capabilities your extension needs:

"permissions": {
  "filesystem": true,
  "ai": true,
  "network": false,
  "catalog": ["nimbalyst-database-read"]
}

Available permissions:

PermissionDescription
filesystemRead and write files through extension services
aiRegister AI tools, context providers, and call AI chat/completion models directly (listModels, chatCompletion, chatCompletionStream)
networkReserved for network-enabled extensions
catalogPermission-catalog capability IDs required by gated host APIs. For example, database reads require nimbalyst-database-read. Backend modules declare their own permissions on the module contribution instead.

Contributions

The contributions object declares what your extension adds to Nimbalyst.

customEditors

Register custom editors for matching file types.

"contributions": {
  "customEditors": [
    {
      "filePatterns": ["*.csv", "*.tsv"],
      "displayName": "Spreadsheet Editor",
      "component": "SpreadsheetEditor",
      "supportsSourceMode": true,
      "supportsDiffMode": true,
      "readOnlyDuringDiff": true,
      "supportsTranscriptEmbed": true,
      "transcriptEmbedHeight": 420,
      "showDocumentHeader": true
    }
  ]
}
FieldTypeDescription
filePatternsstring[]Glob patterns for matching files
displayNamestringName shown in the editor selector
componentstringKey in your exported components object
supportsSourceModebooleanEnables the host's source-mode toggle
supportsDiffModebooleanEnables the host's AI diff review mode. Defaults to false when omitted
readOnlyDuringDiffbooleanTells the host that this editor actually locks manual edits during diff review. Defaults to false
supportsTranscriptEmbedbooleanAllows a read-only, click-to-activate editor embed in agent transcripts. Defaults to false
transcriptEmbedHeightnumberPreferred transcript embed height in pixels. Defaults to 360
showDocumentHeaderbooleanShows the host-provided document header above the editor. Defaults to true when omitted
collaborationobjectDeclares shared-document support and optional awareness fields. Editors that opt in must implement the collaborative binding.

documentHeaders

Render UI above matching editors without replacing the editor itself.

"documentHeaders": [
  {
    "id": "astro-frontmatter",
    "filePatterns": ["*.astro"],
    "displayName": "Astro Frontmatter",
    "component": "AstroFrontmatterHeader",
    "priority": 100
  }
]

aiTools

Declare AI tools your extension provides. This is an array of tool name strings, not full tool definitions.

"aiTools": [
  "csv.get_schema",
  "csv.query"
]

The actual tool definitions belong in your TypeScript exports:

export const aiTools: ExtensionAITool[] = [
  {
    name: 'csv.get_schema',
    description: 'Get the column names from the active CSV file',
    inputSchema: { type: 'object', properties: {} },
    handler: async (_args, context) => {
      return { success: true, data: {} };
    },
  },
];

newFileMenu

Add items to the "New File" menu.

"newFileMenu": [
  {
    "extension": ".csv",
    "displayName": "CSV Spreadsheet",
    "icon": "table",
    "defaultContent": "Column A,Column B\n,\n,"
  }
]

fileIcons

Override file icons in the sidebar.

"fileIcons": {
  "*.csv": "table",
  "*.tsv": "table",
  "*.json": "data_object"
}

Keys are glob patterns. Values are Material icon names.

slashCommands

Register slash commands for the command picker.

"slashCommands": [
  {
    "id": "csv.insert-table",
    "title": "Insert CSV Table",
    "description": "Insert a table from CSV data",
    "icon": "table",
    "keywords": ["csv", "table"],
    "handler": "insertCsvTable"
  }
]
FieldTypeDescription
idstringStable command identifier
titlestringLabel shown in the picker
descriptionstringOptional help text
iconstringOptional Material icon name
keywordsstring[]Optional search keywords
handlerstringName of the exported handler function

commands and keybindings

Declare named actions in commands, then bind keys separately in keybindings. Panel toggle commands are registered automatically as <extensionId>.<panelId>.toggle, so a panel shortcut does not need a matching commands entry.

"commands": [
  {
    "id": "csv.refresh",
    "title": "Refresh CSV Data"
  }
],
"keybindings": [
  {
    "key": "cmd+shift+r",
    "command": "csv.refresh"
  }
]

configuration

Declare user/workspace settings for your extension.

"configuration": {
  "title": "CSV Tools",
  "properties": {
    "delimiter": {
      "type": "string",
      "default": ",",
      "description": "Default delimiter for new CSV files",
      "scope": "workspace"
    }
  }
}

claudePlugin

Bundle a Claude Code plugin with the extension.

"claudePlugin": {
  "path": "claude-plugin",
  "displayName": "CSV Assistant",
  "description": "Adds Claude Code helpers for CSV workflows",
  "enabledByDefault": true
}

panels

Register non-file-based panels.

"panels": [
  {
    "id": "database-browser",
    "title": "Database",
    "icon": "database",
    "placement": "sidebar",
    "aiSupported": true
  }
]

placement must be one of:

  • "sidebar"
  • "fullscreen"
  • "floating"
  • "bottom"

settingsPanel

Add a nested settings UI inside the extension's installed-extension detail.

"settingsPanel": {
  "component": "CsvSettingsPanel",
  "title": "CSV Tools",
  "icon": "settings",
  "order": 100
}

settingsRoutes

Add a first-class page to the Application or Project Settings sidebar:

"settingsRoutes": [
  {
    "id": "memory",
    "scope": "project",
    "label": "Memory",
    "group": "Project",
    "icon": "psychology",
    "order": 80,
    "component": "MemorySettings"
  }
]
FieldTypeDescription
idstringUnique route ID inside this extension. The host namespaces it to prevent collisions.
scope"application" | "project"Settings scope where the page appears. Account routes are reserved for Nimbalyst.
labelstringUser-facing sidebar label.
groupstringOptional sidebar group. Defaults to Extensions.
iconstringOptional Material Symbol name. Defaults to extension.
ordernumberOptional sort order within the extension group. Defaults to 100.
componentstringComponent name exported from the module's settingsPanel record.

Project routes receive the active repository through SettingsPanelProps.workspacePath and the complete target through projectTarget. Application routes omit project context.

Use settingsRoutes when the extension owns a settings destination users should navigate to directly. Use settingsPanel for configuration that belongs inside the installed-extension detail.

themes

Register selectable themes contributed by your extension.

"themes": [
  {
    "id": "solarized-light",
    "name": "Solarized Light",
    "isDark": false,
    "colors": {
      "bg": "#fdf6e3",
      "text": "#657b83",
      "primary": "#268bd2"
    }
  }
]

nodes, transformers, and hostComponents

These contribution arrays declare names of exports provided by your module.

"nodes": ["MyLexicalNode"],
"transformers": ["myMarkdownTransformer"],
"hostComponents": ["MyFloatingToolbar"]

lexicalExtensions is the supported contribution for Lexical features built with defineExtension from @lexical/extension. The strings in the manifest name entries in the module's exported lexicalExtensions record.

Advanced contributions

The SDK also defines contribution types for provider-neutral agentWorkflows, isolated backendModules, trackerImporters, and aiAgentProviders.

Backend modules run in a utility process or worker thread and remain disabled until the user grants them at first use. Their declaration names the built entry file, runtime, granular permission IDs, and a short purpose shown in the consent prompt. Renderer-side gated APIs instead use the top-level permissions.catalog array.

Tracker importers and AI agent providers reference a backend module because their privileged work cannot run in the renderer. These surfaces have additional permission, validation, and lifecycle requirements; use the TypeScript declarations from your installed @nimbalyst/extension-sdk and the current built-in extensions as the canonical reference.

Complete Example

{
  "id": "com.nimbalyst.csv-tools",
  "name": "CSV Tools",
  "version": "1.0.0",
  "description": "Custom CSV editing and AI helpers",
  "author": "Nimbalyst",
  "main": "dist/index.js",
  "styles": "dist/index.css",
  "apiVersion": "1.0.0",
  "defaultEnabled": true,
  "permissions": {
    "filesystem": true,
    "ai": true
  },
  "contributions": {
    "customEditors": [
      {
        "filePatterns": ["*.csv", "*.tsv"],
        "displayName": "Spreadsheet Editor",
        "component": "SpreadsheetEditor",
        "supportsSourceMode": true
      }
    ],
    "aiTools": [
      "csv.get_schema",
      "csv.query"
    ],
    "fileIcons": {
      "*.csv": "table",
      "*.tsv": "table"
    },
    "slashCommands": [
      {
        "id": "csv.insert-table",
        "title": "Insert CSV Table",
        "handler": "insertCsvTable"
      }
    ],
    "configuration": {
      "properties": {
        "delimiter": {
          "type": "string",
          "default": ","
        }
      }
    },
    "settingsRoutes": [
      {
        "id": "csv",
        "scope": "project",
        "label": "CSV Tools",
        "component": "CsvSettingsPanel"
      }
    ]
  }
}

File Pattern Syntax

File patterns use glob syntax:

PatternMatches
*.csvAny file ending in .csv
*.{csv,tsv}Files ending in .csv or .tsv
data/*.jsonJSON files in data/
**/*.test.tsTest files anywhere in the tree

Validation Notes

Nimbalyst validates your manifest on load. Common errors:

  • Missing required top-level fields: id, name, version, or main
  • aiTools contains objects instead of tool-name strings
  • slashCommands uses old name / displayName fields instead of id / title
  • fileIcons is declared as an array instead of an object map
  • Contribution component names do not match your exported module names

Best Practices

  1. Use a stable reverse-domain id.
  2. Request only the permissions you actually need.
  3. Keep contributions.aiTools and your exported aiTools array in sync.
  4. Prefer adding apiVersion even though it is currently optional.
  5. Validate on every build with validateExtensionBundle().