@heidi-dang/oh-my-opencode 3.13.0 → 3.13.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/dist/cli/index.js CHANGED
@@ -7096,11 +7096,14 @@ var init_session_category_registry = __esm(() => {
7096
7096
  });
7097
7097
 
7098
7098
  // src/shared/verify-task-completion.ts
7099
- async function verifyTaskCompletionState(client, sessionID) {
7099
+ async function verifyTaskCompletionState(client, sessionID, options) {
7100
7100
  try {
7101
7101
  const response = await client.session.messages({
7102
7102
  path: { id: sessionID }
7103
7103
  });
7104
+ if (response === null || response === undefined) {
7105
+ throw new Error("SDK returned null or undefined session messages");
7106
+ }
7104
7107
  const messages = normalizeSDKResponse(response, [], { preferResponseOnMissingData: true });
7105
7108
  let lastCompleteTaskIndex = -1;
7106
7109
  let lastCompleteTaskPart = null;
@@ -7156,10 +7159,14 @@ async function verifyTaskCompletionState(client, sessionID) {
7156
7159
  return false;
7157
7160
  }
7158
7161
  }
7162
+ if (options?.requireCompleteTask && lastCompleteTaskIndex === -1) {
7163
+ log("[verifyTaskCompletionState] complete_task was required but not found, fail-closed:", sessionID);
7164
+ return false;
7165
+ }
7159
7166
  return true;
7160
7167
  } catch (error) {
7161
- log("[verifyTaskCompletionState] Error verifying task completion state, defaulting to true:", error);
7162
- return true;
7168
+ log("[verifyTaskCompletionState] Error verifying task completion state, fail-closed:", error);
7169
+ return false;
7163
7170
  }
7164
7171
  }
