Skip to content

Commit 9631444

Browse files
committed
test: CLI typed 方法补测(debug/mcp --url/plugin/cloud/features/reviewPrompt)
1 parent 222a535 commit 9631444

6 files changed

Lines changed: 481 additions & 0 deletions

File tree

‎README.md‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ Typical scenarios:
7979
| Auth / MCP / misc | Active development | `login`, `loginWithApiKey`, `loginWithAccessToken`, `loginDeviceAuth`, `loginStatus`, `logout`, `mcpList` / `mcpAdd` / `mcpGet` / `mcpRemove` / `mcpLogin` / `mcpLogout`, `update`, `features`, `completion`, `app` |
8080
| Session admin | Active development | `archiveSession`, `unarchiveSession`, `queue`, `deleteSession`, `deleteSessionForce`, `agents`, `migrateRollouts` |
8181
| App-server WebSocket route | Active development | `CodexAppServerClient.runTurn` / `runTurnAsync`, `thread/start` / `thread/resume`, agent-message deltas, `sessionKey → threadId` LRU (1000) |
82+
| App-server protocol surface | Active development | `thread/list` / `read` / `fork` / `archive` / `unarchive` / `delete`, `turn/interrupt` / `turn/steer`, `model/list`-style escape hatch `execRpc`; `turnId` exposed via `onTurnStarted` + `AppServerTurnResult` |
83+
| CLI typed additions | Active development | `debugModels(Bundled)` / `debugPromptInput`, `mcpAddUrl(WithBearer)`, `pluginAdd/List/Remove` + `pluginMarketplace*`, `cloudExec` / `cloudList`, `featuresEnable/Disable/List`, `reviewPrompt` |
8284
| Config model | Active development | `CodexClientConfig` POJO (plain, Spring-bindable), `CodexAppServerConfig` POJO |
8385

8486
> **Note**: `codex mcp-server` was removed upstream — `CodexClient.mcpServer()`
@@ -296,6 +298,25 @@ try (CodexAppServerClient client = new CodexAppServerClient(config)) {
296298
}
297299
```
298300

301+
### 8.4 App-server protocol operations
302+
303+
```java
304+
try (CodexAppServerClient client = new CodexAppServerClient(config)) {
305+
List<AppServerThread> threads = client.listThreads(20);
306+
AppServerThread forked = client.forkThread("th_123");
307+
client.steerTurn("th_123", "turn_9", "也检查一下测试覆盖率"); // redirect a running turn
308+
client.interruptTurn("th_123", "turn_9"); // cancel a running turn
309+
client.archiveThread("th_123");
310+
String raw = client.execRpc("model/list", Map.of("limit", 10)); // escape hatch
311+
}
312+
```
313+
314+
Lifecycle calls run over a short-lived connection with the documented
315+
tolerant `initialize` handshake; thread state is server-side, so
316+
`steerTurn` / `interruptTurn` work while the original turn connection is
317+
still streaming. Running turns expose their id via
318+
`AppServerTurnRequest.onTurnStarted` and `AppServerTurnResult.getTurnId()`.
319+
299320
The turn maps to `thread/start` (or `thread/resume` when `sessionKey` already
300321
maps to a thread id) → `turn/start` → `item/completed` (only agent messages
301322
surface) → `turn/completed`. Unknown notifications are logged at debug level

‎README.zh-CN.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ SDK 覆盖:
7676
| 认证 / MCP / 其他 | 活跃开发 | `login`、`loginWithApiKey`、`loginWithAccessToken`、`loginDeviceAuth`、`loginStatus`、`logout`、`mcpList` / `mcpAdd` / `mcpGet` / `mcpRemove` / `mcpLogin` / `mcpLogout`、`update`、`features`、`completion`、`app` |
7777
| 会话管理 | 活跃开发 | `archiveSession`、`unarchiveSession`、`queue`、`deleteSession`、`deleteSessionForce`、`agents`、`migrateRollouts` |
7878
| App-server WebSocket 路线 | 活跃开发 | `CodexAppServerClient.runTurn` / `runTurnAsync`、`thread/start` / `thread/resume`、agent 消息 delta、`sessionKey → threadId` LRU(1000) |
79+
| App-server 协议面 | 活跃开发 | `thread/list` / `read` / `fork` / `archive` / `unarchive` / `delete`、`turn/interrupt` / `turn/steer`、逃生通道 `execRpc`;`turnId` 经 `onTurnStarted` 与 `AppServerTurnResult` 暴露 |
80+
| CLI typed 补齐 | 活跃开发 | `debugModels(Bundled)` / `debugPromptInput`、`mcpAddUrl(WithBearer)`、`pluginAdd/List/Remove` + `pluginMarketplace*`、`cloudExec` / `cloudList`、`featuresEnable/Disable/List`、`reviewPrompt` |
7981
| 配置模型 | 活跃开发 | `CodexClientConfig` POJO(纯对象,可绑定 Spring 配置)、`CodexAppServerConfig` POJO |
8082

8183
> **注意**:上游已移除 `codex mcp-server` 子命令——`CodexClient.mcpServer()`
@@ -288,6 +290,24 @@ try (CodexAppServerClient client = new CodexAppServerClient(config)) {
288290
}
289291
```
290292

