Skip to content
nikcli
Docs
Documentation

Plugins

How nikcli installs plugins, patches server/TUI config, loads built-ins, and exposes plugin hooks.

Overview

Plugins extend server-side agent behavior and TUI behavior. Server plugin loading is in packages/nikcli/src/plugin/index.ts. Plugin installation and config patching are in packages/nikcli/src/plugin/installer.ts. TUI plugin runtime lives under packages/tui/src/plugin.

Runtime

Server hooks

Provider auth, tool hooks, event hooks, notifications, and session behavior load in the server plugin service.

UI

TUI hooks

TUI plugins can register commands, routes, dialogs, keybinds, and sidebar features.

CLI

Installer

nikcli plugin installs a package, reads its manifest, and patches local or global config.

Default

Built-ins

Internal auth and notification plugins always load; external built-ins load unless disabled.

Install a plugin

Terminal
bash
nikcli plugin @scope/my-plugin
nikcli plugin @scope/my-plugin --global
nikcli plugin @scope/my-plugin@1.2.3 --force

The install task performs four steps:

  1. Resolve and install the package target.
  2. Read plugin metadata from package.json.
  3. Detect server and/or TUI targets from manifest or exports.
  4. Patch nikcli.json and/or tui.json in the selected scope.
FlagBehavior
--globalPatch global config under Global.Path.config instead of project config.
--forceReplace an existing plugin entry for the same package.
version suffixInstaller preserves the requested package spec and version.

Config patching

patchPluginConfig uses jsonc-parser edits instead of string hacks. It can patch server config plugin and TUI config depending on detected targets. Duplicate detection compares package names, not only the full versioned spec.

ModeWhen used
addNo existing plugin entry for the package.
noopSame plugin spec is already configured and force is false.
replaceExisting package entry differs and --force is set.
server plugin config
json
{
  "plugin": [
    "@scope/my-plugin"
  ]
}

Server runtime

Server plugin loading starts with internal plugins that are imported directly. Then configured plugins plus external built-ins are loaded. If a plugin path is not file://, nikcli installs the package before importing it.

  1. Build plugin input, including SDK client and runtime helpers.
  2. Load internal auth/notification plugins.
  3. Copy configured plugin specifiers from config.
  4. Add external built-ins unless NIKCLI_DISABLE_DEFAULT_PLUGINS is set.
  5. Ignore old Codex/Copilot auth plugin specs that are now first-party.
  6. Install and import package specifiers.
  7. Load v1 server export when present, otherwise invoke exported plugin functions.
  8. Deduplicate duplicate function references from named and default exports.

TUI runtime

TUI plugin APIs are built in packages/tui/src/plugin/api.tsx and loaded by plugin/runtime.ts. Plugins can add routes, commands, dialogs, keybinds, and UI surfaces while the TUI app is running.

API areaCapability
RouteNavigate home, session, changes, tree, graph, GitHub, or plugin routes.
CommandRegister command palette entries and key-triggered commands.
DialogOpen, clear, size, and inspect dialog stack.
KeybindMatch, print, and create plugin keybind definitions.
Slots/featuresRegister sidebar or system plugin manager UI where supported.
Storageapi.storage.memory(key, { initial }) keeps per-plugin state in memory across hot reloads; api.storage.store(...) persists it to disk and syncs it across TUI instances.

A plugin that throws while rendering is contained: the slot or route renders nothing and the crash surfaces as a single error toast instead of taking the TUI down.

TUI plugin discovery and hot reload

