Agent Config Sync
Purpose
Define how wai manages AI agent configurations as a single source of truth, with projections to tool-specific formats like .claude/, .cursorrules, .windsurfrules, and AGENTS.md.
Problem Statement
Modern development involves multiple AI coding assistants (Claude Code, Cursor, Windsurf, etc.), each requiring its own configuration format and location. Maintaining consistent agent instructions across these tools leads to configuration drift, duplicated effort, and inconsistent behavior. Developers need a single source of truth for agent configurations that can be projected to each tool’s expected format automatically.
Design Rationale
Single Source of Truth
Storing all agent configuration in .wai/resources/agent-config/ is a Type 1 decision. This centralizes skills, rules, and context files in one location, making them versionable, reviewable, and consistent. Tool-specific files become projections of this canonical source rather than independent configurations.
Projection Strategies
Three projection strategies (symlink, inline, reference) provide flexibility for different tool requirements. This is a Type 2 decision — the strategies may evolve, but the concept of projecting from a single source is foundational.
- Symlink: Creates filesystem symlinks from tool locations to the canonical files. Most efficient, but requires symlink support.
- Inline: Concatenates source files into a single output file with auto-generated headers. Works everywhere, but requires re-running sync after changes.
- Reference: Generates an index file pointing to
.wai/locations. Lightweight, but requires tool support for following references.
Auto-Generated Headers
Projected files include # Auto-generated by wai — do not edit directly headers to prevent accidental direct edits and make the generation pipeline visible.
Scope and Requirements
This spec covers the storage, organization, and projection of agent configuration files.
Non-Goals
- Defining the content or semantics of agent rules/skills
- Managing tool-specific settings beyond agent instructions (e.g., Cursor’s editor settings)
- Automatic detection and sync on file change (manual
wai syncis required) - Remote or team-wide config sharing
Requirement: Agent Config Storage
Agent configurations SHALL be stored in a structured directory within .wai/resources/.
Scenario: Config directory structure
- WHEN wai is initialized
- THEN the agent-config directory structure is:
.wai/resources/agent-config/ ├── skills/ # Reusable agent capabilities ├── rules/ # Behavioral guidelines ├── context/ # Project-specific context └── .projections.yml
Requirement: Projections Configuration
A .projections.yml file SHALL define how configs are projected to tool-specific locations.
Scenario: Projections file format
- WHEN configuring projections
- THEN
.projections.ymlfollows this format:projections: - target: .claude/ strategy: symlink sources: - skills/ - rules/ - target: .cursorrules strategy: inline sources: - rules/ - context/ - target: AGENTS.md strategy: inline sources: - context/
Requirement: Sync Command
The CLI SHALL provide a wai sync command to execute projections.
Scenario: Execute projections
- WHEN user runs
wai sync - THEN the system reads
.projections.yml - AND generates projected files according to each target’s strategy
- AND reports which files were created or updated
Scenario: Check sync status
- WHEN user runs
wai sync --status - THEN the system shows which projections are up-to-date and which need syncing
- AND does not modify any files
Requirement: Config Management
The CLI SHALL support managing agent config files.
Scenario: Add a skill
- WHEN user runs
wai config add skill <file> - THEN the system copies the file to
.wai/resources/agent-config/skills/
Scenario: Add a rule
- WHEN user runs
wai config add rule <file> - THEN the system copies the file to
.wai/resources/agent-config/rules/
Scenario: List configs
- WHEN user runs
wai config list - THEN the system shows all files in skills/, rules/, and context/ directories
Requirement: Import Existing Configs
The CLI SHALL support importing configurations from existing tool-specific files.
Scenario: Import from Claude directory
- WHEN user runs
wai import .claude/ - THEN the system detects Claude-specific config files
- AND copies them into the appropriate agent-config subdirectories
Scenario: Import from cursorrules
- WHEN user runs
wai import .cursorrules - THEN the system reads the cursorrules file
- AND imports the content as agent rules
Requirement: Auto-Generated Headers
Projected files SHALL include headers indicating they are auto-generated.
Scenario: Generated file header
- WHEN a file is generated via
wai sync - THEN it begins with a comment:
# Auto-generated by wai — do not edit directly - AND includes the source path for reference
Requirements
Requirement: Claude Code Built-in Projection Target
The sync system SHALL support claude-code as a built-in projection target that
automatically maps hierarchical wai skills to Claude Code command files with
translated frontmatter.
Scenario: Built-in target activation
- WHEN a projection defines
target: claude-code - THEN the system treats it as a built-in target, not a filesystem path
- AND scans
skills/<category>/<action>/SKILL.mdfor all hierarchical skills
Scenario: Skill file generated at correct path
- WHEN
wai syncprocesses aclaude-codetarget - AND a skill exists at
skills/issue/gather/SKILL.md - THEN the system writes
.claude/commands/issue/gather.md - AND creates the
.claude/commands/issue/directory if it does not exist
Scenario: Frontmatter translation
- WHEN a wai SKILL.md has frontmatter
name: issue/gatheranddescription: "Gather issues from codebase" - THEN the generated Claude Code file has frontmatter:
name: "Issue: Gather" description: "Gather issues from codebase" category: "Issue" - AND the skill body is written unchanged after the frontmatter block
- AND the
namefield is derived by capitalising the first letter of each path segment and joining with:(e.g.,issue/gather→Issue: Gather)
Scenario: Auto-generated header
- WHEN a Claude Code file is generated by
wai sync - THEN the
---frontmatter delimiter is on line 1 of the generated file (required for frontmatter parsers that enforce strict position) - AND the file body (after the closing
---of the frontmatter) begins with:<!-- Auto-generated by wai — do not edit directly --> - AND the source path is noted (e.g.,
<!-- Source: skills/issue/gather/SKILL.md -->)
Requirement: Hierarchical Skill Names
Skill names SHALL support a single / separator to enable category/action grouping
that maps directly to Claude Code’s invocation path convention (/category:action).
Scenario: Create hierarchical skill
- WHEN user runs
wai resource add skill issue/gather - THEN the system creates
.wai/resources/agent-config/skills/issue/gather/SKILL.md - AND the skill is listed with name
issue/gather
Scenario: Flat names unchanged
- WHEN user runs
wai resource add skill my-skill - THEN the system creates
.wai/resources/agent-config/skills/my-skill/SKILL.md - AND existing flat naming behavior is preserved
Scenario: Invalid hierarchical names rejected
- WHEN user provides a skill name with two or more slashes (e.g.,
a/b/c) - THEN the system rejects it with a clear error: only one
/is allowed
Scenario: Empty segments rejected
- WHEN user provides a name with an empty segment (e.g.,
/gatherorissue/) - THEN the system rejects it with an error explaining both segments must be non-empty
Scenario: Category grouping in list output
- WHEN user runs
wai resource list skills - AND hierarchical skills exist (e.g.,
issue/gather,issue/create) - THEN skills are displayed with their full hierarchical name (e.g.,
issue/gather) - AND the JSON output includes a
categoryfield for hierarchical skills
Scenario: Frontmatter name for hierarchical skill
- WHEN user runs
wai resource add skill issue/gather - THEN the generated SKILL.md frontmatter contains
name: issue/gather(the full hierarchical name, not just the action segment) - AND this name is what
add-claude-code-projectionreads for frontmatter translation
Scenario: Flat-name collision with category directory rejected
- WHEN a flat skill named
issuealready exists atskills/issue/SKILL.md - AND user runs
wai resource add skill issue/gather - THEN the system errors with a message explaining that
issueis already a flat skill and cannot also be used as a category name - AND suggests renaming the existing flat skill before creating the category
Requirement: Skill Template Library
The CLI SHALL provide built-in templates that scaffold common agent pipeline skill patterns when creating a new skill.
Scenario: Create skill from template
- WHEN user runs
wai resource add skill issue/gather --template gather - THEN the system creates
SKILL.mdwith the gather template body - AND the template uses
$ARGUMENTS,$PROJECT,$REPO_ROOTplaceholders - AND the SKILL.md is ready to use without further editing of placeholders
Scenario: Available templates
- WHEN user runs
wai resource add skill <name> --template <name> - THEN the system accepts the following template names:
gather— research stub:wai search $ARGUMENTS, codebase exploration,wai add researchcreate— creation stub: artifact retrieval viawai search --latest, item loop with output trackingtdd— test-first stub: RED/GREEN/REFACTOR loop withcargo test/just checkrule-of-5— review stub: 5-pass review with convergence check and APPROVED / NEEDS_CHANGES / NEEDS_HUMAN verdict
Scenario: Unknown template name rejected
- WHEN user runs
wai resource add skill <name> --template unknown-template - THEN the system rejects the command with an error
- AND lists the valid template names in the error message
Scenario: No template gives bare stub
- WHEN user runs
wai resource add skill <name>without--template - THEN the system creates the existing minimal stub (no regression)
Scenario: Templates are portable
- WHEN a template-generated SKILL.md is used in a different project
- THEN all project-specific values are provided via
$ARGUMENTS,$PROJECT, or$REPO_ROOTat runtime — no hardcoded project names exist in the template