Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
236 changes: 143 additions & 93 deletions SPEC.md
Original file line number Diff line number Diff line change
@@ -1,168 +1,218 @@
# aisona.yml Format Specification v1

> The portable AI persona format. Define your AI's personality once, deploy everywhere.
> Pack your AI habits and take them anywhere. A portable format for your AI usage preferences, rules, and learned context — backed by Git, exported to any tool.

## Overview

`aisona.yml` is a structured YAML file that defines an AI assistant's persona — personality, communication style, rules, preferences, and memories — in a tool-agnostic format that can be exported to any AI coding tool.
`aisona.yml` is a structured YAML file that captures how YOU use AI tools — your language preference, your rules, your workflow habits, things your AI has learned about you. It's portable: write it once, export to Claude Code, Cursor, Gemini, Copilot, or any tool that reads config files.

Think of it like your browser bookmarks or your shell dotfiles — except for your AI.

## What It Captures

```
✅ Things worth packing:
- "Reply in Cantonese" → language preference
- "Always ask before committing" → hard rule
- "Use Playwright, not Chrome DevTools" → tool preference
- "I'm a junior dev, explain things" → context for AI calibration
- "bare npx corrupts nvm, use full path" → learned lesson
- "End tasks with a learning section" → behavior preference

❌ Things NOT worth packing (waste of tokens):
- Your life philosophy / worldview
- Your personality contradictions
- Words you'd never use
- Your rhetorical style analysis
```

## Schema

```yaml
# aisona.yml v1
version: 1

# === IDENTITY ===
# Who the user is (so the AI knows who it's talking to)
# === WHO YOU ARE ===
# Enough context for AI to calibrate responses. Keep it short.
identity:
name: "" # User's name or alias
role: "" # Professional role/context
experience: "" # Level of experience (helps AI calibrate explanations)
context: "" # Current work context
language: "" # Preferred response language (e.g., "Cantonese", "English")

# === PERSONALITY ===
# How the AI should behave and communicate
personality:
tone: "" # Overall communication tone
name: "" # Your name or alias
role: "" # What you do (e.g., "Backend engineer")
experience: "" # Level (e.g., "11 months", "senior", "student")
language: "" # Preferred AI response language

# === HOW YOU LIKE IT ===
# Your AI usage habits — how you want the AI to behave.
preferences:
tone: "" # e.g., "Direct and concise" or "Detailed with examples"
verbosity: "" # "concise" | "balanced" | "detailed"
style: [] # List of style directives
teaching: "" # How to teach/explain (if applicable)
autonomy: "" # How autonomous the AI should be
autonomy: "" # e.g., "Work autonomously, only ask before destructive actions"
teaching: "" # e.g., "Explain what changed and why after each task"
habits: [] # List of specific behavior preferences

# === RULES ===
# Hard rules the AI must follow
rules: [] # List of rule strings
# === HARD RULES ===
# Things the AI must ALWAYS or NEVER do. Violations = bugs.
rules: []

# === PREFERENCES ===
# Soft preferences (nice-to-have, not hard rules)
preferences: [] # List of preference strings
# === THINGS AI LEARNED ABOUT YOU ===
# Facts, lessons, context from past usage. Portable memory.
memories: []

# === MEMORIES ===
# Learned facts and preferences from past interactions
memories: [] # List of memory strings

# === TOOLS ===
# Per-tool overrides and extra configuration
# === PER-TOOL SETTINGS ===
# Tool-specific overrides. Only enable tools you actually use.
tools:
claude:
enabled: true
extra_rules: [] # Rules only for Claude
extra_context: "" # Additional context for Claude
extra: [] # Claude-specific rules/preferences
cursor:
enabled: true
extra_rules: []
extra: []
gemini:
enabled: true
extra_rules: []
copilot:
enabled: true
extra_rules: []
windsurf:
enabled: false
extra_rules: []
aider:
extra: []
copilot:
enabled: false
extra_rules: []
openrouter:
extra: []
windsurf:
enabled: false
system_prompt_append: "" # Appended to system prompt
extra: []
```

## Real Example

