oh-my-opencode 4.1.1 → 4.1.2

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.
@@ -10,6 +10,7 @@ type ContinuationOptions = {
10
10
  };
11
11
  export type ContinuationResult = {
12
12
  status: "dispatched";
13
+ sessionID: string;
13
14
  } | {
14
15
  status: "session_creation_rejected";
15
16
  } | {
@@ -1,4 +1,4 @@
1
- import type { RalphLoopOptions, RalphLoopState } from "./types";
1
+ import type { IterationCommitExpectation, RalphLoopOptions, RalphLoopState } from "./types";
2
2
  export declare function createLoopStateController(options: {
3
3
  directory: string;
4
4
  stateDir: string | undefined;
@@ -14,9 +14,9 @@ export declare function createLoopStateController(options: {
14
14
  cancelLoop(sessionID: string): boolean;
15
15
  getState(): RalphLoopState | null;
16
16
  clear(): boolean;
17
- incrementIteration(): RalphLoopState | null;
17
+ incrementIteration(expected?: IterationCommitExpectation): RalphLoopState | null;
18
18
  setSessionID(sessionID: string): RalphLoopState | null;
19
- setMessageCountAtStart(sessionID: string, messageCountAtStart: number): RalphLoopState | null;
19
+ setMessageCountAtStart(sessionID: string, messageCountAtStart: number, expectedStartedAt?: string): RalphLoopState | null;
20
20
  markVerificationPending(sessionID: string): RalphLoopState | null;
21
21
  setVerificationSessionID(sessionID: string, verificationSessionID: string): RalphLoopState | null;
22
22
  restartAfterFailedVerification(sessionID: string, messageCountAtStart?: number): RalphLoopState | null;
@@ -1,9 +1,10 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
2
  import type { RalphLoopState } from "./types";
3
+ import type { IterationCommitExpectation } from "./types";
3
4
  type LoopStateController = {
4
5
  restartAfterFailedVerification: (sessionID: string, messageCountAtStart?: number) => RalphLoopState | null;
5
6
  clearVerificationState: (sessionID: string, messageCountAtStart?: number) => RalphLoopState | null;
6
- incrementIteration: () => RalphLoopState | null;
7
+ incrementIteration: (expected?: IterationCommitExpectation) => RalphLoopState | null;
7
8
  clear: () => boolean;
8
9
  setVerificationSessionID: (sessionID: string, verificationSessionID: string) => RalphLoopState | null;
9
10
  };
@@ -1,9 +1,9 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
- import type { RalphLoopOptions, RalphLoopState } from "./types";
2
+ import type { IterationCommitExpectation, RalphLoopOptions, RalphLoopState } from "./types";
3
3
  type LoopStateController = {
4
4
  getState: () => RalphLoopState | null;
5
5
  clear: () => boolean;
6
- incrementIteration: () => RalphLoopState | null;
6
+ incrementIteration: (expected?: IterationCommitExpectation) => RalphLoopState | null;
7
7
  setSessionID: (sessionID: string) => RalphLoopState | null;
8
8
  markVerificationPending: (sessionID: string) => RalphLoopState | null;
9
9
  setVerificationSessionID: (sessionID: string, verificationSessionID: string) => RalphLoopState | null;
@@ -1,6 +1,6 @@
1
- import type { RalphLoopState } from "./types";
1
+ import type { IterationCommitExpectation, RalphLoopState } from "./types";
2
2
  export declare function getStateFilePath(directory: string, customPath?: string): string;
3
3
  export declare function readState(directory: string, customPath?: string): RalphLoopState | null;
4
4
  export declare function writeState(directory: string, state: RalphLoopState, customPath?: string): boolean;
5
5
  export declare function clearState(directory: string, customPath?: string): boolean;
6
- export declare function incrementIteration(directory: string, customPath?: string): RalphLoopState | null;
6
+ export declare function incrementIteration(directory: string, customPath?: string, expected?: IterationCommitExpectation): RalphLoopState | null;
@@ -15,6 +15,10 @@ export interface RalphLoopState {
15
15
  verification_pending?: boolean;
16
16
  strategy?: "reset" | "continue";
17
17
  }
18
+ export interface IterationCommitExpectation {
19
+ iteration: number;
20
+ sessionID: string;
21
+ }
18
22
  export interface RalphLoopOptions {
19
23
  config?: RalphLoopConfig;
20
24
  getTranscriptPath?: (sessionId: string) => string;
@@ -1,8 +1,8 @@
1
1
  import type { PluginInput } from "@opencode-ai/plugin";
2
- import type { RalphLoopState } from "./types";
2
+ import type { IterationCommitExpectation, RalphLoopState } from "./types";
3
3
  type LoopStateController = {
4
4
  clearVerificationState: (sessionID: string, messageCountAtStart?: number) => RalphLoopState | null;
5
- incrementIteration: () => RalphLoopState | null;
5
+ incrementIteration: (expected?: IterationCommitExpectation) => RalphLoopState | null;
6
6
  clear: () => boolean;
7
7
  };
8
8
  export declare function handleFailedVerification(ctx: PluginInput, input: {
package/dist/index.js CHANGED
@@ -58612,10 +58612,13 @@ function clearState(directory, customPath) {
58612
58612
  return false;
58613
58613
  }
58614
58614
  }
58615
- function incrementIteration(directory, customPath) {
58615
+ function incrementIteration(directory, customPath, expected) {
58616
58616
  const state3 = readState(directory, customPath);
58617
58617
  if (!state3)
58618
58618
  return null;
58619
+ if (expected && (state3.iteration !== expected.iteration || state3.session_id !== expected.sessionID)) {
58620
+ return null;
58621
+ }
58619
58622
  state3.iteration += 1;
58620
58623
  if (writeState(directory, state3, customPath)) {
58621
58624
  return state3;
@@ -74093,6 +74096,12 @@ async function runAggressiveTruncationStrategy(params) {
74093
74096
  clearSessionState(params.autoCompactState, params.sessionID);
74094
74097
  setTimeout(async () => {
74095
74098
  try {
74099
+ if (await isSessionActive(params.client, params.sessionID)) {
74100
+ log("[auto-compact] skipped delayed auto prompt because session became active", {
74101
+ sessionID: params.sessionID
74102
+ });
74103
+ return;
74104
+ }
74096
74105
  const sdkMessage = await findNearestMessageWithFieldsFromSDK(params.client, params.sessionID);
74097
74106
  const previousMessage = sdkMessage ?? (() => {
74098
74107
  const messageDir = getMessageDir(params.sessionID);
@@ -74114,7 +74123,12 @@ async function runAggressiveTruncationStrategy(params) {
74114
74123
  },
74115
74124
  query: { directory: params.directory }
74116
74125
  });
74117
- } catch {}
74126
+ } catch (error) {
74127
+ log("[auto-compact] delayed auto prompt failed", {
74128
+ sessionID: params.sessionID,
74129
+ error: String(error)
74130
+ });
74131
+ }
74118
74132
  }, 500);
74119
74133
  return { handled: true, nextTruncateAttempt };
74120
74134
  }
@@ -75462,6 +75476,12 @@ function getNextReachableFallback(sessionID, state3) {
75462
75476
  }
75463
75477
 
75464
75478
  // src/hooks/model-fallback/fallback-state-controller.ts
75479
+ function canonicalizeModelIDForDuplicateCheck(modelID) {
75480
+ return modelID.toLowerCase().replace(/\./g, "-");
75481
+ }
75482
+ function isSameFailedModel(state3, providerID, modelID) {
75483
+ return state3.providerID.toLowerCase() === providerID.toLowerCase() && canonicalizeModelIDForDuplicateCheck(state3.modelID) === canonicalizeModelIDForDuplicateCheck(modelID);
75484
+ }
75465
75485
  function createModelFallbackStateController(input) {
75466
75486
  const { pendingModelFallbacks, lastToastKey, sessionFallbackChains } = input;
75467
75487
  function setSessionFallbackChain(sessionID, fallbackChain) {
@@ -75500,6 +75520,10 @@ function createModelFallbackStateController(input) {
75500
75520
  log(`[model-fallback] Pending fallback already armed for session: ${sessionID}`);
75501
75521
  return false;
75502
75522
  }
75523
+ if (existing.attemptCount > 0 && isSameFailedModel(existing, currentProviderID, currentModelID)) {
75524
+ log(`[model-fallback] Ignoring duplicate fallback arm for already handled model in session: ${sessionID}`);
75525
+ return false;
75526
+ }
75503
75527
  existing.providerID = currentProviderID;
75504
75528
  existing.modelID = currentModelID;
75505
75529
  existing.pending = true;
@@ -80225,6 +80249,31 @@ function detectBannedCommand(command) {
80225
80249
  }
80226
80250
  return;
80227
80251
  }
80252
+ function detectWindowsShellType(shellPath) {
80253
+ if (!shellPath) {
80254
+ return;
80255
+ }
80256
+ const shellName = shellPath.replace(/\\/g, "/").split("/").pop()?.toLowerCase();
80257
+ if (shellName === "cmd" || shellName === "cmd.exe") {
80258
+ return "cmd";
80259
+ }
80260
+ if (shellName === "powershell" || shellName === "powershell.exe" || shellName === "pwsh" || shellName === "pwsh.exe") {
80261
+ return "powershell";
80262
+ }
80263
+ return;
80264
+ }
80265
+ function detectCommandShellType() {
80266
+ if (process.platform === "win32" && process.env.SHELL) {
80267
+ const shellType = detectWindowsShellType(process.env.SHELL);
80268
+ if (shellType) {
80269
+ return shellType;
80270
+ }
80271
+ }
80272
+ if (process.platform === "win32" && !process.env.SHELL && !process.env.MSYSTEM) {
80273
+ return detectWindowsShellType(process.env.ComSpec) ?? "cmd";
80274
+ }
80275
+ return detectShellType();
80276
+ }
80228
80277
  function createNonInteractiveEnvHook(_ctx) {
80229
80278
  return {
80230
80279
  "tool.execute.before": async (input, output) => {
@@ -80243,7 +80292,7 @@ function createNonInteractiveEnvHook(_ctx) {
80243
80292
  if (!isGitCommand) {
80244
80293
  return;
80245
80294
  }
80246
- const shellType = detectShellType();
80295
+ const shellType = detectCommandShellType();
80247
80296
  const envPrefix = buildEnvPrefix(NON_INTERACTIVE_ENV, shellType);
80248
80297
  if (command.trim().startsWith(envPrefix.trim())) {
80249
80298
  return;
@@ -81165,8 +81214,8 @@ function createLoopStateController(options) {
81165
81214
  clear() {
81166
81215
  return clearState(directory, stateDir);
81167
81216
  },
81168
- incrementIteration() {
81169
- return incrementIteration(directory, stateDir);
81217
+ incrementIteration(expected) {
81218
+ return incrementIteration(directory, stateDir, expected);
81170
81219
  },
81171
81220
  setSessionID(sessionID) {
81172
81221
  const state3 = readState(directory, stateDir);
@@ -81179,11 +81228,14 @@ function createLoopStateController(options) {
81179
81228
  }
81180
81229
  return state3;
81181
81230
  },
81182
- setMessageCountAtStart(sessionID, messageCountAtStart) {
81231
+ setMessageCountAtStart(sessionID, messageCountAtStart, expectedStartedAt) {
81183
81232
  const state3 = readState(directory, stateDir);
81184
81233
  if (!state3 || state3.session_id !== sessionID) {
81185
81234
  return null;
81186
81235
  }
81236
+ if (state3.iteration !== 1 || state3.verification_pending || state3.message_count_at_start !== undefined || expectedStartedAt !== undefined && state3.started_at !== expectedStartedAt) {
81237
+ return null;
81238
+ }
81187
81239
  state3.message_count_at_start = messageCountAtStart;
81188
81240
  if (!writeState(directory, state3, stateDir)) {
81189
81241
  return null;
@@ -81933,9 +81985,9 @@ async function continueIteration(ctx, state3, options) {
81933
81985
  previousSessionID: options.previousSessionID,
81934
81986
  newSessionID
81935
81987
  });
81936
- return { status: "dispatched" };
81988
+ return { status: "dispatch_rejected", error: "state commit failed after reset dispatch" };
81937
81989
  }
81938
- return { status: "dispatched" };
81990
+ return { status: "dispatched", sessionID: newSessionID };
81939
81991
  }
81940
81992
  try {
81941
81993
  const promptResult = await injectContinuationPrompt(ctx, {
@@ -81950,7 +82002,7 @@ async function continueIteration(ctx, state3, options) {
81950
82002
  } catch (error) {
81951
82003
  return { status: "dispatch_rejected", error };
81952
82004
  }
81953
- return { status: "dispatched" };
82005
+ return { status: "dispatched", sessionID: options.previousSessionID };
81954
82006
  }
81955
82007
 
81956
82008
  // src/hooks/ralph-loop/pending-verification-handler.ts
@@ -82448,11 +82500,21 @@ function createRalphLoopEventHandler(ctx, options) {
82448
82500
  })) {
82449
82501
  return;
82450
82502
  }
82451
- const committed = options.loopState.incrementIteration();
82503
+ const committed = options.loopState.incrementIteration({
82504
+ iteration: stateBeforeCommit.iteration,
82505
+ sessionID: result.sessionID
82506
+ });
82452
82507
  if (committed) {
82453
82508
  showIterationToast(ctx, committed);
82454
82509
  } else {
82455
82510
  log(`[${HOOK_NAME3}] Dispatch succeeded but iteration commit failed`, { sessionID });
82511
+ options.loopState.clear();
82512
+ showToastBestEffort3(ctx, {
82513
+ title: "Ralph Loop Failed",
82514
+ message: "Dispatch succeeded but iteration commit failed",
82515
+ variant: "warning",
82516
+ duration: 5000
82517
+ });
82456
82518
  }
82457
82519
  return;
82458
82520
  }
@@ -82580,12 +82642,22 @@ function createRalphLoopEventHandler(ctx, options) {
82580
82642
  })) {
82581
82643
  return;
82582
82644
  }
82583
- const committed = options.loopState.incrementIteration();
82645
+ const committed = options.loopState.incrementIteration({
82646
+ iteration: stateBeforeCommit.iteration,
82647
+ sessionID: result.sessionID
82648
+ });
82584
82649
  if (committed) {
82585
82650
  showIterationToast(ctx, committed);
82586
82651
  runtimeErrorRetriedSessions.set(sessionID, committed.iteration);
82587
82652
  } else {
82588
82653
  log(`[${HOOK_NAME3}] Dispatch succeeded but iteration commit failed after runtime error`, { sessionID });
82654
+ options.loopState.clear();
82655
+ showToastBestEffort3(ctx, {
82656
+ title: "Ralph Loop Failed",
82657
+ message: "Dispatch succeeded but iteration commit failed",
82658
+ variant: "warning",
82659
+ duration: 5000
82660
+ });
82589
82661
  }
82590
82662
  return;
82591
82663
  }
@@ -82646,12 +82718,14 @@ function createRalphLoopHook(ctx, options) {
82646
82718
  if (!startSuccess || typeof loopOptions?.messageCountAtStart === "number") {
82647
82719
  return startSuccess;
82648
82720
  }
82721
+ const startedState = loopState.getState();
82722
+ const expectedStartedAt = startedState?.session_id === sessionID ? startedState.started_at : undefined;
82649
82723
  ctx.client.session.messages({
82650
82724
  path: { id: sessionID },
82651
82725
  query: { directory: ctx.directory }
82652
82726
  }).then((messagesResponse) => {
82653
82727
  const messageCountAtStart = getMessageCountFromResponse2(messagesResponse);
82654
- loopState.setMessageCountAtStart(sessionID, messageCountAtStart);
82728
+ loopState.setMessageCountAtStart(sessionID, messageCountAtStart, expectedStartedAt);
82655
82729
  }).catch(() => {});
82656
82730
  return startSuccess;
82657
82731
  },
@@ -93550,7 +93624,7 @@ function createRecoveryLogic(ctx, getTailState) {
93550
93624
  agent: launchAgent ?? expectedPromptConfig.agent,
93551
93625
  ...model ? { model } : {},
93552
93626
  ...tools ? { tools } : {},
93553
- parts: [createInternalAgentTextPart(AGENT_RECOVERY_PROMPT)]
93627
+ parts: [createInternalAgentContinuationTextPart(AGENT_RECOVERY_PROMPT)]
93554
93628
  },
93555
93629
  query: { directory: ctx.directory }
93556
93630
  });
@@ -95371,6 +95445,18 @@ function createSessionStatusHandler(deps, helpers, sessionStatusRetryKeys) {
95371
95445
 
95372
95446
  // src/hooks/runtime-fallback/event-handler.ts
95373
95447
  init_event_session_id();
95448
+ function resolveEventModel(props) {
95449
+ const model = props?.model;
95450
+ if (typeof model === "string") {
95451
+ return model;
95452
+ }
95453
+ const providerID = props?.providerID;
95454
+ const modelID = props?.modelID;
95455
+ if (typeof providerID === "string" && typeof modelID === "string") {
95456
+ return `${providerID}/${modelID}`;
95457
+ }
95458
+ return;
95459
+ }
95374
95460
  function createEventHandler(deps, helpers) {
95375
95461
  const { config, pluginConfig, sessionStates, sessionLastAccess, sessionRetryInFlight, sessionAwaitingFallbackResult, sessionFallbackTimeouts, sessionStatusRetryKeys } = deps;
95376
95462
  const sessionStatusHandler = createSessionStatusHandler(deps, helpers, sessionStatusRetryKeys);
@@ -95475,6 +95561,18 @@ function createEventHandler(deps, helpers) {
95475
95561
  });
95476
95562
  return;
95477
95563
  }
95564
+ if (sessionAwaitingFallbackResult.has(sessionID)) {
95565
+ const pendingFallbackModel = sessionStates.get(sessionID)?.pendingFallbackModel;
95566
+ const eventModel = resolveEventModel(props);
95567
+ if (!pendingFallbackModel || eventModel !== pendingFallbackModel) {
95568
+ log(`[${HOOK_NAME11}] session.error skipped - awaiting fallback result`, {
95569
+ sessionID,
95570
+ pendingFallbackModel,
95571
+ eventModel
95572
+ });
95573
+ return;
95574
+ }
95575
+ }
95478
95576
  sessionAwaitingFallbackResult.delete(sessionID);
95479
95577
  helpers.clearSessionFallbackTimeout(sessionID);
95480
95578
  log(`[${HOOK_NAME11}] session.error received`, {
@@ -103868,11 +103966,12 @@ function mergeWithClaudeCodeAgents(serverAgents, directory) {
103868
103966
  const toAgentInfoList = (record) => Object.entries(record).map(([name, config2]) => ({
103869
103967
  name,
103870
103968
  mode: config2.mode,
103969
+ hidden: config2.hidden,
103871
103970
  model: config2.model
103872
103971
  }));
103873
103972
  const mergedAgentMap = new Map;
103874
103973
  const addIfAbsent = (agent) => {
103875
- const key = agent.name.toLowerCase();
103974
+ const key = stripAgentListSortPrefix(agent.name).trim().toLowerCase();
103876
103975
  if (!mergedAgentMap.has(key)) {
103877
103976
  mergedAgentMap.set(key, agent);
103878
103977
  }
@@ -103905,10 +104004,10 @@ function findPrimaryAgentMatch(agents, requestedAgentName) {
103905
104004
  return agents.find((agent) => agent.mode === "primary" && matchesRequestedAgent(agent, requestedAgentName));
103906
104005
  }
103907
104006
  function findCallableAgentMatch(agents, requestedAgentName) {
103908
- return agents.find((agent) => isTaskCallableAgentMode(agent.mode) && matchesRequestedAgent(agent, requestedAgentName));
104007
+ return agents.find((agent) => isTaskCallableAgentMode(agent.mode) && agent.hidden !== true && matchesRequestedAgent(agent, requestedAgentName));
103909
104008
  }
103910
104009
  function listCallableAgentNames(agents) {
103911
- return agents.filter((agent) => isTaskCallableAgentMode(agent.mode)).map((agent) => stripAgentListSortPrefix(agent.name)).sort().join(", ");
104010
+ return agents.filter((agent) => isTaskCallableAgentMode(agent.mode) && agent.hidden !== true).map((agent) => stripAgentListSortPrefix(agent.name)).sort().join(", ");
103912
104011
  }
103913
104012
 
103914
104013
  // src/tools/call-omo-agent/background-executor.ts
@@ -113776,13 +113875,14 @@ ${originalText}`;
113776
113875
  ...variant !== undefined ? { variant } : {},
113777
113876
  ...resolvedTools ? { tools: resolvedTools } : {}
113778
113877
  };
113779
- const shouldDeferReply = shouldReply && await this.isSessionActive(task.parentSessionId);
113780
- if (shouldDeferReply) {
113781
- this.queuePendingParentWake(task.parentSessionId, notification2, parentPromptContext);
113878
+ const shouldDeferNotification = await this.isSessionActive(task.parentSessionId);
113879
+ if (shouldDeferNotification) {
113880
+ this.queuePendingParentWake(task.parentSessionId, notification2, parentPromptContext, shouldReply);
113782
113881
  log("[background-agent] Deferred notification until parent session is idle:", {
113783
113882
  taskId: task.id,
113784
113883
  allComplete,
113785
- isTaskFailure
113884
+ isTaskFailure,
113885
+ shouldReply
113786
113886
  });
113787
113887
  } else {
113788
113888
  try {
@@ -113825,15 +113925,17 @@ ${originalText}`;
113825
113925
  async isSessionActive(sessionID) {
113826
113926
  return isSessionActive(this.client, sessionID);
113827
113927
  }
113828
- queuePendingParentWake(sessionID, notification2, promptContext) {
113928
+ queuePendingParentWake(sessionID, notification2, promptContext, shouldReply) {
113829
113929
  const pendingWake = this.pendingParentWakes.get(sessionID);
113830
113930
  if (pendingWake) {
113831
113931
  pendingWake.notifications.push(notification2);
113832
113932
  pendingWake.promptContext = promptContext;
113933
+ pendingWake.shouldReply = pendingWake.shouldReply || shouldReply;
113833
113934
  } else {
113834
113935
  this.pendingParentWakes.set(sessionID, {
113835
113936
  promptContext,
113836
- notifications: [notification2]
113937
+ notifications: [notification2],
113938
+ shouldReply
113837
113939
  });
113838
113940
  }
113839
113941
  this.schedulePendingParentWakeFlush(sessionID);
@@ -113863,7 +113965,7 @@ ${originalText}`;
113863
113965
  await promptAsyncInDirectory(this.client, {
113864
113966
  path: { id: sessionID },
113865
113967
  body: {
113866
- noReply: false,
113968
+ noReply: !pendingWake.shouldReply,
113867
113969
  ...pendingWake.promptContext,
113868
113970
  parts: [createInternalAgentTextPart(notificationContent)]
113869
113971
  }
@@ -138840,6 +138942,10 @@ function createEventHandler2(args) {
138840
138942
  const lastHandledRetryStatusKey = new Map;
138841
138943
  const lastKnownModelBySession = new Map;
138842
138944
  const resolveFallbackProviderID = (sessionID, providerHint) => {
138945
+ const normalizedProviderHint = providerHint?.trim();
138946
+ if (normalizedProviderHint) {
138947
+ return normalizedProviderHint;
138948
+ }
138843
138949
  const sessionModel = getSessionModel(sessionID);
138844
138950
  if (sessionModel?.providerID) {
138845
138951
  return sessionModel.providerID;
@@ -138848,10 +138954,6 @@ function createEventHandler2(args) {
138848
138954
  if (lastKnownModel?.providerID) {
138849
138955
  return lastKnownModel.providerID;
138850
138956
  }
138851
- const normalizedProviderHint = providerHint?.trim();
138852
- if (normalizedProviderHint) {
138853
- return normalizedProviderHint;
138854
- }
138855
138957
  const connectedProvider = readConnectedProvidersCache()?.[0];
138856
138958
  if (connectedProvider) {
138857
138959
  return connectedProvider;
@@ -2,6 +2,7 @@ export type AgentMode = "subagent" | "primary" | "all" | undefined;
2
2
  export type AgentInfo = {
3
3
  name: string;
4
4
  mode?: "subagent" | "primary" | "all";
5
+ hidden?: boolean;
5
6
  model?: string | {
6
7
  providerID: string;
7
8
  modelID: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-opencode",
3
- "version": "4.1.1",
3
+ "version": "4.1.2",
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",
@@ -33,7 +33,8 @@
33
33
  "postinstall": "node postinstall.mjs",
34
34
  "prepublishOnly": "bun run clean && bun run build",
35
35
  "test:model-capabilities": "bun test src/shared/model-capability-aliases.test.ts src/shared/model-capability-guardrails.test.ts src/shared/model-capabilities.test.ts src/cli/doctor/checks/model-resolution.test.ts --bail",
36
- "typecheck": "tsc --noEmit",
36
+ "typecheck": "tsgo --noEmit",
37
+ "typecheck:script": "tsgo --noEmit -p script/tsconfig.json",
37
38
  "test": "bun run script/run-ci-tests.ts"
38
39
  },
39
40
  "keywords": [
@@ -63,35 +64,36 @@
63
64
  "@modelcontextprotocol/sdk": "^1.29.0",
64
65
  "@opencode-ai/plugin": "^1.4.0",
65
66
  "@opencode-ai/sdk": "^1.4.0",
66
- "commander": "^14.0.2",
67
- "detect-libc": "^2.0.0",
68
- "diff": "^8.0.3",
67
+ "commander": "^14.0.3",
68
+ "detect-libc": "^2.1.2",
69
+ "diff": "^8.0.4",
69
70
  "js-yaml": "^4.1.1",
70
71
  "jsonc-parser": "^3.3.1",
71
72
  "picocolors": "^1.1.1",
72
73
  "picomatch": "^4.0.4",
73
- "posthog-node": "^5.29.2",
74
- "vscode-jsonrpc": "^8.2.0"
74
+ "posthog-node": "^5.34.1",
75
+ "vscode-jsonrpc": "^8.2.1"
75
76
  },
76
77
  "devDependencies": {
78
+ "@typescript/native-preview": "7.0.0-dev.20260513.1",
77
79
  "@types/js-yaml": "^4.0.9",
78
80
  "@types/picomatch": "^3.0.2",
79
- "bun-types": "1.3.11",
80
- "typescript": "^5.7.3",
81
- "zod": "^4.3.0"
81
+ "bun-types": "1.3.12",
82
+ "typescript": "^5.9.3",
83
+ "zod": "^4.4.3"
82
84
  },
83
85
  "optionalDependencies": {
84
- "oh-my-opencode-darwin-arm64": "4.1.1",
85
- "oh-my-opencode-darwin-x64": "4.1.1",
86
- "oh-my-opencode-darwin-x64-baseline": "4.1.1",
87
- "oh-my-opencode-linux-arm64": "4.1.1",
88
- "oh-my-opencode-linux-arm64-musl": "4.1.1",
89
- "oh-my-opencode-linux-x64": "4.1.1",
90
- "oh-my-opencode-linux-x64-baseline": "4.1.1",
91
- "oh-my-opencode-linux-x64-musl": "4.1.1",
92
- "oh-my-opencode-linux-x64-musl-baseline": "4.1.1",
93
- "oh-my-opencode-windows-x64": "4.1.1",
94
- "oh-my-opencode-windows-x64-baseline": "4.1.1"
86
+ "oh-my-opencode-darwin-arm64": "4.1.2",
87
+ "oh-my-opencode-darwin-x64": "4.1.2",
88
+ "oh-my-opencode-darwin-x64-baseline": "4.1.2",
89
+ "oh-my-opencode-linux-arm64": "4.1.2",
90
+ "oh-my-opencode-linux-arm64-musl": "4.1.2",
91
+ "oh-my-opencode-linux-x64": "4.1.2",
92
+ "oh-my-opencode-linux-x64-baseline": "4.1.2",
93
+ "oh-my-opencode-linux-x64-musl": "4.1.2",
94
+ "oh-my-opencode-linux-x64-musl-baseline": "4.1.2",
95
+ "oh-my-opencode-windows-x64": "4.1.2",
96
+ "oh-my-opencode-windows-x64-baseline": "4.1.2"
95
97
  },
96
98
  "overrides": {
97
99
  "hono": "^4.12.18",