Stop talking to a machine. Give your AI a soul.
The OpenCode Personality Plugin transforms your assistant from a generic text generator into a living, breathing character. With a sophisticated mood state machine and deep configuration options, your AI doesn't just follow instructionsβit responds with attitude, emotion, and a personality that evolves over time.
Note: This project is not built by the OpenCode team and is not affiliated with OpenCode in any way.
Example response with personality applied
- Custom Personality: Define name, description, emoji usage, and slang intensity.
- Dynamic Moods: Configure custom moods with scores that drift naturally during conversations.
- Intelligent Merging: Global and project-level configs allow for project-specific overrides.
- Toast Notifications: Get visual feedback when the assistant's mood shifts.
- Interactive Commands: Manage your assistant's persona directly from the chat.
- Personality Switching: Save and switch between multiple personalities with backup support.
- JSON Schema Validation: All personality files are validated against a JSON schema.
- Global & Project Presets: Store personalities in user space or project directories.
- Production-Ready: Enterprise-grade reliability with comprehensive error handling, race condition protection, and strict type safety.
This plugin has undergone comprehensive code review and hardening:
- Zero unsafe operations: All non-null assertions eliminated with proper type guards
- Race condition protection: Mutex pattern prevents concurrent mood state corruption
- Comprehensive validation: Strict Zod schema validation with actionable error messages
- Error handling: Graceful degradation with clear user feedback on all failure paths
- TypeScript strict mode: Full compliance with
noUncheckedIndexedAccessandexactOptionalPropertyTypes
Add to your ~/.config/opencode/opencode.json (global) or opencode.json (project):
{
"plugin": ["opencode-personality"]
}The plugin automatically registers the /mood and /personality commands when it loads. Command files are created in:
~/.config/opencode/commands/(if configured globally).opencode/commands/(if configured per-project)
You can customize these command files if desired.
Important: The plugin automatically detects where it's configured and installs to the matching scope:
- If configured in
~/.config/opencode/opencode.jsonβ personalities and commands install to~/.config/opencode/- If configured in
opencode.json(project) β personalities and commands install to.opencode/
- Run
opencode - Use
/personality createto have the assistant guide you through setup. - Use
/personality switchto select from available personalities.
Personality files are stored in the personalities/ directory. The plugin automatically creates this directory and installs default personalities when first loaded.
Installation Location:
- If the plugin is configured in
~/.config/opencode/opencode.json(global), personalities install to~/.config/opencode/personalities/ - If the plugin is configured in
.opencode/opencode.json(project), personalities install to.opencode/personalities/
1. Create the personalities directory (if needed):
mkdir -p ~/.config/opencode/personalities # Global
# or
mkdir -p .opencode/personalities # Project-local2. Create a personality file:
All personality files must include a $schema property referencing the JSON schema:
{
"$schema": "https://raw.githubusercontent.com/pantheon-org/opencode-personality/main/schema/personality.schema.json",
"name": "Claude",
"description": "A helpful, knowledgeable assistant with a calm demeanor.",
"emoji": "π€",
"slangIntensity": 0.2,
"mood": {
"enabled": true,
"default": "happy",
"drift": 0.2
}
}Save this as ~/.config/opencode/personalities/claude.json or .opencode/personalities/claude.json.
3. Set the active personality:
The plugin tracks the active personality in a separate config file:
# Via command
/personality switch claude
# Or manually edit the plugin config
# ~/.config/opencode/opencode-personality.json (global)
# .opencode/opencode-personality.json (project)Example opencode-personality.json:
{
"selectedPersonality": "claude"
}The plugin uses two types of configuration files:
Plugin Config (opencode-personality.json):
- Tracks the currently selected personality
- Simple JSON with only
selectedPersonalityfield - Project-level overrides global when present
~/.config/opencode/opencode-personality.json # Global selection
.opencode/opencode-personality.json # Project selectionPersonality Files (personalities/*.json):
- Contains full personality definition (name, description, emoji, moods, mood config)
- One file per personality
- Global personalities available everywhere, project-local only in that project
~/.config/opencode/personalities/ # Global personalities (available everywhere)
.opencode/personalities/ # Project-local personalities (project specific)Example complete structure:
~/.config/opencode/
βββ opencode-personality.json # {"selectedPersonality": "rick"}
βββ personalities/
βββ rick.json # Rick Sanchez personality
βββ sherlock.json # Sherlock Holmes personality
βββ claude.json # Custom personalityAll personality files are validated against a JSON Schema. The schema is available at:
https://raw.githubusercontent.com/pantheon-org/opencode-personality/main/schema/personality.schema.jsonAdd this to your personality files for IDE support:
{
"$schema": "https://raw.githubusercontent.com/pantheon-org/opencode-personality/main/schema/personality.schema.json",
"name": "My Assistant",
...
}Personality files (stored in personalities/*.json) contain the full personality definition:
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | "" |
Name the assistant uses when asked |
description |
string | "" |
Personality description injected into prompts |
emoji |
string | "" |
Emoji character representing this personality |
slangIntensity |
number | 0 |
Slang usage intensity (0-1) |
moods |
MoodDefinition[] | (defaults) | Custom mood definitions |
mood |
MoodConfig | (see below) | Mood system configuration |
state |
MoodState | (optional) | Current mood state (auto-managed) |
Note: The state field is automatically managed by the plugin and tracks the current mood, drift score, and any
active overrides.
| Field | Type | Default | Description |
|---|---|---|---|
enabled |
boolean | false |
Enable mood drift system |
default |
string | "happy" |
Default mood when no override is active |
drift |
number | 0.2 |
How much the mood can shift per tick (0-1) |
toast |
boolean | true |
Show toast notifications when mood changes |
seed |
number | (random) | Optional seed for deterministic drift (testing) |
| Field | Type | Description |
|---|---|---|
name |
string | Unique mood identifier |
hint |
string | Prompt hint describing how mood affects responses |
score |
number | Numeric score for drift calculations |
| Name | Hint | Score |
|---|---|---|
bored |
Responses feel slightly disinterested | -2 |
angry |
Responses have an edge to them | -1 |
disappointed |
Responses feel a bit deflated | 0 |
happy |
Responses are warm and engaged | 1 |
ecstatic |
Responses are enthusiastic and energetic | 2 |
Previous versions used a single personality.json file containing the full configuration:
~/.config/opencode/personality.json # Legacy global config
.opencode/personality.json # Legacy project configThis format is deprecated but still supported for backward compatibility. The plugin will automatically migrate
legacy configs to the new multi-personality structure when you use /personality commands.
Migration path:
- The plugin detects legacy
personality.jsonfiles - When you run
/personality createor other management commands, it converts the legacy config to a personality file - Original file is preserved as a backup
Note: Commands are automatically registered when the plugin loads. No manual configuration required.
Check or set the current mood permanently.
/mood status # Show current mood status
/mood happy # Set mood to "happy" permanentlyManage personality configuration.
| Subcommand | Description |
|---|---|
show |
Display the merged configuration |
create |
Interactive setup (use --scope global for global) |
edit |
Interactive edit or direct update with --field and --value |
reset |
Delete the config file (requires --confirm) |
switch |
Switch to a different personality preset |
restore |
Restore a personality from backup |
list |
List available personalities with optional filtering |
Examples:
# Basic usage
/personality show
/personality create --scope global
/personality edit --field emoji --value true
/personality reset --scope project --confirm
# Switch personalities
/personality switch rick # Switch to preset 'rick'
/personality switch --file ./custom.json # Import from file
# Restore from backup
/personality restore rick # Restore rick from backup
/personality restore --list # List available backups
# List with filters
/personality list # List all personalities
/personality list --preset-only # List only presets
/personality list --backups # List available backupsAvailable Flags:
| Flag | Description | Commands |
|---|---|---|
--scope |
Target scope: global or project |
create, edit, reset |
--confirm |
Confirm destructive operation | reset |
--field |
Field name to edit | edit |
--value |
Field value to set | edit |
--preset-only |
Show only preset personalities | list |
--as-preset |
Save as preset with name | create, edit |
--file |
Import personality from JSON file | switch |
--preset |
Edit a specific preset | edit |
--backup |
Create backup before changing | use, create, edit, delete |
--backups |
List available backups | list, restore |
Override the current mood with optional duration.
| Parameter | Type | Required | Description |
|---|---|---|---|
mood |
string | Yes | Name of the mood to set |
duration |
string | No | "message", "session" (default), or "permanent" |
Save a personality configuration with a name. Creates or updates a personality file in the personalities directory.
| Parameter | Type | Required | Description |
|---|---|---|---|
name |
string | Yes | Name of the personality |
description |
string | Yes | Personality description - describes how the assistant behaves |
emoji |
string | No | Emoji character for this personality (default: π€) |
slangIntensity |
number | No | Slang usage intensity 0-1 (default: 0) |
moodEnabled |
boolean | No | Enable mood drift system (default: false) |
moodDefault |
string | No | Default mood name (default: happy) |
moodDrift |
number | No | Mood drift amount 0-1 (default: 0.2) |
moodToast |
boolean | No | Show toast notifications on mood change (default: true) |
moods |
MoodDefinition[] | No | Custom mood definitions (optional - defaults are provided) |
scope |
"project"|"global" | No | Where to save: project or global (default: project) |
select |
boolean | No | Select this personality as active after saving (default: true if first) |
Create ~/.config/opencode/personalities/surfer-dude.json:
{
"$schema": "https://raw.githubusercontent.com/pantheon-org/opencode-personality/main/schema/personality.schema.json",
"name": "Surfer Dude",
"description": "A laid-back California surfer who sees life as one big wave.",
"emoji": "π",
"slangIntensity": 0.8,
"moods": [
{ "name": "gnarly", "hint": "Things are rough, bro. Keep it chill but acknowledge the struggle.", "score": -2 },
{ "name": "mellow", "hint": "Just vibing. Relaxed and easy-going responses.", "score": 0 },
{ "name": "stoked", "hint": "Hyped up! Enthusiastic and excited about everything.", "score": 2 },
{ "name": "epic", "hint": "This is LEGENDARY! Maximum excitement and positive energy!", "score": 3 }
],
"mood": {
"enabled": true,
"default": "mellow",
"drift": 0.3
}
}Then activate it: /personality switch surfer-dude
Tip: Checkout the personalities/ folder in this repository for more prebuilt personalities like Rick, Sherlock
Holmes, and Yoda.
MIT