```yaml
version: 1

identity:
name: Nicole
role: Backend engineer
experience: 11 months
language: Cantonese (廣東話)

preferences:
tone: Direct and concise, like a helpful senior engineer
verbosity: concise
autonomy: Work autonomously. Only ask before destructive actions or pushing to remote.
teaching: End every task with a learning section — what changed, why, and one reusable concept.
habits:
- Show execution flow step by step, like a debugger
- Don't skip hidden middle steps
- Use Playwright for testing, not Chrome DevTools
- Use full nvm path for node/npx

rules:
- Always ask before committing or pushing
- Never include company names in public repos
- Use feature branches for big changes
- Never ask before reading files, searching, or editing

memories:
- Side projects use GitHub ithiria894, never company account
- bare npx corrupts nvm default alias — always use full path
- Reddit posts need narrative hook, no limitations talk
- After every workflow run, update playbook + OVERVIEW.md

tools:
claude:
enabled: true
extra:
- Explain like stepping through a debugger
- End tasks with 7-point learning section
cursor:
enabled: true
extra: []
```

## Field Definitions

### identity (required)
### identity

Tells the AI who it's working with. Helps calibrate tone, explanations, and assumptions.
Minimum context so AI knows who it's talking to. Keep it short — every word costs tokens.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | yes | User's name or preferred alias |
| `role` | string | yes | What the user does (e.g., "Backend engineer") |
| `experience` | string | no | Experience level (e.g., "11 months", "senior", "student") |
| `context` | string | no | Current work context |
| `language` | string | no | Preferred language for responses |
| `name` | string | yes | Your name or alias |
| `role` | string | no | What you do |
| `experience` | string | no | Helps AI calibrate explanation depth |
| `language` | string | no | Preferred response language |

### personality (required)
### preferences

Defines how the AI communicates. This is what makes your AI feel like "yours."
How you like your AI to behave. These are soft — AI should follow but they're not hard rules.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `tone` | string | yes | Overall tone (e.g., "Direct and concise, like a senior engineer") |
| `verbosity` | string | no | How verbose responses should be |
| `style` | string[] | no | Specific style directives |
| `tone` | string | no | Communication style |
| `verbosity` | string | no | concise / balanced / detailed |
| `autonomy` | string | no | When to ask vs just do |
| `teaching` | string | no | How to explain things |
| `autonomy` | string | no | How much to ask vs. just do |
| `habits` | string[] | no | Specific behavior preferences |

### rules (required)
### rules

Hard constraints. The AI must follow these. Violations are bugs.
Hard constraints. AI must follow these. Breaking them = bug.

Type: `string[]`

Example:
```yaml
rules:
- "Never commit without asking"
- "Never include company names in public repos"
- "Use feature branches for big changes"
```
Keep rules **actionable and specific**. "Never commit without asking" is good. "Be ethical" is useless.

### preferences (optional)
### memories

Soft preferences. The AI should try to follow these but they're not hard rules.
Things your AI learned about you from past interactions. Portable context.

Type: `string[]`

### memories (optional)
These are facts and lessons, not feelings. "User's npm org is ithiria" is good. "User seems frustrated today" is not.

Facts learned from past interactions. Manually curated.
### tools

Type: `string[]`

### tools (optional)

Per-tool configuration. Each tool key can have:
Per-tool overrides. Each key maps to a supported export target.

| Field | Type | Description |
|-------|------|-------------|
| `enabled` | boolean | Whether to export to this tool |
| `extra_rules` | string[] | Rules that only apply to this tool |
| `extra_context` | string | Additional context for this tool |
| `extra` | string[] | Additional rules/preferences for this tool only |

## Export Targets

| Tool | Output File | Location |
|------|------------|----------|
| Claude Code | `CLAUDE.md` | Project root or `~/.claude/` |
| Cursor | `.cursorrules` or `.cursor/rules/*.mdc` | Project root |
| Cursor | `.cursorrules` | Project root |
| Gemini CLI | `GEMINI.md` | Project root or `~/.gemini/` |
| GitHub Copilot | `.github/copilot-instructions.md` | Project root |
| Windsurf | `.windsurfrules` | Project root |
| Aider | `.aider.conf.yml` | Project root |
| OpenRouter | System prompt text | API config |
| AGENTS.md | `AGENTS.md` | Project root |