Local TUI plugins are discovered from plugin/tui/ and plugins/tui/ inside every config root — the project .nikcli directories, the global config dir, NIKCLI_CONFIG_DIR, and the managed dir. Anything else is declared in tui.json. The extra tui level matters: {plugin,plugins}/*.{ts,js} is the server plugin loader's territory, so a TUI plugin placed directly there is loaded as a server plugin and fails.

project layout
bash
.nikcli/
  tui.json            # optional: declare plugins with options
  plugin/tui/hud.tsx  # discovered automatically

Editing a local plugin swaps that one plugin in the running TUI, typically within ~100 ms. Other plugins — including built-ins — are never touched, in-memory state kept in api.storage.memory survives, and a broken save keeps the last working version alive with one error toast until the file is fixed. npm package plugins do not hot reload: their entrypoints resolve into the package cache and are immutable for the session.

Change on diskEffect on the running TUI
Edit a local plugin fileThat plugin is disposed and re-initialized from the fresh module.
Add a file to plugin/tui/The plugin is loaded and activated.
Add or remove a tui.json entryThe plugin is loaded, or torn down.
Change plugin optionsThat plugin restarts with the new options.
Flip plugin_enabledThe plugin is disposed or initialized. Plugin-manager toggles are stored in KV and still win.
Note
Hot reload is on by default. Set NIKCLI_DISABLE_PLUGIN_RELOAD=1 to load plugins once at startup; --pure / NIKCLI_PURE skips external TUI plugins entirely.

Built-in plugins

Internal built-ins are directly imported and do not depend on package installation. They include Codex auth, GitHub Copilot auth, xAI auth, Cursor auth, Cloudflare Workers/Gateway auth, and the notification plugin. External built-ins are appended from the built-in list unless disabled.

Built-inPurpose
Codex authFirst-party Codex authentication support.
GitHub Copilot authCopilot and enterprise provider auth.
xAI authxAI provider auth integration.
Cursor authCursor ACP/provider auth integration.
Cloudflare authCloudflare Workers and AI Gateway auth flows.
Notify pluginSession idle/error, permission, question, Slack, Discord, and macOS notifications.
Terminal
bash
NIKCLI_DISABLE_DEFAULT_PLUGINS=1 nikcli

Internal TUI feature plugins

Beyond the auth and notification plugins, the TUI ships a set of internal feature plugins that ship inside packages/tui/src/feature-plugins/. They run in-process and don't need to be installed:

PluginCapability
homeRotating tip line in the home.bottom slot.
sidebarSix slot plugins: context/cost, MCP, LSP, todo, modified files, footer.
systemPlugin manager (list / toggle / install) and OpenRouter Fusion presets.
backgroundPaints a real image behind the TUI; owns /background.
loopsLoops manager, creation wizard and live sidebar.
missionMissions manager, planning wizard and live sidebar.
brainArms the Brain consolidation scheduler; /brain runs a pass on demand.
browserBrowser-use control surface for the browser tool.
chatbotChatBot control panel for Discord / Slack / Teams / GChat / Linear / GitHub webhooks.
computerProbes the host for the computer tool's screenshot and input capabilities.
connectorsFirst-party connector health, cache refresh, and credential removal.
observabilityLive OpenTelemetry spans and OTLP endpoint dialogs.
islandToggles the macOS Island notch integration. Registered only under --island.

Each one — its commands, slash aliases, KV keys and internals — is documented in TUI feature plugins, which doubles as the reference for the plugin API since the internal plugins use exactly the API an npm plugin gets.

Plugin manifest

The installer reads package metadata with readPluginPackage. Target detection accepts explicit plugin target metadata and also detects packages that expose ./server and/or ./tui exports. A package with only main or string exports is treated as a server plugin.

package.json
json
{
  "name": "@scope/my-plugin",
  "version": "1.0.0",
  "exports": {
    "./server": "./dist/server.js",
    "./tui": "./dist/tui.js"
  },
  "oc-plugin": ["server", "tui"]
}
Tuple targets

Target entries may also be tuples with target options, such as a TUI target plus plugin options. The patcher preserves target options when adding config.

Skills

Skills are related but not the same as plugins. Skills are prompt/context assets discovered by skill/skill.ts. The skill glob scans skill/**/SKILL.md and skills/**/SKILL.md under config directories, plus external sources unless disabled.

FeaturePluginSkill
Runtime codeYes, imported and executed.No, prompt/context instructions and assets.
Config fieldpluginDiscovered from directories and external skill locations.
TUI managerSystem plugin manager and plugin APIs.Skills dialog and skill install/search UI.
Disable flagNIKCLI_DISABLE_DEFAULT_PLUGINS for default external plugins.NIKCLI_DISABLE_EXTERNAL_SKILLS for external skills.

Notifications

Notifications are implemented as an internal plugin created by createNotifyPlugin. It reads notifications.notify and notifications.todo, applies rate limits, retry/backoff, circuit breaker behavior, quiet hours, and connector-backed Slack or Discord delivery.

notify config
json
{
  "notifications": {
    "notify": {
      "enabled": true,
      "events": {
        "sessionIdle": true,
        "sessionError": true,
        "permissionAsked": true,
        "questionAsked": true
      },
      "slack": { "enabled": true, "connector": "slack", "channel": "#builds" }
    }
  }
}

Failure modes

SymptomLikely causeFix
Install failedPackage resolution, registry auth, or unavailable version.Check the error detail from Process.RunFailedError and npm registry settings.
No plugin targets foundPackage lacks recognized manifest targets and exports.Add oc-plugin, ./server, ./tui, main, or string exports.
Invalid JSON while patchingTarget config file is not valid JSONC.Fix reported line/column and rerun install.
Plugin loads twicePackage exports same function as named and default export.Runtime deduplicates identical function references; check distinct functions if duplicates remain.
Built-in plugin install failsExternal built-in package could not be installed.Server publishes a session error and continues without that built-in.
TUI plugin route missingPlugin route id was not registered or runtime disposed.Check TUI plugin runtime status and route registration.

Source anchors

NeedFile
Server plugin runtimepackages/nikcli/src/plugin/index.ts
Plugin install and patchingpackages/nikcli/src/plugin/installer.ts
Plugin package parsing@nikcli-ai/util/plugin-shared
CLI commandpackages/nikcli/src/cli/cmd/plug.ts
TUI plugin APIpackages/tui/src/plugin/api.tsx
TUI plugin runtimepackages/tui/src/plugin/runtime.ts
System plugin managerpackages/tui/src/feature-plugins/system
Home, sidebar, background, loop, mission, brain, browser, chatbot, computer, connectors and observability pluginspackages/tui/src/feature-plugins/
Internal plugin registrypackages/tui/src/plugin/internal.ts
Island file bridge@nikcli-ai/util/island-bridge
Island TUI pluginpackages/tui/src/feature-plugins/island/index.tsx
Plugin contracts packagepackages/plugin
Skillspackages/nikcli/src/skill/skill.ts