7165
7172
  var init_verify_task_completion = __esm(() => {
@@ -8924,7 +8931,7 @@ var {
8924
8931
  // package.json
8925
8932
  var package_default = {
8926
8933
  name: "@heidi-dang/oh-my-opencode",
8927
- version: "3.13.0",
8934
+ version: "3.13.1",
8928
8935
  description: "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
8929
8936
  main: "dist/index.js",
8930
8937
  types: "dist/index.d.ts",
@@ -9000,17 +9007,17 @@ var package_default = {
9000
9007
  typescript: "^5.7.3"
9001
9008
  },
9002
9009
  optionalDependencies: {
9003
- "@heidi-dang/oh-my-opencode-darwin-arm64": "3.12.5",
9004
- "@heidi-dang/oh-my-opencode-darwin-x64": "3.12.5",
9005
- "@heidi-dang/oh-my-opencode-darwin-x64-baseline": "3.12.5",
9006
- "@heidi-dang/oh-my-opencode-linux-arm64": "3.12.5",
9007
- "@heidi-dang/oh-my-opencode-linux-arm64-musl": "3.12.5",
9008
- "@heidi-dang/oh-my-opencode-linux-x64": "3.12.5",
9009
- "@heidi-dang/oh-my-opencode-linux-x64-baseline": "3.12.5",
9010
- "@heidi-dang/oh-my-opencode-linux-x64-musl": "3.12.5",
9011
- "@heidi-dang/oh-my-opencode-linux-x64-musl-baseline": "3.12.5",
9012
- "@heidi-dang/oh-my-opencode-windows-x64": "3.12.5",
9013
- "@heidi-dang/oh-my-opencode-windows-x64-baseline": "3.12.5"
9010
+ "@heidi-dang/oh-my-opencode-darwin-arm64": "3.13.1",
9011
+ "@heidi-dang/oh-my-opencode-darwin-x64": "3.13.1",
9012
+ "@heidi-dang/oh-my-opencode-darwin-x64-baseline": "3.13.1",
9013
+ "@heidi-dang/oh-my-opencode-linux-arm64": "3.13.1",
9014
+ "@heidi-dang/oh-my-opencode-linux-arm64-musl": "3.13.1",
9015
+ "@heidi-dang/oh-my-opencode-linux-x64": "3.13.1",
9016
+ "@heidi-dang/oh-my-opencode-linux-x64-baseline": "3.13.1",
9017
+ "@heidi-dang/oh-my-opencode-linux-x64-musl": "3.13.1",
9018
+ "@heidi-dang/oh-my-opencode-linux-x64-musl-baseline": "3.13.1",
9019
+ "@heidi-dang/oh-my-opencode-windows-x64": "3.13.1",
9020
+ "@heidi-dang/oh-my-opencode-windows-x64-baseline": "3.13.1"
9014
9021
  },
9015
9022
  overrides: {
9016
9023
  "@opencode-ai/sdk": "^1.2.17",
package/dist/index.js CHANGED
@@ -19945,11 +19945,14 @@ var SessionCategoryRegistry = {
19945
19945
  };
19946
19946
  // src/shared/verify-task-completion.ts
19947
19947
  init_logger();
19948
- async function verifyTaskCompletionState(client, sessionID) {
19948
+ async function verifyTaskCompletionState(client, sessionID, options) {
19949
19949
  try {
19950
19950
  const response = await client.session.messages({
19951
19951
  path: { id: sessionID }
19952
19952
  });
19953
+ if (response === null || response === undefined) {
19954
+ throw new Error("SDK returned null or undefined session messages");
19955
+ }
19953
19956
  const messages = normalizeSDKResponse(response, [], { preferResponseOnMissingData: true });
19954
19957
  let lastCompleteTaskIndex = -1;
19955
19958
  let lastCompleteTaskPart = null;
@@ -20005,10 +20008,14 @@ async function verifyTaskCompletionState(client, sessionID) {
20005
20008
  return false;
20006
20009
  }
20007
20010
  }
20011
+ if (options?.requireCompleteTask && lastCompleteTaskIndex === -1) {
20012
+ log("[verifyTaskCompletionState] complete_task was required but not found, fail-closed:", sessionID);
20013
+ return false;
20014
+ }
20008
20015
  return true;
20009
20016
  } catch (error) {
20010
- log("[verifyTaskCompletionState] Error verifying task completion state, defaulting to true:", error);
20011
- return true;
20017
+ log("[verifyTaskCompletionState] Error verifying task completion state, fail-closed:", error);
20018
+ return false;
20012
20019
  }
20013
20020
  }
20014
20021
  // src/cli/config-manager/config-context.ts
@@ -59927,25 +59934,6 @@ Session ID: ${input.sessionID}`;
59927
59934
  log("[task] Poll complete - terminal finish detected", { sessionID: input.sessionID, pollCount });
59928
59935
  break;
59929
59936
  }
59930
- const lastAssistant = [...msgs].reverse().find((m) => m.info?.role === "assistant");
59931
- const hasAssistantText = msgs.some((m) => {
59932
- if (m.info?.role !== "assistant")
59933
- return false;
59934
- const parts = m.parts ?? [];
59935
- return parts.some((p) => {
59936
- if (p.type !== "text" && p.type !== "reasoning")
59937
- return false;
59938
- const text = (p.text ?? "").trim();
59939
- return text.length > 0;
59940
- });
59941
- });
59942
- if (!lastAssistant?.info?.finish && hasAssistantText) {
59943
- log("[task] Poll complete - assistant text detected (fallback)", {
59944
- sessionID: input.sessionID,
59945
- pollCount
59946
- });
59947
- break;
59948
- }
59949
59937
  }
59950
59938
  if (Date.now() - pollStart >= maxPollTimeMs) {
59951
59939
  timedOut = true;
@@ -60588,6 +60576,11 @@ async function executeSyncTask(args, ctx, executorCtx, parentContext, agentToUse
60588
60576
  if (pollError) {
60589
60577
  return pollError;
60590
60578
  }
60579
+ const isLegitimatelyComplete = await verifyTaskCompletionState(client2, sessionID, { requireCompleteTask: true });
60580
+ if (!isLegitimatelyComplete) {
60581
+ const duration4 = formatDuration2(startTime);
60582
+ return `Task verification failed after ${duration4}. The subagent session completed but could not verify successful completion. This may indicate the subagent did not call complete_task, or the task was rejected. Agent: ${agentToUse}${args.category ? ` (category: ${args.category})` : ""} Session ID: ${sessionID}`;
60583
+ }
60591
60584
  const result = await deps.fetchSyncResult(client2, sessionID);
60592
60585
  if (!result.ok) {
60593
60586
  return result.error;
@@ -1 +1,4 @@
1
- export declare function verifyTaskCompletionState(client: any, sessionID: string): Promise<boolean>;
1
+ export declare function verifyTaskCompletionState(client: any, sessionID: string, options?: {
2
+ /** If true, requires complete_task to have been called. If false (default), allows completion when no complete_task found. */
3
+ requireCompleteTask?: boolean;
4
+ }): Promise<boolean>;
@@ -1,3 +1,17 @@
1
+ /**
2
+ * Poll a sync session until completion or timeout.
3
+ *
4
+ * IMPORTANT: This function returns null ONLY when:
5
+ * 1. isSessionComplete() returns true (verified terminal finish), OR
6
+ * 2. Timeout is reached (timedOut = true)
7
+ *
8
+ * The fallback path "assistant text detected" was REMOVED because it cannot verify
9
+ * that complete_task was actually called and succeeded. Treating assistant text
10
+ * as completion is a security vulnerability - it allows bypass of the authoritative
11
+ * completion gate.
12
+ *
13
+ * @returns null if session completed (verified), error string if failed, timeout message if timed out
14
+ */
1
15
  import type { ToolContextWithMetadata, OpencodeClient } from "./types";
2
16
  import type { SessionMessage } from "./executor-types";
3
17
  export declare function isSessionComplete(messages: SessionMessage[]): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heidi-dang/oh-my-opencode",
3
- "version": "3.13.0",
3
+ "version": "3.13.1",
4
4
  "description": "The Best AI Agent Harness - Batteries-Included OpenCode Plugin with Multi-Model Orchestration, Parallel Background Agents, and Crafted LSP/AST Tools",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -76,17 +76,17 @@
76
76
  "typescript": "^5.7.3"
77
77
  },
78
78
  "optionalDependencies": {
79
- "@heidi-dang/oh-my-opencode-darwin-arm64": "3.12.5",
80
- "@heidi-dang/oh-my-opencode-darwin-x64": "3.12.5",
81
- "@heidi-dang/oh-my-opencode-darwin-x64-baseline": "3.12.5",
82
- "@heidi-dang/oh-my-opencode-linux-arm64": "3.12.5",
83
- "@heidi-dang/oh-my-opencode-linux-arm64-musl": "3.12.5",
84
- "@heidi-dang/oh-my-opencode-linux-x64": "3.12.5",
85
- "@heidi-dang/oh-my-opencode-linux-x64-baseline": "3.12.5",
86
- "@heidi-dang/oh-my-opencode-linux-x64-musl": "3.12.5",
87
- "@heidi-dang/oh-my-opencode-linux-x64-musl-baseline": "3.12.5",
88
- "@heidi-dang/oh-my-opencode-windows-x64": "3.12.5",
89
- "@heidi-dang/oh-my-opencode-windows-x64-baseline": "3.12.5"
79
+ "@heidi-dang/oh-my-opencode-darwin-arm64": "3.13.1",
80
+ "@heidi-dang/oh-my-opencode-darwin-x64": "3.13.1",
81
+ "@heidi-dang/oh-my-opencode-darwin-x64-baseline": "3.13.1",
82
+ "@heidi-dang/oh-my-opencode-linux-arm64": "3.13.1",
83
+ "@heidi-dang/oh-my-opencode-linux-arm64-musl": "3.13.1",
84
+ "@heidi-dang/oh-my-opencode-linux-x64": "3.13.1",
85
+ "@heidi-dang/oh-my-opencode-linux-x64-baseline": "3.13.1",
86
+ "@heidi-dang/oh-my-opencode-linux-x64-musl": "3.13.1",
87
+ "@heidi-dang/oh-my-opencode-linux-x64-musl-baseline": "3.13.1",
88
+ "@heidi-dang/oh-my-opencode-windows-x64": "3.13.1",
89
+ "@heidi-dang/oh-my-opencode-windows-x64-baseline": "3.13.1"
90
90
  },
91
91
  "overrides": {
92
92
  "@opencode-ai/sdk": "^1.2.17",