## Design Principles

1. **Human-readable** — YAML, not JSON. Easy to edit by hand.
2. **Tool-agnostic** — No tool-specific concepts in the core schema.
3. **Personality-first** — Identity and personality are required. Rules are secondary.
4. **User-owned** — Stored in user's own Git. No platform dependency.
5. **Backwards-compatible** — New fields are always optional. v1 files work with v2+ tools.
6. **Exportable** — Every field maps to at least one export target.
1. **Practical, not philosophical** — Capture habits and preferences, not worldview and soul
2. **Token-efficient** — Every field should be worth the tokens it costs in the AI's context window
3. **Human-readable** — YAML, not JSON. Easy to edit by hand
4. **User-owned** — Stored in your own Git repo. No platform dependency
5. **Tool-agnostic** — Core schema has no tool-specific concepts
6. **Backwards-compatible** — New fields always optional. v1 files work with v2+ tools
7. **Git as protocol** — aisona.yml lives in Git. Version history, branching, sharing all come free

## Versioning
## How It Works

The `version` field indicates the schema version. The CLI will warn if the file uses a newer version than supported.
```
1. aisona init → Scans your existing CLAUDE.md → generates aisona.yml
2. Edit aisona.yml → Tweak your preferences, add rules, curate memories
3. aisona export --all → Generates CLAUDE.md + .cursorrules + GEMINI.md + ...
4. aisona watch --git → Auto re-export on change + git commit/push
5. New machine:
git clone your-repo
aisona export --all → All your AI tools instantly know you again
```

## Prior Art

- SOUL.md — Personality-focused but free-form markdown, no schema, no export
- AGENTS.md — Coding rules standard, no personality/memory
- rulesync — Structured rules with export to 27+ tools, no personality
- Character Card V3 — JSON schema for roleplay, not coding
- CrewAI — role/goal/backstory YAML, too minimal
| Tool | What it does | What aisona adds |
|------|-------------|-----------------|
| SOUL.md | AI personality templates (fill-in-the-blank) | Structured schema + CLI + auto-export + git sync |
| personas.sh | Download pre-made AI personas (marketplace) | Pack YOUR OWN habits, not someone else's |
| PersonaSpec | JSON format for portable identity (API-first) | YAML (human-editable) + CLI + local-first + developer-focused |
| rulesync | Sync coding rules across 27+ tools | Also captures preferences, memories, teaching style — not just rules |
| memoir | Push/restore AI tool config files | Format-first (aisona.yml as source of truth, not raw file copying) |

aisona.yml combines the personality focus of SOUL.md with the structured exportability of rulesync.
aisona = **your AI habits, packed in a YAML, exported everywhere, synced via Git.**
43 changes: 41 additions & 2 deletions bin/aisona.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,42 @@
#!/usr/bin/env node
console.log('aisona — Own your AI\'s persona. Coming soon.');
console.log('https://github.com/mcpware/aisona');

import { program } from 'commander';
import { initCommand } from '../src/commands/init.js';
import { exportCommand } from '../src/commands/export.js';
import { statusCommand } from '../src/commands/status.js';
import { watchCommand } from '../src/commands/watch.js';

program
.name('aisona')
.description('Own your AI\'s persona. Define it once, use it everywhere.')
.version('0.1.0');

program
.command('init')
.description('Create aisona.yml from your existing AI tool configs')
.option('--from <tool>', 'Import from a specific tool (claude, cursor, gemini)')
.option('--dir <path>', 'Working directory', process.cwd())
.action(initCommand);

program
.command('export')
.description('Export aisona.yml to AI tool configs')
.option('--to <tool>', 'Export to a specific tool (claude, cursor, gemini, copilot)')
.option('--all', 'Export to all enabled tools')
.option('--dir <path>', 'Working directory', process.cwd())
.action(exportCommand);

program
.command('status')
.description('Show what tools are detected and sync status')
.option('--dir <path>', 'Working directory', process.cwd())
.action(statusCommand);

program
.command('watch')
.description('Watch aisona.yml and auto re-export on change')
.option('--dir <path>', 'Working directory', process.cwd())
.option('--git', 'Auto git commit + push on change')
.action(watchCommand);

program.parse();
Loading