Documentation Index
Fetch the complete documentation index at: https://mintlify.com/analogdevicesinc/codefusion-studio/llms.txt
Use this file to discover all available pages before exploring further.
CodeFusion Studio’s plugin system is the mechanism through which firmware platforms, RTOS configurations, middleware stacks, and custom code templates are delivered to the development environment. Rather than building platform logic into the CFS core, all platform-specific behavior — file scaffolding, code generation templates, System Planner controls, and workspace structure — is encapsulated in plugins that are loaded dynamically at startup. This design lets teams upgrade an RTOS, integrate proprietary middleware, or enforce coding standards without forking or modifying the base application.
Plugin types
CFS supports three plugin types, each addressing a different stage of the development workflow:
| Plugin type | Role | Where it appears in the UI |
|---|
| Workspace plugin | Provides a complete, pre-configured single- or multi-core workspace template with source files, tool settings, and recommended configurations | Workspace Creation Wizard → Select a workspace template |
| Project plugin | Defines how an individual per-core project is structured, which files it contains, and what configuration options are presented to the user | Workspace Creation Wizard → Manually configure the workspace |
| Code generation plugin | Generates source code and configuration files from user selections in System Planner (pin mux, memory allocation, peripheral config, etc.) | Generate Code page in System Planner |
Code generation plugins are frequently bundled inside project plugins — a single .cfsplugin manifest can declare both a project and a codegen service.
Plugin types are not mutually exclusive. A single plugin manifest can implement workspace, project, and codegen features simultaneously by declaring all three service blocks in the features section.
The .cfsplugin manifest
Every plugin is identified by a .cfsplugin file — a JSON manifest that declares the plugin’s identity, the hardware it targets, the services it provides, and the UI properties it exposes in System Planner.
Key manifest fields
| Field | Type | Description |
|---|
schemaVersion | string | Manifest schema version (e.g. "1.2.0") |
pluginId | string | Unique reverse-DNS identifier (e.g. "com.analog.project.zephyr.plugin") |
pluginName | string | Human-readable display name |
pluginDescription | string | Short description shown in the Workspace Wizard |
pluginVersion | string | SemVer version of the plugin |
pluginApiVersion | number | Plugin API version — use 1 for current releases |
author | string | Plugin author or organization |
firmwarePlatform | string | Firmware platform: "msdk", "zephyr", "SHARC-FX", or a custom identifier |
supportedSocs | array | SoC + board + package combinations this plugin supports |
supportedHostPlatforms | array | Optional. Restrict to "windows", "linux", "osx" |
features | object | Service declarations: workspace, project, and/or codegen |
properties | object | UI property declarations for System Planner |
supportedSocs section
The supportedSocs array declares which SoC, board, and package combinations activate this plugin. SoC data models are distributed through the Package Manager, ensuring engineers always have access to the latest hardware data. These data models provide the baseline hardware configuration used by the System Planner.
"supportedSocs": [
{
"name": "MAX32655",
"board": "EvKit_V1",
"package": "ctbga"
}
]
Each entry must specify a name (SoC identifier), board (board name as distributed in the data model package), and package (package variant in lowercase).
properties section
The properties section declares UI fields that appear in System Planner for the project or peripheral scope. Properties are persisted into .cfsconfig under PlatformConfig and are available at code generation time via template context variables.
The following example adds a CHOSEN identifier and a BAUD rate field to the UART0 peripheral, and makes the PARITY control available:
{
"properties": {
"project": [],
"peripheral": {
"UART0": {
"supportedControls": [
{ "Id": "PARITY" }
],
"addedControls": [
{
"Id": "CHOSEN",
"Description": "Chosen. Multiple values can be separated by commas.",
"Type": "identifier"
},
{
"Id": "BAUD",
"Description": "Baud Rate",
"Hint": "115200",
"Type": "integer"
}
],
"modifiedControls": []
}
}
}
}
The three sub-keys under a peripheral name carry distinct semantics:
| Key | Purpose |
|---|
supportedControls | SoC controls from the hardware data model to expose in the UI |
addedControls | New fields not present in the hardware model (e.g. BAUD rate, Zephyr chosen node) |
modifiedControls | Overrides for default values or descriptions of existing hardware controls |
Minimal plugin manifest example
{
"schemaVersion": "1.2.0",
"pluginId": "com.example.my-project-plugin",
"pluginName": "My Project Plugin",
"pluginDescription": "Generates projects for My Platform.",
"pluginVersion": "1.0.0",
"pluginApiVersion": 1,
"author": "Your Name",
"firmwarePlatform": "my-platform",
"supportedSocs": [
{
"name": "MY-SOC-100",
"board": "MY-BOARD",
"package": "tqfp"
}
],
"features": {
"project": {
"files": [
{ "src": "files/main.c", "dst": "src/main.c" }
],
"templates": [
{ "src": "templates/Makefile.eta", "dst": "Makefile" }
]
}
},
"properties": {
"project": [
{
"id": "ProjectName",
"name": "Project Name",
"category": "Project Settings",
"default": "${context.coreId}",
"type": "string",
"required": true
}
]
}
}
Plugin directory structure
A plugin lives in a single directory. The only required file is the .cfsplugin manifest; all other files are optional:
my-plugin/
├── .cfsplugin # Required — plugin manifest
├── index.ts # Optional — custom TypeScript service logic
├── files/ # Optional — static files copied verbatim to output
├── templates/ # Optional — Eta templates rendered during generation
└── config-patches/ # Optional — JSON fragments merged into .cfsconfig
└── <soc-id>/
├── system.json
└── <project-id>.json
| Entry | Purpose |
|---|
.cfsplugin | Declares plugin identity, supported SoCs, and service configuration |
index.ts | Exports a class to override or extend default generation behavior |
files/ | Static assets copied verbatim to the destination project |
templates/ | Eta templates rendered using project context variables |
config-patches/ | JSON fragments deep-merged into the generated .cfsconfig defaults |
Plugins that consist only of a .cfsplugin file with no index.ts (template-only plugins) are deprecated. New plugins should always include an index.ts that explicitly extends GenericPlugin from the cfs-plugins-sdk package.
Plugin integration with the CFS UI
Workspace Creation Wizard
Plugins surface at two decision points in the Workspace Creation Wizard:
- Select a workspace template — CFS lists all workspace plugins whose
supportedSocs entry matches the selected SoC, board, and package. Choosing a template selects the corresponding workspace plugin, which provides the full project scaffold.
- Manually configure the workspace — CFS lists all project plugins compatible with the selected SoC/core combination. You select one plugin per core; CFS stores the plugin binding in the
.cfsworkspace and .cfsconfig files.
System Planner
After workspace creation, System Planner reads the plugin bindings from .cfsconfig and uses the plugin’s properties section to render configuration panels for each peripheral and project-level setting. Controls declared in supportedControls, addedControls, and modifiedControls determine exactly which fields are visible and editable for each peripheral.
Code generation
When you click Generate Code in System Planner (or run cfsutil workspace create), CFS invokes the code generation plugin’s generateCode service. The plugin receives the full .cfsconfig state — including all pin assignments, peripheral settings, memory allocations, and AI model entries — and renders output files from its templates/ directory using the Eta templating engine.
The cfs-plugins-sdk package
The cfs-plugins-sdk is the official TypeScript SDK for building custom CFS plugins. It is distributed as part of the codefusion-studio repository starting with tag v2.2.0.
Installation
Add the SDK as a Git-based dependency in your plugin’s package.json:
{
"dependencies": {
"cfs-plugins-sdk": "https://github.com/analogdevicesinc/codefusion-studio.git#workspace=cfs-plugins-sdk&tag=v2.2.0"
},
"resolutions": {
"cfs-types@workspace:^": "https://github.com/analogdevicesinc/codefusion-studio.git#workspace=cfs-types&tag=v2.2.0"
}
}
Then run yarn install.
GenericPlugin base class
The recommended approach for most plugins is to extend GenericPlugin, which provides default implementations of all service interfaces using Eta templates and JSON config patches:
import { GenericPlugin } from "cfs-plugins-sdk";
import type { CfsProject } from "cfs-types";
class MyProjectPlugin extends GenericPlugin {
override async generateProject(
baseDir: string,
context: CfsProject
): Promise<void> {
// Custom pre-generation logic
await super.generateProject(baseDir, context);
// Custom post-generation logic
}
}
export default MyProjectPlugin;
Service interfaces
| Interface | Trigger | Method signature |
|---|
CfsWorkspaceGenerationService | Workspace creation | generateWorkspace(cfsWorkspace: CfsWorkspace): Promise<void> |
CfsProjectGenerationService | Per-core project creation | generateProject(baseDir: string, context: CfsProject): Promise<void> |
CfsCodeGenerationService | System Planner Generate Code | generateCode(data: Record<string, unknown>, baseDir: string): Promise<string[]> |
CfsPropertyProviderService | System Planner panel render | getProperties(scope: CfsFeatureScope, context?: Record<string, unknown>): CfsPluginProperty[] |
CfsSocControlsOverrideService | System Planner peripheral render | overrideControls(scope: CfsFeatureScope, soc: CfsSocDataModel): Record<string, SocControl[]> |
CfsMemoryAccessOverrideService | Memory Allocation panel | getMemoryAccessOverrides(partName: string, coreId: string): Record<string, string[] | undefined> | undefined |
CfsProjectConfigService | .cfsconfig save | configureProject(soc: string, config: ConfiguredProject): Promise<ConfiguredProject> |
CfsSystemConfigService | .cfsconfig save | configureSystem(config: CfsConfig): Promise<CfsConfig> |
Key SDK exports
| Export | Description |
|---|
GenericPlugin | Base class implementing all services using Eta templates and JSON config patches |
CfsEtaWorkspaceGenerator | Generates workspace structure from Eta templates |
CfsEtaProjectGenerator | Generates per-core project structure from Eta templates |
CfsEtaCodeGenerator | Generates code output files from Eta templates |
CfsJsonProjectConfig | Reads config-patches/<soc>/<project-id>.json and merges into project config |
CfsJsonSystemConfig | Reads config-patches/<soc>/system.json and merges into system config |
CfsSocControlsOverride | Filters and modifies SoC controls by part name pattern |
PropertyProvider | Manages plugin properties and SoC control overrides |
CLI plugin extension mechanism
cfsutil is built on the oclif framework, which supports dynamic plugin loading. Two example oclif plugin templates are included in the repository to demonstrate how to extend the CLI:
add-soc pattern
An oclif plugin that implements the get-data-models hook can add custom SoC data models to cfsutil. The hook returns a simple object mapping SoC names to data model JSON file paths:
{
"soc1234": "/path/to/soc/data/model/soc1234.json",
"soc5678": "/path/to/soc/data/model/soc5678.json"
}
After linking the plugin, the new SoCs appear in cfsutil socs list.
add-codegen pattern
An oclif plugin that implements the get-engines and generate-code hooks can add additional code generation engines. The get-engines hook describes the engine:
[
{
"name": "example-code-generation-engine",
"label": "Example Code Generation",
"description": "An example code generation engine.",
"version": "1.0.0",
"socs": [],
"features": ["Pin Config"]
}
]
The generate-code hook receives the engine name, SoC data model, and current configuration, and returns a map of filename to generated code lines.
Linking plugins to cfsutil
# Link a locally built oclif plugin
cfsutil plugins link /path/to/plugin/dist
# List all registered CLI plugins
cfsutil plugins
# List all registered CFS workspace/project plugins
cfsutil cfsplugins list
Plugin activation and discovery
VS Code extension discovery
The CfsPluginManager (part of the cfs-lib package) scans for plugins at VS Code startup. It reads the cfs.plugins.searchDirectories setting, validates plugin metadata in each discovered .cfsplugin file, and registers plugin features for both the CFS UI and cfsutil.
Activating a custom plugin
After building your plugin (yarn build), register its output directory in your workspace settings.json:
"cfs.plugins.searchDirectories": [
"/path/to/your/plugins/dist"
]
Restart VS Code (or reload the window) to detect the new plugin. The plugin will appear in the Workspace Creation Wizard for any SoC/board combination listed in its supportedSocs.
Increment pluginVersion in your .cfsplugin manifest whenever you make changes. CFS uses the version string to detect plugin updates and re-register the plugin’s features without requiring a full reinstall.
Development workflow summary
- Scaffold — Create a directory with a
.cfsplugin manifest, an index.ts extending GenericPlugin, and optional files/, templates/, and config-patches/ directories.
- Declare SoCs — Populate
supportedSocs with the target SoC, board, and package.
- Define properties — Add UI fields to the
properties section to control code generation behavior.
- Write templates — Use Eta syntax in
templates/*.eta files to emit platform-specific source code using it.context variables.
- Build — Compile TypeScript to CommonJS:
yarn build. The output .cjs file must be in the same directory as the .cfsplugin manifest.
- Test — Write unit tests with Mocha and run
yarn test.
- Activate — Add the
dist/ path to cfs.plugins.searchDirectories in settings.json and restart VS Code.
- Iterate — Bump
pluginVersion on each change and restart VS Code to pick up updates.
For complete API documentation, templating guides, and advanced examples, see the CFS Plugins SDK README.