Skip to content

Commit b7d532b

Browse files
committed
feat: align opencode-java-sdk with opencode v1.17.18
- Add 22 domain model POJOs (Project, Config, Provider, FileNode, VcsInfo, Command, Skill, McpStatus, LspStatus, FormatterStatus, SessionStatus, SessionTodo, MessageInfo, FileDiff, FileContent, FileSearchResult, Symbol, QuestionRequest, PermissionRequest, ProviderAuthMethod, ProviderAuthAuthorization, ProviderList, OpenCodePath) - Refactor OpenCodeHttpClient: extract delete/patch/put/postNoBody/ getWithQuery helpers; existing methods unchanged behavior - Add ~50 new endpoint methods: Config/Project/Provider/File/Find/ Misc/Session extended/Question/Permission/Auth/Instance-lifecycle - Extend OpenCodeCli with full v1.17.18 command surface: serve/web/acp/ attach/generate, providers/auth/mcp, upgrade/uninstall, stats/export/ import/db/debug, github/pr/plugin/console - Add OpenCodeClient facade methods delegating to httpClient/cli - Add EventHandler interface + subscribeSession/subscribeEventTypes/ subscribeHandler filter APIs on OpenCodeSseClient - Add eventStream()/onSessionEvent()/onEvent()/onEventTypes() facade helpers on OpenCodeClient - Extend OpenCodeHttpClientTest with 28 new endpoint path tests (30 tests total, all passing) - Update README with complete HTTP API mapping table (8 categories) and CLI subcommand reference
1 parent c120645 commit b7d532b

30 files changed

Lines changed: 2878 additions & 38 deletions

README.md

Lines changed: 210 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@
88

99
三条通道互不降级。入口类 [`OpenCodeClient`](src/main/java/io/github/hiwepy/opencode/OpenCodeClient.java)
1010

