@khalilgharbaoui/opencode-claude-code-plugin 0.2.6 → 0.3.0

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/dist/index.d.ts CHANGED
@@ -201,6 +201,7 @@ interface ClaudeStreamMessage {
201
201
  type: string;
202
202
  subtype?: string;
203
203
  request_id?: string;
204
+ event?: ClaudeStreamMessage;
204
205
  request?: {
205
206
  subtype?: string;
206
207
  tool_name?: string;
package/dist/index.js CHANGED
@@ -145,7 +145,7 @@ function mapTool(name, input, opts) {
145
145
  const toolName = parts.slice(1).join("_");
146
146
  const openCodeName = `${serverName}_${toolName}`;
147
147
  log.debug("mapping MCP tool", { original: name, mapped: openCodeName });
148
- return { name: openCodeName, input, executed: false };
148
+ return { name: openCodeName, input, executed: true };
149
149
  }
150
150
  }
151
151
  if (OPENCODE_HANDLED_TOOLS.has(name)) {
@@ -825,10 +825,12 @@ function buildCliArgs(opts) {
825
825
  appendSystemPromptFile
826
826
  } = opts;
827
827
  const args = [
828
+ "--print",
828
829
  "--output-format",
829
830
  "stream-json",
830
831
  "--input-format",
831
832
  "stream-json",
833
+ "--include-partial-messages",
832
834
  "--verbose"
833
835
  ];
834
836
  if (model) {
@@ -1267,6 +1269,25 @@ import { unlink as unlink2 } from "fs/promises";
1267
1269
  import { homedir as homedir2, tmpdir as tmpdir3 } from "os";
1268
1270
  import { randomUUID as randomUUID2 } from "crypto";
1269
1271
  import { dirname as dirname2, join as join3 } from "path";
1272
+ function hasNewUserContent(prompt) {
1273
+ for (let i = prompt.length - 1; i >= 0; i--) {
1274
+ const msg = prompt[i];
1275
+ if (msg.role === "assistant") return false;
1276
+ if (msg.role !== "user") continue;
1277
+ const content = msg.content;
1278
+ if (typeof content === "string") {
1279
+ if (content.trim()) return true;
1280
+ continue;
1281
+ }
1282
+ if (Array.isArray(content)) {
1283
+ for (const part of content) {
1284
+ if (part.type === "text" && part.text && part.text.trim()) return true;
1285
+ if (part.type === "tool-result") return true;
1286
+ }
1287
+ }
1288
+ }
1289
+ return false;
1290
+ }
1270
1291
  function readPromptFileIfPresent(path4) {
1271
1292
  try {
1272
1293
  const content = readFileSync2(path4, "utf8").trim();
@@ -1692,6 +1713,24 @@ var ClaudeCodeLanguageModel = class {
1692
1713
  warnings
1693
1714
  };
1694
1715
  }
1716
+ if (!hasNewUserContent(options.prompt)) {
1717
+ log.info("doGenerate short-circuit: no new user content");
1718
+ return {
1719
+ content: [],
1720
+ finishReason: this.toFinishReason("stop"),
1721
+ usage: this.toUsage({ input_tokens: 0, output_tokens: 0 }),
1722
+ request: { body: { text: "" } },
1723
+ response: {
1724
+ id: generateId(),
1725
+ timestamp: /* @__PURE__ */ new Date(),
1726
+ modelId: this.modelId
1727
+ },
1728
+ providerMetadata: {
1729
+ "claude-code": { synthetic: true, path: "no-new-user-content" }
1730
+ },
1731
+ warnings
1732
+ };
1733
+ }
1695
1734
  const hasPriorConversation = options.prompt.filter((m) => m.role === "user" || m.role === "assistant").length > 1;
1696
1735
  if (!hasPriorConversation) {
1697
1736
  deleteClaudeSessionId(sk);
@@ -1743,11 +1782,16 @@ var ClaudeCodeLanguageModel = class {
1743
1782
  let thinkingText = "";
1744
1783
  let resultMeta = {};
1745
1784
  const toolCalls = [];
1785
+ let gotPartialEvents = false;
1746
1786
  const result = await new Promise((resolve3, reject) => {
1747
1787
  rl.on("line", (line) => {
1748
1788
  if (!line.trim()) return;
1749
1789
  try {
1750
- const msg = JSON.parse(line);
1790
+ const outer = JSON.parse(line);
1791
+ const msg = outer.type === "stream_event" && outer.event ? { ...outer.event, session_id: outer.session_id } : outer;
1792
+ if (outer.type === "stream_event") {
1793
+ gotPartialEvents = true;
1794
+ }
1751
1795
  if (this.handleControlRequest(msg, proc)) {
1752
1796
  return;
1753
1797
  }
@@ -1756,7 +1800,7 @@ var ClaudeCodeLanguageModel = class {
1756
1800
  setClaudeSessionId(sk, msg.session_id);
1757
1801
  }
1758
1802
  }
1759
- if (msg.type === "assistant" && msg.message?.content) {
1803
+ if (msg.type === "assistant" && msg.message?.content && !gotPartialEvents) {
1760
1804
  for (const block of msg.message.content) {
1761
1805
  if (block.type === "text" && block.text) {
1762
1806
  responseText += block.text;
@@ -1975,6 +2019,24 @@ ${plan}
1975
2019
  request: { body: { text: "" } }
1976
2020
  };
1977
2021
  }
2022
+ if (!hasNewUserContent(options.prompt)) {
2023
+ log.info("doStream short-circuit: no new user content");
2024
+ const stream2 = new ReadableStream({
2025
+ start(controller) {
2026
+ controller.enqueue({ type: "stream-start", warnings });
2027
+ controller.enqueue({
2028
+ type: "finish",
2029
+ finishReason: toFinishReason("stop"),
2030
+ usage: toUsage({ input_tokens: 0, output_tokens: 0 }),
2031
+ providerMetadata: {
2032
+ "claude-code": { synthetic: true, path: "no-new-user-content" }
2033
+ }
2034
+ });
2035
+ controller.close();
2036
+ }
2037
+ });
2038
+ return { stream: stream2, request: { body: { text: "" } } };
2039
+ }
1978
2040
  const hasPriorConversation = options.prompt.filter((m) => m.role === "user" || m.role === "assistant").length > 1;
1979
2041
  if (!hasPriorConversation) {
1980
2042
  deleteClaudeSessionId(sk);
@@ -2141,12 +2203,17 @@ ${plan}
2141
2203
  } catch {
2142
2204
  }
2143
2205
  };
2206
+ let gotPartialEvents = false;
2144
2207
  const lineHandler = (line) => {
2145
2208
  if (!line.trim()) return;
2146
2209
  if (controllerClosed) return;
2147
2210
  startResultFallback();
2148
2211
  try {
2149
- const msg = JSON.parse(line);
2212
+ const outer = JSON.parse(line);
2213
+ const msg = outer.type === "stream_event" && outer.event ? { ...outer.event, session_id: outer.session_id } : outer;
2214
+ if (outer.type === "stream_event") {
2215
+ gotPartialEvents = true;
2216
+ }
2150
2217
  if (handleControlRequest(msg, proc)) {
2151
2218
  return;
2152
2219
  }
@@ -2338,7 +2405,7 @@ ${plan}
2338
2405
  }
2339
2406
  }
2340
2407
  }
2341
- if (msg.type === "assistant" && msg.message?.content) {
2408
+ if (msg.type === "assistant" && msg.message?.content && !gotPartialEvents) {
2342
2409
  const hasText = msg.message.content.some(
2343
2410
  (b) => b.type === "text" && b.text
2344
2411
  );