@khalilgharbaoui/opencode-claude-code-plugin 0.18.1 → 0.18.3

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
@@ -789,7 +789,7 @@ The plugin respects the standard Claude Code thinking env vars. If you set them
789
789
  ## Quirks worth knowing
790
790
 
791
791
  - **Empty text blocks are dropped.** Claude sometimes opens a `content_block_start` for text but never sends a delta. The plugin no longer emits the empty block (which was triggering Anthropic 400s like `cache_control cannot be set for empty text blocks`).
792
- - **Smart incomplete-turn continuation.** By default, the plugin keeps the current opencode stream open and feeds Claude CLI a small internal continuation message when Claude emits a `result` after reasoning/tool activity without a useful visible answer. It still stops normally on final-looking answers, questions, blockers, errors, aborts, or internal safety-budget exhaustion. Disable with `"autoContinueIncompleteTurns": false`.
792
+ - **Smart incomplete-turn continuation.** By default, the plugin keeps the current opencode stream open and feeds Claude CLI a small internal continuation message when Claude emits a `result` after reasoning/tool activity without a useful visible answer. It still stops normally on final-looking answers, questions, blockers, errors, aborts, or internal safety-budget exhaustion. It also resumes an answer the model was cut off mid-sentence: a `max_tokens` stop means truncation rather than completion, so the turn continues instead of ending on half a sentence, capped at 8 attempts and 10 minutes. Every other stop reason is taken at face value. Disable with `"autoContinueIncompleteTurns": false`.
793
793
  - **`AskUserQuestion`** from the CLI is converted into plain text content rather than forwarded as a tool call — unless `"Question"` is in `proxyTools`, in which case it is routed through opencode's native `question` tool (see [AskUserQuestion](#askuserquestion)).
794
794
  - **Wire-inactivity watchdog.** Once the CLI has produced any content, the stream closes gracefully if stdout goes silent for 60 seconds without a `result` message arriving. Resets on every line received, so long mid-turn pauses (Sonnet between text-end and the next tool_use, for example) are tolerated. On a user-initiated abort, the watchdog shortens to 5 seconds.
795
795
  - **Per-iteration usage.** When the CLI internally retries with tools, the plugin only counts the last iteration's usage so opencode's context accounting stays accurate.
package/dist/index.js CHANGED
@@ -4533,6 +4533,12 @@ var AUTO_CONTINUE_MAX_ELAPSED_MS = 10 * 60 * 1e3;
4533
4533
  var AUTO_CONTINUE_NO_PROGRESS_LIMIT = 2;
4534
4534
  var PROXY_RESULT_BOUNDARY_GRACE_MS = 250;
4535
4535
  var AUTO_CONTINUE_PROMPT = "Continue the task from where you stopped. Do not summarize; keep working until the requested task is complete, you need clarification, or you hit a real blocker.";
4536
+ function autoContinueEnabledFor(compactionMode, configured) {
4537
+ return compactionMode ? false : configured;
4538
+ }
4539
+ function isTruncationStopReason(stopReason) {
4540
+ return stopReason === "max_tokens" || stopReason === "max_output_tokens";
4541
+ }
4536
4542
  function normalizeVisibleText(text) {
4537
4543
  return text.replace(/\s+/g, " ").trim();
4538
4544
  }
@@ -4619,6 +4625,16 @@ function shouldAutoContinueIncompleteTurn(state, snapshot) {
4619
4625
  if (state.aborted) return { continue: false, reason: "aborted" };
4620
4626
  if (state.sawAskUserQuestion) return { continue: false, reason: "question" };
4621
4627
  if (snapshot.stopReason) {
4628
+ if (isTruncationStopReason(snapshot.stopReason)) {
4629
+ if (state.attempts >= AUTO_CONTINUE_MAX_ATTEMPTS) {
4630
+ return { continue: false, reason: "max-attempts" };
4631
+ }
4632
+ const truncatedAt = snapshot.now ?? Date.now();
4633
+ if (truncatedAt - state.startedAt > AUTO_CONTINUE_MAX_ELAPSED_MS) {
4634
+ return { continue: false, reason: "max-elapsed" };
4635
+ }
4636
+ return { continue: true, reason: "truncated" };
4637
+ }
4622
4638
  return {
4623
4639
  continue: false,
4624
4640
  reason: snapshot.stopReason.replace(/_/g, "-")
@@ -6276,7 +6292,10 @@ ${plan}
6276
6292
  let hadProxyActivitySinceContinue = false;
6277
6293
  let lastStopReason = null;
6278
6294
  const autoContinueState = {
6279
- enabled: self.config.autoContinueIncompleteTurns,
6295
+ enabled: autoContinueEnabledFor(
6296
+ compactionMode,
6297
+ self.config.autoContinueIncompleteTurns
6298
+ ),
6280
6299
  attempts: 0,
6281
6300
  startedAt: Date.now(),
6282
6301
  noProgressCount: 0