293+
### 8.4 App-server 协议操作
294+
295+
```java
296+
try (CodexAppServerClient client = new CodexAppServerClient(config)) {
297+
List<AppServerThread> threads = client.listThreads(20);
298+
AppServerThread forked = client.forkThread("th_123");
299+
client.steerTurn("th_123", "turn_9", "也检查一下测试覆盖率"); // 运行中转向
300+
client.interruptTurn("th_123", "turn_9"); // 运行中打断
301+
client.archiveThread("th_123");
302+
String raw = client.execRpc("model/list", Map.of("limit", 10)); // 逃生通道
303+
}
304+
```
305+
306+
生命周期调用走短连接并带文档规定的容错 `initialize` 握手;线程状态在
307+
服务端,因此原 turn 连接仍在流式输出时 `steerTurn` / `interruptTurn`
308+
同样可用。运行中的 turn 经 `AppServerTurnRequest.onTurnStarted` 与
309+
`AppServerTurnResult.getTurnId()` 暴露其 id。
310+
291311
一个 turn 对应:`thread/start`(`sessionKey` 已有映射时走 `thread/resume`)→
292312
`turn/start` → `item/completed`(仅 agent 消息对外呈现)→ `turn/completed`。
293313
未知通知只记录 debug 日志,不中断 turn。失败——连接、JSON-RPC 错误、

