mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-23 06:54:13 +08:00
feat: Copy project subagents to Claude runtime environment
Enables custom subagents defined in .claude/agents/ to work in GitHub Actions by: - Checking for project agents in GITHUB_WORKSPACE/.claude/agents/ - Creating ~/.claude/agents/ directory if needed - Copying all .md agent files to Claude's runtime location - Following same pattern as slash commands for consistency Includes comprehensive test coverage for the new functionality.
This commit is contained in:
@@ -79,4 +79,31 @@ export async function setupClaudeCodeSettings(
|
||||
console.log(`Slash commands directory not found or error copying: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy project subagents to Claude's agents directory
|
||||
// Use GITHUB_WORKSPACE if available (set by GitHub Actions), otherwise use current directory
|
||||
const workspaceDir = process.env.GITHUB_WORKSPACE || process.cwd();
|
||||
const projectAgentsDir = `${workspaceDir}/.claude/agents`;
|
||||
const claudeAgentsDir = `${home}/.claude/agents`;
|
||||
|
||||
try {
|
||||
await $`test -d ${projectAgentsDir}`.quiet();
|
||||
console.log(`Found project agents directory at ${projectAgentsDir}`);
|
||||
|
||||
// Ensure target agents directory exists
|
||||
await $`mkdir -p ${claudeAgentsDir}`.quiet();
|
||||
|
||||
// Copy all .md files from project agents to Claude's agents directory
|
||||
await $`cp ${projectAgentsDir}/*.md ${claudeAgentsDir}/ 2>/dev/null || true`.quiet();
|
||||
|
||||
// Count copied agents for logging
|
||||
const agentFiles = await $`ls ${claudeAgentsDir}/*.md 2>/dev/null | wc -l`
|
||||
.quiet()
|
||||
.text();
|
||||
const agentCount = parseInt(agentFiles.trim()) || 0;
|
||||
console.log(`Copied ${agentCount} agent(s) to ${claudeAgentsDir}`);
|
||||
} catch (e) {
|
||||
// Directory doesn't exist or no agents to copy - this is expected in most cases
|
||||
console.log(`No project agents directory found at ${projectAgentsDir}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,4 +215,70 @@ describe("setupClaudeCodeSettings", () => {
|
||||
const settingsContent = await readFile(settingsPath, "utf-8");
|
||||
expect(JSON.parse(settingsContent).enableAllProjectMcpServers).toBe(true);
|
||||
});
|
||||
|
||||
test("should copy project agents when .claude/agents directory exists", async () => {
|
||||
// Create a mock project structure with agents
|
||||
const projectDir = join(testHomeDir, "test-project");
|
||||
const projectAgentsDir = join(projectDir, ".claude", "agents");
|
||||
await mkdir(projectAgentsDir, { recursive: true });
|
||||
|
||||
// Create test agent files
|
||||
await writeFile(
|
||||
join(projectAgentsDir, "test-agent.md"),
|
||||
"---\nname: test-agent\ndescription: Test agent\n---\nTest agent content",
|
||||
);
|
||||
await writeFile(
|
||||
join(projectAgentsDir, "another-agent.md"),
|
||||
"---\nname: another-agent\n---\nAnother agent",
|
||||
);
|
||||
|
||||
// Set GITHUB_WORKSPACE to the test project directory
|
||||
const originalWorkspace = process.env.GITHUB_WORKSPACE;
|
||||
process.env.GITHUB_WORKSPACE = projectDir;
|
||||
|
||||
try {
|
||||
await setupClaudeCodeSettings(undefined, testHomeDir);
|
||||
|
||||
// Check that agents were copied
|
||||
const agentsDir = join(testHomeDir, ".claude", "agents");
|
||||
const files = await readdir(agentsDir);
|
||||
expect(files).toContain("test-agent.md");
|
||||
expect(files).toContain("another-agent.md");
|
||||
|
||||
// Verify content was copied correctly
|
||||
const content = await readFile(join(agentsDir, "test-agent.md"), "utf-8");
|
||||
expect(content).toContain("Test agent content");
|
||||
} finally {
|
||||
// Restore original GITHUB_WORKSPACE
|
||||
if (originalWorkspace !== undefined) {
|
||||
process.env.GITHUB_WORKSPACE = originalWorkspace;
|
||||
} else {
|
||||
delete process.env.GITHUB_WORKSPACE;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("should handle missing project agents directory gracefully", async () => {
|
||||
// Set GITHUB_WORKSPACE to a directory without .claude/agents
|
||||
const projectDir = join(testHomeDir, "project-without-agents");
|
||||
await mkdir(projectDir, { recursive: true });
|
||||
|
||||
const originalWorkspace = process.env.GITHUB_WORKSPACE;
|
||||
process.env.GITHUB_WORKSPACE = projectDir;
|
||||
|
||||
try {
|
||||
await setupClaudeCodeSettings(undefined, testHomeDir);
|
||||
|
||||
// Should complete without errors
|
||||
const settingsContent = await readFile(settingsPath, "utf-8");
|
||||
const settings = JSON.parse(settingsContent);
|
||||
expect(settings.enableAllProjectMcpServers).toBe(true);
|
||||
} finally {
|
||||
if (originalWorkspace !== undefined) {
|
||||
process.env.GITHUB_WORKSPACE = originalWorkspace;
|
||||
} else {
|
||||
delete process.env.GITHUB_WORKSPACE;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user