# REQ-006: Bundle Marketplace Content in CLI Package

## Metadata
- **Status:** ready
- **Priority:** critical
- **Dependencies:** REQ-000
- **Blocks:** —
- **Questions:** 0
- **Created:** 2026-03-03

## Context

The ievo CLI downloads agents and templates from GitHub at runtime. This causes two problems:

1. **Offline = broken** — `ievo init` / `ievo add` fail without network access
2. **Version mismatch** — CLI version X may fetch incompatible agent version Y from GitHub HEAD

**Solution**: ship marketplace content (agents, templates, skills, registry) inside the pip package. Bundled content is the default source; GitHub fetch remains as an optional update mechanism.

### Critical format mismatch

The CLI currently installs agents in the **old directory format**:
```
agents/<name>/
  agent.yaml      # manifest
  ROLE.md          # system prompt
  memory/          # session memory
```

The marketplace now stores agents as **single `.md` files** with YAML frontmatter, deployed to `.claude/agents/<name>.md`:
```yaml
---
name: spec-writer
description: >
  Break down features into atomic requirements
model: sonnet
tools: [Read, Write, Edit, Glob, Grep]
memory: user
---

# Agent instructions here...
```

This REQ must migrate the CLI from the old directory format to the new `.md` format.

### Current marketplace structure (source: `../marketplace/`)

**Agents** — 12 files in `agents/*.md`:
spec-writer, architect, coder, code-reviewer, qa, acceptance, docs, evolution, researcher, defrag, tech-lead, hr

**Templates** — 7 files in `templates/*.md`:
IEVO.md, REQ_TEMPLATE.md, QUESTION_TEMPLATE.md, PLAN_TEMPLATE.md, CHANGE_REQUEST_TEMPLATE.md, ACCEPTANCE_REPORT_TEMPLATE.md, PROPOSAL_TEMPLATE.md

**Skills** — 2 directories:
`skills/evo/SKILL.md`, `skills/backlog/SKILL.md`

**Registry** — `registry.yaml` with `file` and `mandatory` fields the CLI does not yet parse.

### Key files to modify

- `src/ievo/core/config.py` — add `CLAUDE_AGENTS_DIR`
- `src/ievo/core/registry.py` — `RegistryEntry` fields, bundled fallback, `.md` download
- `src/ievo/commands/add.py` — deploy `.md` files instead of directories
- `src/ievo/commands/init.py` — deploy templates from bundled content
- `src/ievo/commands/init_templates.py` — remove hardcoded template constants
- `src/ievo/commands/remove.py` — remove `.claude/agents/<name>.md`
- `src/ievo/commands/list_cmd.py` — read frontmatter from `.md` files

### Package inclusion

hatchling automatically includes non-Python files in package directories. No `pyproject.toml` changes needed — placing files under `src/ievo/marketplace/` is sufficient.

## User-facing behavior

`ievo init` creates `.claude/agents/` directory alongside existing `.ievo/` structure. Templates are deployed from bundled content instead of hardcoded Python strings.

`ievo add spec-writer`:
1. Copies bundled `src/ievo/marketplace/agents/spec-writer.md` → `.claude/agents/spec-writer.md`
2. If not bundled, downloads from GitHub
3. If download fails, creates placeholder `.md` with minimal frontmatter

`ievo list --marketplace` shows agents from bundled registry (no network required).

`ievo remove spec-writer` removes `.claude/agents/spec-writer.md` (and legacy `agents/spec-writer/` if exists).

`ievo list` reads agent metadata from `.claude/agents/<name>.md` frontmatter.

## Acceptance Criteria

### AC-1: Bundled content access layer
- `src/ievo/marketplace/__init__.py` provides functions: `bundled_registry_path()`, `bundled_agent_path(name)`, `bundled_template_path(filename)`, `bundled_skill_path(skill_name)`, `list_bundled_agents()`, `list_bundled_templates()`, `load_bundled_registry()`
- All 12 agent `.md` files exist under `src/ievo/marketplace/agents/`
- All 7 template `.md` files exist under `src/ievo/marketplace/templates/`
- Both skill files exist under `src/ievo/marketplace/skills/`
- `registry.yaml` exists under `src/ievo/marketplace/`
- `load_bundled_registry()` returns a parsed dict matching the YAML structure

### AC-2: Registry supports new fields
- `RegistryEntry` has `file: str` and `mandatory: bool` fields (with defaults for backwards compatibility)
- `load_cached()` falls back to bundled registry when cache is missing
- `_parse_registry_file()` classmethod extracts common YAML parsing logic

### AC-3: Agent install uses new format
- `ievo add <name>` deploys a single `.md` file to `.claude/agents/<name>.md`
- Source priority: bundled → GitHub download → placeholder
- Placeholder `.md` contains valid YAML frontmatter with `name` and `description` fields
- Old `AgentPackage` directory creation is removed

### AC-4: Init deploys bundled templates
- `ievo init` creates `.claude/agents/` directory
- `ievo init` deploys `IEVO.md` from bundled content to `.ievo/IEVO.md`
- `ievo init` deploys `REQ_TEMPLATE.md` and `CHANGE_REQUEST_TEMPLATE.md` from bundled content to `spec/templates/`
- Hardcoded `SPEC_REQ_TEMPLATE` and `SPEC_CR_TEMPLATE` constants are removed from `init_templates.py`

### AC-5: Remove handles new format
- `ievo remove <name>` deletes `.claude/agents/<name>.md`
- Also removes legacy `agents/<name>/` directory if it exists

### AC-6: List reads frontmatter
- `ievo list` reads agent metadata from `.claude/agents/<name>.md` YAML frontmatter
- Falls back to legacy `agents/<name>/agent.yaml` if `.md` file not found

### AC-7: Bundled content in wheel
- `uv build` produces a wheel containing all files under `src/ievo/marketplace/`
- `unzip -l dist/ievo-*.whl | grep marketplace` shows `.md` and `.yaml` files

## Negative Acceptance Criteria

- Does NOT remove GitHub fetch — it remains as optional update mechanism
- Does NOT modify agent `.md` file content — files are copied verbatim from marketplace
- Does NOT require network for `ievo init`, `ievo add`, or `ievo list --marketplace`
- Does NOT break existing tests — backwards compatible with old format where needed
- Does NOT add new dependencies — uses only `yaml`, `pathlib`, existing project deps

## Technical Notes

New module: `src/ievo/marketplace/__init__.py` — access layer using `Path(__file__).parent` pattern (consistent with `init.py:169`, `run.py:172`).

Content is copied from `../marketplace/` into `src/ievo/marketplace/` at development time, not at build time. This is a one-time copy operation during implementation.

The `download_agent_md(name, dest_dir) -> bool` function on Registry downloads a single `.md` file from GitHub raw URL, replacing the old directory-based `download_agent()`.
