opencode-worker 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,7 +37,7 @@ Exit codes: `0` ok, `1` worker failed (timeout, nonzero exit, error event, model
37
37
  | `requested` | `{model, variant, agent, timeoutSec}` |
38
38
  | `actual` | provider/model/variant recorded in the isolated session DB (needs `sqlite3`; `null` if unavailable) |
39
39
  | `text` | worker's final text |
40
- | `tools[]` | `{tool, status, input}` per tool call |
40
+ | `tools[]` | `{tool, status, input, exit, output, error}` per tool call; `exit` is the bash exit code (else `null`), `output` capped at 4000 chars |
41
41
  | `cost`, `tokens` | summed from `step_finish` events |
42
42
  | `diff` | `diff -ruN` of `<dir>` before vs after (excludes `.opencode-worker/`) |
43
43
  | `errors[]` | `timeout`, `cancelled`, `nonzero_exit`, `event_error`, `model_mismatch`, `diff_failed`, `unparsed_line` |
@@ -64,11 +64,11 @@ Async by design so long runs never hit client request timeouts.
64
64
 
65
65
  ### Client setup
66
66
 
67
- Claude Code (tools must be allowed in `-p` mode):
67
+ Claude Code (tools must be allowed in `-p` mode; put the prompt right after `-p`, because `--allowedTools` and `--mcp-config` are variadic and swallow trailing arguments):
68
68
 
69
69
  ```sh
70
70
  claude mcp add opencode-worker -e OPENCODE_WORKER_BIN=/path/to/opencode -- npx -y opencode-worker mcp
71
- claude -p --allowedTools "mcp__opencode-worker__worker_start,mcp__opencode-worker__worker_status,mcp__opencode-worker__worker_result" "…"
71
+ claude -p "…" --allowedTools "mcp__opencode-worker__worker_start,mcp__opencode-worker__worker_status,mcp__opencode-worker__worker_result"
72
72
  ```
73
73
 
74
74
  Codex (`~/.codex/config.toml`); without the approval mode, `codex exec` rejects MCP calls under `approval: never`:
package/lib/mcp.mjs CHANGED
@@ -12,6 +12,7 @@ const jobs = new Map(); // live jobs of this server: id -> { record, controller,
12
12
  const JOBS_DIR = process.env.OPENCODE_WORKER_STATE_DIR
13
13
  ?? path.join(process.env.XDG_STATE_HOME || path.join(os.homedir(), ".local/state"), "opencode-worker", "jobs");
14
14
  const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
15
+ const VERSION = JSON.parse(fs.readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
15
16
 
16
17
  // Job records are persisted so results survive server/client restarts.
17
18
  function save(record) {
@@ -116,7 +117,7 @@ export function serveMcp(opts = {}) {
116
117
  const reply = (result) => send({ jsonrpc: "2.0", id, result });
117
118
  const fail = (code, message) => send({ jsonrpc: "2.0", id, error: { code, message } });
118
119
  if (method === "initialize")
119
- return reply({ protocolVersion: params?.protocolVersion ?? PROTOCOL, capabilities: { tools: {} }, serverInfo: { name: "opencode-worker", version: "0.1.0" } });
120
+ return reply({ protocolVersion: params?.protocolVersion ?? PROTOCOL, capabilities: { tools: {} }, serverInfo: { name: "opencode-worker", version: VERSION } });
120
121
  if (method === "ping") return reply({});
121
122
  if (method === "tools/list") return reply({ tools: TOOLS });
122
123
  if (method === "tools/call") {
package/lib/worker.mjs CHANGED
@@ -12,6 +12,7 @@ export const DEFAULTS = {
12
12
  };
13
13
  const STATE_DIR = ".opencode-worker";
14
14
  const HARD_DEADLINE_WRAPPER = ["/usr/bin/perl", "/bin/perl"].find((p) => fs.existsSync(p)) ?? null;
15
+ const TOOL_OUTPUT_MAX = 4000;
15
16
 
16
17
  export class WorkerError extends Error {
17
18
  constructor(code, message) {
@@ -83,7 +84,18 @@ function parseEvents(stdout) {
83
84
  out.sessionID ??= ev.sessionID ?? null;
84
85
  const p = ev.part ?? {};
85
86
  if (ev.type === "text") out.text += p.text ?? "";
86
- else if (ev.type === "tool_use") out.tools.push({ tool: p.tool, status: p.state?.status, input: p.state?.input });
87
+ else if (ev.type === "tool_use") {
88
+ const s = p.state ?? {};
89
+ const output = typeof s.output === "string" ? s.output : s.output == null ? null : JSON.stringify(s.output);
90
+ out.tools.push({
91
+ tool: p.tool,
92
+ status: s.status,
93
+ input: s.input,
94
+ exit: s.metadata?.exit ?? null,
95
+ output: output && output.length > TOOL_OUTPUT_MAX ? output.slice(0, TOOL_OUTPUT_MAX) + `…[truncated ${output.length - TOOL_OUTPUT_MAX} chars]` : output,
96
+ error: s.error ?? null,
97
+ });
98
+ }
87
99
  else if (ev.type === "step_finish") {
88
100
  out.cost += p.cost ?? 0;
89
101
  const t = p.tokens ?? {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-worker",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Run the official OpenCode CLI as an isolated, time-boxed worker. CLI + MCP stdio server.",
5
5
  "type": "module",
6
6
  "bin": { "opencode-worker": "bin/opencode-worker.mjs" },