Skip to content

Commit 38ff2f6

Browse files
authored
feat: add codex to agent list in install-skills command (#9)
1 parent a52414b commit 38ff2f6

7 files changed

Lines changed: 69 additions & 5 deletions

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
group=io.flamingock
2-
version=1.2.1
2+
version=1.2.2

src/main/java/io/flamingock/cli/executor/command/InstallSkillsCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class InstallSkillsCommand implements Callable<Integer> {
4141
private boolean global;
4242

4343
@Option(names = {"-a", "--agent"},
44-
description = "Target AI assistant: claude, github, cursor, opencode, gemini, windsurf, pi")
44+
description = "Target AI assistant: claude, codex, github, cursor, opencode, gemini, windsurf, pi")
4545
private String agent;
4646

4747
private final SkillsInstallationTargetResolver targetResolver;

src/main/java/io/flamingock/cli/executor/skills/SkillsInstallationTarget.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ public static SkillsInstallationTarget claude(Path destinationSkillsDir) {
6161
return new SkillsInstallationTarget("local:claude", destinationSkillsDir);
6262
}
6363

64+
/**
65+
* Creates an agent-specific installation target for the <code>codex</code> assistant.
66+
*
67+
* @param destinationSkillsDir codex destination directory
68+
* @return codex installation target
69+
*/
70+
public static SkillsInstallationTarget codex(Path destinationSkillsDir) {
71+
return new SkillsInstallationTarget("local:codex", destinationSkillsDir);
72+
}
73+
6474
/**
6575
* Creates an agent-specific installation target for the <code>github</code> assistant.
6676
*

src/main/java/io/flamingock/cli/executor/skills/SkillsInstallationTargetResolver.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public List<SkillsInstallationTarget> resolveTargets(Path workingDirectory, bool
6262
*
6363
* @param workingDirectory current command working directory
6464
* @param global whether global mode was requested
65-
* @param agent target AI assistant identifier (claude, github, cursor, opencode, gemini, windsurf, pi)
65+
* @param agent target AI assistant identifier (claude, codex, github, cursor, opencode, gemini, windsurf, pi)
6666
* @return resolved installation targets
6767
*/
6868
public List<SkillsInstallationTarget> resolveTargets(Path workingDirectory, boolean global, String agent) {
@@ -80,6 +80,10 @@ public List<SkillsInstallationTarget> resolveTargets(Path workingDirectory, bool
8080
Path destination = directoryResolver.resolveDirectory(workingDirectory, CLAUDE_PATH);
8181
yield List.of(SkillsInstallationTarget.claude(destination));
8282
}
83+
case "codex" -> {
84+
Path destination = directoryResolver.resolveDirectory(workingDirectory, LOCAL_SKILLS_PATH);
85+
yield List.of(SkillsInstallationTarget.codex(destination));
86+
}
8387
case "github" -> {
8488
Path destination = directoryResolver.resolveDirectory(workingDirectory, GITHUB_PATH);
8589
yield List.of(SkillsInstallationTarget.github(destination));
@@ -105,7 +109,7 @@ public List<SkillsInstallationTarget> resolveTargets(Path workingDirectory, bool
105109
yield List.of(SkillsInstallationTarget.pi(destination));
106110
}
107111
default -> throw new IllegalStateException(
108-
"Unsupported agent: '" + agent + "'. Supported values: claude, github, cursor, opencode, gemini, windsurf, pi.");
112+
"Unsupported agent: '" + agent + "'. Supported values: claude, codex, github, cursor, opencode, gemini, windsurf, pi.");
109113
};
110114
}
111115
}

