Skip to content

Conversation

@ranyitz
Copy link
Owner

@ranyitz ranyitz commented Jan 18, 2026

Add subagents support for Cursor and Claude Code

This PR adds support for Cursor Subagents and Claude Code Subagents to aicm.

Summary

  • Agents are markdown files with YAML frontmatter stored in an agents/ directory
  • Installed to .cursor/agents/ and .claude/agents/ (Codex not supported yet)
  • Supports local agents, preset agents, workspace mode, and multi-target installation
  • Includes collision warnings and deduplication for preset agents
  • Clean command removes aicm-managed agents while preserving user-created ones

Configuration

Only fields supported by both platforms are documented: name, description, model. Platform-specific fields are preserved but only function on their respective platform.

- Add AgentFile type and loadAgentsFromDirectory to config
- Add writeAgentsToTargets with collision warnings and deduplication
- Add cleanAgents function for cleanup
- Support workspace mode with agent merging
- Add comprehensive e2e tests and documentation
@ranyitz ranyitz requested a review from Copilot January 18, 2026 13:15
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds support for subagents in Cursor and Claude Code, enabling users to define specialized AI assistants as markdown files with YAML frontmatter. The implementation follows a similar pattern to existing skills functionality, with support for local agents, preset agents, workspace mode, and multi-target installation.

Changes:

  • Added agents directory support alongside existing rules, commands, and skills
  • Implemented agent loading, deduplication, and collision warnings for preset conflicts
  • Extended install and clean commands to handle agent files with metadata tracking

Reviewed changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/fixtures/agents-* Test fixtures demonstrating various agent configurations (basic, preset, workspace, collision, multitarget)
tests/e2e/agents.test.ts Comprehensive end-to-end tests for agent installation, collision handling, workspace merging, and cleanup
tests/e2e/install.test.ts Updated success messages to include "agents"
tests/e2e/hooks.test.ts Updated success messages to include "agents"
src/utils/config.ts Added AgentFile type, loadAgentsFromDirectory function, and integrated agents into config loading
src/commands/install.ts Implemented agent installation logic with metadata tracking and collision warnings
src/commands/install-workspaces.ts Added workspace agent merging and installation support
src/commands/clean.ts Implemented selective cleanup of aicm-managed agents using metadata file
README.md Added comprehensive agents documentation with examples and configuration details

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ranyitz
Copy link
Owner Author

ranyitz commented Jan 18, 2026

@codex review this pr

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd884a872c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 559 to 563
// Remove previously managed agents
for (const agentPath of existingMetadata.managedAgents || []) {
const fullPath = path.join(targetAgentsDir, agentPath);
if (fs.existsSync(fullPath)) {
fs.removeSync(fullPath);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject agent paths that escape target directory

The cleanup loop trusts existingMetadata.managedAgents and joins each entry directly into targetAgentsDir. If a repo (or preset) includes a crafted .cursor/agents/.aicm.json with absolute paths or ../ segments, path.join will resolve outside the agents directory and fs.removeSync will delete arbitrary files when install runs (same pattern exists in cleanAgents). This becomes a security foot‑gun whenever users run aicm in untrusted repos. Consider resolving each entry and verifying it stays within targetAgentsDir (and skipping anything that escapes).

Useful? React with 👍 / 👎.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codex Not due to security, but can you fix it to check that path is inside of the project directory and not outside of it to prevent deleting files outside of the repo?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, we'll add agent names instead of paths

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT about this Claude code example?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fixture as part of a test (inspired by this example of course). The main difference is that while I will copy the "tools" metadata field if specified, I don't mention it because it's not supported by Cursor, and I want to have something which is compatible in both formats.

Unfortunately, unlike skills, this is not an open standard. Hopefully once this becomes a standard things will be more aligned between different harnesses.

Store only agent names (not paths) in managedAgents metadata and
validate that names don't contain path separators before deletion.
This prevents malicious .aicm.json files from deleting arbitrary
files outside the agents directory.
@ranyitz ranyitz enabled auto-merge (squash) January 19, 2026 15:33
@ranyitz ranyitz merged commit 029bc0e into main Jan 19, 2026
4 checks passed
@ranyitz ranyitz deleted the feat/subagents-support branch January 19, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants