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:
| Permission | Description |
|---|---|
filesystem | Read and write files through extension services |
ai | Register AI tools, context providers, and call AI chat/completion models directly (listModels, chatCompletion, chatCompletionStream) |
network | Reserved for network-enabled extensions |
catalog | Permission-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
}
]
}
| Field | Type | Description |
|---|---|---|
filePatterns | string[] | Glob patterns for matching files |
displayName | string | Name shown in the editor selector |
component | string | Key in your exported components object |
supportsSourceMode | boolean | Enables the host's source-mode toggle |
supportsDiffMode | boolean | Enables the host's AI diff review mode. Defaults to false when omitted |
readOnlyDuringDiff | boolean | Tells the host that this editor actually locks manual edits during diff review. Defaults to false |
supportsTranscriptEmbed | boolean | Allows a read-only, click-to-activate editor embed in agent transcripts. Defaults to false |
transcriptEmbedHeight | number | Preferred transcript embed height in pixels. Defaults to 360 |
showDocumentHeader | boolean | Shows the host-provided document header above the editor. Defaults to true when omitted |
collaboration | object | Declares 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"
}
]
| Field | Type | Description |
|---|---|---|
id | string | Stable command identifier |
title | string | Label shown in the picker |
description | string | Optional help text |
icon | string | Optional Material icon name |
keywords | string[] | Optional search keywords |
handler | string | Name 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"
}
]
| Field | Type | Description |
|---|---|---|
id | string | Unique 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. |
label | string | User-facing sidebar label. |
group | string | Optional sidebar group. Defaults to Extensions. |
icon | string | Optional Material Symbol name. Defaults to extension. |
order | number | Optional sort order within the extension group. Defaults to 100. |
component | string | Component 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:
| Pattern | Matches |
|---|---|
*.csv | Any file ending in .csv |
*.{csv,tsv} | Files ending in .csv or .tsv |
data/*.json | JSON files in data/ |
**/*.test.ts | Test files anywhere in the tree |
Validation Notes
Nimbalyst validates your manifest on load. Common errors:
- Missing required top-level fields:
id,name,version, ormain aiToolscontains objects instead of tool-name stringsslashCommandsuses oldname/displayNamefields instead ofid/titlefileIconsis declared as an array instead of an object map- Contribution component names do not match your exported module names
Best Practices
- Use a stable reverse-domain
id. - Request only the permissions you actually need.
- Keep
contributions.aiToolsand your exportedaiToolsarray in sync. - Prefer adding
apiVersioneven though it is currently optional. - Validate on every build with
validateExtensionBundle().