src/test/java/io/flamingock/cli/executor/command/InstallSkillsCommandTest.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ void call_defaultAgentPassesNullToResolver() {
6161
@Test
6262
void call_withInvalidAgentAgentsReturnsExitCodeOne() {
6363
FailingTargetResolver targetResolver = new FailingTargetResolver(
64-
new IllegalStateException("Unsupported agent: 'agents'. Supported values: claude, github, cursor, opencode, gemini, windsurf, pi.")
64+
new IllegalStateException("Unsupported agent: 'agents'. Supported values: claude, codex, github, cursor, opencode, gemini, windsurf, pi.")
6565
);
6666
RecordingPipeline pipeline = new RecordingPipeline(new SkillsInstallationResult(List.of(), List.of()));
6767
InstallSkillsCommand command = new InstallSkillsCommand(targetResolver, pipeline, tempDir);
@@ -81,6 +81,7 @@ void call_withInvalidAgentAgentsReturnsExitCodeOne() {
8181
String stderr = errContent.toString(StandardCharsets.UTF_8);
8282
assertTrue(stderr.contains("agents"));
8383
assertTrue(stderr.contains("claude"));
84+
assertTrue(stderr.contains("codex"));
8485
assertTrue(stderr.contains("github"));
8586
assertTrue(stderr.contains("cursor"));
8687
assertTrue(stderr.contains("opencode"));
@@ -106,6 +107,23 @@ void call_withAgentClaudePassesClaudeToResolver() {
106107
assertEquals("claude", targetResolver.agent);
107108
}
108109

110+
@Test
111+
void call_withAgentCodexPassesCodexToResolver() {
112+
SkillsInstallationTarget resolvedTarget = SkillsInstallationTarget.codex(tempDir.resolve(".agents/skills"));
113+
RecordingTargetResolver targetResolver = new RecordingTargetResolver(List.of(resolvedTarget));
114+
RecordingPipeline pipeline = new RecordingPipeline(new SkillsInstallationResult(
115+
List.of(resolvedTarget),
116+
List.of("flamingock-core")
117+
));
118+
InstallSkillsCommand command = new InstallSkillsCommand(targetResolver, pipeline, tempDir);
119+
120+
int exitCode = new CommandLine(command).execute("-a", "codex");
121+
122+
assertEquals(0, exitCode);
123+
assertTrue(targetResolver.called);
124+
assertEquals("codex", targetResolver.agent);
125+
}
126+
109127
@Test
110128
void call_withAgentGithubPassesGithubToResolver() {
111129
SkillsInstallationTarget resolvedTarget = SkillsInstallationTarget.github(tempDir.resolve(".github/skills"));

src/test/java/io/flamingock/cli/executor/skills/SkillsInstallationTargetResolverTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ void resolveTargets_agentsAgentThrowsWithSupportedValues() {
7272
String message = exception.getMessage();
7373
assertTrue(message.contains("agents"));
7474
assertTrue(message.contains("claude"));
75+
assertTrue(message.contains("codex"));
7576
assertTrue(message.contains("github"));
7677
assertTrue(message.contains("cursor"));
7778
assertTrue(message.contains("opencode"));
@@ -93,6 +94,20 @@ void resolveTargets_claudeAgentResolvesToClaudePath() {
9394
assertTrue(directoryResolver.called);
9495
}
9596

97+
@Test
98+
void resolveTargets_codexAgentResolvesToAgentsPath() {
99+
RecordingDirectoryResolver directoryResolver = new RecordingDirectoryResolver(tempDir.resolve(".agents/skills"));
100+
SkillsInstallationTargetResolver resolver = new SkillsInstallationTargetResolver(directoryResolver);
101+
102+
List<SkillsInstallationTarget> targets = resolver.resolveTargets(tempDir, false, "codex");
103+
104+
assertEquals(1, targets.size());
105+
assertEquals("local:codex", targets.get(0).identifier());
106+
assertEquals(tempDir.resolve(".agents/skills"), targets.get(0).destinationSkillsDir());
107+
assertArrayEquals(new String[]{".agents", "skills"}, directoryResolver.segments);
108+
assertTrue(directoryResolver.called);
109+
}
110+
96111
@Test
97112
void resolveTargets_geminiAgentResolvesToGeminiPath() {
98113
RecordingDirectoryResolver directoryResolver = new RecordingDirectoryResolver(tempDir.resolve(".gemini/skills"));
@@ -184,6 +199,7 @@ void resolveTargets_invalidAgentThrowsWithSupportedValues() {
184199
String message = exception.getMessage();
185200
assertTrue(message.contains("foo"));
186201
assertTrue(message.contains("claude"));
202+
assertTrue(message.contains("codex"));
187203
assertTrue(message.contains("github"));
188204
assertTrue(message.contains("cursor"));
189205
assertTrue(message.contains("opencode"));

src/test/java/io/flamingock/cli/executor/skills/SkillsInstallationTargetTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,22 @@ void claudeFactoryCreatesTargetWithClaudeIdentifier() {
5555
assertEquals(dest, target.destinationSkillsDir());
5656
}
5757

58+
@Test
59+
void codexFactoryCreatesTargetWithCodexIdentifier() {
60+
Path dest = Path.of("/some/path/.agents/skills");
61+
SkillsInstallationTarget target = SkillsInstallationTarget.codex(dest);
62+
63+
assertEquals("local:codex", target.identifier());
64+
assertEquals(dest, target.destinationSkillsDir());
65+
}
66+
67+
@Test
68+
void codexFactoryRejectsNullPath() {
69+
assertThrows(NullPointerException.class,
70+
() -> SkillsInstallationTarget.codex(null),
71+
"destinationSkillsDir must not be null");
72+
}
73+
5874
@Test
5975
void githubFactoryCreatesTargetWithGithubIdentifier() {
6076
Path dest = Path.of("/some/path/.github/skills");

0 commit comments

Comments
 (0)