‎src/main/java/io/github/easy4j/codex/CodexClient.java‎

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,6 +789,172 @@ public CodexCliResult apply(String taskId) {
789789
*/
790790
public CodexCliResult features() { return cli.features(); }
791791

792+
/**
793+
* Runs {@code codex debug models} — the raw model catalog as JSON.
794+
*
795+
* @return the raw CLI invocation result; never {@code null}.
796+
* @since 3.0.0
797+
*/
798+
public CodexCliResult debugModels() { return cli.debugModels(); }
799+
800+
/**
801+
* Runs {@code codex debug models --bundled} — only the bundled catalog.
802+
*
803+
* @return the raw CLI invocation result; never {@code null}.
804+
* @since 3.0.0
805+
*/
806+
public CodexCliResult debugModelsBundled() { return cli.debugModelsBundled(); }
807+
808+
/**
809+
* Runs {@code codex debug prompt-input <prompt>} — the model-visible
810+
* prompt input list as JSON.
811+
*
812+
* @param prompt the prompt to render.
813+
* @return the raw CLI invocation result; never {@code null}.
814+
* @since 3.0.0
815+
*/
816+
public CodexCliResult debugPromptInput(String prompt) { return cli.debugPromptInput(prompt); }
817+
818+
/**
819+
* Runs {@code codex mcp add <name> --url <url>} — registers a streamable
820+
* HTTP MCP server.
821+
*
822+
* @param name the MCP server name.
823+
* @param url the streamable HTTP endpoint URL.
824+
* @return the raw CLI invocation result; never {@code null}.
825+
* @since 3.0.0
826+
*/
827+
public CodexCliResult mcpAddUrl(String name, String url) { return cli.mcpAddUrl(name, url); }
828+
829+
/**
830+
* Runs {@code codex mcp add <name> --url <url> --bearer-token-env-var <env>}
831+
* — registers an HTTP MCP server whose bearer token lives in an env var.
832+
*
833+
* @param name the MCP server name.
834+
* @param url the streamable HTTP endpoint URL.
835+
* @param bearerTokenEnvVar environment variable holding the bearer token.
836+
* @return the raw CLI invocation result; never {@code null}.
837+
* @since 3.0.0
838+
*/
839+
public CodexCliResult mcpAddUrlWithBearer(String name, String url, String bearerTokenEnvVar) {
840+
return cli.mcpAddUrlWithBearer(name, url, bearerTokenEnvVar);
841+
}
842+
843+
/**
844+
* Runs {@code codex plugin add <plugin[@marketplace]>}.
845+
*
846+
* @param pluginRef plugin reference.
847+
* @return the raw CLI invocation result; never {@code null}.
848+
* @since 3.0.0
849+
*/
850+
public CodexCliResult pluginAdd(String pluginRef) { return cli.pluginAdd(pluginRef); }
851+
852+
/**
853+
* Runs {@code codex plugin list}.
854+
*
855+
* @return the raw CLI invocation result; never {@code null}.
856+
* @since 3.0.0
857+
*/
858+
public CodexCliResult pluginList() { return cli.pluginList(); }
859+
860+
/**
861+
* Runs {@code codex plugin remove <plugin[@marketplace]>}.
862+
*
863+
* @param pluginRef plugin reference to remove.
864+
* @return the raw CLI invocation result; never {@code null}.
865+
* @since 3.0.0
866+
*/
867+
public CodexCliResult pluginRemove(String pluginRef) { return cli.pluginRemove(pluginRef); }
868+
869+
/**
870+
* Runs {@code codex plugin marketplace add <source>}.
871+
*
872+
* @param source the marketplace source.
873+
* @return the raw CLI invocation result; never {@code null}.
874+
* @since 3.0.0
875+
*/
876+
public CodexCliResult pluginMarketplaceAdd(String source) { return cli.pluginMarketplaceAdd(source); }
877+
878+
/**
879+
* Runs {@code codex plugin marketplace list}.
880+
*
881+
* @return the raw CLI invocation result; never {@code null}.
882+
* @since 3.0.0
883+
*/
884+
public CodexCliResult pluginMarketplaceList() { return cli.pluginMarketplaceList(); }
885+
886+
/**
887+
* Runs {@code codex plugin marketplace remove <name>}.
888+
*
889+
* @param name the marketplace name.
890+
* @return the raw CLI invocation result; never {@code null}.
891+
* @since 3.0.0
892+
*/
893+
public CodexCliResult pluginMarketplaceRemove(String name) { return cli.pluginMarketplaceRemove(name); }
894+
895+
/**
896+
* Runs {@code codex plugin marketplace upgrade <name>}.
897+
*
898+
* @param name the marketplace name to upgrade.
899+
* @return the raw CLI invocation result; never {@code null}.
900+
* @since 3.0.0
901+
*/
902+
public CodexCliResult pluginMarketplaceUpgrade(String name) { return cli.pluginMarketplaceUpgrade(name); }
903+
904+
/**
905+
* Runs {@code codex cloud exec --env <envId> <query>} — submits a cloud task.
906+
*
907+
* @param envId the cloud environment id.
908+
* @param query the task query.
909+
* @return the raw CLI invocation result; never {@code null}.
910+
* @since 3.0.0
911+
*/
912+
public CodexCliResult cloudExec(String envId, String query) { return cli.cloudExec(envId, query); }
913+
914+
/**
915+
* Runs {@code codex cloud list --env <envId> --json}.
916+
*
917+
* @param envId the cloud environment id.
918+
* @return the raw CLI invocation result; never {@code null}.
919+
* @since 3.0.0
920+
*/
921+
public CodexCliResult cloudList(String envId) { return cli.cloudList(envId); }
922+
923+
/**
924+
* Runs {@code codex features enable <feature>}.
925+
*
926+
* @param feature the feature flag name.
927+
* @return the raw CLI invocation result; never {@code null}.
928+
* @since 3.0.0
929+
*/
930+
public CodexCliResult featuresEnable(String feature) { return cli.featuresEnable(feature); }
931+
932+
/**
933+
* Runs {@code codex features disable <feature>}.
934+
*
935+
* @param feature the feature flag name.
936+
* @return the raw CLI invocation result; never {@code null}.
937+
* @since 3.0.0
938+
*/
939+
public CodexCliResult featuresDisable(String feature) { return cli.featuresDisable(feature); }
940+
941+
/**
942+
* Runs {@code codex features list}.
943+
*
944+
* @return the raw CLI invocation result; never {@code null}.
945+
* @since 3.0.0
946+
*/
947+
public CodexCliResult featuresList() { return cli.featuresList(); }
948+
949+
/**
950+
* Runs {@code codex review <prompt>} — a custom-instruction review.
951+
*
952+
* @param prompt the review instruction.
953+
* @return the raw CLI invocation result; never {@code null}.
954+
* @since 3.0.0
955+
*/
956+
public CodexCliResult reviewPrompt(String prompt) { return cli.reviewPrompt(prompt); }
957+
792958
/**
793959
* Runs {@code codex mcp-server}.
794960
*

0 commit comments

Comments
 (0)