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:
@@ -12,12 +12,12 @@ export default defineConfig({
|
|||||||
root: path.resolve(__dirname, '.'),
|
root: path.resolve(__dirname, '.'),
|
||||||
plugins: [react(), themeStoragePlugin()],
|
plugins: [react(), themeStoragePlugin()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: [
|
||||||
'@desktop': path.resolve(__dirname, './src'),
|
{ find: '@opencode-ai/sdk/v2', replacement: path.resolve(__dirname, '../../node_modules/@opencode-ai/sdk/dist/v2/client.js') },
|
||||||
'@openchamber/ui': path.resolve(__dirname, '../ui/src'),
|
{ find: '@openchamber/ui', replacement: path.resolve(__dirname, '../ui/src') },
|
||||||
'@': path.resolve(__dirname, '../ui/src'),
|
{ find: '@desktop', replacement: path.resolve(__dirname, './src') },
|
||||||
'@opencode-ai/sdk': path.resolve(__dirname, '../../node_modules/@opencode-ai/sdk/dist/client.js'),
|
{ find: '@', replacement: path.resolve(__dirname, '../ui/src') },
|
||||||
},
|
],
|
||||||
},
|
},
|
||||||
worker: {
|
worker: {
|
||||||
format: 'es',
|
format: 'es',
|
||||||
@@ -31,7 +31,7 @@ export default defineConfig({
|
|||||||
__APP_VERSION__: JSON.stringify(packageJson.version),
|
__APP_VERSION__: JSON.stringify(packageJson.version),
|
||||||
},
|
},
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
include: ['@opencode-ai/sdk'],
|
include: ['@opencode-ai/sdk/v2'],
|
||||||
exclude: [
|
exclude: [
|
||||||
'@tauri-apps/plugin-dialog',
|
'@tauri-apps/plugin-dialog',
|
||||||
'@tauri-apps/api/core',
|
'@tauri-apps/api/core',
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { Message, Part } from '@opencode-ai/sdk';
|
import type { Message, Part } from '@opencode-ai/sdk/v2';
|
||||||
import { useShallow } from 'zustand/react/shallow';
|
import { useShallow } from 'zustand/react/shallow';
|
||||||
|
|
||||||
import { defaultCodeDark, defaultCodeLight } from '@/lib/codeTheme';
|
import { defaultCodeDark, defaultCodeLight } from '@/lib/codeTheme';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Streamdown } from 'streamdown';
|
import { Streamdown } from 'streamdown';
|
||||||
import { FadeInOnReveal } from './message/FadeInOnReveal';
|
import { FadeInOnReveal } from './message/FadeInOnReveal';
|
||||||
import type { Part } from '@opencode-ai/sdk';
|
import type { Part } from '@opencode-ai/sdk/v2';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { RiFileCopyLine, RiCheckLine, RiDownloadLine } from '@remixicon/react';
|
import { RiFileCopyLine, RiCheckLine, RiDownloadLine } from '@remixicon/react';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { Message, Part } from '@opencode-ai/sdk';
|
import type { Message, Part } from '@opencode-ai/sdk/v2';
|
||||||
|
|
||||||
import ChatMessage from './ChatMessage';
|
import ChatMessage from './ChatMessage';
|
||||||
import { PermissionCard } from './PermissionCard';
|
import { PermissionCard } from './PermissionCard';
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { useSessionStore } from '@/stores/useSessionStore';
|
|||||||
import { useMessageStore } from '@/stores/messageStore';
|
import { useMessageStore } from '@/stores/messageStore';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { RiLoader4Line, RiSearchLine, RiTimeLine, RiGitBranchLine } from '@remixicon/react';
|
import { RiLoader4Line, RiSearchLine, RiTimeLine, RiGitBranchLine } from '@remixicon/react';
|
||||||
import type { Part } from '@opencode-ai/sdk';
|
import type { Part } from '@opencode-ai/sdk/v2';
|
||||||
|
|
||||||
interface TimelineDialogProps {
|
interface TimelineDialogProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { Message, Part } from '@opencode-ai/sdk';
|
import type { Message, Part } from '@opencode-ai/sdk/v2';
|
||||||
import { useCurrentSessionActivity } from '@/hooks/useSessionActivity';
|
import { useCurrentSessionActivity } from '@/hooks/useSessionActivity';
|
||||||
import { useUIStore } from '@/stores/useUIStore';
|
import { useUIStore } from '@/stores/useUIStore';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { Part } from '@opencode-ai/sdk';
|
import type { Part } from '@opencode-ai/sdk/v2';
|
||||||
|
|
||||||
import AssistantTextPart from './parts/AssistantTextPart';
|
import AssistantTextPart from './parts/AssistantTextPart';
|
||||||
import UserTextPart from './parts/UserTextPart';
|
import UserTextPart from './parts/UserTextPart';
|
||||||
@@ -8,7 +8,7 @@ import ToolPart from './parts/ToolPart';
|
|||||||
import ProgressiveGroup from './parts/ProgressiveGroup';
|
import ProgressiveGroup from './parts/ProgressiveGroup';
|
||||||
import MigratingPart from './parts/MigratingPart';
|
import MigratingPart from './parts/MigratingPart';
|
||||||
import { MessageFilesDisplay } from '../FileAttachment';
|
import { MessageFilesDisplay } from '../FileAttachment';
|
||||||
import type { ToolPart as ToolPartType } from '@opencode-ai/sdk';
|
import type { ToolPart as ToolPartType } from '@opencode-ai/sdk/v2';
|
||||||
import type { StreamPhase, ToolPopupContent, AgentMentionInfo } from './types';
|
import type { StreamPhase, ToolPopupContent, AgentMentionInfo } from './types';
|
||||||
import type { TurnGroupingContext } from '../hooks/useTurnGrouping';
|
import type { TurnGroupingContext } from '../hooks/useTurnGrouping';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Message } from '@opencode-ai/sdk';
|
import type { Message } from '@opencode-ai/sdk/v2';
|
||||||
|
|
||||||
export interface MessageRoleInfo {
|
export interface MessageRoleInfo {
|
||||||
role: string;
|
role: string;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Part } from '@opencode-ai/sdk';
|
import type { Part } from '@opencode-ai/sdk/v2';
|
||||||
|
|
||||||
type PartWithText = Part & { text?: string; content?: string; value?: string };
|
type PartWithText = Part & { text?: string; content?: string; value?: string };
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { Part } from '@opencode-ai/sdk';
|
import type { Part } from '@opencode-ai/sdk/v2';
|
||||||
import { MarkdownRenderer } from '../../MarkdownRenderer';
|
import { MarkdownRenderer } from '../../MarkdownRenderer';
|
||||||
import type { StreamPhase } from '../types';
|
import type { StreamPhase } from '../types';
|
||||||
import type { ContentChangeReason } from '@/hooks/useChatScrollManager';
|
import type { ContentChangeReason } from '@/hooks/useChatScrollManager';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { Part } from '@opencode-ai/sdk';
|
import type { Part } from '@opencode-ai/sdk/v2';
|
||||||
import type { ContentChangeReason } from '@/hooks/useChatScrollManager';
|
import type { ContentChangeReason } from '@/hooks/useChatScrollManager';
|
||||||
import { ReasoningTimelineBlock } from './ReasoningPart';
|
import { ReasoningTimelineBlock } from './ReasoningPart';
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import { RiArrowDownSLine, RiArrowRightSLine, RiStackLine } from '@remixicon/react';
|
import { RiArrowDownSLine, RiArrowRightSLine, RiStackLine } from '@remixicon/react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import type { TurnActivityPart } from '../../hooks/useTurnGrouping';
|
import type { TurnActivityPart } from '../../hooks/useTurnGrouping';
|
||||||
import type { ToolPart as ToolPartType } from '@opencode-ai/sdk';
|
import type { ToolPart as ToolPartType } from '@opencode-ai/sdk/v2';
|
||||||
import type { ContentChangeReason } from '@/hooks/useChatScrollManager';
|
import type { ContentChangeReason } from '@/hooks/useChatScrollManager';
|
||||||
import type { ToolPopupContent } from '../types';
|
import type { ToolPopupContent } from '../types';
|
||||||
import ToolPart from './ToolPart';
|
import ToolPart from './ToolPart';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { ComponentType } from 'react';
|
import type { ComponentType } from 'react';
|
||||||
import type { Part } from '@opencode-ai/sdk';
|
import type { Part } from '@opencode-ai/sdk/v2';
|
||||||
import { RiArrowDownSLine, RiArrowRightSLine, RiBrainAi3Line, RiChatAi3Line } from '@remixicon/react';
|
import { RiArrowDownSLine, RiArrowRightSLine, RiBrainAi3Line, RiChatAi3Line } from '@remixicon/react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import type { ContentChangeReason } from '@/hooks/useChatScrollManager';
|
import type { ContentChangeReason } from '@/hooks/useChatScrollManager';
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { RiArrowDownSLine, RiArrowRightSLine, RiBookLine, RiFileEditLine, RiFile
|
|||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { SimpleMarkdownRenderer } from '../../MarkdownRenderer';
|
import { SimpleMarkdownRenderer } from '../../MarkdownRenderer';
|
||||||
import { getToolMetadata, getLanguageFromExtension, isImageFile, getImageMimeType } from '@/lib/toolHelpers';
|
import { getToolMetadata, getLanguageFromExtension, isImageFile, getImageMimeType } from '@/lib/toolHelpers';
|
||||||
import type { ToolPart as ToolPartType, ToolState as ToolStateUnion } from '@opencode-ai/sdk';
|
import type { ToolPart as ToolPartType, ToolState as ToolStateUnion } from '@opencode-ai/sdk/v2';
|
||||||
import { toolDisplayStyles } from '@/lib/typography';
|
import { toolDisplayStyles } from '@/lib/typography';
|
||||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
||||||
import { useDirectoryStore } from '@/stores/useDirectoryStore';
|
import { useDirectoryStore } from '@/stores/useDirectoryStore';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import type { Part } from '@opencode-ai/sdk';
|
import type { Part } from '@opencode-ai/sdk/v2';
|
||||||
import type { AgentMentionInfo } from '../types';
|
import type { AgentMentionInfo } from '../types';
|
||||||
|
|
||||||
type PartWithText = Part & { text?: string; content?: string; value?: string };
|
type PartWithText = Part & { text?: string; content?: string; value?: string };
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import { useUIStore } from '@/stores/useUIStore';
|
|||||||
import { useDeviceInfo } from '@/lib/device';
|
import { useDeviceInfo } from '@/lib/device';
|
||||||
import { isVSCodeRuntime } from '@/lib/desktop';
|
import { isVSCodeRuntime } from '@/lib/desktop';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import type { Agent } from '@opencode-ai/sdk';
|
import type { Agent } from '@opencode-ai/sdk/v2';
|
||||||
import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay';
|
import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay';
|
||||||
|
|
||||||
interface AgentsSidebarProps {
|
interface AgentsSidebarProps {
|
||||||
|
|||||||
@@ -400,10 +400,8 @@ export const DirectoryTree: React.FC<DirectoryTreeProps> = ({
|
|||||||
|
|
||||||
const tempClient = opencodeClient.getApiClient();
|
const tempClient = opencodeClient.getApiClient();
|
||||||
const response = await tempClient.file.list({
|
const response = await tempClient.file.list({
|
||||||
query: {
|
|
||||||
path: '.',
|
path: '.',
|
||||||
directory: path
|
directory: path
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.data) {
|
if (!response.data) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import { RiCheckboxBlankLine, RiCheckboxLine, RiDeleteBinLine } from '@remixicon
|
|||||||
import { MobileOverlayPanel } from '@/components/ui/MobileOverlayPanel';
|
import { MobileOverlayPanel } from '@/components/ui/MobileOverlayPanel';
|
||||||
import { DirectoryExplorerDialog } from './DirectoryExplorerDialog';
|
import { DirectoryExplorerDialog } from './DirectoryExplorerDialog';
|
||||||
import { cn, formatPathForDisplay } from '@/lib/utils';
|
import { cn, formatPathForDisplay } from '@/lib/utils';
|
||||||
import type { Session } from '@opencode-ai/sdk';
|
import type { Session } from '@opencode-ai/sdk/v2';
|
||||||
import type { WorktreeMetadata } from '@/types/worktree';
|
import type { WorktreeMetadata } from '@/types/worktree';
|
||||||
import {
|
import {
|
||||||
archiveWorktree,
|
archiveWorktree,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { Session } from '@opencode-ai/sdk';
|
import type { Session } from '@opencode-ai/sdk/v2';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import {
|
|||||||
import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay';
|
import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay';
|
||||||
import { RiGitBranchLine, RiLoader4Line } from '@remixicon/react';
|
import { RiGitBranchLine, RiLoader4Line } from '@remixicon/react';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import type { Session } from '@opencode-ai/sdk';
|
import type { Session } from '@opencode-ai/sdk/v2';
|
||||||
import { useRuntimeAPIs } from '@/hooks/useRuntimeAPIs';
|
import { useRuntimeAPIs } from '@/hooks/useRuntimeAPIs';
|
||||||
import { useUIStore } from '@/stores/useUIStore';
|
import { useUIStore } from '@/stores/useUIStore';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { AssistantMessage, Message, Part, ReasoningPart, TextPart, ToolPart } from '@opencode-ai/sdk';
|
import type { AssistantMessage, Message, Part, ReasoningPart, TextPart, ToolPart } from '@opencode-ai/sdk/v2';
|
||||||
import { useShallow } from 'zustand/react/shallow';
|
import { useShallow } from 'zustand/react/shallow';
|
||||||
|
|
||||||
import type { MessageStreamPhase } from '@/stores/types/sessionTypes';
|
import type { MessageStreamPhase } from '@/stores/types/sessionTypes';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { Part } from '@opencode-ai/sdk';
|
import type { Part } from '@opencode-ai/sdk/v2';
|
||||||
|
|
||||||
import { MessageFreshnessDetector } from '@/lib/messageFreshness';
|
import { MessageFreshnessDetector } from '@/lib/messageFreshness';
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useSessionStore } from '@/stores/useSessionStore';
|
|||||||
import { useConfigStore } from '@/stores/useConfigStore';
|
import { useConfigStore } from '@/stores/useConfigStore';
|
||||||
import { useUIStore, type EventStreamStatus } from '@/stores/useUIStore';
|
import { useUIStore, type EventStreamStatus } from '@/stores/useUIStore';
|
||||||
import { useDirectoryStore } from '@/stores/useDirectoryStore';
|
import { useDirectoryStore } from '@/stores/useDirectoryStore';
|
||||||
import type { Part, Session, Message, Permission } from '@opencode-ai/sdk';
|
import type { Part, Session, Message, Permission } from '@opencode-ai/sdk/v2';
|
||||||
import { streamDebugEnabled } from '@/stores/utils/streamDebug';
|
import { streamDebugEnabled } from '@/stores/utils/streamDebug';
|
||||||
import { handleTodoUpdatedEvent } from '@/stores/useTodoStore';
|
import { handleTodoUpdatedEvent } from '@/stores/useTodoStore';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { AssistantMessage, Message, Part } from '@opencode-ai/sdk';
|
import type { AssistantMessage, Message, Part } from '@opencode-ai/sdk/v2';
|
||||||
import { useSessionStore, MEMORY_LIMITS } from '@/stores/useSessionStore';
|
import { useSessionStore, MEMORY_LIMITS } from '@/stores/useSessionStore';
|
||||||
import { opencodeClient } from '@/lib/opencode/client';
|
import { opencodeClient } from '@/lib/opencode/client';
|
||||||
import { readSessionCursor } from '@/lib/messageCursorPersistence';
|
import { readSessionCursor } from '@/lib/messageCursorPersistence';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useConfigStore } from '@/stores/useConfigStore';
|
import { useConfigStore } from '@/stores/useConfigStore';
|
||||||
import { useUIStore } from '@/stores/useUIStore';
|
import { useUIStore } from '@/stores/useUIStore';
|
||||||
import type { Provider } from '@opencode-ai/sdk';
|
import type { Provider } from '@opencode-ai/sdk/v2';
|
||||||
|
|
||||||
type ProviderModel = Provider["models"][string];
|
type ProviderModel = Provider["models"][string];
|
||||||
type ProviderWithModelList = Omit<Provider, "models"> & { models: ProviderModel[] };
|
type ProviderWithModelList = Omit<Provider, "models"> & { models: ProviderModel[] };
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { Session } from '@opencode-ai/sdk';
|
import type { Session } from '@opencode-ai/sdk/v2';
|
||||||
import { useSessionStore } from '@/stores/useSessionStore';
|
import { useSessionStore } from '@/stores/useSessionStore';
|
||||||
import { useUIStore } from '@/stores/useUIStore';
|
import { useUIStore } from '@/stores/useUIStore';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import type { Part } from "@opencode-ai/sdk";
|
import type { Part } from "@opencode-ai/sdk/v2";
|
||||||
import { isFullySyntheticMessage } from "@/lib/messages/synthetic";
|
import { isFullySyntheticMessage } from "@/lib/messages/synthetic";
|
||||||
|
|
||||||
export interface MessageInfo {
|
export interface MessageInfo {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Message } from '@opencode-ai/sdk';
|
import type { Message } from '@opencode-ai/sdk/v2';
|
||||||
|
|
||||||
export class MessageFreshnessDetector {
|
export class MessageFreshnessDetector {
|
||||||
private static instance: MessageFreshnessDetector;
|
private static instance: MessageFreshnessDetector;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Agent } from "@opencode-ai/sdk";
|
import type { Agent } from "@opencode-ai/sdk/v2";
|
||||||
|
|
||||||
export interface AgentMentionSource {
|
export interface AgentMentionSource {
|
||||||
value: string;
|
value: string;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Part } from '@opencode-ai/sdk';
|
import type { Part } from '@opencode-ai/sdk/v2';
|
||||||
|
|
||||||
type TextLikePart = Part & { text?: string; content?: string };
|
type TextLikePart = Part & { text?: string; content?: string };
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Part } from "@opencode-ai/sdk";
|
import type { Part } from "@opencode-ai/sdk/v2";
|
||||||
|
|
||||||
export const isSyntheticPart = (part: Part | undefined): boolean => {
|
export const isSyntheticPart = (part: Part | undefined): boolean => {
|
||||||
if (!part || typeof part !== "object") {
|
if (!part || typeof part !== "object") {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { createOpencodeClient, OpencodeClient } from "@opencode-ai/sdk";
|
import { createOpencodeClient, OpencodeClient } from "@opencode-ai/sdk/v2";
|
||||||
import type { FilesAPI, RuntimeAPIs } from "../api/types";
|
import type { FilesAPI, RuntimeAPIs } from "../api/types";
|
||||||
import { getDesktopHomeDirectory } from "../desktop";
|
import { getDesktopHomeDirectory } from "../desktop";
|
||||||
import type {
|
import type {
|
||||||
@@ -12,7 +12,7 @@ import type {
|
|||||||
TextPartInput,
|
TextPartInput,
|
||||||
FilePartInput,
|
FilePartInput,
|
||||||
Event,
|
Event,
|
||||||
} from "@opencode-ai/sdk";
|
} from "@opencode-ai/sdk/v2";
|
||||||
type StreamEvent<TData> = {
|
type StreamEvent<TData> = {
|
||||||
data: TData;
|
data: TData;
|
||||||
event?: string;
|
event?: string;
|
||||||
@@ -238,9 +238,9 @@ class OpencodeService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await this.client.path.get({
|
const response = await this.client.path.get(
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
||||||
});
|
);
|
||||||
const info = response.data;
|
const info = response.data;
|
||||||
if (info) {
|
if (info) {
|
||||||
addCandidate(info.directory);
|
addCandidate(info.directory);
|
||||||
@@ -253,9 +253,9 @@ class OpencodeService {
|
|||||||
|
|
||||||
if (!candidates.size) {
|
if (!candidates.size) {
|
||||||
try {
|
try {
|
||||||
const project = await this.client.project.current({
|
const project = await this.client.project.current(
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
||||||
});
|
);
|
||||||
addCandidate(project.data?.worktree);
|
addCandidate(project.data?.worktree);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.debug('Failed to load project info:', error);
|
console.debug('Failed to load project info:', error);
|
||||||
@@ -296,19 +296,17 @@ class OpencodeService {
|
|||||||
|
|
||||||
// Session Management
|
// Session Management
|
||||||
async listSessions(): Promise<Session[]> {
|
async listSessions(): Promise<Session[]> {
|
||||||
const response = await this.client.session.list({
|
const response = await this.client.session.list(
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
||||||
});
|
);
|
||||||
return Array.isArray(response.data) ? response.data : [];
|
return Array.isArray(response.data) ? response.data : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
async createSession(params?: { parentID?: string; title?: string }): Promise<Session> {
|
async createSession(params?: { parentID?: string; title?: string }): Promise<Session> {
|
||||||
const response = await this.client.session.create({
|
const response = await this.client.session.create({
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined,
|
...(this.currentDirectory ? { directory: this.currentDirectory } : {}),
|
||||||
body: {
|
|
||||||
parentID: params?.parentID,
|
parentID: params?.parentID,
|
||||||
title: params?.title
|
title: params?.title
|
||||||
}
|
|
||||||
});
|
});
|
||||||
if (!response.data) throw new Error('Failed to create session');
|
if (!response.data) throw new Error('Failed to create session');
|
||||||
return response.data;
|
return response.data;
|
||||||
@@ -316,8 +314,8 @@ class OpencodeService {
|
|||||||
|
|
||||||
async getSession(id: string): Promise<Session> {
|
async getSession(id: string): Promise<Session> {
|
||||||
const response = await this.client.session.get({
|
const response = await this.client.session.get({
|
||||||
path: { id },
|
sessionID: id,
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
...(this.currentDirectory ? { directory: this.currentDirectory } : {})
|
||||||
});
|
});
|
||||||
if (!response.data) throw new Error('Session not found');
|
if (!response.data) throw new Error('Session not found');
|
||||||
return response.data;
|
return response.data;
|
||||||
@@ -325,17 +323,17 @@ class OpencodeService {
|
|||||||
|
|
||||||
async deleteSession(id: string): Promise<boolean> {
|
async deleteSession(id: string): Promise<boolean> {
|
||||||
const response = await this.client.session.delete({
|
const response = await this.client.session.delete({
|
||||||
path: { id },
|
sessionID: id,
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
...(this.currentDirectory ? { directory: this.currentDirectory } : {})
|
||||||
});
|
});
|
||||||
return response.data || false;
|
return response.data || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateSession(id: string, title?: string): Promise<Session> {
|
async updateSession(id: string, title?: string): Promise<Session> {
|
||||||
const response = await this.client.session.update({
|
const response = await this.client.session.update({
|
||||||
path: { id },
|
sessionID: id,
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined,
|
...(this.currentDirectory ? { directory: this.currentDirectory } : {}),
|
||||||
body: { title }
|
title
|
||||||
});
|
});
|
||||||
if (!response.data) throw new Error('Failed to update session');
|
if (!response.data) throw new Error('Failed to update session');
|
||||||
return response.data;
|
return response.data;
|
||||||
@@ -343,8 +341,8 @@ class OpencodeService {
|
|||||||
|
|
||||||
async getSessionMessages(id: string): Promise<{ info: Message; parts: Part[] }[]> {
|
async getSessionMessages(id: string): Promise<{ info: Message; parts: Part[] }[]> {
|
||||||
const response = await this.client.session.messages({
|
const response = await this.client.session.messages({
|
||||||
path: { id },
|
sessionID: id,
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
...(this.currentDirectory ? { directory: this.currentDirectory } : {})
|
||||||
});
|
});
|
||||||
return response.data || [];
|
return response.data || [];
|
||||||
}
|
}
|
||||||
@@ -618,9 +616,8 @@ class OpencodeService {
|
|||||||
// Use SDK session.prompt() method
|
// Use SDK session.prompt() method
|
||||||
// DON'T send messageID - let server generate it (fixes Claude empty response issue)
|
// DON'T send messageID - let server generate it (fixes Claude empty response issue)
|
||||||
await this.client.session.prompt({
|
await this.client.session.prompt({
|
||||||
path: { id: params.id },
|
sessionID: params.id,
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined,
|
...(this.currentDirectory ? { directory: this.currentDirectory } : {}),
|
||||||
body: {
|
|
||||||
// messageID intentionally omitted - server will generate
|
// messageID intentionally omitted - server will generate
|
||||||
model: {
|
model: {
|
||||||
providerID: params.providerID,
|
providerID: params.providerID,
|
||||||
@@ -628,7 +625,6 @@ class OpencodeService {
|
|||||||
},
|
},
|
||||||
agent: params.agent,
|
agent: params.agent,
|
||||||
parts
|
parts
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Return temporary ID for optimistic UI
|
// Return temporary ID for optimistic UI
|
||||||
@@ -637,19 +633,22 @@ class OpencodeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async abortSession(id: string): Promise<boolean> {
|
async abortSession(id: string): Promise<boolean> {
|
||||||
const response = await this.client.session.abort({
|
const response = await this.client.session.abort(
|
||||||
path: { id },
|
{
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined,
|
sessionID: id,
|
||||||
throwOnError: true,
|
...(this.currentDirectory ? { directory: this.currentDirectory } : {})
|
||||||
});
|
},
|
||||||
|
{ throwOnError: true }
|
||||||
|
);
|
||||||
return Boolean(response.data);
|
return Boolean(response.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async revertSession(sessionId: string, messageId: string, partId?: string): Promise<Session> {
|
async revertSession(sessionId: string, messageId: string, partId?: string): Promise<Session> {
|
||||||
const response = await this.client.session.revert({
|
const response = await this.client.session.revert({
|
||||||
path: { id: sessionId },
|
sessionID: sessionId,
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined,
|
...(this.currentDirectory ? { directory: this.currentDirectory } : {}),
|
||||||
body: { messageID: messageId, partID: partId }
|
messageID: messageId,
|
||||||
|
partID: partId
|
||||||
});
|
});
|
||||||
if (!response.data) throw new Error('Failed to revert session');
|
if (!response.data) throw new Error('Failed to revert session');
|
||||||
return response.data;
|
return response.data;
|
||||||
@@ -657,33 +656,25 @@ class OpencodeService {
|
|||||||
|
|
||||||
async unrevertSession(sessionId: string): Promise<Session> {
|
async unrevertSession(sessionId: string): Promise<Session> {
|
||||||
const response = await this.client.session.unrevert({
|
const response = await this.client.session.unrevert({
|
||||||
path: { id: sessionId },
|
sessionID: sessionId,
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
...(this.currentDirectory ? { directory: this.currentDirectory } : {})
|
||||||
});
|
});
|
||||||
if (!response.data) throw new Error('Failed to unrevert session');
|
if (!response.data) throw new Error('Failed to unrevert session');
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async forkSession(sessionId: string, messageId?: string): Promise<Session> {
|
async forkSession(sessionId: string, messageId?: string): Promise<Session> {
|
||||||
const baseUrl = this.baseUrl.replace(/\/$/, '');
|
const response = await this.client.session.fork({
|
||||||
const url = new URL(`/api/session/${sessionId}/fork`, baseUrl);
|
sessionID: sessionId,
|
||||||
|
...(this.currentDirectory ? { directory: this.currentDirectory } : {}),
|
||||||
if (this.currentDirectory) {
|
messageID: messageId
|
||||||
url.searchParams.set('directory', this.currentDirectory);
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch(url.toString(), {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify(messageId ? { messageID: messageId } : {}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.data) {
|
||||||
const text = await response.text();
|
throw new Error('Failed to fork session');
|
||||||
throw new Error(`Failed to fork session: ${text || response.statusText}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return response.json();
|
return response.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSessionStatus(): Promise<
|
async getSessionStatus(): Promise<
|
||||||
@@ -741,10 +732,11 @@ class OpencodeService {
|
|||||||
permissionId: string,
|
permissionId: string,
|
||||||
response: 'once' | 'always' | 'reject'
|
response: 'once' | 'always' | 'reject'
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const result = await this.client.postSessionIdPermissionsPermissionId({
|
const result = await this.client.permission.respond({
|
||||||
path: { id: sessionId, permissionID: permissionId },
|
sessionID: sessionId,
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined,
|
permissionID: permissionId,
|
||||||
body: { response }
|
...(this.currentDirectory ? { directory: this.currentDirectory } : {}),
|
||||||
|
response
|
||||||
});
|
});
|
||||||
return result.data || false;
|
return result.data || false;
|
||||||
}
|
}
|
||||||
@@ -800,9 +792,9 @@ class OpencodeService {
|
|||||||
providers: Provider[];
|
providers: Provider[];
|
||||||
default: { [key: string]: string };
|
default: { [key: string]: string };
|
||||||
}> {
|
}> {
|
||||||
const response = await this.client.config.providers({
|
const response = await this.client.config.providers(
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
||||||
});
|
);
|
||||||
if (!response.data) throw new Error('Failed to get providers');
|
if (!response.data) throw new Error('Failed to get providers');
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
@@ -829,9 +821,9 @@ class OpencodeService {
|
|||||||
// Agent Management
|
// Agent Management
|
||||||
async listAgents(): Promise<Agent[]> {
|
async listAgents(): Promise<Agent[]> {
|
||||||
try {
|
try {
|
||||||
const response = await this.client.app.agents({
|
const response = await this.client.app.agents(
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
||||||
});
|
);
|
||||||
return response.data || [];
|
return response.data || [];
|
||||||
} catch {
|
} catch {
|
||||||
return [];
|
return [];
|
||||||
@@ -868,17 +860,15 @@ class OpencodeService {
|
|||||||
|
|
||||||
const connect = async (attempt: number): Promise<void> => {
|
const connect = async (attempt: number): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
|
const subscribeParameters = resolvedDirectory ? { directory: resolvedDirectory } : undefined;
|
||||||
const subscribeOptions: {
|
const subscribeOptions: {
|
||||||
query?: { directory?: string };
|
|
||||||
signal: AbortSignal;
|
signal: AbortSignal;
|
||||||
sseDefaultRetryDelay: number;
|
sseDefaultRetryDelay: number;
|
||||||
sseMaxRetryDelay: number;
|
sseMaxRetryDelay: number;
|
||||||
onSseError?: (error: unknown) => void;
|
onSseError?: (error: unknown) => void;
|
||||||
onSseEvent: (event: StreamEvent<unknown>) => void;
|
onSseEvent: (event: StreamEvent<unknown>) => void;
|
||||||
headers?: Record<string, string>;
|
headers?: Record<string, string>;
|
||||||
lastEventId?: string;
|
|
||||||
} = {
|
} = {
|
||||||
query: resolvedDirectory ? { directory: resolvedDirectory } : undefined,
|
|
||||||
signal: abortController.signal,
|
signal: abortController.signal,
|
||||||
sseDefaultRetryDelay: 3000,
|
sseDefaultRetryDelay: 3000,
|
||||||
sseMaxRetryDelay: 30000,
|
sseMaxRetryDelay: 30000,
|
||||||
@@ -904,11 +894,10 @@ class OpencodeService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (lastEventId) {
|
if (lastEventId) {
|
||||||
subscribeOptions.lastEventId = lastEventId;
|
|
||||||
subscribeOptions.headers = { ...(subscribeOptions.headers || {}), 'Last-Event-ID': lastEventId };
|
subscribeOptions.headers = { ...(subscribeOptions.headers || {}), 'Last-Event-ID': lastEventId };
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await this.client.event.subscribe(subscribeOptions);
|
const result = await this.client.event.subscribe(subscribeParameters, subscribeOptions);
|
||||||
|
|
||||||
if (onOpen && !abortController.signal.aborted) {
|
if (onOpen && !abortController.signal.aborted) {
|
||||||
console.log('[OpencodeClient] SSE connection opened');
|
console.log('[OpencodeClient] SSE connection opened');
|
||||||
@@ -1019,9 +1008,9 @@ class OpencodeService {
|
|||||||
// Command Management
|
// Command Management
|
||||||
async listCommands(): Promise<Array<{ name: string; description?: string; agent?: string; model?: string }>> {
|
async listCommands(): Promise<Array<{ name: string; description?: string; agent?: string; model?: string }>> {
|
||||||
try {
|
try {
|
||||||
const response = await this.client.command.list({
|
const response = await this.client.command.list(
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
||||||
});
|
);
|
||||||
// Return only lightweight info for autocomplete
|
// Return only lightweight info for autocomplete
|
||||||
return (response.data || []).map((cmd: Record<string, unknown>) => ({
|
return (response.data || []).map((cmd: Record<string, unknown>) => ({
|
||||||
name: cmd.name as string,
|
name: cmd.name as string,
|
||||||
@@ -1037,9 +1026,9 @@ class OpencodeService {
|
|||||||
|
|
||||||
async listCommandsWithDetails(): Promise<Array<{ name: string; description?: string; agent?: string; model?: string; template?: string; subtask?: boolean }>> {
|
async listCommandsWithDetails(): Promise<Array<{ name: string; description?: string; agent?: string; model?: string; template?: string; subtask?: boolean }>> {
|
||||||
try {
|
try {
|
||||||
const response = await this.client.command.list({
|
const response = await this.client.command.list(
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
||||||
});
|
);
|
||||||
// Return full command details including template
|
// Return full command details including template
|
||||||
return (response.data || []).map((cmd: Record<string, unknown>) => ({
|
return (response.data || []).map((cmd: Record<string, unknown>) => ({
|
||||||
name: cmd.name as string,
|
name: cmd.name as string,
|
||||||
@@ -1056,9 +1045,9 @@ class OpencodeService {
|
|||||||
|
|
||||||
async getCommandDetails(name: string): Promise<{ name: string; template: string; description?: string; agent?: string; model?: string } | null> {
|
async getCommandDetails(name: string): Promise<{ name: string; template: string; description?: string; agent?: string; model?: string } | null> {
|
||||||
try {
|
try {
|
||||||
const response = await this.client.command.list({
|
const response = await this.client.command.list(
|
||||||
query: this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
this.currentDirectory ? { directory: this.currentDirectory } : undefined
|
||||||
});
|
);
|
||||||
|
|
||||||
if (response.data) {
|
if (response.data) {
|
||||||
const command = response.data.find((cmd: Record<string, unknown>) => cmd.name === name);
|
const command = response.data.find((cmd: Record<string, unknown>) => cmd.name === name);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Session } from '@opencode-ai/sdk';
|
import type { Session } from '@opencode-ai/sdk/v2';
|
||||||
import type { WorktreeMetadata } from '@/types/worktree';
|
import type { WorktreeMetadata } from '@/types/worktree';
|
||||||
|
|
||||||
export type SessionDeleteRequest = {
|
export type SessionDeleteRequest = {
|
||||||
|
|||||||
@@ -216,10 +216,8 @@ export const useFileStore = create<FileStore>()(
|
|||||||
const filename = lastSlashIndex > 0 ? path.substring(lastSlashIndex + 1) : path;
|
const filename = lastSlashIndex > 0 ? path.substring(lastSlashIndex + 1) : path;
|
||||||
|
|
||||||
const response = await tempClient.file.read({
|
const response = await tempClient.file.read({
|
||||||
query: {
|
|
||||||
path: filename,
|
path: filename,
|
||||||
directory: directory,
|
directory: directory,
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.data && "content" in response.data) {
|
if (response.data && "content" in response.data) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { devtools, persist, createJSONStorage } from "zustand/middleware";
|
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 { opencodeClient } from "@/lib/opencode/client";
|
||||||
import { isExecutionForkMetaText } from "@/lib/messages/executionMeta";
|
import { isExecutionForkMetaText } from "@/lib/messages/executionMeta";
|
||||||
import type { SessionMemoryState, MessageStreamLifecycle, AttachedFile } from "./types/sessionTypes";
|
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)}`;
|
const messageId = `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
||||||
|
|
||||||
await apiClient.session.init({
|
await apiClient.session.init({
|
||||||
path: { id: sessionId },
|
sessionID: sessionId,
|
||||||
body: {
|
...(directory ? { directory } : {}),
|
||||||
messageID: messageId,
|
messageID: messageId,
|
||||||
providerID,
|
providerID,
|
||||||
modelID,
|
modelID,
|
||||||
},
|
|
||||||
query: directory ? { directory } : undefined,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -600,12 +598,10 @@ export const useMessageStore = create<MessageStore>()(
|
|||||||
|
|
||||||
if (command === "summarize") {
|
if (command === "summarize") {
|
||||||
await apiClient.session.summarize({
|
await apiClient.session.summarize({
|
||||||
path: { id: sessionId },
|
sessionID: sessionId,
|
||||||
body: {
|
...(directory ? { directory } : {}),
|
||||||
providerID,
|
providerID,
|
||||||
modelID,
|
modelID,
|
||||||
},
|
|
||||||
query: directory ? { directory } : undefined,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { devtools, persist, createJSONStorage } from "zustand/middleware";
|
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 { opencodeClient } from "@/lib/opencode/client";
|
||||||
import { getSafeStorage } from "./utils/safeStorage";
|
import { getSafeStorage } from "./utils/safeStorage";
|
||||||
import type { WorktreeMetadata } from "@/types/worktree";
|
import type { WorktreeMetadata } from "@/types/worktree";
|
||||||
@@ -254,9 +254,9 @@ export const useSessionStore = create<SessionStore>()(
|
|||||||
const apiClient = opencodeClient.getApiClient();
|
const apiClient = opencodeClient.getApiClient();
|
||||||
|
|
||||||
const fetchSessions = async (directoryParam?: string | null): Promise<Session[]> => {
|
const fetchSessions = async (directoryParam?: string | null): Promise<Session[]> => {
|
||||||
const response = await apiClient.session.list({
|
const response = await apiClient.session.list(
|
||||||
query: directoryParam ? { directory: directoryParam } : undefined,
|
directoryParam ? { directory: directoryParam } : undefined
|
||||||
});
|
);
|
||||||
return Array.isArray(response.data) ? response.data : [];
|
return Array.isArray(response.data) ? response.data : [];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -536,9 +536,9 @@ export const useSessionStore = create<SessionStore>()(
|
|||||||
const attempts = 20;
|
const attempts = 20;
|
||||||
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
||||||
try {
|
try {
|
||||||
const response = await apiClient.session.list({
|
const response = await apiClient.session.list(
|
||||||
query: targetDirectory ? { directory: targetDirectory } : undefined,
|
targetDirectory ? { directory: targetDirectory } : undefined
|
||||||
});
|
);
|
||||||
const list = Array.isArray(response.data) ? response.data : [];
|
const list = Array.isArray(response.data) ? response.data : [];
|
||||||
const candidate = list.find((entry) => {
|
const candidate = list.find((entry) => {
|
||||||
if (existingIds.has(entry.id)) return false;
|
if (existingIds.has(entry.id)) return false;
|
||||||
@@ -817,8 +817,8 @@ export const useSessionStore = create<SessionStore>()(
|
|||||||
const shareRequest = async () => {
|
const shareRequest = async () => {
|
||||||
const directory = sessionDirectory ?? opencodeClient.getDirectory();
|
const directory = sessionDirectory ?? opencodeClient.getDirectory();
|
||||||
return apiClient.session.share({
|
return apiClient.session.share({
|
||||||
path: { id },
|
sessionID: id,
|
||||||
query: directory ? { directory } : undefined,
|
...(directory ? { directory } : {})
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const response = overrideDirectory
|
const response = overrideDirectory
|
||||||
@@ -849,8 +849,8 @@ export const useSessionStore = create<SessionStore>()(
|
|||||||
const unshareRequest = async () => {
|
const unshareRequest = async () => {
|
||||||
const directory = sessionDirectory ?? opencodeClient.getDirectory();
|
const directory = sessionDirectory ?? opencodeClient.getDirectory();
|
||||||
return apiClient.session.unshare({
|
return apiClient.session.unshare({
|
||||||
path: { id },
|
sessionID: id,
|
||||||
query: directory ? { directory } : undefined,
|
...(directory ? { directory } : {})
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const response = overrideDirectory
|
const response = overrideDirectory
|
||||||
|
|||||||
@@ -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";
|
import type { Permission, PermissionResponse } from "@/types/permission";
|
||||||
|
|
||||||
export interface AttachedFile {
|
export interface AttachedFile {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import type { StoreApi, UseBoundStore } from "zustand";
|
import type { StoreApi, UseBoundStore } from "zustand";
|
||||||
import { devtools, persist, createJSONStorage } from "zustand/middleware";
|
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 { opencodeClient } from "@/lib/opencode/client";
|
||||||
import { emitConfigChange, scopeMatches, subscribeToConfigChanges } from "@/lib/configSync";
|
import { emitConfigChange, scopeMatches, subscribeToConfigChanges } from "@/lib/configSync";
|
||||||
import {
|
import {
|
||||||
@@ -62,8 +62,10 @@ export type AgentWithExtras = Agent & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Helper to check if agent is built-in (handles both SDK 'builtIn' and API 'native')
|
// Helper to check if agent is built-in (handles both SDK 'builtIn' and API 'native')
|
||||||
export const isAgentBuiltIn = (agent: Agent): boolean =>
|
export const isAgentBuiltIn = (agent: Agent): boolean => {
|
||||||
agent.builtIn || (agent as AgentWithExtras).native === true;
|
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)
|
// 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)
|
// Checks both top-level hidden and options.hidden (OpenCode API inconsistency workaround)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import type { StoreApi, UseBoundStore } from "zustand";
|
import type { StoreApi, UseBoundStore } from "zustand";
|
||||||
import { devtools, persist, createJSONStorage } from "zustand/middleware";
|
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 { opencodeClient } from "@/lib/opencode/client";
|
||||||
import { scopeMatches, subscribeToConfigChanges } from "@/lib/configSync";
|
import { scopeMatches, subscribeToConfigChanges } from "@/lib/configSync";
|
||||||
import type { ModelMetadata } from "@/types";
|
import type { ModelMetadata } from "@/types";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import type { StoreApi, UseBoundStore } from "zustand";
|
import type { StoreApi, UseBoundStore } from "zustand";
|
||||||
import { devtools } from "zustand/middleware";
|
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 { Permission, PermissionResponse } from "@/types/permission";
|
||||||
import type { SessionStore, AttachedFile, EditPermissionMode } from "./types/sessionTypes";
|
import type { SessionStore, AttachedFile, EditPermissionMode } from "./types/sessionTypes";
|
||||||
import { ACTIVE_SESSION_WINDOW, MEMORY_LIMITS } from "./types/sessionTypes";
|
import { ACTIVE_SESSION_WINDOW, MEMORY_LIMITS } from "./types/sessionTypes";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Part } from "@opencode-ai/sdk";
|
import type { Part } from "@opencode-ai/sdk/v2";
|
||||||
|
|
||||||
const extractTextFromDelta = (delta: unknown): string => {
|
const extractTextFromDelta = (delta: unknown): string => {
|
||||||
if (!delta) return '';
|
if (!delta) return '';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Message, Part } from "@opencode-ai/sdk";
|
import type { Message, Part } from "@opencode-ai/sdk/v2";
|
||||||
|
|
||||||
type TokenBreakdown = {
|
type TokenBreakdown = {
|
||||||
input?: number;
|
input?: number;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Session, Message, Part, Provider } from "@opencode-ai/sdk";
|
import type { Session, Message, Part, Provider } from "@opencode-ai/sdk/v2";
|
||||||
|
|
||||||
export type { Session, Message, Part, Provider };
|
export type { Session, Message, Part, Provider };
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,12 @@ export default defineConfig({
|
|||||||
base: './', // Use relative paths for VS Code webview
|
base: './', // Use relative paths for VS Code webview
|
||||||
plugins: [react()],
|
plugins: [react()],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: [
|
||||||
'@': path.resolve(__dirname, '../ui/src'),
|
{ find: '@opencode-ai/sdk/v2', replacement: path.resolve(__dirname, '../../node_modules/@opencode-ai/sdk/dist/v2/client.js') },
|
||||||
'@vscode': path.resolve(__dirname, './webview'),
|
{ find: '@openchamber/ui', replacement: path.resolve(__dirname, '../ui/src') },
|
||||||
'@openchamber/ui': path.resolve(__dirname, '../ui/src'),
|
{ find: '@vscode', replacement: path.resolve(__dirname, './webview') },
|
||||||
'@opencode-ai/sdk': path.resolve(__dirname, '../../node_modules/@opencode-ai/sdk/dist/client.js'),
|
{ find: '@', replacement: path.resolve(__dirname, '../ui/src') },
|
||||||
},
|
],
|
||||||
},
|
},
|
||||||
worker: {
|
worker: {
|
||||||
format: 'es',
|
format: 'es',
|
||||||
@@ -26,7 +26,7 @@ export default defineConfig({
|
|||||||
},
|
},
|
||||||
envPrefix: ['VITE_'],
|
envPrefix: ['VITE_'],
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
include: ['@opencode-ai/sdk'],
|
include: ['@opencode-ai/sdk/v2'],
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
outDir: path.resolve(__dirname, 'dist/webview'),
|
outDir: path.resolve(__dirname, 'dist/webview'),
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ export default defineConfig({
|
|||||||
themeStoragePlugin(),
|
themeStoragePlugin(),
|
||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: [
|
||||||
'@': path.resolve(__dirname, '../ui/src'),
|
{ find: '@opencode-ai/sdk/v2', replacement: path.resolve(__dirname, '../../node_modules/@opencode-ai/sdk/dist/v2/client.js') },
|
||||||
'@web': path.resolve(__dirname, './src'),
|
{ find: '@openchamber/ui', replacement: path.resolve(__dirname, '../ui/src') },
|
||||||
'@openchamber/ui': path.resolve(__dirname, '../ui/src'),
|
{ find: '@web', replacement: path.resolve(__dirname, './src') },
|
||||||
'@opencode-ai/sdk': path.resolve(__dirname, '../../node_modules/@opencode-ai/sdk/dist/client.js'),
|
{ find: '@', replacement: path.resolve(__dirname, '../ui/src') },
|
||||||
},
|
],
|
||||||
},
|
},
|
||||||
worker: {
|
worker: {
|
||||||
format: 'es',
|
format: 'es',
|
||||||
@@ -31,7 +31,7 @@ export default defineConfig({
|
|||||||
__APP_VERSION__: JSON.stringify(packageJson.version),
|
__APP_VERSION__: JSON.stringify(packageJson.version),
|
||||||
},
|
},
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
include: ['@opencode-ai/sdk'],
|
include: ['@opencode-ai/sdk/v2'],
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
port: 5173,
|
port: 5173,
|
||||||
|
|||||||
+5
-5
@@ -12,10 +12,10 @@ export default defineConfig({
|
|||||||
themeStoragePlugin(),
|
themeStoragePlugin(),
|
||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: [
|
||||||
'@': path.resolve(__dirname, './src'),
|
{ find: '@opencode-ai/sdk/v2', replacement: path.resolve(__dirname, './node_modules/@opencode-ai/sdk/dist/v2/client.js') },
|
||||||
'@opencode-ai/sdk': path.resolve(__dirname, './node_modules/@opencode-ai/sdk/dist/client.js'),
|
{ find: '@', replacement: path.resolve(__dirname, './src') },
|
||||||
},
|
],
|
||||||
},
|
},
|
||||||
worker: {
|
worker: {
|
||||||
format: 'es',
|
format: 'es',
|
||||||
@@ -25,7 +25,7 @@ export default defineConfig({
|
|||||||
global: 'globalThis',
|
global: 'globalThis',
|
||||||
},
|
},
|
||||||
optimizeDeps: {
|
optimizeDeps: {
|
||||||
include: ['@opencode-ai/sdk'],
|
include: ['@opencode-ai/sdk/v2'],
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
chunkSizeWarningLimit: 1200,
|
chunkSizeWarningLimit: 1200,
|
||||||
|
|||||||
Reference in New Issue
Block a user