ctx0 System Entries
This document describes the system entries feature - global default vault entries that all users inherit, defined in code as the single source of truth.
Overview
System entries are global defaults that exist in code, not in the database. They provide:
- Instant updates to all users - Change code, redeploy, everyone sees it immediately
- No migration needed - Existing users see system entries without database seeding
- User customization - Users can "fork" entries by editing them
- Reset to default - Users can revert customizations anytime
┌─────────────────────────────────────────────────────────────────┐
│ GLOBAL SYSTEM ENTRIES │
│ (defined in code - you control) │
│ │
│ packages/ctx0/src/system-entries/ │
│ ├── index.ts # Exports SYSTEM_ENTRIES array │
│ ├── types.ts # SystemEntry, MergedEntry types │
│ ├── folders.ts # /skills/, /agents/ folders │
│ └── agents/ │
│ ├── ctx0.ts # ctx0 AGENT.md + config.json │
│ └── curator.ts # curator AGENT.md + config.json │
│ │
└────────────────────────────┬────────────────────────────────────┘
│
│ merged at read time
▼
┌─────────────────────────────────────────────────────────────────┐
│ USER ENTRIES (overrides) │
│ (ctx0_entries table) │
│ │
│ Only contains entries the user has customized: │
│ - User edits /agents/curator/AGENT.md → fork saved here │
│ - User creates /agents/my-agent/ → stored here │
│ - User deletes fork → reverts to system default │
│ │
└────────────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ MERGED VAULT VIEW │
│ │
│ /skills/ ← system (locked folder) │
│ /agents/ ← system (locked folder) │
│ /agents/ctx0/AGENT.md ← system OR user fork │
│ /agents/curator/AGENT.md ← system OR user fork │
│ /agents/my-agent/ ← user-created │
│ /contacts/sarah-chen ← user-created │
│ │
└─────────────────────────────────────────────────────────────────┘
User Flow
- View vault → User sees merged view (system + their entries)
- Edit system entry → Fork created in their table, marked
is_fork=true - See customized badge → UI shows "CUSTOM" badge on forked entries
- Reset to default → Delete fork from their table, system version shows again
- Owner updates → You change code, all non-forked users see update instantly
Current System Entries
Folders (Locked)
| Path | Type | Description |
|---|---|---|
/skills | folder | Skills folder (locked) |
/agents | folder | Agents folder (locked) |
/agents/ctx0 | folder | ctx0 agent folder (locked) |
/agents/curator | folder | Curator agent folder (locked) |
Files (Editable / Forkable)
| Path | Type | Description |
|---|---|---|
/agents/ctx0/AGENT.md | agent | ctx0 system prompt |
/agents/ctx0/config.json | agent | ctx0 configuration |
/agents/curator/AGENT.md | agent | Curator system prompt |
/agents/curator/config.json | agent | Curator configuration |
Code Structure
SystemEntry Type
interface SystemEntry { /** Full path (e.g., "/agents/ctx0/AGENT.md") */ path: string; /** Entry kind (file or folder) */ entryKind: 'file' | 'folder'; /** Entry type */ entryType: EntryType; /** Whether the entry is locked (cannot be edited/deleted) */ isLocked: boolean; /** Entry title */ title?: string; /** Content (for files) */ content?: string; /** Version number - increment when you update content */ version: number; }
Source Files
| File | Purpose |
|---|---|
packages/ctx0/src/system-entries/index.ts | Main export, SYSTEM_ENTRIES array |
packages/ctx0/src/system-entries/types.ts | TypeScript interfaces |
packages/ctx0/src/system-entries/folders.ts | System folder definitions |
packages/ctx0/src/system-entries/agents/ctx0.ts | ctx0 agent content |
packages/ctx0/src/system-entries/agents/curator.ts | Curator agent content |
Helper Functions
import { SYSTEM_ENTRIES, getSystemEntry, isSystemPath, getSystemEntriesUnderPath, getSystemChildren, } from '@bot0/ctx0'; // Get a system entry by path const entry = getSystemEntry('/agents/ctx0/AGENT.md'); // Check if a path is a system path const isSystem = isSystemPath('/agents/ctx0'); // Get all entries under a path const children = getSystemEntriesUnderPath('/agents');
Vault Merge Logic
The vault module provides functions to merge system entries with user entries:
import { getMergedVaultTree, getMergedEntryContent, getMergedEntry, } from '@bot0/ctx0'; // Get the full merged tree for a user const tree = await getMergedVaultTree(supabase, userId); // Get content for a path (checks user first, then system) const content = await getMergedEntryContent(supabase, userId, '/agents/ctx0/AGENT.md'); // Get a single merged entry const entry = await getMergedEntry(supabase, userId, '/agents/ctx0/AGENT.md');
MergedEntry Type
interface MergedEntry { path: string; entryKind: 'file' | 'folder'; entryType: EntryType; isLocked: boolean; title?: string; version: number; /** True if this is from system entries */ isSystem: boolean; /** True if user has forked this system entry */ isFork: boolean; /** True if user can reset to system default */ canReset: boolean; }
Fork and Reset Logic
Forking a System Entry
When a user edits a system entry, create a fork:
import { forkSystemEntry } from '@bot0/ctx0'; // User edits /agents/ctx0/AGENT.md await forkSystemEntry( supabase, userId, '/agents/ctx0/AGENT.md', newContent );
This creates a row in ctx0_entries with is_fork=true.
Resetting to Default
When a user wants to revert to the system version:
import { resetToSystemDefault } from '@bot0/ctx0'; // Delete the user's fork await resetToSystemDefault( supabase, userId, '/agents/ctx0/AGENT.md' );
This deletes the user's fork, so they see the system version again.
Desktop UI
The Desktop app shows system entries with visual indicators:
Sidebar Icons
| Icon | Meaning |
|---|---|
| Folder (yellow) | Regular folder |
| Folder (gray) with lock | Locked system folder |
| MD icon | Markdown file |
| {} icon (yellow) | JSON file |
Badges
| Badge | Meaning |
|---|---|
SYS (purple) | System entry - defined by bot0 |
CUSTOM (green) | User has customized this system entry |
Status Bar
When viewing a system entry, the content area shows:
- "System entry" indicator for unmodified system entries
- "Customized" indicator for forked entries
- "Reset to default" button for forked entries
Adding New System Entries
1. Add to Source
Create or update files in packages/ctx0/src/system-entries/:
// packages/ctx0/src/system-entries/agents/my-agent.ts import type { SystemEntry } from '../types'; export const MY_AGENT_MD = `--- name: my-agent description: My custom agent tools: - ctx0_remember --- You are my-agent... `; export const MY_AGENT: SystemEntry[] = [ { path: '/agents/my-agent/AGENT.md', entryKind: 'file', entryType: 'agent', isLocked: false, title: 'My Agent', content: MY_AGENT_MD, version: 1, }, ];
2. Add to SYSTEM_ENTRIES
Update packages/ctx0/src/system-entries/index.ts:
import { MY_AGENT } from './agents/my-agent'; export const SYSTEM_ENTRIES: SystemEntry[] = [ ...SYSTEM_FOLDERS, ...CTX0_AGENT, ...CURATOR_AGENT, ...MY_AGENT, // Add new entries ];
3. Rebuild and Deploy
pnpm --filter @bot0/ctx0 build
All users will see the new entry immediately (unless they've forked it).
Updating System Entry Content
To update a system entry's content:
- Edit the content in the source file
- Increment the
versionfield - Rebuild and deploy
// Before export const CTX0_AGENT: SystemEntry[] = [ { path: '/agents/ctx0/AGENT.md', content: CTX0_AGENT_MD, version: 1, // Current version }, ]; // After updating content export const CTX0_AGENT: SystemEntry[] = [ { path: '/agents/ctx0/AGENT.md', content: CTX0_AGENT_MD_V2, version: 2, // Increment version }, ];
The version field can be used to show "update available" indicators for users who have forked old versions.
Database Schema
The ctx0_entries table has these columns for system entry support:
| Column | Type | Description |
|---|---|---|
is_system | boolean | Entry was created by system (legacy) |
is_locked | boolean | Entry cannot be modified/deleted |
is_fork | boolean | User fork of a system entry |
Benefits
- Code as source of truth - System entries live in git, version controlled
- No database seeding - No migration jobs, no seed scripts
- Instant updates - Change code, redeploy, everyone sees it
- Clean separation - User table only has their customizations
- Reset capability - Users can always get back to defaults
Related Documentation
- ctx0 Vault Structure - Folder organization
- ctx0 Agents - Agent system design
- Drizzle Schema Management - Database migrations