Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added support for `gpt-5.2` model from OpenAI
- Added `django-crontask` integration and scheduler service scaffolding for periodic tasks.
- Added GitHub CLI (`gh`) tool support in Git platform middleware for GitHub operations.
- Added support for `.agents/skills` directory as an additional location for project-specific skills, providing more flexibility in organizing skills alongside existing `.daiv/skills`, `.cursor/skills`, and `.claude/skills` directories.

### Changed

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ DAIV is an open-source automation assistant designed to enhance developer produc
- ⚙️ **Configurable Behavior**: A `.daiv.yml` file in your repo's default branch lets you tailor DAIV's features (like toggling auto-issue addressing).
- ⚡ **Slash Commands**: Command-based interactions for common tasks on issues and merge requests, such as help to list available commands, cloning issues to multiple repositories, etc.
- 🔧 **MCP Tools**: Supporting [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) tools to extend the capabilities of the agents.
- 🎯 **Agent Skills**: Modular, reusable capabilities that give agents domain-specific expertise. Define custom workflows in your repository's `.daiv/skills/` directory, or use builtin skills like changelog maintenance and AGENTS.md generation.
- 🎯 **Agent Skills**: Modular, reusable capabilities that give agents domain-specific expertise. Define custom workflows in your repository's `.daiv/skills/`, `.agents/skills/`, `.cursor/skills/`, or `.claude/skills/` directory, or use builtin skills like changelog maintenance and AGENTS.md generation.
- 📦 **Sandbox**: Running commands in a secure sandbox to allow the agents to perform actions on the codebase, such as installing/updating dependencies, generating translations, etc. with your own docker image.
- 📊 **Monitoring**: Monitoring the behavior of the agents to allow you to analyze the performance and identify potential issues.
- 🤖 **Providers Support**: [OpenAI](https://openai.com/api/), [Anthropic](https://www.anthropic.com/api), [Gemini](https://ai.google.dev/gemini) and [OpenRouter](https://openrouter.ai/) are the supported LLM providers.
Expand Down
3 changes: 2 additions & 1 deletion daiv/automation/agent/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
DAIV_SKILLS_PATH = ".daiv/skills"
CURSOR_SKILLS_PATH = ".cursor/skills"
CLAUDE_CODER_SKILLS_PATH = ".claude/skills"
AGENTS_SKILLS_PATH = ".agents/skills"

# Paths where the skills are stored in repository.
SKILLS_SOURCES = [DAIV_SKILLS_PATH, CURSOR_SKILLS_PATH, CLAUDE_CODER_SKILLS_PATH]
SKILLS_SOURCES = [DAIV_SKILLS_PATH, CURSOR_SKILLS_PATH, CLAUDE_CODER_SKILLS_PATH, AGENTS_SKILLS_PATH]

# Path where the memory is stored in repository.
DAIV_MEMORY_PATH = ".daiv/AGENTS.md"
Expand Down
21 changes: 16 additions & 5 deletions docs/ai-agents/skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,16 @@ This architecture ensures minimal context usage—agents only know Skills exist

## Skills Directory Structure

Skills live in the `.daiv/skills/` directory at the root of your repository:
Skills can be placed in any of the following directories at the root of your repository:

- `.daiv/skills/` (default)
- `.agents/skills/`
- `.cursor/skills/`
- `.claude/skills/`

DAIV automatically scans all these directories and loads skills from each.

Example structure:

```
your-repository/
Expand All @@ -68,11 +77,13 @@ your-repository/
│ │ ├── SKILL.md # Required: YAML frontmatter + instructions
│ │ ├── checklist.md # Optional: supporting documentation
│ │ └── review.py # Optional: helper script
│ ├── web-research/
│ │ ├── SKILL.md
│ │ └── search_helper.py
│ └── creating-agents-md-file/ # Builtin skill (auto-copied)
│ └── SKILL.md
├── .agents/
│ └── skills/
│ └── web-research/
│ ├── SKILL.md
│ └── search_helper.py
├── src/
└── README.md
```
Expand All @@ -86,7 +97,7 @@ DAIV includes builtin Skills that are automatically loaded to the `.daiv/skills/
| `generating-agents-md` | Generates or updates an AGENTS.md file reflecting repository structure and conventions | Issues |
| `skills-creator` | Creates a new Skill in the `.daiv/skills/` directory | Issues |

You can override builtin skills by creating a Skill with the same name in your project's `.daiv/skills/` directory.
You can override builtin skills by creating a Skill with the same name in any of your project's skills directories.

---

Expand Down
43 changes: 43 additions & 0 deletions tests/unit_tests/automation/agent/middlewares/test_skills.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,3 +429,46 @@ async def test_skill_tool_appends_named_arguments_when_missing_placeholder(self)
assert isinstance(result, Command)
messages = result.update["messages"]
assert messages[1].content.endswith("\n\n$ARGUMENTS: --flag=1")

async def test_discovers_skills_from_multiple_sources(self, tmp_path: Path):
from deepagents.backends.filesystem import FilesystemBackend

repo_name = "repoX"
builtin = tmp_path / "builtin_skills"
(builtin / "skill-one").mkdir(parents=True)
(builtin / "skill-one" / "SKILL.md").write_text(_make_skill_md(name="skill-one", description="builtin one"))

# Create skills in different source directories
daiv_skill = tmp_path / repo_name / ".daiv" / "skills" / "daiv-skill"
daiv_skill.mkdir(parents=True)
(daiv_skill / "SKILL.md").write_text(_make_skill_md(name="daiv-skill", description="from daiv"))

agents_skill = tmp_path / repo_name / ".agents" / "skills" / "agents-skill"
agents_skill.mkdir(parents=True)
(agents_skill / "SKILL.md").write_text(_make_skill_md(name="agents-skill", description="from agents"))

cursor_skill = tmp_path / repo_name / ".cursor" / "skills" / "cursor-skill"
cursor_skill.mkdir(parents=True)
(cursor_skill / "SKILL.md").write_text(_make_skill_md(name="cursor-skill", description="from cursor"))

backend = FilesystemBackend(root_dir=tmp_path, virtual_mode=True)
middleware = SkillsMiddleware(
backend=backend,
sources=[f"/{repo_name}/.daiv/skills", f"/{repo_name}/.agents/skills", f"/{repo_name}/.cursor/skills"],
)
runtime = _make_runtime(repo_working_dir=str(tmp_path / repo_name))

with patch("automation.agent.middlewares.skills.BUILTIN_SKILLS_PATH", builtin):
result = await middleware.abefore_agent({"messages": [HumanMessage(content="hello")]}, runtime, Mock())

assert result is not None
skills = {skill["name"]: skill for skill in result["skills_metadata"]}
assert set(skills) == {"skill-one", "daiv-skill", "agents-skill", "cursor-skill"}
assert skills["skill-one"]["description"] == "builtin one"
assert skills["skill-one"]["metadata"]["is_builtin"] is True
assert skills["daiv-skill"]["description"] == "from daiv"
assert "is_builtin" not in skills["daiv-skill"]["metadata"]
assert skills["agents-skill"]["description"] == "from agents"
assert "is_builtin" not in skills["agents-skill"]["metadata"]
assert skills["cursor-skill"]["description"] == "from cursor"
assert "is_builtin" not in skills["cursor-skill"]["metadata"]