11+
> 当前 SDK 适配 opencode **v1.17.18** CLI + Server HTTP API。
12+
>
13+
> 三个分支:
14+
> - `feature/1.0.x` — JDK 1.8 兼容线(`1.0.x.20260630-SNAPSHOT`
15+
> - `main` / `feature/2.0.x` — JDK 17 兼容线(`2.0.x.20260630-SNAPSHOT`
16+
> - `feature/3.0.x` — JDK 21 兼容线(`3.0.x.20260630-SNAPSHOT`
17+
1118
Spring Boot 应用请使用 [opencode-spring-boot-starter](../opencode-spring-boot-starter)
1219

1320
## 快速开始
@@ -27,11 +34,11 @@ System.out.println("version: " + health.getVersion());
2734
Session session = client.createSession("my-task");
2835

2936
// 发送 prompt 并等待响应
30-
PromptResult result = client.prompt(session.getId(), "Explain how closures work in JavaScript");
37+
PromptResult result = client.chatCompletion(session.getId(), "Explain how closures work in JavaScript");
3138
System.out.println(result.getTextContent());
3239

3340
// 异步发送(不等待)
34-
client.promptAsync(session.getId(), "Write a hello world in Python");
41+
client.chatCompletionAsync(session.getId(), "Write a hello world in Python");
3542

3643
// 列出 agents
3744
List<Agent> agents = client.listAgents();
@@ -41,60 +48,234 @@ client.close();
4148

4249
## HTTP Server API 映射
4350

51+
### Session / Prompt(核心)
52+
4453
| Java 方法 | HTTP API | 说明 |
4554
|-----------|----------|------|
4655
| `health()` | `GET /global/health` | 健康检查 |
4756
| `createSession(title)` | `POST /session` | 创建会话 |
4857
| `getSession(id)` | `GET /session/:id` | 获取会话 |
4958
| `listSessions()` | `GET /session` | 列出会话 |
59+
| `listSessions(search, limit, start)` | `GET /session?...` | 分页/过滤 |
60+
| `findSessionByTitle(title)` | `GET /session?search=` | 按 title 精确查找 |
5061
| `deleteSession(id)` | `DELETE /session/:id` | 删除会话 |
51-
| `prompt(sessionId, request)` | `POST /session/:id/message` | 发送 prompt,同步等待 |
52-
| `promptAsync(sessionId, request)` | `POST /session/:id/prompt_async` | 异步发送,不等待 |
5362
| `getMessages(sessionId)` | `GET /session/:id/message` | 获取消息历史 |
63+
| `getMessage(sessionId, messageId)` | `GET /session/:id/message/:messageID` | 获取单条 message |
64+
| `chatCompletion(sessionId, request)` | `POST /session/:id/message` | 发送 prompt,同步等待 |
65+
| `chatCompletionAsync(sessionId, request)` | `POST /session/:id/prompt_async` | 异步发送,不等待 |
5466
| `abort(sessionId)` | `POST /session/:id/abort` | 中止会话 |
67+
| `runSessionCommand(id, command, args, agent, model)` | `POST /session/:id/command` | 运行 slash command |
5568
| `listAgents()` | `GET /agent` | 列出 agents |
5669

70+
### Session 扩展
71+
72+
| Java 方法 | HTTP API | 说明 |
73+
|-----------|----------|------|
74+
| `getSessionStatusMap()` | `GET /session/status` | 所有 session 状态 |
75+
| `getSessionChildren(id)` | `GET /session/:id/children` | 列出 forked sessions |
76+
| `getSessionTodo(id)` | `GET /session/:id/todo` | session 任务列表 |
77+
| `getSessionDiff(id, messageID?)` | `GET /session/:id/diff` | 文件 diff |
78+
| `shareSession(id)` | `POST /session/:id/share` | 创建分享链接 |
79+
| `unshareSession(id)` | `DELETE /session/:id/share` | 取消分享 |
80+
| `forkSession(id, messageID?)` | `POST /session/:id/fork` | Fork session |
81+
| `initSession(id, messageID, providerID, modelID)` | `POST /session/:id/init` | 用首个 message 初始化 |
82+
| `summarizeSession(id, providerID, modelID)` | `POST /session/:id/summarize` | AI 摘要压缩 |
83+
| `revertSession(id, messageID, partID?)` | `POST /session/:id/revert` | 回退到指定 message |
84+
| `unrevertSession(id)` | `POST /session/:id/unrevert` | 撤销回退 |
85+
86+
### Config
87+
88+
| Java 方法 | HTTP API | 说明 |
89+
|-----------|----------|------|
90+
| `getOpenCodeConfig()` | `GET /config` | 实例配置 |
91+
| `getGlobalOpenCodeConfig()` | `GET /global/config` | 全局配置 |
92+
| `updateOpenCodeConfig(body)` | `PATCH /config` | 更新实例配置 |
93+
| `updateGlobalOpenCodeConfig(body)` | `PATCH /global/config` | 更新全局配置 |
94+
| `getConfigProviders()` | `GET /config/providers` | 已配置的 providers + 默认模型 |
95+
96+
### Project
97+
98+
| Java 方法 | HTTP API | 说明 |
99+
|-----------|----------|------|
100+
| `listProjects()` | `GET /project` | 所有项目 |
101+
| `getCurrentProject()` | `GET /project/current` | 当前项目 |
102+
| `updateProject(id, body)` | `PATCH /project/:id` | 更新项目元数据 |
103+
| `initProjectGit()` | `POST /project/git/init` | 初始化 git 仓库 |
104+
105+
### Provider / Auth
106+
107+
| Java 方法 | HTTP API | 说明 |
108+
|-----------|----------|------|
109+
| `listProviders()` | `GET /provider` | providers + defaults + connected |
110+
| `listProviderAuthMethods()` | `GET /provider/auth` | 每个 provider 的认证方式 |
111+
| `providerOAuthAuthorize(id, method)` | `POST /provider/:id/oauth/authorize` | 启动 OAuth 授权 |
112+
| `providerOAuthCallback(id, code)` | `POST /provider/:id/oauth/callback` | 处理 OAuth 回调 |
113+
| `setAuth(id, body)` | `PUT /auth/:id` | 设置 provider 凭证 |
114+
| `removeAuth(id)` | `DELETE /auth/:id` | 清除 provider 凭证 |
115+
116+
### File / Find
117+
118+
| Java 方法 | HTTP API | 说明 |
119+
|-----------|----------|------|
120+
| `listFiles(path)` | `GET /file?path=` | 列出文件/目录树 |
121+
| `getFileContent(path)` | `GET /file/content?path=` | 读取文件内容 |
122+
| `getFileStatus()` | `GET /file/status` | git 状态 |
123+
| `find(pattern)` | `GET /find?pattern=` | ripgrep 文本搜索 |
124+
| `findFiles(query)` | `GET /find/file?query=` | 按文件名查找 |
125+
| `findSymbols(query)` | `GET /find/symbol?query=` | LSP 符号搜索 |
126+
127+
### Misc
128+
129+
| Java 方法 | HTTP API | 说明 |
130+
|-----------|----------|------|
131+
| `listCommands()` | `GET /command` | slash commands |
132+
| `listSkills()` | `GET /skill` | 已注册 skills |
133+
| `listFormatters()` | `GET /formatter` | formatter 状态 |
134+
| `listLsps()` | `GET /lsp` | LSP 状态 |
135+
| `listMcpServers()` | `GET /mcp` | MCP 服务器状态 |
136+
| `addMcpServer(name, config)` | `POST /mcp` | 动态添加 MCP |
137+
| `getPath()` | `GET /path` | 工作目录相关路径 |
138+
| `getVcs()` | `GET /vcs` | git 分支/脏标志 |
139+
| `disposeInstance()` | `POST /instance/dispose` | 释放当前 instance |
140+
| `globalDispose()` | `POST /global/dispose` | 释放所有 instance |
141+
| `globalUpgrade(target?)` | `POST /global/upgrade` | 升级 opencode |
142+
143+
### Question / Permission
144+
145+
| Java 方法 | HTTP API | 说明 |
146+
|-----------|----------|------|
147+
| `listQuestions()` | `GET /question` | 待回答问题 |
148+
| `replyQuestion(id, answers)` | `POST /question/:id/reply` | 回复 |
149+
| `rejectQuestion(id)` | `POST /question/:id/reject` | 拒绝 |
150+
| `listPermissions()` | `GET /permission` | 待审批权限 |
151+
| `replyPermission(id, response, remember)` | `POST /permission/:id/reply` | 回复权限请求 |
152+
57153
完整 API 文档:https://opencode.ai/docs/server/
58154

59155
## SSE 事件流
60156

157+
### 基础订阅
158+
61159
```java
62160
OpenCodeSseClient sse = client.sse();
63161
sse.subscribe(event -> {
64162
System.out.println("event: " + event.getType());
65163
});
66164

67-
// 或使用阻塞队列
165+
// 阻塞队列
68166
BlockingQueue<Event> queue = sse.subscribeQueue();
69167
Event event = queue.take();
70168
```
71169

170+
### 类型化 EventHandler(推荐)
171+
172+
```java
173+
client.onSessionEvent(sessionId, new EventHandler() {
174+
@Override public void onTextDelta(String delta, Event event) {
175+
System.out.print(delta);
176+
}
177+
@Override public void onToolCall(String name, Map<String, Object> input, Event event) {
178+
System.out.println("\ntool call: " + name);
179+
}
180+
@Override public void onSessionIdle(String sessionId, Event event) {
181+
System.out.println("\n[done]");
182+
}
183+
});
184+
```
185+
186+
### 事件类型过滤
187+
188+
```java
189+
// 只关心 text.delta 和 session.idle
190+
Set<String> types = new HashSet<>(Arrays.asList("message.part.updated", "session.idle"));
191+
client.onEventTypes(types, event -> { /* ... */ });
192+
```
193+
72194
## CLI 封装
73195

196+
### 核心子命令
197+
74198
```java
75199
OpenCodeCli cli = client.cli();
76200

77201
// 非交互模式执行
78202
OpenCodeCliResult result = cli.run("Explain async/await in JavaScript");
79203
System.out.println(result.getStdout());
80204

81-
// 指定模型
205+
// 指定模型 / agent
82206
cli.run("Hello", "anthropic/claude-sonnet-4-5");
207+
cli.run("Hello", "plan", "anthropic/claude-sonnet-4-5");
83208

84-
// JSON 格式输出
85-
OpenCodeCliResult jsonResult = cli.runJson("Hello");
209+
// JSON 格式输出(流式事件)
210+
cli.runJson("Hello");
86211

87-
// 会话管理
212+
// 会话 / agents / models
88213
cli.sessionList();
89214
cli.sessionDelete("session-id");
90-
91-
// 其他命令
92215
cli.agentList();
93216
cli.models();
217+
cli.models("anthropic", true, false); // provider + verbose + refresh
218+
```
219+
220+
### 服务端 / 升级 / 卸载
221+
222+
```java
223+
cli.serve(4096, "127.0.0.1"); // opencode serve --port 4096 --hostname 127.0.0.1
224+
cli.web(4096, "127.0.0.1"); // opencode web ...
225+
cli.acp("/path/to/project"); // ACP server
226+
cli.generate(); // 输出 OpenAPI spec
227+
cli.attach("http://localhost:4096", "/path", null, "user", "pass");
228+
cli.upgrade(); // 升级到最新
229+
cli.upgrade("v1.18.0", "npm"); // 升级到指定版本
230+
cli.uninstall(false, false, false, true); // --force 跳过确认
231+
```
232+
233+
### Provider / Auth / MCP
234+
235+
```java
236+
cli.providersList();
237+
cli.providersLogin("anthropic", "api-key");
238+
cli.providersLogout("anthropic");
239+
94240
cli.mcpList();
95-
cli.authList();
241+
cli.mcpAdd("context7", "https://mcp.context7.com/sse");
242+
cli.mcpLogout("context7");
243+
cli.mcpAuth("context7");
244+
cli.mcpDebug("context7");
245+
```
246+
247+
### Stats / Export / Import / DB / Debug
248+
249+
```java
250+
cli.stats(7, 10, 5, ""); // --days 7 --tools 10 --models 5 --project current
251+
cli.export("session-id", true); // --sanitize
252+
cli.importSession("https://opncd.ai/s/abc123"); // share URL
253+
cli.db("SELECT count(*) FROM session;", "json");
254+
cli.dbPath();
255+
256+
cli.debugConfig();
257+
cli.debugPaths();
258+
cli.debugInfo();
259+
cli.debugScrap();
260+
cli.debugSkill();
261+
cli.debugStartup();
96262
```
97263

264+
### GitHub / Plugin / Console
265+
266+
```java
267+
cli.githubInstall();
268+
cli.githubRun("issue_comment", "ghp_xxx");
269+
cli.pr(123);
270+
271+
cli.plugin("opencode-anthropic-vertex", false, true);
272+
cli.consoleLogin();
273+
cli.consoleOrgs();
274+
cli.consoleOpen();
275+
```
276+
277+
所有 `cli*()` 方法在 `OpenCodeClient` 也有等价 facade 形式(如 `cliServe``cliModels` 等)。
278+
98279
## 配置
99280

100281
`OpenCodeClientConfig` 字段:
@@ -107,11 +288,19 @@ cli.authList();
107288
| `connectTimeoutMillis` | `15000` | 连接超时(毫秒) |
108289
| `readTimeoutMillis` | `300000` | 读超时(毫秒) |
109290
| `verifySsl` | `true` | 是否校验 HTTPS 证书 |
110-
| `localExecutable` | `opencode` | CLI 可执行文件路径 |
111-
| `localTimeoutSeconds` | `300` | CLI 命令超时(秒) |
112291
| `defaultModel` | `null` | 默认模型(`provider/model`|
113292
| `defaultAgent` | `null` | 默认 agent |
114293

294+
`OpenCodeCliConfig` 字段:
295+
296+
| 字段 | 默认值 | 说明 |
297+
|------|--------|------|
298+
| `executable` | `opencode` | CLI 可执行文件路径 |
299+
| `timeout` | `300` | CLI 命令超时(秒) |
300+
| `probeTimeoutSeconds` | `5` | CLI 可用性探测超时 |
301+
| `workingDirectory` | `null` | CLI 子进程工作目录 |
302+
| `maxConcurrentExecutions` | `0` | 最大并发子进程数(0 = 不限) |
303+
115304
## 认证
116305

117306
OpenCode Server 支持 HTTP Basic Auth,通过环境变量配置:
@@ -120,7 +309,7 @@ OpenCode Server 支持 HTTP Basic Auth,通过环境变量配置:
120309
OPENCODE_SERVER_PASSWORD=your-password opencode serve
121310
```
122311

123-
Java 端对应 `OpenCodeClientConfig``username``password` 字段。
312+
Java 端对应 `OpenCodeHttpClientConfig``username``password` 字段。
124313

125314
## 前置条件
126315

@@ -130,9 +319,14 @@ Java 端对应 `OpenCodeClientConfig` 的 `username` 和 `password` 字段。
130319

131320
## 发布与 JDK
132321

133-
- 本模块要求 **JDK 17**
322+
- 三条分支对应三档 JDK:
323+
- `feature/1.0.x` — JDK 1.8
324+
- `main` / `feature/2.0.x` — JDK 17
325+
- `feature/3.0.x` — JDK 21
134326
- 发布快照/正式版:
135327

136328
```bash
137329
mvn clean deploy -DskipTests
138330
```
331+
332+
发布到阿里云 Maven 仓库(`2624322-snapshot-3EoOv3` / `2624322-release-6F6h6R`),详细见 `pom.xml``distributionManagement`

0 commit comments

Comments
 (0)