feat: migrate to OpenCode SDK v2

Update all import statements to use @opencode-ai/sdk/v2
Modify Vite configurations to alias new SDK path
Update API client method signatures for SDK v2 compatibility
This commit is contained in:
Bohdan Triapitsyn
2026-01-03 13:39:59 +02:00
parent 5029acfb9d
commit f2507d58cf
46 changed files with 167 additions and 184 deletions
+2 -4
View File
@@ -216,10 +216,8 @@ export const useFileStore = create<FileStore>()(
const filename = lastSlashIndex > 0 ? path.substring(lastSlashIndex + 1) : path;
const response = await tempClient.file.read({
query: {
path: filename,
directory: directory,
},
path: filename,
directory: directory,
});
if (response.data && "content" in response.data) {
+10 -14
View File
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { create } from "zustand";
import { devtools, persist, createJSONStorage } from "zustand/middleware";
import type { Message, Part } from "@opencode-ai/sdk";
import type { Message, Part } from "@opencode-ai/sdk/v2";
import { opencodeClient } from "@/lib/opencode/client";
import { isExecutionForkMetaText } from "@/lib/messages/executionMeta";
import type { SessionMemoryState, MessageStreamLifecycle, AttachedFile } from "./types/sessionTypes";
@@ -586,13 +586,11 @@ export const useMessageStore = create<MessageStore>()(
const messageId = `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
await apiClient.session.init({
path: { id: sessionId },
body: {
messageID: messageId,
providerID,
modelID,
},
query: directory ? { directory } : undefined,
sessionID: sessionId,
...(directory ? { directory } : {}),
messageID: messageId,
providerID,
modelID,
});
return;
@@ -600,12 +598,10 @@ export const useMessageStore = create<MessageStore>()(
if (command === "summarize") {
await apiClient.session.summarize({
path: { id: sessionId },
body: {
providerID,
modelID,
},
query: directory ? { directory } : undefined,
sessionID: sessionId,
...(directory ? { directory } : {}),
providerID,
modelID,
});
return;
+11 -11
View File
@@ -1,6 +1,6 @@
import { create } from "zustand";
import { devtools, persist, createJSONStorage } from "zustand/middleware";
import type { Session } from "@opencode-ai/sdk";
import type { Session } from "@opencode-ai/sdk/v2";
import { opencodeClient } from "@/lib/opencode/client";
import { getSafeStorage } from "./utils/safeStorage";
import type { WorktreeMetadata } from "@/types/worktree";
@@ -254,9 +254,9 @@ export const useSessionStore = create<SessionStore>()(
const apiClient = opencodeClient.getApiClient();
const fetchSessions = async (directoryParam?: string | null): Promise<Session[]> => {
const response = await apiClient.session.list({
query: directoryParam ? { directory: directoryParam } : undefined,
});
const response = await apiClient.session.list(
directoryParam ? { directory: directoryParam } : undefined
);
return Array.isArray(response.data) ? response.data : [];
};
@@ -536,9 +536,9 @@ export const useSessionStore = create<SessionStore>()(
const attempts = 20;
for (let attempt = 0; attempt < attempts; attempt += 1) {
try {
const response = await apiClient.session.list({
query: targetDirectory ? { directory: targetDirectory } : undefined,
});
const response = await apiClient.session.list(
targetDirectory ? { directory: targetDirectory } : undefined
);
const list = Array.isArray(response.data) ? response.data : [];
const candidate = list.find((entry) => {
if (existingIds.has(entry.id)) return false;
@@ -817,8 +817,8 @@ export const useSessionStore = create<SessionStore>()(
const shareRequest = async () => {
const directory = sessionDirectory ?? opencodeClient.getDirectory();
return apiClient.session.share({
path: { id },
query: directory ? { directory } : undefined,
sessionID: id,
...(directory ? { directory } : {})
});
};
const response = overrideDirectory
@@ -849,8 +849,8 @@ export const useSessionStore = create<SessionStore>()(
const unshareRequest = async () => {
const directory = sessionDirectory ?? opencodeClient.getDirectory();
return apiClient.session.unshare({
path: { id },
query: directory ? { directory } : undefined,
sessionID: id,
...(directory ? { directory } : {})
});
};
const response = overrideDirectory
+1 -1
View File
@@ -1,4 +1,4 @@
import type { Session, Message, Part } from "@opencode-ai/sdk";
import type { Session, Message, Part } from "@opencode-ai/sdk/v2";
import type { Permission, PermissionResponse } from "@/types/permission";
export interface AttachedFile {
+5 -3
View File
@@ -1,7 +1,7 @@
import { create } from "zustand";
import type { StoreApi, UseBoundStore } from "zustand";
import { devtools, persist, createJSONStorage } from "zustand/middleware";
import type { Agent } from "@opencode-ai/sdk";
import type { Agent } from "@opencode-ai/sdk/v2";
import { opencodeClient } from "@/lib/opencode/client";
import { emitConfigChange, scopeMatches, subscribeToConfigChanges } from "@/lib/configSync";
import {
@@ -62,8 +62,10 @@ export type AgentWithExtras = Agent & {
};
// Helper to check if agent is built-in (handles both SDK 'builtIn' and API 'native')
export const isAgentBuiltIn = (agent: Agent): boolean =>
agent.builtIn || (agent as AgentWithExtras).native === true;
export const isAgentBuiltIn = (agent: Agent): boolean => {
const extended = agent as AgentWithExtras & { builtIn?: boolean };
return extended.native === true || extended.builtIn === true;
};
// Helper to check if agent is hidden (internal agents like title, compaction, summary)
// Checks both top-level hidden and options.hidden (OpenCode API inconsistency workaround)
+1 -1
View File
@@ -1,7 +1,7 @@
import { create } from "zustand";
import type { StoreApi, UseBoundStore } from "zustand";
import { devtools, persist, createJSONStorage } from "zustand/middleware";
import type { Provider, Agent } from "@opencode-ai/sdk";
import type { Provider, Agent } from "@opencode-ai/sdk/v2";
import { opencodeClient } from "@/lib/opencode/client";
import { scopeMatches, subscribeToConfigChanges } from "@/lib/configSync";
import type { ModelMetadata } from "@/types";
+1 -1
View File
@@ -1,7 +1,7 @@
import { create } from "zustand";
import type { StoreApi, UseBoundStore } from "zustand";
import { devtools } from "zustand/middleware";
import type { Session, Message, Part } from "@opencode-ai/sdk";
import type { Session, Message, Part } from "@opencode-ai/sdk/v2";
import type { Permission, PermissionResponse } from "@/types/permission";
import type { SessionStore, AttachedFile, EditPermissionMode } from "./types/sessionTypes";
import { ACTIVE_SESSION_WINDOW, MEMORY_LIMITS } from "./types/sessionTypes";
+1 -1
View File
@@ -1,4 +1,4 @@
import type { Part } from "@opencode-ai/sdk";
import type { Part } from "@opencode-ai/sdk/v2";
const extractTextFromDelta = (delta: unknown): string => {
if (!delta) return '';
+1 -1
View File
@@ -1,4 +1,4 @@
import type { Message, Part } from "@opencode-ai/sdk";
import type { Message, Part } from "@opencode-ai/sdk/v2";
type TokenBreakdown = {
input?: number;