CodeAlta plugins are trusted source packages that can extend the shell, prompt flow, agent runtime, timeline projections, and the in-session alta live tool.
Plugins are for local automation you choose to run. Building a source plugin can execute SDK/NuGet/MSBuild logic, and loading it executes .NET code inside the CodeAlta process.
Install and enable only plugins you trust. Source plugins are built on your machine and loaded into the CodeAlta process, so a plugin has the same practical risk profile as running local code.
Plugin APIs are preview surface area before CodeAlta 1.0. Interfaces, contribution points, service exposure, and behavior can change between 0.x releases; some CodeAlta capabilities may not be exposed yet, and some exposed capabilities may still be incomplete or incorrectly shaped.
CodeAlta discovers dynamic source plugins from:
~/.alta/plugins/<package-id>/plugin.cs for global plugins;<project>/.alta/plugins/<package-id>/plugin.cs for project-scoped plugins.Project-scoped plugins apply only to the matching project. Global plugins apply across workspaces.
Open plugin management with Ctrl+G Ctrl+N, /plugins, or /plugin.
The dialog shows:
You can also use a headless status summary:
alta --plugins-status
Source plugins are enabled by default when discovered. Disable a plugin in TOML when you do not want it built or loaded:
[plugins.HelloWorld]
enabled = false
When a plugin is broken, start CodeAlta with a bypass:
alta --no-plugins
alta --plugin-safe-mode
Or set:
CODEALTA_DISABLE_PLUGINS=1
These bypasses are recognized before plugin-contributed command-line options.
Create ~/.alta/plugins/HelloWorld/plugin.cs:
Keep early plugins small and focused. The preview API is easiest to track when each plugin owns one narrow workflow and avoids depending on undocumented host internals.
using CodeAlta.Plugins.Abstractions;
using XenoAtom.Terminal.UI.Controls;
using CliCommand = XenoAtom.CommandLine.Command;
[Plugin(DisplayName = "Hello Plugin", Description = "Adds a command, prompt note, and status row.")]
public sealed class HelloPlugin : PluginBase
{
public override IEnumerable<PluginCommandContribution> GetCommands()
{
yield return Command.Prompt(
"hello",
"Show a hello notification.",
static async (context, cancellationToken) =>
{
await context.Ui.NotifyAsync("Hello from a plugin.", cancellationToken);
return PluginCommandResult.Handled;
});
}
public override IEnumerable<PluginSystemPromptContribution> GetSystemPromptContributions()
{
yield return Prompt.Developer("When the user asks about the hello plugin, explain that it is installed.");
}
public override IEnumerable<XenoAtom.CommandLine.CommandNode> GetCommandLineContributions()
{
yield return new CliCommand("hello", "Run hello plugin command-line actions.");
}
public override IEnumerable<PluginUiContribution> GetUiContributions()
{
yield return PluginUi.Status("Hello", static _ => "hello plugin active");
yield return PluginUi.Visual(PluginUiRegion.ThreadFooter, static _ => new Markup("[dim]Hello plugin[/]"));
}
}
Restart CodeAlta or refresh plugin state from the management UI. CodeAlta generates the plugin-root build files it owns and invokes dotnet build plugin.cs from the plugin package directory.
Plugins can contribute:
Built-in plugins use the same model. For example, the statistics plugin projects per-turn/session statistics from normalized agent events without writing plugin messages into canonical conversation history.
alta live toolPlugins can add in-session live-tool command roots by returning PluginAltaCommandContribution records from PluginBase.GetAltaCommands().
Those commands appear in:
alta --help
alta tool capability list
Trusted plugins can also invoke built-in alta commands through Services.Alta.InvokeAsync(...). Mutating plugin-originated commands include the plugin key in provenance so later sidebars, timelines, and reports can explain who created or submitted work.
Services.Tasks.Run(...) or the PluginBase.Tasks shortcut for background work so CodeAlta can cancel and track plugin tasks during unload.Directory.Build.props, Directory.Build.targets, Directory.Packages.props, or global.json.EnableDynamicLoading=true) so the plugin load context can resolve them.A plugin that starts unmanaged background work, captures host-static state, or pins native resources can keep running after you expect it to unload. Prefer CodeAlta-managed task services and cancellable operations.