Read this when touching persona definition parsing or frontmatter editing.
Persona definitions are Markdown files in ~/.pi/agent/agents/ with an optional --- frontmatter block. The extension parses them with a hand-written YAML subset parser (no YAML dependency) and edits fields in place so user formatting/comments survive.
AgentDef (parsed): name, description, model (provider/id), thinking (ThinkingLevel), tools: string[], excludeTools: string[], prompt (path to external Markdown file, max 64 KB), body text.
| Constant | Value / location | Meaning |
|---|---|---|
AGENTS_SUBDIR |
agents |
subdir under ~/.pi/agent/ |
STATE_FILENAME |
agent-state.json |
persisted active persona name |
MAX_PROMPT_FILE_BYTES |
64 * 1024 | hard cap for external prompt files |
UNSUPPORTED_YAML_SCALAR_PREFIX |
/^[!&*[{\|>-]/ |
scalar prefixes that make the file "unsupported" (read-only in menus) |
DEFAULT_EFFORT |
medium |
thinking level when unspecified |
key: value scalars and block lists (- item with 2-space indent, see DESCRIPTION_BLOCK_INDENT / isBlockValueLine). Anything containing an unsupported scalar prefix (!, &, *, [, {, |, >, - inline) marks the file as unsupported → shown but not editable.UTF8_BOM constant) — must be stripped before parsing.updateFrontmatterFields) rewrite ONLY the target key's extent (findKeyExtent), leaving all other lines byte-identical — comments and blank lines inside frontmatter must survive./ separator (MODEL_ID_SEPARATOR); thinking values validated against THINKING_LEVELS.ssh-manager_*); they are expanded against tools registered in the running session (expandToolPatterns), not matched against a static list.agent-state.json) stores only the active persona name; if the named file no longer exists, the state is treated as absent (no error).