Arcana ARCANA

Plugin Guide

Plugins extend Arcana's core functionality with custom tools, hooks, and behaviors. Unlike skills (which are instruction sets), plugins can modify the agent's runtime, add new tools, and intercept events.

Plugins vs Skills

AspectSkillPlugin
FormatSKILL.md (markdown)JavaScript/TypeScript module
CapabilityInstructions & contextRuntime code, tools, hooks
LoadingAlways availableRequires workspace trust
PermissionsRead-only (instructions)Requires explicit permission

Plugin Structure

plugins/
  my-plugin/
    index.js           # Entry point
    package.json       # Dependencies and metadata
    README.md          # Documentation

Plugin Manifest

{
  "name": "my-plugin",
  "version": "1.0.0",
  "description": "Adds custom functionality to Arcana",
  "arcana": {
    "permissions": ["shell", "filesystem"],
    "hooks": ["before:tool-call", "after:session-end"]
  }
}

Plugin Permissions

Plugins must declare their required permissions in the manifest:

PermissionGrantsRisk
shellExecute shell commandsHigh — can modify system
filesystemRead/write filesMedium — can modify project
networkMake HTTP requestsMedium — data exfiltration risk
memoryRead/write memory databaseLow — affects agent context only
uiModify TUI renderingLow — display only

Plugin Hooks

Hooks let plugins intercept events in the agent lifecycle:

// before:tool-call — runs before any tool executes
module.exports = {
  'before:tool-call': async (context) => {
    // context.tool — the tool being called
    // context.args — the arguments
    // Return false to block the tool call
    if (context.tool === 'shell' && context.args.command.includes('rm -rf')) {
      return false; // Block dangerous commands
    }
  },

  'after:tool-call': async (context) => {
    // Runs after tool execution
    console.log(`Tool ${context.tool} completed`);
  },

  'before:session-start': async (context) => {
    // Runs at session start
    // Can modify system prompt, inject context
    context.systemPrompt += '\nExtra context from plugin';
  },

  'after:session-end': async (context) => {
    // Runs when session ends
    // Good for cleanup, logging, analytics
  }
};

Available Hooks

HookDescription
before:session-startBefore session initialization
after:session-endAfter session cleanup
before:tool-callBefore any tool execution
after:tool-callAfter tool execution
before:promptBefore sending prompt to LLM
after:responseAfter receiving LLM response
before:memory-writeBefore writing to memory

Loading Plugins

# Plugins are loaded from the project's plugins/ directory
# They require workspace trust to load

# Trust the workspace first
arcana trust

# Then start Arcana — plugins load automatically
arcana

Creating a Plugin

# 1. Create the plugin directory
mkdir -p plugins/my-plugin

# 2. Create package.json
cat > plugins/my-plugin/package.json << 'EOF'
{
  "name": "my-plugin",
  "version": "1.0.0",
  "arcana": {
    "permissions": ["shell"],
    "hooks": ["before:tool-call"]
  }
}
EOF

# 3. Create the plugin entry point
cat > plugins/my-plugin/index.js << 'EOF'
module.exports = {
  'before:tool-call': async (ctx) => {
    if (ctx.tool === 'shell') {
      console.log(`[my-plugin] Shell command: ${ctx.args.command}`);
    }
  }
};
EOF

# 4. Trust and test
arcana trust
arcana

Security Considerations

  • Plugins require workspace trust to load
  • Declared permissions are shown to the user at load time
  • Plugins run in the same process as Arcana
  • Only load plugins from sources you trust
  • Review plugin code before enabling in production
Last updated: Jul 24, 2026