0,
+ }}
+ />
+
{mcpStats().enabled} MCP
+
+
+ )
+}
diff --git a/packages/app/src/components/session/session-context-breakdown.test.ts b/packages/app/src/components/session/session-context-breakdown.test.ts
index f38aecb55da9..f941f577a54a 100644
--- a/packages/app/src/components/session/session-context-breakdown.test.ts
+++ b/packages/app/src/components/session/session-context-breakdown.test.ts
@@ -1,5 +1,5 @@
import { describe, expect, test } from "bun:test"
-import type { Message, Part } from "@opencode-ai/sdk/v2/client"
+import type { Message, Part } from "@opencoder-ai/sdk/v2/client"
import { estimateSessionContextBreakdown } from "./session-context-breakdown"
const user = (id: string) => {
diff --git a/packages/app/src/components/session/session-context-breakdown.ts b/packages/app/src/components/session/session-context-breakdown.ts
index e263b2957b37..afa02c3540e7 100644
--- a/packages/app/src/components/session/session-context-breakdown.ts
+++ b/packages/app/src/components/session/session-context-breakdown.ts
@@ -1,4 +1,4 @@
-import type { Message, Part } from "@opencode-ai/sdk/v2/client"
+import type { Message, Part } from "@opencoder-ai/sdk/v2/client"
export type SessionContextBreakdownKey = "system" | "user" | "assistant" | "tool" | "other"
diff --git a/packages/app/src/components/session/session-context-metrics.test.ts b/packages/app/src/components/session/session-context-metrics.test.ts
index 0e109a71bdac..6cbd7af71cc7 100644
--- a/packages/app/src/components/session/session-context-metrics.test.ts
+++ b/packages/app/src/components/session/session-context-metrics.test.ts
@@ -1,5 +1,5 @@
import { describe, expect, test } from "bun:test"
-import type { Message } from "@opencode-ai/sdk/v2/client"
+import type { Message } from "@opencoder-ai/sdk/v2/client"
import { getSessionContextMetrics } from "./session-context-metrics"
const assistant = (
diff --git a/packages/app/src/components/session/session-context-metrics.ts b/packages/app/src/components/session/session-context-metrics.ts
index 0789b05f1730..e1507d20c9c3 100644
--- a/packages/app/src/components/session/session-context-metrics.ts
+++ b/packages/app/src/components/session/session-context-metrics.ts
@@ -1,4 +1,4 @@
-import type { AssistantMessage, Message } from "@opencode-ai/sdk/v2/client"
+import type { AssistantMessage, Message } from "@opencoder-ai/sdk/v2/client"
type Provider = {
id: string
diff --git a/packages/app/src/components/session/session-context-tab.tsx b/packages/app/src/components/session/session-context-tab.tsx
index 81220b3adb2f..4fc47f60458c 100644
--- a/packages/app/src/components/session/session-context-tab.tsx
+++ b/packages/app/src/components/session/session-context-tab.tsx
@@ -3,14 +3,14 @@ import type { JSX } from "solid-js"
import { useParams } from "@solidjs/router"
import { useSync } from "@/context/sync"
import { useLayout } from "@/context/layout"
-import { checksum } from "@opencode-ai/util/encode"
-import { findLast } from "@opencode-ai/util/array"
-import { Icon } from "@opencode-ai/ui/icon"
-import { Accordion } from "@opencode-ai/ui/accordion"
-import { StickyAccordionHeader } from "@opencode-ai/ui/sticky-accordion-header"
-import { Code } from "@opencode-ai/ui/code"
-import { Markdown } from "@opencode-ai/ui/markdown"
-import type { Message, Part, UserMessage } from "@opencode-ai/sdk/v2/client"
+import { checksum } from "@opencoder-ai/util/encode"
+import { findLast } from "@opencoder-ai/util/array"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { Accordion } from "@opencoder-ai/ui/accordion"
+import { StickyAccordionHeader } from "@opencoder-ai/ui/sticky-accordion-header"
+import { Code } from "@opencoder-ai/ui/code"
+import { Markdown } from "@opencoder-ai/ui/markdown"
+import type { Message, Part, UserMessage } from "@opencoder-ai/sdk/v2/client"
import { useLanguage } from "@/context/language"
import { getSessionContextMetrics } from "./session-context-metrics"
import { estimateSessionContextBreakdown, type SessionContextBreakdownKey } from "./session-context-breakdown"
diff --git a/packages/app/src/components/session/session-header.tsx b/packages/app/src/components/session/session-header.tsx
index b85b9a536a9d..f695a0533dc4 100644
--- a/packages/app/src/components/session/session-header.tsx
+++ b/packages/app/src/components/session/session-header.tsx
@@ -9,20 +9,20 @@ import { usePlatform } from "@/context/platform"
import { useServer } from "@/context/server"
import { useSync } from "@/context/sync"
import { useGlobalSDK } from "@/context/global-sdk"
-import { getFilename } from "@opencode-ai/util/path"
+import { getFilename } from "@opencoder-ai/util/path"
import { decode64 } from "@/utils/base64"
import { Persist, persisted } from "@/utils/persist"
-import { Icon } from "@opencode-ai/ui/icon"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { Button } from "@opencode-ai/ui/button"
-import { AppIcon } from "@opencode-ai/ui/app-icon"
-import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
-import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
-import { Popover } from "@opencode-ai/ui/popover"
-import { TextField } from "@opencode-ai/ui/text-field"
-import { Keybind } from "@opencode-ai/ui/keybind"
-import { showToast } from "@opencode-ai/ui/toast"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { Button } from "@opencoder-ai/ui/button"
+import { AppIcon } from "@opencoder-ai/ui/app-icon"
+import { DropdownMenu } from "@opencoder-ai/ui/dropdown-menu"
+import { Tooltip, TooltipKeybind } from "@opencoder-ai/ui/tooltip"
+import { Popover } from "@opencoder-ai/ui/popover"
+import { TextField } from "@opencoder-ai/ui/text-field"
+import { Keybind } from "@opencoder-ai/ui/keybind"
+import { showToast } from "@opencoder-ai/ui/toast"
import { StatusPopover } from "../status-popover"
const OPEN_APPS = [
diff --git a/packages/app/src/components/session/session-new-view.tsx b/packages/app/src/components/session/session-new-view.tsx
index ab96652d4499..a129f73d3539 100644
--- a/packages/app/src/components/session/session-new-view.tsx
+++ b/packages/app/src/components/session/session-new-view.tsx
@@ -3,8 +3,8 @@ import { DateTime } from "luxon"
import { useSync } from "@/context/sync"
import { useSDK } from "@/context/sdk"
import { useLanguage } from "@/context/language"
-import { Icon } from "@opencode-ai/ui/icon"
-import { getDirectory, getFilename } from "@opencode-ai/util/path"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { getDirectory, getFilename } from "@opencoder-ai/util/path"
const MAIN_WORKTREE = "main"
const CREATE_WORKTREE = "create"
diff --git a/packages/app/src/components/session/session-sortable-tab.tsx b/packages/app/src/components/session/session-sortable-tab.tsx
index b94e7a8e96cf..d06e33043107 100644
--- a/packages/app/src/components/session/session-sortable-tab.tsx
+++ b/packages/app/src/components/session/session-sortable-tab.tsx
@@ -1,11 +1,11 @@
import { createMemo, Show } from "solid-js"
import type { JSX } from "solid-js"
import { createSortable } from "@thisbeyond/solid-dnd"
-import { FileIcon } from "@opencode-ai/ui/file-icon"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { TooltipKeybind } from "@opencode-ai/ui/tooltip"
-import { Tabs } from "@opencode-ai/ui/tabs"
-import { getFilename } from "@opencode-ai/util/path"
+import { FileIcon } from "@opencoder-ai/ui/file-icon"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { TooltipKeybind } from "@opencoder-ai/ui/tooltip"
+import { Tabs } from "@opencoder-ai/ui/tabs"
+import { getFilename } from "@opencoder-ai/util/path"
import { useFile } from "@/context/file"
import { useLanguage } from "@/context/language"
import { useCommand } from "@/context/command"
diff --git a/packages/app/src/components/session/session-sortable-terminal-tab.tsx b/packages/app/src/components/session/session-sortable-terminal-tab.tsx
index 6fe6186d5102..5604480e1047 100644
--- a/packages/app/src/components/session/session-sortable-terminal-tab.tsx
+++ b/packages/app/src/components/session/session-sortable-terminal-tab.tsx
@@ -2,10 +2,10 @@ import type { JSX } from "solid-js"
import { Show, createEffect, onCleanup } from "solid-js"
import { createStore } from "solid-js/store"
import { createSortable } from "@thisbeyond/solid-dnd"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { Tabs } from "@opencode-ai/ui/tabs"
-import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
-import { Icon } from "@opencode-ai/ui/icon"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { Tabs } from "@opencoder-ai/ui/tabs"
+import { DropdownMenu } from "@opencoder-ai/ui/dropdown-menu"
+import { Icon } from "@opencoder-ai/ui/icon"
import { useTerminal, type LocalPTY } from "@/context/terminal"
import { useLanguage } from "@/context/language"
diff --git a/packages/app/src/components/settings-general.tsx b/packages/app/src/components/settings-general.tsx
index 439f542bb1cb..42d8c2075a3b 100644
--- a/packages/app/src/components/settings-general.tsx
+++ b/packages/app/src/components/settings-general.tsx
@@ -1,12 +1,12 @@
import { Component, Show, createMemo, createResource, type JSX } from "solid-js"
import { createStore } from "solid-js/store"
-import { Button } from "@opencode-ai/ui/button"
-import { Icon } from "@opencode-ai/ui/icon"
-import { Select } from "@opencode-ai/ui/select"
-import { Switch } from "@opencode-ai/ui/switch"
-import { Tooltip } from "@opencode-ai/ui/tooltip"
-import { useTheme, type ColorScheme } from "@opencode-ai/ui/theme"
-import { showToast } from "@opencode-ai/ui/toast"
+import { Button } from "@opencoder-ai/ui/button"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { Select } from "@opencoder-ai/ui/select"
+import { Switch } from "@opencoder-ai/ui/switch"
+import { Tooltip } from "@opencoder-ai/ui/tooltip"
+import { useTheme, type ColorScheme } from "@opencoder-ai/ui/theme"
+import { showToast } from "@opencoder-ai/ui/toast"
import { useLanguage } from "@/context/language"
import { usePlatform } from "@/context/platform"
import { useSettings, monoFontFamily } from "@/context/settings"
diff --git a/packages/app/src/components/settings-keybinds.tsx b/packages/app/src/components/settings-keybinds.tsx
index bcc731af99fb..27f5bfc6400b 100644
--- a/packages/app/src/components/settings-keybinds.tsx
+++ b/packages/app/src/components/settings-keybinds.tsx
@@ -1,10 +1,10 @@
import { Component, For, Show, createMemo, onCleanup, onMount } from "solid-js"
import { createStore } from "solid-js/store"
-import { Button } from "@opencode-ai/ui/button"
-import { Icon } from "@opencode-ai/ui/icon"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { TextField } from "@opencode-ai/ui/text-field"
-import { showToast } from "@opencode-ai/ui/toast"
+import { Button } from "@opencoder-ai/ui/button"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { TextField } from "@opencoder-ai/ui/text-field"
+import { showToast } from "@opencoder-ai/ui/toast"
import fuzzysort from "fuzzysort"
import { formatKeybind, parseKeybind, useCommand } from "@/context/command"
import { useLanguage } from "@/context/language"
diff --git a/packages/app/src/components/settings-models.tsx b/packages/app/src/components/settings-models.tsx
index 3a0b7a4fb1b3..fd58a1779607 100644
--- a/packages/app/src/components/settings-models.tsx
+++ b/packages/app/src/components/settings-models.tsx
@@ -1,10 +1,10 @@
-import { useFilteredList } from "@opencode-ai/ui/hooks"
-import { ProviderIcon } from "@opencode-ai/ui/provider-icon"
-import { Switch } from "@opencode-ai/ui/switch"
-import { Icon } from "@opencode-ai/ui/icon"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { TextField } from "@opencode-ai/ui/text-field"
-import type { IconName } from "@opencode-ai/ui/icons/provider"
+import { useFilteredList } from "@opencoder-ai/ui/hooks"
+import { ProviderIcon } from "@opencoder-ai/ui/provider-icon"
+import { Switch } from "@opencoder-ai/ui/switch"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { TextField } from "@opencoder-ai/ui/text-field"
+import type { IconName } from "@opencoder-ai/ui/icons/provider"
import { type Component, For, Show } from "solid-js"
import { useLanguage } from "@/context/language"
import { useModels } from "@/context/models"
diff --git a/packages/app/src/components/settings-permissions.tsx b/packages/app/src/components/settings-permissions.tsx
index 348854491ab2..4121bae07b99 100644
--- a/packages/app/src/components/settings-permissions.tsx
+++ b/packages/app/src/components/settings-permissions.tsx
@@ -1,5 +1,5 @@
-import { Select } from "@opencode-ai/ui/select"
-import { showToast } from "@opencode-ai/ui/toast"
+import { Select } from "@opencoder-ai/ui/select"
+import { showToast } from "@opencoder-ai/ui/toast"
import { Component, For, createMemo, type JSX } from "solid-js"
import { useGlobalSync } from "@/context/global-sync"
import { useLanguage } from "@/context/language"
diff --git a/packages/app/src/components/settings-providers.tsx b/packages/app/src/components/settings-providers.tsx
index a3375c9c608b..efe17c91f7ff 100644
--- a/packages/app/src/components/settings-providers.tsx
+++ b/packages/app/src/components/settings-providers.tsx
@@ -1,9 +1,9 @@
-import { Button } from "@opencode-ai/ui/button"
-import { useDialog } from "@opencode-ai/ui/context/dialog"
-import { ProviderIcon } from "@opencode-ai/ui/provider-icon"
-import { Tag } from "@opencode-ai/ui/tag"
-import { showToast } from "@opencode-ai/ui/toast"
-import { iconNames, type IconName } from "@opencode-ai/ui/icons/provider"
+import { Button } from "@opencoder-ai/ui/button"
+import { useDialog } from "@opencoder-ai/ui/context/dialog"
+import { ProviderIcon } from "@opencoder-ai/ui/provider-icon"
+import { Tag } from "@opencoder-ai/ui/tag"
+import { showToast } from "@opencoder-ai/ui/toast"
+import { iconNames, type IconName } from "@opencoder-ai/ui/icons/provider"
import { popularProviders, useProviders } from "@/hooks/use-providers"
import { createMemo, type Component, For, Show } from "solid-js"
import { useLanguage } from "@/context/language"
diff --git a/packages/app/src/components/status-popover.tsx b/packages/app/src/components/status-popover.tsx
index 38152b82314c..de9eb8002a44 100644
--- a/packages/app/src/components/status-popover.tsx
+++ b/packages/app/src/components/status-popover.tsx
@@ -1,13 +1,13 @@
import { createEffect, createMemo, createSignal, For, onCleanup, Show, type Accessor, type JSXElement } from "solid-js"
import { createStore, reconcile } from "solid-js/store"
import { useNavigate } from "@solidjs/router"
-import { useDialog } from "@opencode-ai/ui/context/dialog"
-import { Popover } from "@opencode-ai/ui/popover"
-import { Tabs } from "@opencode-ai/ui/tabs"
-import { Button } from "@opencode-ai/ui/button"
-import { Switch } from "@opencode-ai/ui/switch"
-import { Icon } from "@opencode-ai/ui/icon"
-import { showToast } from "@opencode-ai/ui/toast"
+import { useDialog } from "@opencoder-ai/ui/context/dialog"
+import { Popover } from "@opencoder-ai/ui/popover"
+import { Tabs } from "@opencoder-ai/ui/tabs"
+import { Button } from "@opencoder-ai/ui/button"
+import { Switch } from "@opencoder-ai/ui/switch"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { showToast } from "@opencoder-ai/ui/toast"
import { useSync } from "@/context/sync"
import { useSDK } from "@/context/sdk"
import { normalizeServerUrl, useServer } from "@/context/server"
diff --git a/packages/app/src/components/terminal.tsx b/packages/app/src/components/terminal.tsx
index ccf7012d20ab..fc9c9fdcee83 100644
--- a/packages/app/src/components/terminal.tsx
+++ b/packages/app/src/components/terminal.tsx
@@ -6,9 +6,9 @@ import { monoFontFamily, useSettings } from "@/context/settings"
import { parseKeybind, matchKeybind } from "@/context/command"
import { SerializeAddon } from "@/addons/serialize"
import { LocalPTY } from "@/context/terminal"
-import { resolveThemeVariant, useTheme, withAlpha, type HexColor } from "@opencode-ai/ui/theme"
+import { resolveThemeVariant, useTheme, withAlpha, type HexColor } from "@opencoder-ai/ui/theme"
import { useLanguage } from "@/context/language"
-import { showToast } from "@opencode-ai/ui/toast"
+import { showToast } from "@opencoder-ai/ui/toast"
import { disposeIfDisposable, getHoveredLinkText, setOptionIfSupported } from "@/utils/runtime-adapters"
import { terminalWriter } from "@/utils/terminal-writer"
diff --git a/packages/app/src/components/titlebar.tsx b/packages/app/src/components/titlebar.tsx
index 039a25faee80..7c873da0e78d 100644
--- a/packages/app/src/components/titlebar.tsx
+++ b/packages/app/src/components/titlebar.tsx
@@ -1,11 +1,11 @@
import { createEffect, createMemo, Show, untrack } from "solid-js"
import { createStore } from "solid-js/store"
import { useLocation, useNavigate } from "@solidjs/router"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { Icon } from "@opencode-ai/ui/icon"
-import { Button } from "@opencode-ai/ui/button"
-import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
-import { useTheme } from "@opencode-ai/ui/theme"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { Button } from "@opencoder-ai/ui/button"
+import { Tooltip, TooltipKeybind } from "@opencoder-ai/ui/tooltip"
+import { useTheme } from "@opencoder-ai/ui/theme"
import { useLayout } from "@/context/layout"
import { usePlatform } from "@/context/platform"
diff --git a/packages/app/src/context/command.tsx b/packages/app/src/context/command.tsx
index 237d7188467a..02993d7991ac 100644
--- a/packages/app/src/context/command.tsx
+++ b/packages/app/src/context/command.tsx
@@ -1,7 +1,7 @@
import { createEffect, createMemo, onCleanup, onMount, type Accessor } from "solid-js"
import { createStore } from "solid-js/store"
-import { createSimpleContext } from "@opencode-ai/ui/context"
-import { useDialog } from "@opencode-ai/ui/context/dialog"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
+import { useDialog } from "@opencoder-ai/ui/context/dialog"
import { useLanguage } from "@/context/language"
import { useSettings } from "@/context/settings"
import { Persist, persisted } from "@/utils/persist"
diff --git a/packages/app/src/context/comments.test.ts b/packages/app/src/context/comments.test.ts
index bee5c7871e07..afd9c3ff6464 100644
--- a/packages/app/src/context/comments.test.ts
+++ b/packages/app/src/context/comments.test.ts
@@ -9,7 +9,7 @@ beforeAll(async () => {
useNavigate: () => () => undefined,
useParams: () => ({}),
}))
- mock.module("@opencode-ai/ui/context", () => ({
+ mock.module("@opencoder-ai/ui/context", () => ({
createSimpleContext: () => ({
use: () => undefined,
provider: () => undefined,
diff --git a/packages/app/src/context/comments.tsx b/packages/app/src/context/comments.tsx
index ecf63e45b648..c952a993a9a8 100644
--- a/packages/app/src/context/comments.tsx
+++ b/packages/app/src/context/comments.tsx
@@ -1,6 +1,6 @@
import { batch, createMemo, createRoot, onCleanup } from "solid-js"
import { createStore, reconcile, type SetStoreFunction, type Store } from "solid-js/store"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { useParams } from "@solidjs/router"
import { Persist, persisted } from "@/utils/persist"
import { createScopedCache } from "@/utils/scoped-cache"
diff --git a/packages/app/src/context/file.tsx b/packages/app/src/context/file.tsx
index 99c6d2e4219d..d92803a3f6fe 100644
--- a/packages/app/src/context/file.tsx
+++ b/packages/app/src/context/file.tsx
@@ -1,9 +1,9 @@
import { batch, createEffect, createMemo, onCleanup } from "solid-js"
import { createStore, produce, reconcile } from "solid-js/store"
-import { createSimpleContext } from "@opencode-ai/ui/context"
-import { showToast } from "@opencode-ai/ui/toast"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
+import { showToast } from "@opencoder-ai/ui/toast"
import { useParams } from "@solidjs/router"
-import { getFilename } from "@opencode-ai/util/path"
+import { getFilename } from "@opencoder-ai/util/path"
import { useSDK } from "./sdk"
import { useSync } from "./sync"
import { useLanguage } from "@/context/language"
diff --git a/packages/app/src/context/file/content-cache.ts b/packages/app/src/context/file/content-cache.ts
index 4b724068834b..ca49360feb89 100644
--- a/packages/app/src/context/file/content-cache.ts
+++ b/packages/app/src/context/file/content-cache.ts
@@ -1,4 +1,4 @@
-import type { FileContent } from "@opencode-ai/sdk/v2"
+import type { FileContent } from "@opencoder-ai/sdk/v2"
const MAX_FILE_CONTENT_ENTRIES = 40
const MAX_FILE_CONTENT_BYTES = 20 * 1024 * 1024
diff --git a/packages/app/src/context/file/tree-store.ts b/packages/app/src/context/file/tree-store.ts
index a86051d286ec..6ae49a11d83e 100644
--- a/packages/app/src/context/file/tree-store.ts
+++ b/packages/app/src/context/file/tree-store.ts
@@ -1,5 +1,5 @@
import { createStore, produce, reconcile } from "solid-js/store"
-import type { FileNode } from "@opencode-ai/sdk/v2"
+import type { FileNode } from "@opencoder-ai/sdk/v2"
type DirectoryState = {
expanded: boolean
diff --git a/packages/app/src/context/file/types.ts b/packages/app/src/context/file/types.ts
index 7ce8a37c25e6..5fe9cbde9b12 100644
--- a/packages/app/src/context/file/types.ts
+++ b/packages/app/src/context/file/types.ts
@@ -1,4 +1,4 @@
-import type { FileContent } from "@opencode-ai/sdk/v2"
+import type { FileContent } from "@opencoder-ai/sdk/v2"
export type FileSelection = {
startLine: number
diff --git a/packages/app/src/context/file/watcher.ts b/packages/app/src/context/file/watcher.ts
index fbf71992791a..6de20720465a 100644
--- a/packages/app/src/context/file/watcher.ts
+++ b/packages/app/src/context/file/watcher.ts
@@ -1,4 +1,4 @@
-import type { FileNode } from "@opencode-ai/sdk/v2"
+import type { FileNode } from "@opencoder-ai/sdk/v2"
type WatcherEvent = {
type: string
diff --git a/packages/app/src/context/global-sdk.tsx b/packages/app/src/context/global-sdk.tsx
index 3f93b76a723c..39c5a26ad611 100644
--- a/packages/app/src/context/global-sdk.tsx
+++ b/packages/app/src/context/global-sdk.tsx
@@ -1,5 +1,5 @@
-import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2/client"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createOpencodeClient, type Event } from "@opencoder-ai/sdk/v2/client"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { createGlobalEmitter } from "@solid-primitives/event-bus"
import { batch, onCleanup } from "solid-js"
import { usePlatform } from "./platform"
diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx
index 62c7eb66ec9c..d47fd550a3b8 100644
--- a/packages/app/src/context/global-sync.tsx
+++ b/packages/app/src/context/global-sync.tsx
@@ -5,7 +5,7 @@ import {
type ProviderAuthResponse,
type ProviderListResponse,
createOpencodeClient,
-} from "@opencode-ai/sdk/v2/client"
+} from "@opencoder-ai/sdk/v2/client"
import { createStore, produce, reconcile } from "solid-js/store"
import { useGlobalSDK } from "./global-sdk"
import type { InitError } from "../pages/error"
@@ -21,8 +21,8 @@ import {
Switch,
Match,
} from "solid-js"
-import { showToast } from "@opencode-ai/ui/toast"
-import { getFilename } from "@opencode-ai/util/path"
+import { showToast } from "@opencoder-ai/ui/toast"
+import { getFilename } from "@opencoder-ai/util/path"
import { usePlatform } from "./platform"
import { useLanguage } from "@/context/language"
import { Persist, persisted } from "@/utils/persist"
diff --git a/packages/app/src/context/global-sync/bootstrap.ts b/packages/app/src/context/global-sync/bootstrap.ts
index 2137a19a823e..d585f77e4067 100644
--- a/packages/app/src/context/global-sync/bootstrap.ts
+++ b/packages/app/src/context/global-sync/bootstrap.ts
@@ -7,12 +7,12 @@ import {
type ProviderListResponse,
type QuestionRequest,
createOpencodeClient,
-} from "@opencode-ai/sdk/v2/client"
+} from "@opencoder-ai/sdk/v2/client"
import { batch } from "solid-js"
import { reconcile, type SetStoreFunction, type Store } from "solid-js/store"
-import { retry } from "@opencode-ai/util/retry"
-import { getFilename } from "@opencode-ai/util/path"
-import { showToast } from "@opencode-ai/ui/toast"
+import { retry } from "@opencoder-ai/util/retry"
+import { getFilename } from "@opencoder-ai/util/path"
+import { showToast } from "@opencoder-ai/ui/toast"
import { cmp, normalizeProviderList } from "./utils"
import type { State, VcsCache } from "./types"
diff --git a/packages/app/src/context/global-sync/child-store.ts b/packages/app/src/context/global-sync/child-store.ts
index af08c3bd431b..d06b14622df8 100644
--- a/packages/app/src/context/global-sync/child-store.ts
+++ b/packages/app/src/context/global-sync/child-store.ts
@@ -1,7 +1,7 @@
import { createRoot, createEffect, getOwner, onCleanup, runWithOwner, type Accessor, type Owner } from "solid-js"
import { createStore, type SetStoreFunction, type Store } from "solid-js/store"
import { Persist, persisted } from "@/utils/persist"
-import type { VcsInfo } from "@opencode-ai/sdk/v2/client"
+import type { VcsInfo } from "@opencoder-ai/sdk/v2/client"
import {
DIR_IDLE_TTL_MS,
MAX_DIR_STORES,
diff --git a/packages/app/src/context/global-sync/event-reducer.test.ts b/packages/app/src/context/global-sync/event-reducer.test.ts
index ad63f3c202eb..9ad8c681f56a 100644
--- a/packages/app/src/context/global-sync/event-reducer.test.ts
+++ b/packages/app/src/context/global-sync/event-reducer.test.ts
@@ -1,5 +1,5 @@
import { describe, expect, test } from "bun:test"
-import type { Message, Part, PermissionRequest, Project, QuestionRequest, Session } from "@opencode-ai/sdk/v2/client"
+import type { Message, Part, PermissionRequest, Project, QuestionRequest, Session } from "@opencoder-ai/sdk/v2/client"
import { createStore } from "solid-js/store"
import type { State } from "./types"
import { applyDirectoryEvent, applyGlobalEvent } from "./event-reducer"
diff --git a/packages/app/src/context/global-sync/event-reducer.ts b/packages/app/src/context/global-sync/event-reducer.ts
index fa1a43d4793f..8a39ffbde86f 100644
--- a/packages/app/src/context/global-sync/event-reducer.ts
+++ b/packages/app/src/context/global-sync/event-reducer.ts
@@ -1,4 +1,4 @@
-import { Binary } from "@opencode-ai/util/binary"
+import { Binary } from "@opencoder-ai/util/binary"
import { produce, reconcile, type SetStoreFunction, type Store } from "solid-js/store"
import type {
FileDiff,
@@ -10,7 +10,7 @@ import type {
Session,
SessionStatus,
Todo,
-} from "@opencode-ai/sdk/v2/client"
+} from "@opencoder-ai/sdk/v2/client"
import type { State, VcsCache } from "./types"
import { trimSessions } from "./session-trim"
diff --git a/packages/app/src/context/global-sync/session-trim.test.ts b/packages/app/src/context/global-sync/session-trim.test.ts
index be12c074b5dc..cd80c6dc52b3 100644
--- a/packages/app/src/context/global-sync/session-trim.test.ts
+++ b/packages/app/src/context/global-sync/session-trim.test.ts
@@ -1,5 +1,5 @@
import { describe, expect, test } from "bun:test"
-import type { PermissionRequest, Session } from "@opencode-ai/sdk/v2/client"
+import type { PermissionRequest, Session } from "@opencoder-ai/sdk/v2/client"
import { trimSessions } from "./session-trim"
const session = (input: { id: string; parentID?: string; created: number; updated?: number; archived?: number }) =>
diff --git a/packages/app/src/context/global-sync/session-trim.ts b/packages/app/src/context/global-sync/session-trim.ts
index 800ba74a6849..458b49607a69 100644
--- a/packages/app/src/context/global-sync/session-trim.ts
+++ b/packages/app/src/context/global-sync/session-trim.ts
@@ -1,4 +1,4 @@
-import type { PermissionRequest, Session } from "@opencode-ai/sdk/v2/client"
+import type { PermissionRequest, Session } from "@opencoder-ai/sdk/v2/client"
import { cmp } from "./utils"
import { SESSION_RECENT_LIMIT, SESSION_RECENT_WINDOW } from "./types"
diff --git a/packages/app/src/context/global-sync/types.ts b/packages/app/src/context/global-sync/types.ts
index ade0b973a2a5..bfab9d994301 100644
--- a/packages/app/src/context/global-sync/types.ts
+++ b/packages/app/src/context/global-sync/types.ts
@@ -16,7 +16,7 @@ import type {
SessionStatus,
Todo,
VcsInfo,
-} from "@opencode-ai/sdk/v2/client"
+} from "@opencoder-ai/sdk/v2/client"
import type { Accessor } from "solid-js"
import type { SetStoreFunction, Store } from "solid-js/store"
diff --git a/packages/app/src/context/global-sync/utils.ts b/packages/app/src/context/global-sync/utils.ts
index 6b78134a611b..2f9eab3f2e2c 100644
--- a/packages/app/src/context/global-sync/utils.ts
+++ b/packages/app/src/context/global-sync/utils.ts
@@ -1,4 +1,4 @@
-import type { Project, ProviderListResponse } from "@opencode-ai/sdk/v2/client"
+import type { Project, ProviderListResponse } from "@opencoder-ai/sdk/v2/client"
export const cmp = (a: string, b: string) => (a < b ? -1 : a > b ? 1 : 0)
diff --git a/packages/app/src/context/highlights.tsx b/packages/app/src/context/highlights.tsx
index 476209e41732..c6d9169391b0 100644
--- a/packages/app/src/context/highlights.tsx
+++ b/packages/app/src/context/highlights.tsx
@@ -1,7 +1,7 @@
import { createEffect, createSignal, onCleanup } from "solid-js"
import { createStore } from "solid-js/store"
-import { createSimpleContext } from "@opencode-ai/ui/context"
-import { useDialog } from "@opencode-ai/ui/context/dialog"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
+import { useDialog } from "@opencoder-ai/ui/context/dialog"
import { usePlatform } from "@/context/platform"
import { useSettings } from "@/context/settings"
import { persisted } from "@/utils/persist"
diff --git a/packages/app/src/context/language.tsx b/packages/app/src/context/language.tsx
index a5d894e62eba..b14c486e640d 100644
--- a/packages/app/src/context/language.tsx
+++ b/packages/app/src/context/language.tsx
@@ -1,7 +1,7 @@
import * as i18n from "@solid-primitives/i18n"
import { createEffect, createMemo } from "solid-js"
import { createStore } from "solid-js/store"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { Persist, persisted } from "@/utils/persist"
import { dict as en } from "@/i18n/en"
import { dict as zh } from "@/i18n/zh"
@@ -19,22 +19,22 @@ import { dict as no } from "@/i18n/no"
import { dict as br } from "@/i18n/br"
import { dict as th } from "@/i18n/th"
import { dict as bs } from "@/i18n/bs"
-import { dict as uiEn } from "@opencode-ai/ui/i18n/en"
-import { dict as uiZh } from "@opencode-ai/ui/i18n/zh"
-import { dict as uiZht } from "@opencode-ai/ui/i18n/zht"
-import { dict as uiKo } from "@opencode-ai/ui/i18n/ko"
-import { dict as uiDe } from "@opencode-ai/ui/i18n/de"
-import { dict as uiEs } from "@opencode-ai/ui/i18n/es"
-import { dict as uiFr } from "@opencode-ai/ui/i18n/fr"
-import { dict as uiDa } from "@opencode-ai/ui/i18n/da"
-import { dict as uiJa } from "@opencode-ai/ui/i18n/ja"
-import { dict as uiPl } from "@opencode-ai/ui/i18n/pl"
-import { dict as uiRu } from "@opencode-ai/ui/i18n/ru"
-import { dict as uiAr } from "@opencode-ai/ui/i18n/ar"
-import { dict as uiNo } from "@opencode-ai/ui/i18n/no"
-import { dict as uiBr } from "@opencode-ai/ui/i18n/br"
-import { dict as uiTh } from "@opencode-ai/ui/i18n/th"
-import { dict as uiBs } from "@opencode-ai/ui/i18n/bs"
+import { dict as uiEn } from "@opencoder-ai/ui/i18n/en"
+import { dict as uiZh } from "@opencoder-ai/ui/i18n/zh"
+import { dict as uiZht } from "@opencoder-ai/ui/i18n/zht"
+import { dict as uiKo } from "@opencoder-ai/ui/i18n/ko"
+import { dict as uiDe } from "@opencoder-ai/ui/i18n/de"
+import { dict as uiEs } from "@opencoder-ai/ui/i18n/es"
+import { dict as uiFr } from "@opencoder-ai/ui/i18n/fr"
+import { dict as uiDa } from "@opencoder-ai/ui/i18n/da"
+import { dict as uiJa } from "@opencoder-ai/ui/i18n/ja"
+import { dict as uiPl } from "@opencoder-ai/ui/i18n/pl"
+import { dict as uiRu } from "@opencoder-ai/ui/i18n/ru"
+import { dict as uiAr } from "@opencoder-ai/ui/i18n/ar"
+import { dict as uiNo } from "@opencoder-ai/ui/i18n/no"
+import { dict as uiBr } from "@opencoder-ai/ui/i18n/br"
+import { dict as uiTh } from "@opencoder-ai/ui/i18n/th"
+import { dict as uiBs } from "@opencoder-ai/ui/i18n/bs"
export type Locale =
| "en"
diff --git a/packages/app/src/context/layout.tsx b/packages/app/src/context/layout.tsx
index 71f0294e7e6c..dff5908378fd 100644
--- a/packages/app/src/context/layout.tsx
+++ b/packages/app/src/context/layout.tsx
@@ -1,11 +1,11 @@
import { createStore, produce } from "solid-js/store"
import { batch, createEffect, createMemo, onCleanup, onMount, type Accessor } from "solid-js"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { useGlobalSync } from "./global-sync"
import { useGlobalSDK } from "./global-sdk"
import { useServer } from "./server"
import { usePlatform } from "./platform"
-import { Project } from "@opencode-ai/sdk/v2"
+import { Project } from "@opencoder-ai/sdk/v2"
import { Persist, persisted, removePersisted } from "@/utils/persist"
import { same } from "@/utils/same"
import { createScrollPersistence, type SessionScroll } from "./layout-scroll"
diff --git a/packages/app/src/context/local.tsx b/packages/app/src/context/local.tsx
index ac5da60e8629..28606f655e8f 100644
--- a/packages/app/src/context/local.tsx
+++ b/packages/app/src/context/local.tsx
@@ -1,9 +1,9 @@
import { createStore } from "solid-js/store"
import { batch, createMemo } from "solid-js"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { useSDK } from "./sdk"
import { useSync } from "./sync"
-import { base64Encode } from "@opencode-ai/util/encode"
+import { base64Encode } from "@opencoder-ai/util/encode"
import { useProviders } from "@/hooks/use-providers"
import { useModels } from "@/context/models"
import { cycleModelVariant, getConfiguredAgentVariant, resolveModelVariant } from "./model-variant"
diff --git a/packages/app/src/context/models.tsx b/packages/app/src/context/models.tsx
index 12ec8371add1..6843d8d10677 100644
--- a/packages/app/src/context/models.tsx
+++ b/packages/app/src/context/models.tsx
@@ -2,7 +2,7 @@ import { createMemo } from "solid-js"
import { createStore } from "solid-js/store"
import { DateTime } from "luxon"
import { filter, firstBy, flat, groupBy, mapValues, pipe, uniqueBy, values } from "remeda"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { useProviders } from "@/hooks/use-providers"
import { Persist, persisted } from "@/utils/persist"
diff --git a/packages/app/src/context/notification.tsx b/packages/app/src/context/notification.tsx
index 04bc2fdaaaf3..e044fa48ddb1 100644
--- a/packages/app/src/context/notification.tsx
+++ b/packages/app/src/context/notification.tsx
@@ -1,16 +1,16 @@
import { createStore, reconcile } from "solid-js/store"
import { batch, createEffect, createMemo, onCleanup } from "solid-js"
import { useParams } from "@solidjs/router"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { useGlobalSDK } from "./global-sdk"
import { useGlobalSync } from "./global-sync"
import { usePlatform } from "@/context/platform"
import { useLanguage } from "@/context/language"
import { useSettings } from "@/context/settings"
-import { Binary } from "@opencode-ai/util/binary"
-import { base64Encode } from "@opencode-ai/util/encode"
+import { Binary } from "@opencoder-ai/util/binary"
+import { base64Encode } from "@opencoder-ai/util/encode"
import { decode64 } from "@/utils/base64"
-import { EventSessionError } from "@opencode-ai/sdk/v2"
+import { EventSessionError } from "@opencoder-ai/sdk/v2"
import { Persist, persisted } from "@/utils/persist"
import { playSound, soundSrc } from "@/utils/sound"
diff --git a/packages/app/src/context/permission.tsx b/packages/app/src/context/permission.tsx
index 988723834f95..46e774684c28 100644
--- a/packages/app/src/context/permission.tsx
+++ b/packages/app/src/context/permission.tsx
@@ -1,12 +1,12 @@
import { createMemo, onCleanup } from "solid-js"
import { createStore, produce } from "solid-js/store"
-import { createSimpleContext } from "@opencode-ai/ui/context"
-import type { PermissionRequest } from "@opencode-ai/sdk/v2/client"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
+import type { PermissionRequest } from "@opencoder-ai/sdk/v2/client"
import { Persist, persisted } from "@/utils/persist"
import { useGlobalSDK } from "@/context/global-sdk"
import { useGlobalSync } from "./global-sync"
import { useParams } from "@solidjs/router"
-import { base64Encode } from "@opencode-ai/util/encode"
+import { base64Encode } from "@opencoder-ai/util/encode"
import { decode64 } from "@/utils/base64"
type PermissionRespondFn = (input: {
diff --git a/packages/app/src/context/platform.tsx b/packages/app/src/context/platform.tsx
index 6d4464258a06..5aa27c10c95e 100644
--- a/packages/app/src/context/platform.tsx
+++ b/packages/app/src/context/platform.tsx
@@ -1,4 +1,4 @@
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { AsyncStorage, SyncStorage } from "@solid-primitives/storage"
import type { Accessor } from "solid-js"
diff --git a/packages/app/src/context/prompt.tsx b/packages/app/src/context/prompt.tsx
index 064892105184..9ca5f1c026ac 100644
--- a/packages/app/src/context/prompt.tsx
+++ b/packages/app/src/context/prompt.tsx
@@ -1,10 +1,10 @@
import { createStore, type SetStoreFunction } from "solid-js/store"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { batch, createMemo, createRoot, onCleanup } from "solid-js"
import { useParams } from "@solidjs/router"
import type { FileSelection } from "@/context/file"
import { Persist, persisted } from "@/utils/persist"
-import { checksum } from "@opencode-ai/util/encode"
+import { checksum } from "@opencoder-ai/util/encode"
interface PartBase {
content: string
diff --git a/packages/app/src/context/sdk.tsx b/packages/app/src/context/sdk.tsx
index 555933619af2..37865d7ad547 100644
--- a/packages/app/src/context/sdk.tsx
+++ b/packages/app/src/context/sdk.tsx
@@ -1,5 +1,5 @@
-import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2/client"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createOpencodeClient, type Event } from "@opencoder-ai/sdk/v2/client"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { createGlobalEmitter } from "@solid-primitives/event-bus"
import { createEffect, createMemo, onCleanup, type Accessor } from "solid-js"
import { useGlobalSDK } from "./global-sdk"
diff --git a/packages/app/src/context/server.tsx b/packages/app/src/context/server.tsx
index 5d3d0cf3aa6c..a9088916251a 100644
--- a/packages/app/src/context/server.tsx
+++ b/packages/app/src/context/server.tsx
@@ -1,4 +1,4 @@
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { batch, createEffect, createMemo, onCleanup } from "solid-js"
import { createStore } from "solid-js/store"
import { usePlatform } from "@/context/platform"
diff --git a/packages/app/src/context/settings.tsx b/packages/app/src/context/settings.tsx
index d72d4ceb1ec9..2c611a695b0e 100644
--- a/packages/app/src/context/settings.tsx
+++ b/packages/app/src/context/settings.tsx
@@ -1,6 +1,6 @@
import { createStore, reconcile } from "solid-js/store"
import { createEffect, createMemo } from "solid-js"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { persisted } from "@/utils/persist"
export interface NotificationSettings {
diff --git a/packages/app/src/context/sync-optimistic.test.ts b/packages/app/src/context/sync-optimistic.test.ts
index 7deeddd6ee61..0c19568128b1 100644
--- a/packages/app/src/context/sync-optimistic.test.ts
+++ b/packages/app/src/context/sync-optimistic.test.ts
@@ -1,5 +1,5 @@
import { describe, expect, test } from "bun:test"
-import type { Message, Part } from "@opencode-ai/sdk/v2/client"
+import type { Message, Part } from "@opencoder-ai/sdk/v2/client"
import { applyOptimisticAdd, applyOptimisticRemove } from "./sync"
const userMessage = (id: string, sessionID: string): Message => ({
diff --git a/packages/app/src/context/sync.tsx b/packages/app/src/context/sync.tsx
index e5916598b52d..bc9fe3311996 100644
--- a/packages/app/src/context/sync.tsx
+++ b/packages/app/src/context/sync.tsx
@@ -1,11 +1,11 @@
import { batch, createMemo } from "solid-js"
import { createStore, produce, reconcile } from "solid-js/store"
-import { Binary } from "@opencode-ai/util/binary"
-import { retry } from "@opencode-ai/util/retry"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { Binary } from "@opencoder-ai/util/binary"
+import { retry } from "@opencoder-ai/util/retry"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { useGlobalSync } from "./global-sync"
import { useSDK } from "./sdk"
-import type { Message, Part } from "@opencode-ai/sdk/v2/client"
+import type { Message, Part } from "@opencoder-ai/sdk/v2/client"
function sortParts(parts: Part[]) {
return parts.filter((part) => !!part?.id).sort((a, b) => cmp(a.id, b.id))
@@ -293,7 +293,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
const key = keyFor(directory, sessionID)
return runInflight(inflightTodo, key, () =>
- retry(() => client.session.todo({ sessionID })).then((todo) => {
+ retry(() => client.session.todo.list({ sessionID })).then((todo) => {
setStore("todo", sessionID, reconcile(todo.data ?? [], { key: "id" }))
}),
)
diff --git a/packages/app/src/context/terminal.test.ts b/packages/app/src/context/terminal.test.ts
index a250de57c0de..ace9f6b417e6 100644
--- a/packages/app/src/context/terminal.test.ts
+++ b/packages/app/src/context/terminal.test.ts
@@ -8,7 +8,7 @@ beforeAll(async () => {
useNavigate: () => () => undefined,
useParams: () => ({}),
}))
- mock.module("@opencode-ai/ui/context", () => ({
+ mock.module("@opencoder-ai/ui/context", () => ({
createSimpleContext: () => ({
use: () => undefined,
provider: () => undefined,
diff --git a/packages/app/src/context/terminal.tsx b/packages/app/src/context/terminal.tsx
index 64f026219ab9..3724ad136663 100644
--- a/packages/app/src/context/terminal.tsx
+++ b/packages/app/src/context/terminal.tsx
@@ -1,5 +1,5 @@
import { createStore, produce } from "solid-js/store"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { batch, createEffect, createMemo, createRoot, onCleanup } from "solid-js"
import { useParams } from "@solidjs/router"
import { useSDK } from "./sdk"
diff --git a/packages/app/src/i18n/ar.ts b/packages/app/src/i18n/ar.ts
index e3792a3c3cc3..5962f82bd3a2 100644
--- a/packages/app/src/i18n/ar.ts
+++ b/packages/app/src/i18n/ar.ts
@@ -38,6 +38,7 @@ export const dict = {
"command.language.set": "استخدام اللغة: {{language}}",
"command.session.new": "جلسة جديدة",
"command.file.open": "فتح ملف",
+ "command.file.open.description": "فتح ملف",
"command.tab.close": "إغلاق علامة التبويب",
"command.context.addSelection": "إضافة التحديد إلى السياق",
"command.context.addSelection.description": "إضافة الأسطر المحددة من الملف الحالي",
diff --git a/packages/app/src/i18n/br.ts b/packages/app/src/i18n/br.ts
index 07d6ce467aeb..8654255fee5c 100644
--- a/packages/app/src/i18n/br.ts
+++ b/packages/app/src/i18n/br.ts
@@ -38,6 +38,7 @@ export const dict = {
"command.language.set": "Usar idioma: {{language}}",
"command.session.new": "Nova sessão",
"command.file.open": "Abrir arquivo",
+ "command.file.open.description": "Abrir arquivo",
"command.tab.close": "Fechar aba",
"command.context.addSelection": "Adicionar seleção ao contexto",
"command.context.addSelection.description": "Adicionar as linhas selecionadas do arquivo atual",
diff --git a/packages/app/src/i18n/da.ts b/packages/app/src/i18n/da.ts
index ac5c4d494b12..b6191c04c011 100644
--- a/packages/app/src/i18n/da.ts
+++ b/packages/app/src/i18n/da.ts
@@ -44,6 +44,7 @@ export const dict = {
"command.session.new": "Ny session",
"command.file.open": "Åbn fil",
+ "command.file.open.description": "Åbn fil",
"command.tab.close": "Luk fane",
"command.context.addSelection": "Tilføj markering til kontekst",
"command.context.addSelection.description": "Tilføj markerede linjer fra den aktuelle fil",
diff --git a/packages/app/src/i18n/de.ts b/packages/app/src/i18n/de.ts
index 99a950631074..cdfbf4f8f1db 100644
--- a/packages/app/src/i18n/de.ts
+++ b/packages/app/src/i18n/de.ts
@@ -42,6 +42,7 @@ export const dict = {
"command.language.set": "Sprache verwenden: {{language}}",
"command.session.new": "Neue Sitzung",
"command.file.open": "Datei öffnen",
+ "command.file.open.description": "Datei öffnen",
"command.tab.close": "Tab schließen",
"command.context.addSelection": "Auswahl zum Kontext hinzufügen",
"command.context.addSelection.description": "Ausgewählte Zeilen aus der aktuellen Datei hinzufügen",
diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts
index 99513edaa173..38c0f170cdc2 100644
--- a/packages/app/src/i18n/en.ts
+++ b/packages/app/src/i18n/en.ts
@@ -44,6 +44,7 @@ export const dict = {
"command.session.new": "New session",
"command.file.open": "Open file",
+ "command.file.open.description": "Open file",
"command.tab.close": "Close tab",
"command.context.addSelection": "Add selection to context",
"command.context.addSelection.description": "Add selected lines from the current file",
diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts
index 7a6c4974e091..ae149d9dcd78 100644
--- a/packages/app/src/i18n/es.ts
+++ b/packages/app/src/i18n/es.ts
@@ -44,6 +44,7 @@ export const dict = {
"command.session.new": "Nueva sesión",
"command.file.open": "Abrir archivo",
+ "command.file.open.description": "Abrir archivo",
"command.tab.close": "Cerrar pestaña",
"command.context.addSelection": "Añadir selección al contexto",
"command.context.addSelection.description": "Añadir las líneas seleccionadas del archivo actual",
diff --git a/packages/app/src/i18n/fr.ts b/packages/app/src/i18n/fr.ts
index fc3bf2667943..498159e461ac 100644
--- a/packages/app/src/i18n/fr.ts
+++ b/packages/app/src/i18n/fr.ts
@@ -38,6 +38,7 @@ export const dict = {
"command.language.set": "Utiliser la langue : {{language}}",
"command.session.new": "Nouvelle session",
"command.file.open": "Ouvrir un fichier",
+ "command.file.open.description": "Ouvrir un fichier",
"command.tab.close": "Fermer l'onglet",
"command.context.addSelection": "Ajouter la sélection au contexte",
"command.context.addSelection.description": "Ajouter les lignes sélectionnées du fichier actuel",
diff --git a/packages/app/src/i18n/ja.ts b/packages/app/src/i18n/ja.ts
index b597db02a586..148fa70b752f 100644
--- a/packages/app/src/i18n/ja.ts
+++ b/packages/app/src/i18n/ja.ts
@@ -38,6 +38,7 @@ export const dict = {
"command.language.set": "言語を使用: {{language}}",
"command.session.new": "新しいセッション",
"command.file.open": "ファイルを開く",
+ "command.file.open.description": "ファイルを開く",
"command.tab.close": "タブを閉じる",
"command.context.addSelection": "選択範囲をコンテキストに追加",
"command.context.addSelection.description": "現在のファイルから選択した行を追加",
diff --git a/packages/app/src/i18n/ko.ts b/packages/app/src/i18n/ko.ts
index 525bd035651f..fb4a3a912df5 100644
--- a/packages/app/src/i18n/ko.ts
+++ b/packages/app/src/i18n/ko.ts
@@ -42,6 +42,7 @@ export const dict = {
"command.language.set": "언어 사용: {{language}}",
"command.session.new": "새 세션",
"command.file.open": "파일 열기",
+ "command.file.open.description": "파일 열기",
"command.tab.close": "탭 닫기",
"command.context.addSelection": "선택 영역을 컨텍스트에 추가",
"command.context.addSelection.description": "현재 파일에서 선택한 줄을 추가",
diff --git a/packages/app/src/i18n/no.ts b/packages/app/src/i18n/no.ts
index 98e79e1896af..f9e70c31bba3 100644
--- a/packages/app/src/i18n/no.ts
+++ b/packages/app/src/i18n/no.ts
@@ -47,6 +47,7 @@ export const dict = {
"command.session.new": "Ny sesjon",
"command.file.open": "Åpne fil",
+ "command.file.open.description": "Åpne fil",
"command.tab.close": "Lukk fane",
"command.context.addSelection": "Legg til markering i kontekst",
"command.context.addSelection.description": "Legg til valgte linjer fra gjeldende fil",
diff --git a/packages/app/src/i18n/pl.ts b/packages/app/src/i18n/pl.ts
index 983c9c14ac1b..e16e1894ef9f 100644
--- a/packages/app/src/i18n/pl.ts
+++ b/packages/app/src/i18n/pl.ts
@@ -38,6 +38,7 @@ export const dict = {
"command.language.set": "Użyj języka: {{language}}",
"command.session.new": "Nowa sesja",
"command.file.open": "Otwórz plik",
+ "command.file.open.description": "Otwórz plik",
"command.tab.close": "Zamknij kartę",
"command.context.addSelection": "Dodaj zaznaczenie do kontekstu",
"command.context.addSelection.description": "Dodaj zaznaczone linie z bieżącego pliku",
diff --git a/packages/app/src/i18n/ru.ts b/packages/app/src/i18n/ru.ts
index f2c87fe0f1ed..82ae7fb75d15 100644
--- a/packages/app/src/i18n/ru.ts
+++ b/packages/app/src/i18n/ru.ts
@@ -44,6 +44,7 @@ export const dict = {
"command.session.new": "Новая сессия",
"command.file.open": "Открыть файл",
+ "command.file.open.description": "Открыть файл",
"command.tab.close": "Закрыть вкладку",
"command.context.addSelection": "Добавить выделение в контекст",
"command.context.addSelection.description": "Добавить выбранные строки из текущего файла",
diff --git a/packages/app/src/i18n/th.ts b/packages/app/src/i18n/th.ts
index 689e82118968..8a3a022e9f17 100644
--- a/packages/app/src/i18n/th.ts
+++ b/packages/app/src/i18n/th.ts
@@ -44,6 +44,7 @@ export const dict = {
"command.session.new": "เซสชันใหม่",
"command.file.open": "เปิดไฟล์",
+ "command.file.open.description": "เปิดไฟล์",
"command.tab.close": "ปิดแท็บ",
"command.context.addSelection": "เพิ่มส่วนที่เลือกไปยังบริบท",
"command.context.addSelection.description": "เพิ่มบรรทัดที่เลือกจากไฟล์ปัจจุบัน",
diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts
index 1b40013b60de..9e8e00b68955 100644
--- a/packages/app/src/i18n/zh.ts
+++ b/packages/app/src/i18n/zh.ts
@@ -54,7 +54,7 @@ export const dict = {
"command.session.new": "新建会话",
"command.file.open": "打开文件",
-
+ "command.file.open.description": "打开文件",
"command.tab.close": "关闭标签页",
"command.context.addSelection": "将所选内容添加到上下文",
diff --git a/packages/app/src/i18n/zht.ts b/packages/app/src/i18n/zht.ts
index 34aec01b9cb1..899bf80d652d 100644
--- a/packages/app/src/i18n/zht.ts
+++ b/packages/app/src/i18n/zht.ts
@@ -48,6 +48,7 @@ export const dict = {
"command.session.new": "新增工作階段",
"command.file.open": "開啟檔案",
+ "command.file.open.description": "開啟檔案",
"command.tab.close": "關閉分頁",
"command.context.addSelection": "將選取內容加入上下文",
"command.context.addSelection.description": "加入目前檔案中選取的行",
diff --git a/packages/app/src/index.css b/packages/app/src/index.css
index 4af87bca632a..6f75ae260c0c 100644
--- a/packages/app/src/index.css
+++ b/packages/app/src/index.css
@@ -1 +1,57 @@
-@import "@opencode-ai/ui/styles/tailwind";
+@import "@opencoder-ai/ui/styles/tailwind";
+
+:root {
+ a {
+ cursor: default;
+ }
+}
+
+[data-component="markdown"] ul {
+ list-style: disc outside;
+ padding-left: 1.5rem;
+}
+
+[data-component="markdown"] ol {
+ list-style: decimal outside;
+ padding-left: 1.5rem;
+}
+
+[data-component="markdown"] li > p:first-child {
+ display: inline;
+ margin: 0;
+}
+
+[data-component="markdown"] li > p + p {
+ display: block;
+ margin-top: 0.5rem;
+}
+
+*[data-tauri-drag-region] {
+ app-region: drag;
+}
+
+.session-scroller::-webkit-scrollbar {
+ width: 10px !important;
+ height: 10px !important;
+}
+
+.session-scroller::-webkit-scrollbar-track {
+ background: transparent !important;
+ border-radius: 5px !important;
+}
+
+.session-scroller::-webkit-scrollbar-thumb {
+ background: var(--border-weak-base) !important;
+ border-radius: 5px !important;
+ border: 3px solid transparent !important;
+ background-clip: padding-box !important;
+}
+
+.session-scroller::-webkit-scrollbar-thumb:hover {
+ background: var(--border-weak-base) !important;
+}
+
+.session-scroller {
+ scrollbar-width: thin !important;
+ scrollbar-color: var(--border-weak-base) transparent !important;
+}
diff --git a/packages/app/src/pages/directory-layout.tsx b/packages/app/src/pages/directory-layout.tsx
index 2dee09dfb06c..c6891f18c7d7 100644
--- a/packages/app/src/pages/directory-layout.tsx
+++ b/packages/app/src/pages/directory-layout.tsx
@@ -5,10 +5,10 @@ import { SDKProvider, useSDK } from "@/context/sdk"
import { SyncProvider, useSync } from "@/context/sync"
import { LocalProvider } from "@/context/local"
-import { DataProvider } from "@opencode-ai/ui/context"
-import type { QuestionAnswer } from "@opencode-ai/sdk/v2"
+import { DataProvider } from "@opencoder-ai/ui/context"
+import type { QuestionAnswer } from "@opencoder-ai/sdk/v2"
import { decode64 } from "@/utils/base64"
-import { showToast } from "@opencode-ai/ui/toast"
+import { showToast } from "@opencoder-ai/ui/toast"
import { useLanguage } from "@/context/language"
function DirectoryDataProvider(props: ParentProps<{ directory: string }>) {
diff --git a/packages/app/src/pages/error.tsx b/packages/app/src/pages/error.tsx
index a30d86d18093..75b08ae7a496 100644
--- a/packages/app/src/pages/error.tsx
+++ b/packages/app/src/pages/error.tsx
@@ -1,11 +1,11 @@
-import { TextField } from "@opencode-ai/ui/text-field"
-import { Logo } from "@opencode-ai/ui/logo"
-import { Button } from "@opencode-ai/ui/button"
+import { TextField } from "@opencoder-ai/ui/text-field"
+import { Logo } from "@opencoder-ai/ui/logo"
+import { Button } from "@opencoder-ai/ui/button"
import { Component, Show } from "solid-js"
import { createStore } from "solid-js/store"
import { usePlatform } from "@/context/platform"
import { useLanguage } from "@/context/language"
-import { Icon } from "@opencode-ai/ui/icon"
+import { Icon } from "@opencoder-ai/ui/icon"
export type InitError = {
name: string
diff --git a/packages/app/src/pages/home.tsx b/packages/app/src/pages/home.tsx
index ba3a2b942708..c3467eb6757a 100644
--- a/packages/app/src/pages/home.tsx
+++ b/packages/app/src/pages/home.tsx
@@ -1,13 +1,13 @@
import { createMemo, For, Match, Switch } from "solid-js"
-import { Button } from "@opencode-ai/ui/button"
-import { Logo } from "@opencode-ai/ui/logo"
+import { Button } from "@opencoder-ai/ui/button"
+import { Logo } from "@opencoder-ai/ui/logo"
import { useLayout } from "@/context/layout"
import { useNavigate } from "@solidjs/router"
-import { base64Encode } from "@opencode-ai/util/encode"
-import { Icon } from "@opencode-ai/ui/icon"
+import { base64Encode } from "@opencoder-ai/util/encode"
+import { Icon } from "@opencoder-ai/ui/icon"
import { usePlatform } from "@/context/platform"
import { DateTime } from "luxon"
-import { useDialog } from "@opencode-ai/ui/context/dialog"
+import { useDialog } from "@opencoder-ai/ui/context/dialog"
import { DialogSelectDirectory } from "@/components/dialog-select-directory"
import { DialogSelectServer } from "@/components/dialog-select-server"
import { useServer } from "@/context/server"
diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx
index 7eb064f425d9..49aae68c6821 100644
--- a/packages/app/src/pages/layout.tsx
+++ b/packages/app/src/pages/layout.tsx
@@ -16,36 +16,36 @@ import { A, useNavigate, useParams } from "@solidjs/router"
import { useLayout, LocalProject } from "@/context/layout"
import { useGlobalSync } from "@/context/global-sync"
import { Persist, persisted } from "@/utils/persist"
-import { base64Encode } from "@opencode-ai/util/encode"
+import { base64Encode } from "@opencoder-ai/util/encode"
import { decode64 } from "@/utils/base64"
-import { ResizeHandle } from "@opencode-ai/ui/resize-handle"
-import { Button } from "@opencode-ai/ui/button"
-import { Icon } from "@opencode-ai/ui/icon"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
-import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
-import { Dialog } from "@opencode-ai/ui/dialog"
-import { getFilename } from "@opencode-ai/util/path"
-import { Session, type Message } from "@opencode-ai/sdk/v2/client"
+import { ResizeHandle } from "@opencoder-ai/ui/resize-handle"
+import { Button } from "@opencoder-ai/ui/button"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { Tooltip, TooltipKeybind } from "@opencoder-ai/ui/tooltip"
+import { DropdownMenu } from "@opencoder-ai/ui/dropdown-menu"
+import { Dialog } from "@opencoder-ai/ui/dialog"
+import { getFilename } from "@opencoder-ai/util/path"
+import { Session, type Message } from "@opencoder-ai/sdk/v2/client"
import { usePlatform } from "@/context/platform"
import { useSettings } from "@/context/settings"
import { createStore, produce, reconcile } from "solid-js/store"
import { DragDropProvider, DragDropSensors, DragOverlay, SortableProvider, closestCenter } from "@thisbeyond/solid-dnd"
import type { DragEvent } from "@thisbeyond/solid-dnd"
import { useProviders } from "@/hooks/use-providers"
-import { showToast, Toast, toaster } from "@opencode-ai/ui/toast"
+import { showToast, Toast, toaster } from "@opencoder-ai/ui/toast"
import { useGlobalSDK } from "@/context/global-sdk"
import { clearWorkspaceTerminals } from "@/context/terminal"
import { useNotification } from "@/context/notification"
import { usePermission } from "@/context/permission"
-import { Binary } from "@opencode-ai/util/binary"
-import { retry } from "@opencode-ai/util/retry"
+import { Binary } from "@opencoder-ai/util/binary"
+import { retry } from "@opencoder-ai/util/retry"
import { playSound, soundSrc } from "@/utils/sound"
import { createAim } from "@/utils/aim"
import { Worktree as WorktreeState } from "@/utils/worktree"
-import { useDialog } from "@opencode-ai/ui/context/dialog"
-import { useTheme, type ColorScheme } from "@opencode-ai/ui/theme"
+import { useDialog } from "@opencoder-ai/ui/context/dialog"
+import { useTheme, type ColorScheme } from "@opencoder-ai/ui/theme"
import { DialogSelectProvider } from "@/components/dialog-select-provider"
import { DialogSelectServer } from "@/components/dialog-select-server"
import { DialogSettings } from "@/components/dialog-settings"
diff --git a/packages/app/src/pages/layout/helpers.ts b/packages/app/src/pages/layout/helpers.ts
index 6a1e7c0123d8..0aa971298b1d 100644
--- a/packages/app/src/pages/layout/helpers.ts
+++ b/packages/app/src/pages/layout/helpers.ts
@@ -1,5 +1,5 @@
-import { getFilename } from "@opencode-ai/util/path"
-import { type Session } from "@opencode-ai/sdk/v2/client"
+import { getFilename } from "@opencoder-ai/util/path"
+import { type Session } from "@opencoder-ai/sdk/v2/client"
export const workspaceKey = (directory: string) => {
const drive = directory.match(/^([A-Za-z]:)[\\/]+$/)
diff --git a/packages/app/src/pages/layout/inline-editor.tsx b/packages/app/src/pages/layout/inline-editor.tsx
index 4189e4a72a08..85d1622b2e28 100644
--- a/packages/app/src/pages/layout/inline-editor.tsx
+++ b/packages/app/src/pages/layout/inline-editor.tsx
@@ -1,6 +1,6 @@
import { createStore } from "solid-js/store"
import { onCleanup, Show, type Accessor } from "solid-js"
-import { InlineInput } from "@opencode-ai/ui/inline-input"
+import { InlineInput } from "@opencoder-ai/ui/inline-input"
export function createInlineEditorController() {
// This controller intentionally supports one active inline editor at a time.
diff --git a/packages/app/src/pages/layout/sidebar-items.tsx b/packages/app/src/pages/layout/sidebar-items.tsx
index d55090370750..6fc90a22261f 100644
--- a/packages/app/src/pages/layout/sidebar-items.tsx
+++ b/packages/app/src/pages/layout/sidebar-items.tsx
@@ -3,17 +3,17 @@ import { useGlobalSync } from "@/context/global-sync"
import { useLanguage } from "@/context/language"
import { useLayout, type LocalProject, getAvatarColors } from "@/context/layout"
import { useNotification } from "@/context/notification"
-import { base64Encode } from "@opencode-ai/util/encode"
-import { Avatar } from "@opencode-ai/ui/avatar"
-import { DiffChanges } from "@opencode-ai/ui/diff-changes"
-import { HoverCard } from "@opencode-ai/ui/hover-card"
-import { Icon } from "@opencode-ai/ui/icon"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { MessageNav } from "@opencode-ai/ui/message-nav"
-import { Spinner } from "@opencode-ai/ui/spinner"
-import { Tooltip } from "@opencode-ai/ui/tooltip"
-import { getFilename } from "@opencode-ai/util/path"
-import { type Message, type Session, type TextPart, type UserMessage } from "@opencode-ai/sdk/v2/client"
+import { base64Encode } from "@opencoder-ai/util/encode"
+import { Avatar } from "@opencoder-ai/ui/avatar"
+import { DiffChanges } from "@opencoder-ai/ui/diff-changes"
+import { HoverCard } from "@opencoder-ai/ui/hover-card"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { MessageNav } from "@opencoder-ai/ui/message-nav"
+import { Spinner } from "@opencoder-ai/ui/spinner"
+import { Tooltip } from "@opencoder-ai/ui/tooltip"
+import { getFilename } from "@opencoder-ai/util/path"
+import { type Message, type Session, type TextPart, type UserMessage } from "@opencoder-ai/sdk/v2/client"
import { For, Match, Show, Switch, createMemo, onCleanup, type Accessor, type JSX } from "solid-js"
import { agentColor } from "@/utils/agent"
diff --git a/packages/app/src/pages/layout/sidebar-project.tsx b/packages/app/src/pages/layout/sidebar-project.tsx
index 28b129bf7561..d7c26aba836b 100644
--- a/packages/app/src/pages/layout/sidebar-project.tsx
+++ b/packages/app/src/pages/layout/sidebar-project.tsx
@@ -1,11 +1,11 @@
import { createEffect, createMemo, createSignal, For, Show, type Accessor, type JSX } from "solid-js"
-import { base64Encode } from "@opencode-ai/util/encode"
-import { Button } from "@opencode-ai/ui/button"
-import { ContextMenu } from "@opencode-ai/ui/context-menu"
-import { HoverCard } from "@opencode-ai/ui/hover-card"
-import { Icon } from "@opencode-ai/ui/icon"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { Tooltip } from "@opencode-ai/ui/tooltip"
+import { base64Encode } from "@opencoder-ai/util/encode"
+import { Button } from "@opencoder-ai/ui/button"
+import { ContextMenu } from "@opencoder-ai/ui/context-menu"
+import { HoverCard } from "@opencoder-ai/ui/hover-card"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { Tooltip } from "@opencoder-ai/ui/tooltip"
import { createSortable } from "@thisbeyond/solid-dnd"
import { type LocalProject } from "@/context/layout"
import { useGlobalSync } from "@/context/global-sync"
diff --git a/packages/app/src/pages/layout/sidebar-shell.tsx b/packages/app/src/pages/layout/sidebar-shell.tsx
index 23abdf157b4a..095970c3d216 100644
--- a/packages/app/src/pages/layout/sidebar-shell.tsx
+++ b/packages/app/src/pages/layout/sidebar-shell.tsx
@@ -8,8 +8,8 @@ import {
type DragEvent,
} from "@thisbeyond/solid-dnd"
import { ConstrainDragXAxis } from "@/utils/solid-dnd"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { Tooltip, TooltipKeybind } from "@opencoder-ai/ui/tooltip"
import { type LocalProject } from "@/context/layout"
import { sidebarExpanded } from "./sidebar-shell-helpers"
diff --git a/packages/app/src/pages/layout/sidebar-workspace.tsx b/packages/app/src/pages/layout/sidebar-workspace.tsx
index 43d99cf8954e..3323df1fcf94 100644
--- a/packages/app/src/pages/layout/sidebar-workspace.tsx
+++ b/packages/app/src/pages/layout/sidebar-workspace.tsx
@@ -3,16 +3,16 @@ import { createEffect, createMemo, For, Show, type Accessor, type JSX } from "so
import { createStore } from "solid-js/store"
import { createSortable } from "@thisbeyond/solid-dnd"
import { createMediaQuery } from "@solid-primitives/media"
-import { base64Encode } from "@opencode-ai/util/encode"
-import { getFilename } from "@opencode-ai/util/path"
-import { Button } from "@opencode-ai/ui/button"
-import { Collapsible } from "@opencode-ai/ui/collapsible"
-import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
-import { Icon } from "@opencode-ai/ui/icon"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { Spinner } from "@opencode-ai/ui/spinner"
-import { Tooltip } from "@opencode-ai/ui/tooltip"
-import { type Session } from "@opencode-ai/sdk/v2/client"
+import { base64Encode } from "@opencoder-ai/util/encode"
+import { getFilename } from "@opencoder-ai/util/path"
+import { Button } from "@opencoder-ai/ui/button"
+import { Collapsible } from "@opencoder-ai/ui/collapsible"
+import { DropdownMenu } from "@opencoder-ai/ui/dropdown-menu"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { Spinner } from "@opencoder-ai/ui/spinner"
+import { Tooltip } from "@opencoder-ai/ui/tooltip"
+import { type Session } from "@opencoder-ai/sdk/v2/client"
import { type LocalProject } from "@/context/layout"
import { useGlobalSync } from "@/context/global-sync"
import { useLanguage } from "@/context/language"
diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx
index 101f3312c3f6..1220aaf1446d 100644
--- a/packages/app/src/pages/session.tsx
+++ b/packages/app/src/pages/session.tsx
@@ -6,37 +6,37 @@ import { useLocal } from "@/context/local"
import { selectionFromLines, useFile, type FileSelection, type SelectedLineRange } from "@/context/file"
import { createStore, produce } from "solid-js/store"
import { SessionContextUsage } from "@/components/session-context-usage"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { Button } from "@opencode-ai/ui/button"
-import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
-import { Dialog } from "@opencode-ai/ui/dialog"
-import { ResizeHandle } from "@opencode-ai/ui/resize-handle"
-import { Tabs } from "@opencode-ai/ui/tabs"
-import { Select } from "@opencode-ai/ui/select"
-import { useCodeComponent } from "@opencode-ai/ui/context/code"
-import { createAutoScroll } from "@opencode-ai/ui/hooks"
-import { Mark } from "@opencode-ai/ui/logo"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { Button } from "@opencoder-ai/ui/button"
+import { Tooltip, TooltipKeybind } from "@opencoder-ai/ui/tooltip"
+import { Dialog } from "@opencoder-ai/ui/dialog"
+import { ResizeHandle } from "@opencoder-ai/ui/resize-handle"
+import { Tabs } from "@opencoder-ai/ui/tabs"
+import { Select } from "@opencoder-ai/ui/select"
+import { useCodeComponent } from "@opencoder-ai/ui/context/code"
+import { createAutoScroll } from "@opencoder-ai/ui/hooks"
+import { Mark } from "@opencoder-ai/ui/logo"
import { DragDropProvider, DragDropSensors, DragOverlay, SortableProvider, closestCenter } from "@thisbeyond/solid-dnd"
import type { DragEvent } from "@thisbeyond/solid-dnd"
import { useSync } from "@/context/sync"
import { useTerminal, type LocalPTY } from "@/context/terminal"
import { useLayout } from "@/context/layout"
-import { checksum, base64Encode } from "@opencode-ai/util/encode"
-import { findLast } from "@opencode-ai/util/array"
-import { useDialog } from "@opencode-ai/ui/context/dialog"
+import { checksum, base64Encode } from "@opencoder-ai/util/encode"
+import { findLast } from "@opencoder-ai/util/array"
+import { useDialog } from "@opencoder-ai/ui/context/dialog"
import { DialogSelectFile } from "@/components/dialog-select-file"
import FileTree from "@/components/file-tree"
import { useCommand } from "@/context/command"
import { useLanguage } from "@/context/language"
import { useNavigate, useParams } from "@solidjs/router"
-import { UserMessage } from "@opencode-ai/sdk/v2"
+import { UserMessage } from "@opencoder-ai/sdk/v2"
import { useSDK } from "@/context/sdk"
import { usePrompt } from "@/context/prompt"
import { useComments } from "@/context/comments"
import { ConstrainDragYAxis, getDraggableId } from "@/utils/solid-dnd"
import { usePermission } from "@/context/permission"
-import { showToast } from "@opencode-ai/ui/toast"
+import { showToast } from "@opencoder-ai/ui/toast"
import { SessionHeader, SessionContextTab, SortableTab, FileVisual, NewSessionView } from "@/components/session"
import { navMark, navParams } from "@/utils/perf"
import { same } from "@/utils/same"
diff --git a/packages/app/src/pages/session/file-tabs.tsx b/packages/app/src/pages/session/file-tabs.tsx
index 5b3f57dbed98..5bbf3faa87ab 100644
--- a/packages/app/src/pages/session/file-tabs.tsx
+++ b/packages/app/src/pages/session/file-tabs.tsx
@@ -1,12 +1,12 @@
import { type ValidComponent, createEffect, createMemo, For, Match, on, onCleanup, Show, Switch } from "solid-js"
import { createStore, produce } from "solid-js/store"
import { Dynamic } from "solid-js/web"
-import { checksum } from "@opencode-ai/util/encode"
+import { checksum } from "@opencoder-ai/util/encode"
import { decode64 } from "@/utils/base64"
-import { showToast } from "@opencode-ai/ui/toast"
-import { LineComment as LineCommentView, LineCommentEditor } from "@opencode-ai/ui/line-comment"
-import { Mark } from "@opencode-ai/ui/logo"
-import { Tabs } from "@opencode-ai/ui/tabs"
+import { showToast } from "@opencoder-ai/ui/toast"
+import { LineComment as LineCommentView, LineCommentEditor } from "@opencoder-ai/ui/line-comment"
+import { Mark } from "@opencoder-ai/ui/logo"
+import { Tabs } from "@opencoder-ai/ui/tabs"
import { useLayout } from "@/context/layout"
import { useFile, type SelectedLineRange } from "@/context/file"
import { useComments } from "@/context/comments"
diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx
index d5f04ccf91c4..be5e8f93af72 100644
--- a/packages/app/src/pages/session/message-timeline.tsx
+++ b/packages/app/src/pages/session/message-timeline.tsx
@@ -1,12 +1,12 @@
import { For, onCleanup, onMount, Show, type JSX } from "solid-js"
-import { Button } from "@opencode-ai/ui/button"
-import { Icon } from "@opencode-ai/ui/icon"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
-import { InlineInput } from "@opencode-ai/ui/inline-input"
-import { Tooltip } from "@opencode-ai/ui/tooltip"
-import { SessionTurn } from "@opencode-ai/ui/session-turn"
-import type { UserMessage } from "@opencode-ai/sdk/v2"
+import { Button } from "@opencoder-ai/ui/button"
+import { Icon } from "@opencoder-ai/ui/icon"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { DropdownMenu } from "@opencoder-ai/ui/dropdown-menu"
+import { InlineInput } from "@opencoder-ai/ui/inline-input"
+import { Tooltip } from "@opencoder-ai/ui/tooltip"
+import { SessionTurn } from "@opencoder-ai/ui/session-turn"
+import type { UserMessage } from "@opencoder-ai/sdk/v2"
import { shouldMarkBoundaryGesture, normalizeWheelDelta } from "@/pages/session/message-gesture"
const boundaryTarget = (root: HTMLElement, target: EventTarget | null) => {
diff --git a/packages/app/src/pages/session/review-tab.tsx b/packages/app/src/pages/session/review-tab.tsx
index 634491c72dcc..a771c0468d12 100644
--- a/packages/app/src/pages/session/review-tab.tsx
+++ b/packages/app/src/pages/session/review-tab.tsx
@@ -1,7 +1,7 @@
import { createEffect, on, onCleanup, type JSX } from "solid-js"
import { createStore } from "solid-js/store"
-import type { FileDiff } from "@opencode-ai/sdk/v2"
-import { SessionReview } from "@opencode-ai/ui/session-review"
+import type { FileDiff } from "@opencoder-ai/sdk/v2"
+import { SessionReview } from "@opencoder-ai/ui/session-review"
import type { SelectedLineRange } from "@/context/file"
import { useSDK } from "@/context/sdk"
import { useLayout } from "@/context/layout"
diff --git a/packages/app/src/pages/session/session-mobile-tabs.tsx b/packages/app/src/pages/session/session-mobile-tabs.tsx
index 73aebc079aae..c823ea792c21 100644
--- a/packages/app/src/pages/session/session-mobile-tabs.tsx
+++ b/packages/app/src/pages/session/session-mobile-tabs.tsx
@@ -1,5 +1,5 @@
import { Show } from "solid-js"
-import { Tabs } from "@opencode-ai/ui/tabs"
+import { Tabs } from "@opencoder-ai/ui/tabs"
export function SessionMobileTabs(props: {
open: boolean
diff --git a/packages/app/src/pages/session/session-prompt-dock.tsx b/packages/app/src/pages/session/session-prompt-dock.tsx
index 8ec4f3b9f8c5..cc2eb0bbe99b 100644
--- a/packages/app/src/pages/session/session-prompt-dock.tsx
+++ b/packages/app/src/pages/session/session-prompt-dock.tsx
@@ -1,7 +1,7 @@
import { For, Show } from "solid-js"
-import type { QuestionRequest } from "@opencode-ai/sdk/v2"
-import { Button } from "@opencode-ai/ui/button"
-import { BasicTool } from "@opencode-ai/ui/basic-tool"
+import type { QuestionRequest } from "@opencoder-ai/sdk/v2"
+import { Button } from "@opencoder-ai/ui/button"
+import { BasicTool } from "@opencoder-ai/ui/basic-tool"
import { PromptInput } from "@/components/prompt-input"
import { QuestionDock } from "@/components/question-dock"
import { questionSubtitle } from "@/pages/session/session-prompt-helpers"
diff --git a/packages/app/src/pages/session/session-side-panel.tsx b/packages/app/src/pages/session/session-side-panel.tsx
index 33954f64a12d..2cd19c5f7c17 100644
--- a/packages/app/src/pages/session/session-side-panel.tsx
+++ b/packages/app/src/pages/session/session-side-panel.tsx
@@ -1,9 +1,9 @@
import { For, Match, Show, Switch, createMemo, onCleanup, type JSX, type ValidComponent } from "solid-js"
-import { Tabs } from "@opencode-ai/ui/tabs"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
-import { ResizeHandle } from "@opencode-ai/ui/resize-handle"
-import { Mark } from "@opencode-ai/ui/logo"
+import { Tabs } from "@opencoder-ai/ui/tabs"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { Tooltip, TooltipKeybind } from "@opencoder-ai/ui/tooltip"
+import { ResizeHandle } from "@opencoder-ai/ui/resize-handle"
+import { Mark } from "@opencoder-ai/ui/logo"
import FileTree from "@/components/file-tree"
import { SessionContextUsage } from "@/components/session-context-usage"
import { SessionContextTab, SortableTab, FileVisual } from "@/components/session"
@@ -16,12 +16,12 @@ import { ConstrainDragYAxis } from "@/utils/solid-dnd"
import type { DragEvent } from "@thisbeyond/solid-dnd"
import { useComments } from "@/context/comments"
import { useCommand } from "@/context/command"
-import { useDialog } from "@opencode-ai/ui/context/dialog"
+import { useDialog } from "@opencoder-ai/ui/context/dialog"
import { useFile, type SelectedLineRange } from "@/context/file"
import { useLanguage } from "@/context/language"
import { useLayout } from "@/context/layout"
import { useSync } from "@/context/sync"
-import type { Message, UserMessage } from "@opencode-ai/sdk/v2/client"
+import type { Message, UserMessage } from "@opencoder-ai/sdk/v2/client"
type SessionSidePanelViewModel = {
messages: () => Message[]
diff --git a/packages/app/src/pages/session/terminal-panel.tsx b/packages/app/src/pages/session/terminal-panel.tsx
index 7ec4356b13f7..1dd1404196de 100644
--- a/packages/app/src/pages/session/terminal-panel.tsx
+++ b/packages/app/src/pages/session/terminal-panel.tsx
@@ -1,14 +1,14 @@
-import { For, Show, createMemo } from "solid-js"
-import { Tabs } from "@opencode-ai/ui/tabs"
-import { ResizeHandle } from "@opencode-ai/ui/resize-handle"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { TooltipKeybind } from "@opencode-ai/ui/tooltip"
+import { For, Show } from "solid-js"
+import { Tabs } from "@opencoder-ai/ui/tabs"
+import { ResizeHandle } from "@opencoder-ai/ui/resize-handle"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { TooltipKeybind } from "@opencoder-ai/ui/tooltip"
import { DragDropProvider, DragDropSensors, DragOverlay, SortableProvider, closestCenter } from "@thisbeyond/solid-dnd"
import type { DragEvent } from "@thisbeyond/solid-dnd"
import { ConstrainDragYAxis } from "@/utils/solid-dnd"
import { SortableTerminalTab } from "@/components/session"
import { Terminal } from "@/components/terminal"
-import { useTerminal } from "@/context/terminal"
+import { useTerminal, type LocalPTY } from "@/context/terminal"
import { useLanguage } from "@/context/language"
import { useCommand } from "@/context/command"
import { terminalTabLabel } from "@/pages/session/terminal-label"
@@ -28,10 +28,6 @@ export function TerminalPanel(props: {
handleTerminalDragEnd: () => void
onCloseTab: () => void
}) {
- const all = createMemo(() => props.terminal.all())
- const ids = createMemo(() => all().map((pty) => pty.id))
- const byId = createMemo(() => new Map(all().map((pty) => [pty.id, pty])))
-
return (
-
-
+ t.id)}>
+
{(pty) => (
-
+
{(pty) => (
{(draggedId) => {
return (
-
+ t.id === draggedId())}>
{(t) => (
{terminalTabLabel({
diff --git a/packages/app/src/pages/session/use-session-commands.tsx b/packages/app/src/pages/session/use-session-commands.tsx
index 81c71133f641..ae5de21c1ddf 100644
--- a/packages/app/src/pages/session/use-session-commands.tsx
+++ b/packages/app/src/pages/session/use-session-commands.tsx
@@ -1,7 +1,7 @@
import { createMemo } from "solid-js"
import { useNavigate, useParams } from "@solidjs/router"
import { useCommand, type CommandOption } from "@/context/command"
-import { useDialog } from "@opencode-ai/ui/context/dialog"
+import { useDialog } from "@opencoder-ai/ui/context/dialog"
import { useFile, selectionFromLines, type FileSelection, type SelectedLineRange } from "@/context/file"
import { useLanguage } from "@/context/language"
import { useLayout } from "@/context/layout"
@@ -15,10 +15,10 @@ import { DialogSelectFile } from "@/components/dialog-select-file"
import { DialogSelectModel } from "@/components/dialog-select-model"
import { DialogSelectMcp } from "@/components/dialog-select-mcp"
import { DialogFork } from "@/components/dialog-fork"
-import { showToast } from "@opencode-ai/ui/toast"
-import { findLast } from "@opencode-ai/util/array"
+import { showToast } from "@opencoder-ai/ui/toast"
+import { findLast } from "@opencoder-ai/util/array"
import { extractPromptFromParts } from "@/utils/prompt"
-import { UserMessage } from "@opencode-ai/sdk/v2"
+import { UserMessage } from "@opencoder-ai/sdk/v2"
import { combineCommandSections } from "@/pages/session/helpers"
import { canAddSelectionContext } from "@/pages/session/session-command-helpers"
diff --git a/packages/app/src/pages/session/use-session-hash-scroll.ts b/packages/app/src/pages/session/use-session-hash-scroll.ts
index 555761ad1ec9..e56b0140d4d4 100644
--- a/packages/app/src/pages/session/use-session-hash-scroll.ts
+++ b/packages/app/src/pages/session/use-session-hash-scroll.ts
@@ -1,5 +1,5 @@
-import { createEffect, createMemo, on, onCleanup } from "solid-js"
-import { UserMessage } from "@opencode-ai/sdk/v2"
+import { createEffect, on, onCleanup } from "solid-js"
+import { UserMessage } from "@opencoder-ai/sdk/v2"
export const messageIdFromHash = (hash: string) => {
const value = hash.startsWith("#") ? hash.slice(1) : hash
@@ -26,10 +26,6 @@ export const useSessionHashScroll = (input: {
scheduleScrollState: (el: HTMLDivElement) => void
consumePendingMessage: (key: string) => string | undefined
}) => {
- const visibleUserMessages = createMemo(() => input.visibleUserMessages())
- const messageById = createMemo(() => new Map(visibleUserMessages().map((m) => [m.id, m])))
- const messageIndex = createMemo(() => new Map(visibleUserMessages().map((m, i) => [m.id, i])))
-
const clearMessageHash = () => {
if (!window.location.hash) return
window.history.replaceState(null, "", window.location.href.replace(/#.*$/, ""))
@@ -51,9 +47,10 @@ export const useSessionHashScroll = (input: {
}
const scrollToMessage = (message: UserMessage, behavior: ScrollBehavior = "smooth") => {
- if (input.currentMessageId() !== message.id) input.setActiveMessage(message)
+ input.setActiveMessage(message)
- const index = messageIndex().get(message.id) ?? -1
+ const msgs = input.visibleUserMessages()
+ const index = msgs.findIndex((m) => m.id === message.id)
if (index !== -1 && index < input.turnStart()) {
input.setTurnStart(index)
input.scheduleTurnBackfill()
@@ -110,7 +107,7 @@ export const useSessionHashScroll = (input: {
const messageId = messageIdFromHash(hash)
if (messageId) {
input.autoScroll.pause()
- const msg = messageById().get(messageId)
+ const msg = input.visibleUserMessages().find((m) => m.id === messageId)
if (msg) {
scrollToMessage(msg, behavior)
return
@@ -147,14 +144,14 @@ export const useSessionHashScroll = (input: {
createEffect(() => {
if (!input.sessionID() || !input.messagesReady()) return
- visibleUserMessages()
+ input.visibleUserMessages().length
input.turnStart()
const targetId = input.pendingMessage() ?? messageIdFromHash(window.location.hash)
if (!targetId) return
if (input.currentMessageId() === targetId) return
- const msg = messageById().get(targetId)
+ const msg = input.visibleUserMessages().find((m) => m.id === targetId)
if (!msg) return
if (input.pendingMessage() === targetId) input.setPendingMessage(undefined)
diff --git a/packages/app/src/utils/base64.ts b/packages/app/src/utils/base64.ts
index c1f9d88c6e96..2c52b0abeed3 100644
--- a/packages/app/src/utils/base64.ts
+++ b/packages/app/src/utils/base64.ts
@@ -1,4 +1,4 @@
-import { base64Decode } from "@opencode-ai/util/encode"
+import { base64Decode } from "@opencoder-ai/util/encode"
export function decode64(value: string | undefined) {
if (value === undefined) return
diff --git a/packages/app/src/utils/persist.ts b/packages/app/src/utils/persist.ts
index 91c504742a94..a50c120dbc02 100644
--- a/packages/app/src/utils/persist.ts
+++ b/packages/app/src/utils/persist.ts
@@ -1,6 +1,6 @@
import { Platform, usePlatform } from "@/context/platform"
import { makePersisted, type AsyncStorage, type SyncStorage } from "@solid-primitives/storage"
-import { checksum } from "@opencode-ai/util/encode"
+import { checksum } from "@opencoder-ai/util/encode"
import { createResource, type Accessor } from "solid-js"
import type { SetStoreFunction, Store } from "solid-js/store"
diff --git a/packages/app/src/utils/prompt.ts b/packages/app/src/utils/prompt.ts
index 35aec0071aac..e247da864984 100644
--- a/packages/app/src/utils/prompt.ts
+++ b/packages/app/src/utils/prompt.ts
@@ -1,4 +1,4 @@
-import type { AgentPart as MessageAgentPart, FilePart, Part, TextPart } from "@opencode-ai/sdk/v2"
+import type { AgentPart as MessageAgentPart, FilePart, Part, TextPart } from "@opencoder-ai/sdk/v2"
import type { AgentPart, FileAttachmentPart, ImageAttachmentPart, Prompt } from "@/context/prompt"
type Inline =
diff --git a/packages/app/src/utils/server-health.ts b/packages/app/src/utils/server-health.ts
index 929826d0dea4..d4c9164ea1f9 100644
--- a/packages/app/src/utils/server-health.ts
+++ b/packages/app/src/utils/server-health.ts
@@ -1,4 +1,4 @@
-import { createOpencodeClient } from "@opencode-ai/sdk/v2/client"
+import { createOpencodeClient } from "@opencoder-ai/sdk/v2/client"
export type ServerHealth = { healthy: boolean; version?: string }
diff --git a/packages/app/src/utils/sound.ts b/packages/app/src/utils/sound.ts
index 6dea812ec81b..fe82bc448c63 100644
--- a/packages/app/src/utils/sound.ts
+++ b/packages/app/src/utils/sound.ts
@@ -1,48 +1,48 @@
-import alert01 from "@opencode-ai/ui/audio/alert-01.aac"
-import alert02 from "@opencode-ai/ui/audio/alert-02.aac"
-import alert03 from "@opencode-ai/ui/audio/alert-03.aac"
-import alert04 from "@opencode-ai/ui/audio/alert-04.aac"
-import alert05 from "@opencode-ai/ui/audio/alert-05.aac"
-import alert06 from "@opencode-ai/ui/audio/alert-06.aac"
-import alert07 from "@opencode-ai/ui/audio/alert-07.aac"
-import alert08 from "@opencode-ai/ui/audio/alert-08.aac"
-import alert09 from "@opencode-ai/ui/audio/alert-09.aac"
-import alert10 from "@opencode-ai/ui/audio/alert-10.aac"
-import bipbop01 from "@opencode-ai/ui/audio/bip-bop-01.aac"
-import bipbop02 from "@opencode-ai/ui/audio/bip-bop-02.aac"
-import bipbop03 from "@opencode-ai/ui/audio/bip-bop-03.aac"
-import bipbop04 from "@opencode-ai/ui/audio/bip-bop-04.aac"
-import bipbop05 from "@opencode-ai/ui/audio/bip-bop-05.aac"
-import bipbop06 from "@opencode-ai/ui/audio/bip-bop-06.aac"
-import bipbop07 from "@opencode-ai/ui/audio/bip-bop-07.aac"
-import bipbop08 from "@opencode-ai/ui/audio/bip-bop-08.aac"
-import bipbop09 from "@opencode-ai/ui/audio/bip-bop-09.aac"
-import bipbop10 from "@opencode-ai/ui/audio/bip-bop-10.aac"
-import nope01 from "@opencode-ai/ui/audio/nope-01.aac"
-import nope02 from "@opencode-ai/ui/audio/nope-02.aac"
-import nope03 from "@opencode-ai/ui/audio/nope-03.aac"
-import nope04 from "@opencode-ai/ui/audio/nope-04.aac"
-import nope05 from "@opencode-ai/ui/audio/nope-05.aac"
-import nope06 from "@opencode-ai/ui/audio/nope-06.aac"
-import nope07 from "@opencode-ai/ui/audio/nope-07.aac"
-import nope08 from "@opencode-ai/ui/audio/nope-08.aac"
-import nope09 from "@opencode-ai/ui/audio/nope-09.aac"
-import nope10 from "@opencode-ai/ui/audio/nope-10.aac"
-import nope11 from "@opencode-ai/ui/audio/nope-11.aac"
-import nope12 from "@opencode-ai/ui/audio/nope-12.aac"
-import staplebops01 from "@opencode-ai/ui/audio/staplebops-01.aac"
-import staplebops02 from "@opencode-ai/ui/audio/staplebops-02.aac"
-import staplebops03 from "@opencode-ai/ui/audio/staplebops-03.aac"
-import staplebops04 from "@opencode-ai/ui/audio/staplebops-04.aac"
-import staplebops05 from "@opencode-ai/ui/audio/staplebops-05.aac"
-import staplebops06 from "@opencode-ai/ui/audio/staplebops-06.aac"
-import staplebops07 from "@opencode-ai/ui/audio/staplebops-07.aac"
-import yup01 from "@opencode-ai/ui/audio/yup-01.aac"
-import yup02 from "@opencode-ai/ui/audio/yup-02.aac"
-import yup03 from "@opencode-ai/ui/audio/yup-03.aac"
-import yup04 from "@opencode-ai/ui/audio/yup-04.aac"
-import yup05 from "@opencode-ai/ui/audio/yup-05.aac"
-import yup06 from "@opencode-ai/ui/audio/yup-06.aac"
+import alert01 from "@opencoder-ai/ui/audio/alert-01.aac"
+import alert02 from "@opencoder-ai/ui/audio/alert-02.aac"
+import alert03 from "@opencoder-ai/ui/audio/alert-03.aac"
+import alert04 from "@opencoder-ai/ui/audio/alert-04.aac"
+import alert05 from "@opencoder-ai/ui/audio/alert-05.aac"
+import alert06 from "@opencoder-ai/ui/audio/alert-06.aac"
+import alert07 from "@opencoder-ai/ui/audio/alert-07.aac"
+import alert08 from "@opencoder-ai/ui/audio/alert-08.aac"
+import alert09 from "@opencoder-ai/ui/audio/alert-09.aac"
+import alert10 from "@opencoder-ai/ui/audio/alert-10.aac"
+import bipbop01 from "@opencoder-ai/ui/audio/bip-bop-01.aac"
+import bipbop02 from "@opencoder-ai/ui/audio/bip-bop-02.aac"
+import bipbop03 from "@opencoder-ai/ui/audio/bip-bop-03.aac"
+import bipbop04 from "@opencoder-ai/ui/audio/bip-bop-04.aac"
+import bipbop05 from "@opencoder-ai/ui/audio/bip-bop-05.aac"
+import bipbop06 from "@opencoder-ai/ui/audio/bip-bop-06.aac"
+import bipbop07 from "@opencoder-ai/ui/audio/bip-bop-07.aac"
+import bipbop08 from "@opencoder-ai/ui/audio/bip-bop-08.aac"
+import bipbop09 from "@opencoder-ai/ui/audio/bip-bop-09.aac"
+import bipbop10 from "@opencoder-ai/ui/audio/bip-bop-10.aac"
+import nope01 from "@opencoder-ai/ui/audio/nope-01.aac"
+import nope02 from "@opencoder-ai/ui/audio/nope-02.aac"
+import nope03 from "@opencoder-ai/ui/audio/nope-03.aac"
+import nope04 from "@opencoder-ai/ui/audio/nope-04.aac"
+import nope05 from "@opencoder-ai/ui/audio/nope-05.aac"
+import nope06 from "@opencoder-ai/ui/audio/nope-06.aac"
+import nope07 from "@opencoder-ai/ui/audio/nope-07.aac"
+import nope08 from "@opencoder-ai/ui/audio/nope-08.aac"
+import nope09 from "@opencoder-ai/ui/audio/nope-09.aac"
+import nope10 from "@opencoder-ai/ui/audio/nope-10.aac"
+import nope11 from "@opencoder-ai/ui/audio/nope-11.aac"
+import nope12 from "@opencoder-ai/ui/audio/nope-12.aac"
+import staplebops01 from "@opencoder-ai/ui/audio/staplebops-01.aac"
+import staplebops02 from "@opencoder-ai/ui/audio/staplebops-02.aac"
+import staplebops03 from "@opencoder-ai/ui/audio/staplebops-03.aac"
+import staplebops04 from "@opencoder-ai/ui/audio/staplebops-04.aac"
+import staplebops05 from "@opencoder-ai/ui/audio/staplebops-05.aac"
+import staplebops06 from "@opencoder-ai/ui/audio/staplebops-06.aac"
+import staplebops07 from "@opencoder-ai/ui/audio/staplebops-07.aac"
+import yup01 from "@opencoder-ai/ui/audio/yup-01.aac"
+import yup02 from "@opencoder-ai/ui/audio/yup-02.aac"
+import yup03 from "@opencoder-ai/ui/audio/yup-03.aac"
+import yup04 from "@opencoder-ai/ui/audio/yup-04.aac"
+import yup05 from "@opencoder-ai/ui/audio/yup-05.aac"
+import yup06 from "@opencoder-ai/ui/audio/yup-06.aac"
export const SOUND_OPTIONS = [
{ id: "alert-01", label: "sound.option.alert01", src: alert01 },
diff --git a/packages/console/AGENTS.md b/packages/console/AGENTS.md
new file mode 100644
index 000000000000..5837c8e8b2b0
--- /dev/null
+++ b/packages/console/AGENTS.md
@@ -0,0 +1,36 @@
+# Console Web Dashboard
+
+**Package:** `packages/console`
+**Type:** Web dashboard (SolidJS + Hono)
+
+## Overview
+
+Account and usage management dashboard. Consists of frontend app, backend core, Cloudflare Workers functions, and resource handlers.
+
+## Structure
+
+```
+packages/console/
+├── app/ # Frontend (SolidJS)
+├── core/ # Backend logic, DB migrations
+├── function/ # Cloudflare Workers
+├── resource/ # Resource handlers
+└── mail/ # Email service
+```
+
+## Key Patterns
+
+- Frontend uses SolidJS with `@solidjs/start`
+- Backend uses Hono for Edge Functions
+- Database migrations in `core/migrations/`
+- SST deployment via `sst.config.ts`
+
+## Commands
+
+```bash
+# Dev
+bun dev
+
+# Build
+bun turbo build --filter=console
+```
diff --git a/packages/console/app/package.json b/packages/console/app/package.json
index 3d7ef578515f..cc4b1a4208c0 100644
--- a/packages/console/app/package.json
+++ b/packages/console/app/package.json
@@ -1,6 +1,6 @@
{
- "name": "@opencode-ai/console-app",
- "version": "1.1.65",
+ "name": "@opencoder-ai/console-app",
+ "version": "1.1.63",
"type": "module",
"license": "MIT",
"scripts": {
@@ -16,10 +16,10 @@
"@jsx-email/render": "1.1.1",
"@kobalte/core": "catalog:",
"@openauthjs/openauth": "catalog:",
- "@opencode-ai/console-core": "workspace:*",
- "@opencode-ai/console-mail": "workspace:*",
- "@opencode-ai/console-resource": "workspace:*",
- "@opencode-ai/ui": "workspace:*",
+ "@opencoder-ai/console-core": "workspace:*",
+ "@opencoder-ai/console-mail": "workspace:*",
+ "@opencoder-ai/console-resource": "workspace:*",
+ "@opencoder-ai/ui": "workspace:*",
"@smithy/eventstream-codec": "4.2.7",
"@smithy/util-utf8": "4.2.0",
"@solidjs/meta": "catalog:",
diff --git a/packages/console/app/src/app.tsx b/packages/console/app/src/app.tsx
index 3eb70606a45c..ab46e74c157c 100644
--- a/packages/console/app/src/app.tsx
+++ b/packages/console/app/src/app.tsx
@@ -2,8 +2,8 @@ import { MetaProvider, Title, Meta } from "@solidjs/meta"
import { Router } from "@solidjs/router"
import { FileRoutes } from "@solidjs/start/router"
import { Suspense } from "solid-js"
-import { Favicon } from "@opencode-ai/ui/favicon"
-import { Font } from "@opencode-ai/ui/font"
+import { Favicon } from "@opencoder-ai/ui/favicon"
+import { Font } from "@opencoder-ai/ui/font"
import "@ibm/plex/css/ibm-plex.css"
import "./app.css"
import { LanguageProvider } from "~/context/language"
diff --git a/packages/console/app/src/component/email-signup.tsx b/packages/console/app/src/component/email-signup.tsx
index bd33e92006ae..607cbb92cc3b 100644
--- a/packages/console/app/src/component/email-signup.tsx
+++ b/packages/console/app/src/component/email-signup.tsx
@@ -1,6 +1,6 @@
import { action, useSubmission } from "@solidjs/router"
import dock from "../asset/lander/dock.png"
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
import { Show } from "solid-js"
import { useI18n } from "~/context/i18n"
diff --git a/packages/console/app/src/context/auth.ts b/packages/console/app/src/context/auth.ts
index aed07a630f8c..170000040a43 100644
--- a/packages/console/app/src/context/auth.ts
+++ b/packages/console/app/src/context/auth.ts
@@ -1,8 +1,8 @@
import { getRequestEvent } from "solid-js/web"
-import { and, Database, eq, inArray, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js"
-import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
+import { and, Database, eq, inArray, isNull, sql } from "@opencoder-ai/console-core/drizzle/index.js"
+import { UserTable } from "@opencoder-ai/console-core/schema/user.sql.js"
import { redirect } from "@solidjs/router"
-import { Actor } from "@opencode-ai/console-core/actor.js"
+import { Actor } from "@opencoder-ai/console-core/actor.js"
import { createClient } from "@openauthjs/openauth/client"
@@ -12,7 +12,7 @@ export const AuthClient = createClient({
})
import { useSession } from "@solidjs/start/http"
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
export interface AuthSession {
account?: Record<
diff --git a/packages/console/app/src/context/auth.withActor.ts b/packages/console/app/src/context/auth.withActor.ts
index ff377cda4602..1853b69901dd 100644
--- a/packages/console/app/src/context/auth.withActor.ts
+++ b/packages/console/app/src/context/auth.withActor.ts
@@ -1,4 +1,4 @@
-import { Actor } from "@opencode-ai/console-core/actor.js"
+import { Actor } from "@opencoder-ai/console-core/actor.js"
import { getActor } from "./auth"
export async function withActor
(fn: () => T, workspace?: string) {
diff --git a/packages/console/app/src/context/i18n.tsx b/packages/console/app/src/context/i18n.tsx
index 5d178c8b8d97..cd27d35edff7 100644
--- a/packages/console/app/src/context/i18n.tsx
+++ b/packages/console/app/src/context/i18n.tsx
@@ -1,5 +1,5 @@
import { createMemo } from "solid-js"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import { i18n, type Key } from "~/i18n"
import { useLanguage } from "~/context/language"
diff --git a/packages/console/app/src/context/language.tsx b/packages/console/app/src/context/language.tsx
index 2999242f0ffe..60cb01a7ede7 100644
--- a/packages/console/app/src/context/language.tsx
+++ b/packages/console/app/src/context/language.tsx
@@ -1,7 +1,7 @@
import { createEffect } from "solid-js"
import { createStore } from "solid-js/store"
import { getRequestEvent } from "solid-js/web"
-import { createSimpleContext } from "@opencode-ai/ui/context"
+import { createSimpleContext } from "@opencoder-ai/ui/context"
import {
LOCALES,
type Locale,
diff --git a/packages/console/app/src/routes/api/enterprise.ts b/packages/console/app/src/routes/api/enterprise.ts
index 6776a7b3c735..15cc893e0e5e 100644
--- a/packages/console/app/src/routes/api/enterprise.ts
+++ b/packages/console/app/src/routes/api/enterprise.ts
@@ -1,5 +1,5 @@
import type { APIEvent } from "@solidjs/start/server"
-import { AWS } from "@opencode-ai/console-core/aws.js"
+import { AWS } from "@opencoder-ai/console-core/aws.js"
interface EnterpriseFormData {
name: string
diff --git a/packages/console/app/src/routes/bench/[id].tsx b/packages/console/app/src/routes/bench/[id].tsx
index dd96bcbbcee5..10144a1c4c5c 100644
--- a/packages/console/app/src/routes/bench/[id].tsx
+++ b/packages/console/app/src/routes/bench/[id].tsx
@@ -1,8 +1,8 @@
import { Title } from "@solidjs/meta"
import { createAsync, query, useParams } from "@solidjs/router"
import { createSignal, For, Show } from "solid-js"
-import { Database, desc, eq } from "@opencode-ai/console-core/drizzle/index.js"
-import { BenchmarkTable } from "@opencode-ai/console-core/schema/benchmark.sql.js"
+import { Database, desc, eq } from "@opencoder-ai/console-core/drizzle/index.js"
+import { BenchmarkTable } from "@opencoder-ai/console-core/schema/benchmark.sql.js"
import { useI18n } from "~/context/i18n"
interface TaskSource {
diff --git a/packages/console/app/src/routes/bench/index.tsx b/packages/console/app/src/routes/bench/index.tsx
index 17798eff4e1f..2a7e857a1636 100644
--- a/packages/console/app/src/routes/bench/index.tsx
+++ b/packages/console/app/src/routes/bench/index.tsx
@@ -1,8 +1,8 @@
import { Title } from "@solidjs/meta"
import { A, createAsync, query } from "@solidjs/router"
import { createMemo, For, Show } from "solid-js"
-import { Database, desc } from "@opencode-ai/console-core/drizzle/index.js"
-import { BenchmarkTable } from "@opencode-ai/console-core/schema/benchmark.sql.js"
+import { Database, desc } from "@opencoder-ai/console-core/drizzle/index.js"
+import { BenchmarkTable } from "@opencoder-ai/console-core/schema/benchmark.sql.js"
import { useI18n } from "~/context/i18n"
interface BenchmarkResult {
diff --git a/packages/console/app/src/routes/bench/submission.ts b/packages/console/app/src/routes/bench/submission.ts
index 94639439b114..3dfb6db1021e 100644
--- a/packages/console/app/src/routes/bench/submission.ts
+++ b/packages/console/app/src/routes/bench/submission.ts
@@ -1,7 +1,7 @@
import type { APIEvent } from "@solidjs/start/server"
-import { Database } from "@opencode-ai/console-core/drizzle/index.js"
-import { BenchmarkTable } from "@opencode-ai/console-core/schema/benchmark.sql.js"
-import { Identifier } from "@opencode-ai/console-core/identifier.js"
+import { Database } from "@opencoder-ai/console-core/drizzle/index.js"
+import { BenchmarkTable } from "@opencoder-ai/console-core/schema/benchmark.sql.js"
+import { Identifier } from "@opencoder-ai/console-core/identifier.js"
interface SubmissionBody {
model: string
diff --git a/packages/console/app/src/routes/black/subscribe/[plan].tsx b/packages/console/app/src/routes/black/subscribe/[plan].tsx
index 644d87d9b325..909561e1024f 100644
--- a/packages/console/app/src/routes/black/subscribe/[plan].tsx
+++ b/packages/console/app/src/routes/black/subscribe/[plan].tsx
@@ -6,14 +6,14 @@ import { Elements, PaymentElement, useStripe, useElements, AddressElement } from
import { PlanID, plans } from "../common"
import { getActor, useAuthSession } from "~/context/auth"
import { withActor } from "~/context/auth.withActor"
-import { Actor } from "@opencode-ai/console-core/actor.js"
-import { and, Database, eq, isNull } from "@opencode-ai/console-core/drizzle/index.js"
-import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js"
-import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
+import { Actor } from "@opencoder-ai/console-core/actor.js"
+import { and, Database, eq, isNull } from "@opencoder-ai/console-core/drizzle/index.js"
+import { WorkspaceTable } from "@opencoder-ai/console-core/schema/workspace.sql.js"
+import { UserTable } from "@opencoder-ai/console-core/schema/user.sql.js"
import { createList } from "solid-list"
import { Modal } from "~/component/modal"
-import { BillingTable } from "@opencode-ai/console-core/schema/billing.sql.js"
-import { Billing } from "@opencode-ai/console-core/billing.js"
+import { BillingTable } from "@opencoder-ai/console-core/schema/billing.sql.js"
+import { Billing } from "@opencoder-ai/console-core/billing.js"
import { useI18n } from "~/context/i18n"
import { useLanguage } from "~/context/language"
import { formError } from "~/lib/form-error"
diff --git a/packages/console/app/src/routes/debug/index.ts b/packages/console/app/src/routes/debug/index.ts
index 2bdd269e7815..e8229aa303f4 100644
--- a/packages/console/app/src/routes/debug/index.ts
+++ b/packages/console/app/src/routes/debug/index.ts
@@ -1,7 +1,7 @@
import type { APIEvent } from "@solidjs/start/server"
import { json } from "@solidjs/router"
-import { Database } from "@opencode-ai/console-core/drizzle/index.js"
-import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
+import { Database } from "@opencoder-ai/console-core/drizzle/index.js"
+import { UserTable } from "@opencoder-ai/console-core/schema/user.sql.js"
export async function GET(evt: APIEvent) {
return json({
diff --git a/packages/console/app/src/routes/docs/[...path].ts b/packages/console/app/src/routes/docs/[...path].ts
index bbe07f1f076d..03d500927812 100644
--- a/packages/console/app/src/routes/docs/[...path].ts
+++ b/packages/console/app/src/routes/docs/[...path].ts
@@ -1,5 +1,5 @@
import type { APIEvent } from "@solidjs/start/server"
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
import { docs, localeFromRequest, tag } from "~/lib/language"
async function handler(evt: APIEvent) {
diff --git a/packages/console/app/src/routes/docs/index.ts b/packages/console/app/src/routes/docs/index.ts
index bbe07f1f076d..03d500927812 100644
--- a/packages/console/app/src/routes/docs/index.ts
+++ b/packages/console/app/src/routes/docs/index.ts
@@ -1,5 +1,5 @@
import type { APIEvent } from "@solidjs/start/server"
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
import { docs, localeFromRequest, tag } from "~/lib/language"
async function handler(evt: APIEvent) {
diff --git a/packages/console/app/src/routes/s/[id].ts b/packages/console/app/src/routes/s/[id].ts
index 60f8d8ba879d..439209e21c20 100644
--- a/packages/console/app/src/routes/s/[id].ts
+++ b/packages/console/app/src/routes/s/[id].ts
@@ -1,5 +1,5 @@
import type { APIEvent } from "@solidjs/start/server"
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
import { docs, localeFromRequest, tag } from "~/lib/language"
async function handler(evt: APIEvent) {
diff --git a/packages/console/app/src/routes/stripe/webhook.ts b/packages/console/app/src/routes/stripe/webhook.ts
index 828eb4c711cc..3fb115bfdc0e 100644
--- a/packages/console/app/src/routes/stripe/webhook.ts
+++ b/packages/console/app/src/routes/stripe/webhook.ts
@@ -1,13 +1,13 @@
-import { Billing } from "@opencode-ai/console-core/billing.js"
+import { Billing } from "@opencoder-ai/console-core/billing.js"
import type { APIEvent } from "@solidjs/start/server"
-import { and, Database, eq, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js"
-import { BillingTable, PaymentTable, SubscriptionTable } from "@opencode-ai/console-core/schema/billing.sql.js"
-import { Identifier } from "@opencode-ai/console-core/identifier.js"
-import { centsToMicroCents } from "@opencode-ai/console-core/util/price.js"
-import { Actor } from "@opencode-ai/console-core/actor.js"
-import { Resource } from "@opencode-ai/console-resource"
-import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
-import { AuthTable } from "@opencode-ai/console-core/schema/auth.sql.js"
+import { and, Database, eq, isNull, sql } from "@opencoder-ai/console-core/drizzle/index.js"
+import { BillingTable, PaymentTable, SubscriptionTable } from "@opencoder-ai/console-core/schema/billing.sql.js"
+import { Identifier } from "@opencoder-ai/console-core/identifier.js"
+import { centsToMicroCents } from "@opencoder-ai/console-core/util/price.js"
+import { Actor } from "@opencoder-ai/console-core/actor.js"
+import { Resource } from "@opencoder-ai/console-resource"
+import { UserTable } from "@opencoder-ai/console-core/schema/user.sql.js"
+import { AuthTable } from "@opencoder-ai/console-core/schema/auth.sql.js"
export async function POST(input: APIEvent) {
const body = await Billing.stripe().webhooks.constructEventAsync(
diff --git a/packages/console/app/src/routes/workspace-picker.tsx b/packages/console/app/src/routes/workspace-picker.tsx
index ffec2f3beed3..8856665b845b 100644
--- a/packages/console/app/src/routes/workspace-picker.tsx
+++ b/packages/console/app/src/routes/workspace-picker.tsx
@@ -2,11 +2,11 @@ import { query, useParams, action, createAsync, redirect, useSubmission } from "
import { For, Show, createEffect } from "solid-js"
import { createStore } from "solid-js/store"
import { withActor } from "~/context/auth.withActor"
-import { Actor } from "@opencode-ai/console-core/actor.js"
-import { and, Database, eq, isNull } from "@opencode-ai/console-core/drizzle/index.js"
-import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js"
-import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
-import { Workspace } from "@opencode-ai/console-core/workspace.js"
+import { Actor } from "@opencoder-ai/console-core/actor.js"
+import { and, Database, eq, isNull } from "@opencoder-ai/console-core/drizzle/index.js"
+import { WorkspaceTable } from "@opencoder-ai/console-core/schema/workspace.sql.js"
+import { UserTable } from "@opencoder-ai/console-core/schema/user.sql.js"
+import { Workspace } from "@opencoder-ai/console-core/workspace.js"
import { Dropdown, DropdownItem } from "~/component/dropdown"
import { Modal } from "~/component/modal"
import { useI18n } from "~/context/i18n"
diff --git a/packages/console/app/src/routes/workspace.tsx b/packages/console/app/src/routes/workspace.tsx
index 10e503ac526d..fcc92169ed1e 100644
--- a/packages/console/app/src/routes/workspace.tsx
+++ b/packages/console/app/src/routes/workspace.tsx
@@ -4,8 +4,8 @@ import { IconWorkspaceLogo } from "../component/icon"
import { WorkspacePicker } from "./workspace-picker"
import { UserMenu } from "./user-menu"
import { withActor } from "~/context/auth.withActor"
-import { User } from "@opencode-ai/console-core/user.js"
-import { Actor } from "@opencode-ai/console-core/actor.js"
+import { User } from "@opencoder-ai/console-core/user.js"
+import { Actor } from "@opencoder-ai/console-core/actor.js"
import { useLanguage } from "~/context/language"
const getUserEmail = query(async (workspaceID: string) => {
diff --git a/packages/console/app/src/routes/workspace/[id]/billing/billing-section.tsx b/packages/console/app/src/routes/workspace/[id]/billing/billing-section.tsx
index db89a1c9edab..dde2e8f5cd5b 100644
--- a/packages/console/app/src/routes/workspace/[id]/billing/billing-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/billing/billing-section.tsx
@@ -1,7 +1,7 @@
import { action, useParams, useAction, createAsync, useSubmission, json } from "@solidjs/router"
import { createMemo, Match, Show, Switch, createEffect } from "solid-js"
import { createStore } from "solid-js/store"
-import { Billing } from "@opencode-ai/console-core/billing.js"
+import { Billing } from "@opencoder-ai/console-core/billing.js"
import { withActor } from "~/context/auth.withActor"
import { IconCreditCard, IconStripe } from "~/component/icon"
import styles from "./billing-section.module.css"
diff --git a/packages/console/app/src/routes/workspace/[id]/billing/black-section.tsx b/packages/console/app/src/routes/workspace/[id]/billing/black-section.tsx
index ce0eb2c6a12b..352ae2db16df 100644
--- a/packages/console/app/src/routes/workspace/[id]/billing/black-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/billing/black-section.tsx
@@ -1,11 +1,11 @@
import { action, useParams, useAction, useSubmission, json, query, createAsync } from "@solidjs/router"
import { createStore } from "solid-js/store"
import { Show } from "solid-js"
-import { Billing } from "@opencode-ai/console-core/billing.js"
-import { Database, eq, and, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js"
-import { BillingTable, SubscriptionTable } from "@opencode-ai/console-core/schema/billing.sql.js"
-import { Actor } from "@opencode-ai/console-core/actor.js"
-import { Black } from "@opencode-ai/console-core/black.js"
+import { Billing } from "@opencoder-ai/console-core/billing.js"
+import { Database, eq, and, isNull, sql } from "@opencoder-ai/console-core/drizzle/index.js"
+import { BillingTable, SubscriptionTable } from "@opencoder-ai/console-core/schema/billing.sql.js"
+import { Actor } from "@opencoder-ai/console-core/actor.js"
+import { Black } from "@opencoder-ai/console-core/black.js"
import { withActor } from "~/context/auth.withActor"
import { queryBillingInfo } from "../../common"
import styles from "./black-section.module.css"
diff --git a/packages/console/app/src/routes/workspace/[id]/billing/monthly-limit-section.tsx b/packages/console/app/src/routes/workspace/[id]/billing/monthly-limit-section.tsx
index ef54b840998c..16b9c6f40eb6 100644
--- a/packages/console/app/src/routes/workspace/[id]/billing/monthly-limit-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/billing/monthly-limit-section.tsx
@@ -2,7 +2,7 @@ import { json, action, useParams, createAsync, useSubmission } from "@solidjs/ro
import { createEffect, Show } from "solid-js"
import { createStore } from "solid-js/store"
import { withActor } from "~/context/auth.withActor"
-import { Billing } from "@opencode-ai/console-core/billing.js"
+import { Billing } from "@opencoder-ai/console-core/billing.js"
import styles from "./monthly-limit-section.module.css"
import { queryBillingInfo } from "../../common"
import { useI18n } from "~/context/i18n"
diff --git a/packages/console/app/src/routes/workspace/[id]/billing/payment-section.tsx b/packages/console/app/src/routes/workspace/[id]/billing/payment-section.tsx
index 2311be321582..232b4c8b30f0 100644
--- a/packages/console/app/src/routes/workspace/[id]/billing/payment-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/billing/payment-section.tsx
@@ -1,4 +1,4 @@
-import { Billing } from "@opencode-ai/console-core/billing.js"
+import { Billing } from "@opencoder-ai/console-core/billing.js"
import { query, action, useParams, createAsync, useAction } from "@solidjs/router"
import { For, Match, Show, Switch } from "solid-js"
import { withActor } from "~/context/auth.withActor"
diff --git a/packages/console/app/src/routes/workspace/[id]/billing/reload-section.tsx b/packages/console/app/src/routes/workspace/[id]/billing/reload-section.tsx
index 7084be133843..634d18d1eb59 100644
--- a/packages/console/app/src/routes/workspace/[id]/billing/reload-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/billing/reload-section.tsx
@@ -2,9 +2,9 @@ import { json, action, useParams, createAsync, useSubmission } from "@solidjs/ro
import { createEffect, Show, createMemo } from "solid-js"
import { createStore } from "solid-js/store"
import { withActor } from "~/context/auth.withActor"
-import { Billing } from "@opencode-ai/console-core/billing.js"
-import { Database, eq } from "@opencode-ai/console-core/drizzle/index.js"
-import { BillingTable } from "@opencode-ai/console-core/schema/billing.sql.js"
+import { Billing } from "@opencoder-ai/console-core/billing.js"
+import { Database, eq } from "@opencoder-ai/console-core/drizzle/index.js"
+import { BillingTable } from "@opencoder-ai/console-core/schema/billing.sql.js"
import styles from "./reload-section.module.css"
import { queryBillingInfo } from "../../common"
import { useI18n } from "~/context/i18n"
diff --git a/packages/console/app/src/routes/workspace/[id]/graph-section.tsx b/packages/console/app/src/routes/workspace/[id]/graph-section.tsx
index f26c7291d8ab..b3d92cc2143a 100644
--- a/packages/console/app/src/routes/workspace/[id]/graph-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/graph-section.tsx
@@ -1,8 +1,8 @@
-import { and, Database, eq, gte, inArray, isNull, lt, or, sql, sum } from "@opencode-ai/console-core/drizzle/index.js"
-import { UsageTable } from "@opencode-ai/console-core/schema/billing.sql.js"
-import { KeyTable } from "@opencode-ai/console-core/schema/key.sql.js"
-import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
-import { AuthTable } from "@opencode-ai/console-core/schema/auth.sql.js"
+import { and, Database, eq, gte, inArray, isNull, lt, or, sql, sum } from "@opencoder-ai/console-core/drizzle/index.js"
+import { UsageTable } from "@opencoder-ai/console-core/schema/billing.sql.js"
+import { KeyTable } from "@opencoder-ai/console-core/schema/key.sql.js"
+import { UserTable } from "@opencoder-ai/console-core/schema/user.sql.js"
+import { AuthTable } from "@opencoder-ai/console-core/schema/auth.sql.js"
import { useParams } from "@solidjs/router"
import { createEffect, createMemo, onCleanup, Show, For } from "solid-js"
import { createStore } from "solid-js/store"
diff --git a/packages/console/app/src/routes/workspace/[id]/keys/key-section.tsx b/packages/console/app/src/routes/workspace/[id]/keys/key-section.tsx
index 837ab743a5ac..98becedec247 100644
--- a/packages/console/app/src/routes/workspace/[id]/keys/key-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/keys/key-section.tsx
@@ -1,12 +1,12 @@
import { json, query, action, useParams, createAsync, useSubmission } from "@solidjs/router"
import { createEffect, createSignal, For, Show } from "solid-js"
import { IconCopy, IconCheck } from "~/component/icon"
-import { Key } from "@opencode-ai/console-core/key.js"
+import { Key } from "@opencoder-ai/console-core/key.js"
import { withActor } from "~/context/auth.withActor"
import { createStore } from "solid-js/store"
import { formatDateUTC, formatDateForTable } from "../../common"
import styles from "./key-section.module.css"
-import { Actor } from "@opencode-ai/console-core/actor.js"
+import { Actor } from "@opencoder-ai/console-core/actor.js"
import { useI18n } from "~/context/i18n"
import { formError, localizeError } from "~/lib/form-error"
diff --git a/packages/console/app/src/routes/workspace/[id]/members/member-section.tsx b/packages/console/app/src/routes/workspace/[id]/members/member-section.tsx
index 5a440632f8ad..77be6d5ea4aa 100644
--- a/packages/console/app/src/routes/workspace/[id]/members/member-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/members/member-section.tsx
@@ -3,9 +3,9 @@ import { createEffect, For, Show } from "solid-js"
import { withActor } from "~/context/auth.withActor"
import { createStore } from "solid-js/store"
import styles from "./member-section.module.css"
-import { UserRole } from "@opencode-ai/console-core/schema/user.sql.js"
-import { Actor } from "@opencode-ai/console-core/actor.js"
-import { User } from "@opencode-ai/console-core/user.js"
+import { UserRole } from "@opencoder-ai/console-core/schema/user.sql.js"
+import { Actor } from "@opencoder-ai/console-core/actor.js"
+import { User } from "@opencoder-ai/console-core/user.js"
import { RoleDropdown } from "./role-dropdown"
import { useI18n } from "~/context/i18n"
import { useLanguage } from "~/context/language"
diff --git a/packages/console/app/src/routes/workspace/[id]/model-section.tsx b/packages/console/app/src/routes/workspace/[id]/model-section.tsx
index 97f95278a160..837b1d6e4276 100644
--- a/packages/console/app/src/routes/workspace/[id]/model-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/model-section.tsx
@@ -1,8 +1,8 @@
-import { Model } from "@opencode-ai/console-core/model.js"
+import { Model } from "@opencoder-ai/console-core/model.js"
import { query, action, useParams, createAsync, json } from "@solidjs/router"
import { createMemo, For, Show } from "solid-js"
import { withActor } from "~/context/auth.withActor"
-import { ZenData } from "@opencode-ai/console-core/model.js"
+import { ZenData } from "@opencoder-ai/console-core/model.js"
import styles from "./model-section.module.css"
import { querySessionInfo } from "../common"
import {
diff --git a/packages/console/app/src/routes/workspace/[id]/new-user-section.tsx b/packages/console/app/src/routes/workspace/[id]/new-user-section.tsx
index a50efc288d6e..d1eb4d47df50 100644
--- a/packages/console/app/src/routes/workspace/[id]/new-user-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/new-user-section.tsx
@@ -1,8 +1,8 @@
import { query, useParams, createAsync } from "@solidjs/router"
import { createMemo, createSignal, Show } from "solid-js"
import { IconCopy, IconCheck } from "~/component/icon"
-import { Key } from "@opencode-ai/console-core/key.js"
-import { Billing } from "@opencode-ai/console-core/billing.js"
+import { Key } from "@opencoder-ai/console-core/key.js"
+import { Billing } from "@opencoder-ai/console-core/billing.js"
import { withActor } from "~/context/auth.withActor"
import styles from "./new-user-section.module.css"
import { useI18n } from "~/context/i18n"
diff --git a/packages/console/app/src/routes/workspace/[id]/provider-section.tsx b/packages/console/app/src/routes/workspace/[id]/provider-section.tsx
index fe04bf7c0242..558dafd8382a 100644
--- a/packages/console/app/src/routes/workspace/[id]/provider-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/provider-section.tsx
@@ -1,6 +1,6 @@
import { json, query, action, useParams, createAsync, useSubmission } from "@solidjs/router"
import { createEffect, For, Show } from "solid-js"
-import { Provider } from "@opencode-ai/console-core/provider.js"
+import { Provider } from "@opencoder-ai/console-core/provider.js"
import { withActor } from "~/context/auth.withActor"
import { createStore } from "solid-js/store"
import styles from "./provider-section.module.css"
diff --git a/packages/console/app/src/routes/workspace/[id]/settings/settings-section.tsx b/packages/console/app/src/routes/workspace/[id]/settings/settings-section.tsx
index 5e8331e2682c..3ec38a411e78 100644
--- a/packages/console/app/src/routes/workspace/[id]/settings/settings-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/settings/settings-section.tsx
@@ -2,10 +2,10 @@ import { json, action, useParams, useSubmission, createAsync, query } from "@sol
import { createEffect, Show } from "solid-js"
import { createStore } from "solid-js/store"
import { withActor } from "~/context/auth.withActor"
-import { Workspace } from "@opencode-ai/console-core/workspace.js"
+import { Workspace } from "@opencoder-ai/console-core/workspace.js"
import styles from "./settings-section.module.css"
-import { Database, eq } from "@opencode-ai/console-core/drizzle/index.js"
-import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js"
+import { Database, eq } from "@opencoder-ai/console-core/drizzle/index.js"
+import { WorkspaceTable } from "@opencoder-ai/console-core/schema/workspace.sql.js"
import { useI18n } from "~/context/i18n"
import { formError, localizeError } from "~/lib/form-error"
diff --git a/packages/console/app/src/routes/workspace/[id]/usage-section.tsx b/packages/console/app/src/routes/workspace/[id]/usage-section.tsx
index 079a27c3ca79..b30a98256b36 100644
--- a/packages/console/app/src/routes/workspace/[id]/usage-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/usage-section.tsx
@@ -1,4 +1,4 @@
-import { Billing } from "@opencode-ai/console-core/billing.js"
+import { Billing } from "@opencoder-ai/console-core/billing.js"
import { createAsync, query, useParams } from "@solidjs/router"
import { createMemo, For, Show, createEffect, createSignal } from "solid-js"
import { formatDateUTC, formatDateForTable } from "../common"
diff --git a/packages/console/app/src/routes/workspace/common.tsx b/packages/console/app/src/routes/workspace/common.tsx
index 5cbd67183516..8cc8ebcb9f3e 100644
--- a/packages/console/app/src/routes/workspace/common.tsx
+++ b/packages/console/app/src/routes/workspace/common.tsx
@@ -1,11 +1,11 @@
-import { Resource } from "@opencode-ai/console-resource"
-import { Actor } from "@opencode-ai/console-core/actor.js"
+import { Resource } from "@opencoder-ai/console-resource"
+import { Actor } from "@opencoder-ai/console-core/actor.js"
import { action, json, query } from "@solidjs/router"
import { withActor } from "~/context/auth.withActor"
-import { Billing } from "@opencode-ai/console-core/billing.js"
-import { and, Database, desc, eq, isNull } from "@opencode-ai/console-core/drizzle/index.js"
-import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js"
-import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
+import { Billing } from "@opencoder-ai/console-core/billing.js"
+import { and, Database, desc, eq, isNull } from "@opencoder-ai/console-core/drizzle/index.js"
+import { WorkspaceTable } from "@opencoder-ai/console-core/schema/workspace.sql.js"
+import { UserTable } from "@opencoder-ai/console-core/schema/user.sql.js"
export function formatDateForTable(date: Date) {
const options: Intl.DateTimeFormatOptions = {
diff --git a/packages/console/app/src/routes/zen/util/dataDumper.ts b/packages/console/app/src/routes/zen/util/dataDumper.ts
index b852ca0b5c0c..154391ff4cd2 100644
--- a/packages/console/app/src/routes/zen/util/dataDumper.ts
+++ b/packages/console/app/src/routes/zen/util/dataDumper.ts
@@ -1,4 +1,4 @@
-import { Resource, waitUntil } from "@opencode-ai/console-resource"
+import { Resource, waitUntil } from "@opencoder-ai/console-resource"
export function createDataDumper(sessionId: string, requestId: string, projectId: string) {
if (Resource.App.stage !== "production") return
diff --git a/packages/console/app/src/routes/zen/util/handler.ts b/packages/console/app/src/routes/zen/util/handler.ts
index d2bcaa851b2d..5b5a19fc101d 100644
--- a/packages/console/app/src/routes/zen/util/handler.ts
+++ b/packages/console/app/src/routes/zen/util/handler.ts
@@ -1,18 +1,18 @@
import type { APIEvent } from "@solidjs/start/server"
-import { and, Database, eq, isNull, lt, or, sql } from "@opencode-ai/console-core/drizzle/index.js"
-import { KeyTable } from "@opencode-ai/console-core/schema/key.sql.js"
-import { BillingTable, SubscriptionTable, UsageTable } from "@opencode-ai/console-core/schema/billing.sql.js"
-import { centsToMicroCents } from "@opencode-ai/console-core/util/price.js"
-import { getWeekBounds } from "@opencode-ai/console-core/util/date.js"
-import { Identifier } from "@opencode-ai/console-core/identifier.js"
-import { Billing } from "@opencode-ai/console-core/billing.js"
-import { Actor } from "@opencode-ai/console-core/actor.js"
-import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js"
-import { ZenData } from "@opencode-ai/console-core/model.js"
-import { Black, BlackData } from "@opencode-ai/console-core/black.js"
-import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
-import { ModelTable } from "@opencode-ai/console-core/schema/model.sql.js"
-import { ProviderTable } from "@opencode-ai/console-core/schema/provider.sql.js"
+import { and, Database, eq, isNull, lt, or, sql } from "@opencoder-ai/console-core/drizzle/index.js"
+import { KeyTable } from "@opencoder-ai/console-core/schema/key.sql.js"
+import { BillingTable, SubscriptionTable, UsageTable } from "@opencoder-ai/console-core/schema/billing.sql.js"
+import { centsToMicroCents } from "@opencoder-ai/console-core/util/price.js"
+import { getWeekBounds } from "@opencoder-ai/console-core/util/date.js"
+import { Identifier } from "@opencoder-ai/console-core/identifier.js"
+import { Billing } from "@opencoder-ai/console-core/billing.js"
+import { Actor } from "@opencoder-ai/console-core/actor.js"
+import { WorkspaceTable } from "@opencoder-ai/console-core/schema/workspace.sql.js"
+import { ZenData } from "@opencoder-ai/console-core/model.js"
+import { Black, BlackData } from "@opencoder-ai/console-core/black.js"
+import { UserTable } from "@opencoder-ai/console-core/schema/user.sql.js"
+import { ModelTable } from "@opencoder-ai/console-core/schema/model.sql.js"
+import { ProviderTable } from "@opencoder-ai/console-core/schema/provider.sql.js"
import { logger } from "./logger"
import {
AuthError,
diff --git a/packages/console/app/src/routes/zen/util/logger.ts b/packages/console/app/src/routes/zen/util/logger.ts
index aef46ddd0e61..6c9f54f9d822 100644
--- a/packages/console/app/src/routes/zen/util/logger.ts
+++ b/packages/console/app/src/routes/zen/util/logger.ts
@@ -1,4 +1,4 @@
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
export const logger = {
metric: (values: Record) => {
diff --git a/packages/console/app/src/routes/zen/util/provider/provider.ts b/packages/console/app/src/routes/zen/util/provider/provider.ts
index 5f8b631cf089..f9df0ddab8ff 100644
--- a/packages/console/app/src/routes/zen/util/provider/provider.ts
+++ b/packages/console/app/src/routes/zen/util/provider/provider.ts
@@ -1,4 +1,4 @@
-import { ZenData } from "@opencode-ai/console-core/model.js"
+import { ZenData } from "@opencoder-ai/console-core/model.js"
import {
fromAnthropicChunk,
fromAnthropicRequest,
diff --git a/packages/console/app/src/routes/zen/util/rateLimiter.ts b/packages/console/app/src/routes/zen/util/rateLimiter.ts
index 5e4f31e67697..7665145e44ab 100644
--- a/packages/console/app/src/routes/zen/util/rateLimiter.ts
+++ b/packages/console/app/src/routes/zen/util/rateLimiter.ts
@@ -1,8 +1,8 @@
-import { Database, eq, and, sql, inArray } from "@opencode-ai/console-core/drizzle/index.js"
-import { IpRateLimitTable } from "@opencode-ai/console-core/schema/ip.sql.js"
+import { Database, eq, and, sql, inArray } from "@opencoder-ai/console-core/drizzle/index.js"
+import { IpRateLimitTable } from "@opencoder-ai/console-core/schema/ip.sql.js"
import { FreeUsageLimitError } from "./error"
import { logger } from "./logger"
-import { ZenData } from "@opencode-ai/console-core/model.js"
+import { ZenData } from "@opencoder-ai/console-core/model.js"
export function createRateLimiter(limit: ZenData.RateLimit | undefined, rawIp: string, headers: Headers) {
if (!limit) return
diff --git a/packages/console/app/src/routes/zen/util/stickyProviderTracker.ts b/packages/console/app/src/routes/zen/util/stickyProviderTracker.ts
index 8029757c5b61..3cd81bf996fb 100644
--- a/packages/console/app/src/routes/zen/util/stickyProviderTracker.ts
+++ b/packages/console/app/src/routes/zen/util/stickyProviderTracker.ts
@@ -1,4 +1,4 @@
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
export function createStickyTracker(stickyProvider: "strict" | "prefer" | undefined, session: string) {
if (!stickyProvider) return
diff --git a/packages/console/app/src/routes/zen/util/trialLimiter.ts b/packages/console/app/src/routes/zen/util/trialLimiter.ts
index 531e5cf0c302..60dff9f05695 100644
--- a/packages/console/app/src/routes/zen/util/trialLimiter.ts
+++ b/packages/console/app/src/routes/zen/util/trialLimiter.ts
@@ -1,7 +1,7 @@
-import { Database, eq, sql } from "@opencode-ai/console-core/drizzle/index.js"
-import { IpTable } from "@opencode-ai/console-core/schema/ip.sql.js"
+import { Database, eq, sql } from "@opencoder-ai/console-core/drizzle/index.js"
+import { IpTable } from "@opencoder-ai/console-core/schema/ip.sql.js"
import { UsageInfo } from "./provider/provider"
-import { ZenData } from "@opencode-ai/console-core/model.js"
+import { ZenData } from "@opencoder-ai/console-core/model.js"
export function createTrialLimiter(trial: ZenData.Trial | undefined, ip: string, client: string) {
if (!trial) return
diff --git a/packages/console/app/src/routes/zen/v1/models.ts b/packages/console/app/src/routes/zen/v1/models.ts
index ee2b3ab5416e..59a8d8129577 100644
--- a/packages/console/app/src/routes/zen/v1/models.ts
+++ b/packages/console/app/src/routes/zen/v1/models.ts
@@ -1,9 +1,9 @@
import type { APIEvent } from "@solidjs/start/server"
-import { and, Database, eq, isNull } from "@opencode-ai/console-core/drizzle/index.js"
-import { KeyTable } from "@opencode-ai/console-core/schema/key.sql.js"
-import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js"
-import { ModelTable } from "@opencode-ai/console-core/schema/model.sql.js"
-import { ZenData } from "@opencode-ai/console-core/model.js"
+import { and, Database, eq, isNull } from "@opencoder-ai/console-core/drizzle/index.js"
+import { KeyTable } from "@opencoder-ai/console-core/schema/key.sql.js"
+import { WorkspaceTable } from "@opencoder-ai/console-core/schema/workspace.sql.js"
+import { ModelTable } from "@opencoder-ai/console-core/schema/model.sql.js"
+import { ZenData } from "@opencoder-ai/console-core/model.js"
export async function OPTIONS(input: APIEvent) {
return new Response(null, {
diff --git a/packages/console/core/package.json b/packages/console/core/package.json
index 0676595c709a..29d0dd447927 100644
--- a/packages/console/core/package.json
+++ b/packages/console/core/package.json
@@ -1,18 +1,18 @@
{
"$schema": "https://json.schemastore.org/package.json",
- "name": "@opencode-ai/console-core",
- "version": "1.1.65",
+ "name": "@opencoder-ai/console-core",
+ "version": "1.1.63",
"private": true,
"type": "module",
"license": "MIT",
"dependencies": {
"@aws-sdk/client-sts": "3.782.0",
"@jsx-email/render": "1.1.1",
- "@opencode-ai/console-mail": "workspace:*",
- "@opencode-ai/console-resource": "workspace:*",
+ "@opencoder-ai/console-mail": "workspace:*",
+ "@opencoder-ai/console-resource": "workspace:*",
"@planetscale/database": "1.19.0",
"aws4fetch": "1.0.20",
- "drizzle-orm": "0.41.0",
+ "drizzle-orm": "0.45.1",
"postgres": "3.4.7",
"stripe": "18.0.0",
"ulid": "catalog:",
@@ -44,9 +44,9 @@
"@tsconfig/node22": "22.0.2",
"@types/bun": "1.3.0",
"@types/node": "catalog:",
- "drizzle-kit": "0.30.5",
+ "@typescript/native-preview": "catalog:",
+ "drizzle-kit": "0.31.8",
"mysql2": "3.14.4",
- "typescript": "catalog:",
- "@typescript/native-preview": "catalog:"
+ "typescript": "catalog:"
}
}
diff --git a/packages/console/core/script/reset-db.ts b/packages/console/core/script/reset-db.ts
index 02d498901763..21ae97ab2cc5 100644
--- a/packages/console/core/script/reset-db.ts
+++ b/packages/console/core/script/reset-db.ts
@@ -1,4 +1,4 @@
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
import { Database } from "../src/drizzle/index.js"
import { UserTable } from "../src/schema/user.sql.js"
import { AccountTable } from "../src/schema/account.sql.js"
diff --git a/packages/console/core/src/aws.ts b/packages/console/core/src/aws.ts
index a4c1510862c3..138dd3d67a98 100644
--- a/packages/console/core/src/aws.ts
+++ b/packages/console/core/src/aws.ts
@@ -1,5 +1,5 @@
import { z } from "zod"
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
import { AwsClient } from "aws4fetch"
import { fn } from "./util/fn"
diff --git a/packages/console/core/src/billing.ts b/packages/console/core/src/billing.ts
index 2c1cdb0687bb..d6fdfcd2c613 100644
--- a/packages/console/core/src/billing.ts
+++ b/packages/console/core/src/billing.ts
@@ -4,7 +4,7 @@ import { BillingTable, PaymentTable, SubscriptionTable, UsageTable } from "./sch
import { Actor } from "./actor"
import { fn } from "./util/fn"
import { z } from "zod"
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
import { Identifier } from "./identifier"
import { centsToMicroCents } from "./util/price"
import { User } from "./user"
diff --git a/packages/console/core/src/black.ts b/packages/console/core/src/black.ts
index 5f8db62738db..438ebfd7a351 100644
--- a/packages/console/core/src/black.ts
+++ b/packages/console/core/src/black.ts
@@ -1,6 +1,6 @@
import { z } from "zod"
import { fn } from "./util/fn"
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
import { centsToMicroCents } from "./util/price"
import { getWeekBounds } from "./util/date"
import { SubscriptionPlan } from "./schema/billing.sql"
diff --git a/packages/console/core/src/drizzle/index.ts b/packages/console/core/src/drizzle/index.ts
index f0f065de4a53..f7ede1d4f28b 100644
--- a/packages/console/core/src/drizzle/index.ts
+++ b/packages/console/core/src/drizzle/index.ts
@@ -1,5 +1,5 @@
import { drizzle } from "drizzle-orm/planetscale-serverless"
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
export * from "drizzle-orm"
import { Client } from "@planetscale/database"
diff --git a/packages/console/core/src/model.ts b/packages/console/core/src/model.ts
index 9a2908e32e3a..b7b2ec5fcfcb 100644
--- a/packages/console/core/src/model.ts
+++ b/packages/console/core/src/model.ts
@@ -5,7 +5,7 @@ import { ModelTable } from "./schema/model.sql"
import { Identifier } from "./identifier"
import { fn } from "./util/fn"
import { Actor } from "./actor"
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
export namespace ZenData {
const FormatSchema = z.enum(["anthropic", "google", "openai", "oa-compat"])
diff --git a/packages/console/core/src/user.ts b/packages/console/core/src/user.ts
index 8b7a96f443ef..03a073ddef91 100644
--- a/packages/console/core/src/user.ts
+++ b/packages/console/core/src/user.ts
@@ -138,7 +138,7 @@ export namespace User {
.then((rows) => rows[0]),
)
- const { InviteEmail } = await import("@opencode-ai/console-mail/InviteEmail.jsx")
+ const { InviteEmail } = await import("@opencoder-ai/console-mail/InviteEmail.jsx")
await AWS.sendEmail({
to: email,
subject: `You've been invited to join the ${emailInfo.workspaceName} workspace on OpenCode`,
diff --git a/packages/console/function/package.json b/packages/console/function/package.json
index 265546fc7f75..1c0a044dbe38 100644
--- a/packages/console/function/package.json
+++ b/packages/console/function/package.json
@@ -1,6 +1,6 @@
{
- "name": "@opencode-ai/console-function",
- "version": "1.1.65",
+ "name": "@opencoder-ai/console-function",
+ "version": "1.1.63",
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",
@@ -12,18 +12,18 @@
"@cloudflare/workers-types": "catalog:",
"@tsconfig/node22": "22.0.2",
"@types/node": "catalog:",
+ "@typescript/native-preview": "catalog:",
"openai": "5.11.0",
- "typescript": "catalog:",
- "@typescript/native-preview": "catalog:"
+ "typescript": "catalog:"
},
"dependencies": {
- "@ai-sdk/anthropic": "2.0.0",
- "@ai-sdk/openai": "2.0.2",
- "@ai-sdk/openai-compatible": "1.0.1",
+ "@ai-sdk/anthropic": "2.0.57",
+ "@ai-sdk/openai": "2.0.89",
+ "@ai-sdk/openai-compatible": "1.0.30",
"@hono/zod-validator": "catalog:",
- "@opencode-ai/console-core": "workspace:*",
- "@opencode-ai/console-resource": "workspace:*",
"@openauthjs/openauth": "0.0.0-20250322224806",
+ "@opencoder-ai/console-core": "workspace:*",
+ "@opencoder-ai/console-resource": "workspace:*",
"ai": "catalog:",
"hono": "catalog:",
"zod": "catalog:"
diff --git a/packages/console/function/src/auth.ts b/packages/console/function/src/auth.ts
index c26ab215b32b..ac960ebfcad3 100644
--- a/packages/console/function/src/auth.ts
+++ b/packages/console/function/src/auth.ts
@@ -7,16 +7,16 @@ import { THEME_OPENAUTH } from "@openauthjs/openauth/ui/theme"
import { GithubProvider } from "@openauthjs/openauth/provider/github"
import { GoogleOidcProvider } from "@openauthjs/openauth/provider/google"
import { CloudflareStorage } from "@openauthjs/openauth/storage/cloudflare"
-import { Account } from "@opencode-ai/console-core/account.js"
-import { Workspace } from "@opencode-ai/console-core/workspace.js"
-import { Actor } from "@opencode-ai/console-core/actor.js"
-import { Resource } from "@opencode-ai/console-resource"
-import { User } from "@opencode-ai/console-core/user.js"
-import { and, Database, eq, isNull, or } from "@opencode-ai/console-core/drizzle/index.js"
-import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js"
-import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
-import { AuthTable } from "@opencode-ai/console-core/schema/auth.sql.js"
-import { Identifier } from "@opencode-ai/console-core/identifier.js"
+import { Account } from "@opencoder-ai/console-core/account.js"
+import { Workspace } from "@opencoder-ai/console-core/workspace.js"
+import { Actor } from "@opencoder-ai/console-core/actor.js"
+import { Resource } from "@opencoder-ai/console-resource"
+import { User } from "@opencoder-ai/console-core/user.js"
+import { and, Database, eq, isNull, or } from "@opencoder-ai/console-core/drizzle/index.js"
+import { WorkspaceTable } from "@opencoder-ai/console-core/schema/workspace.sql.js"
+import { UserTable } from "@opencoder-ai/console-core/schema/user.sql.js"
+import { AuthTable } from "@opencoder-ai/console-core/schema/auth.sql.js"
+import { Identifier } from "@opencoder-ai/console-core/identifier.js"
type Env = {
AuthStorage: KVNamespace
diff --git a/packages/console/function/src/log-processor.ts b/packages/console/function/src/log-processor.ts
index 327fc930b72e..caffcd5f8ffa 100644
--- a/packages/console/function/src/log-processor.ts
+++ b/packages/console/function/src/log-processor.ts
@@ -1,4 +1,4 @@
-import { Resource } from "@opencode-ai/console-resource"
+import { Resource } from "@opencoder-ai/console-resource"
import type { TraceItem } from "@cloudflare/workers-types"
export default {
diff --git a/packages/console/mail/package.json b/packages/console/mail/package.json
index 0f4bbb6eca7d..bf6617c29262 100644
--- a/packages/console/mail/package.json
+++ b/packages/console/mail/package.json
@@ -1,13 +1,12 @@
{
- "name": "@opencode-ai/console-mail",
- "version": "1.1.65",
+ "name": "@opencoder-ai/console-mail",
+ "version": "1.1.63",
"dependencies": {
"@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3",
"@tsconfig/bun": "1.0.9",
- "@types/react": "18.0.25",
- "react": "18.2.0",
- "solid-js": "catalog:"
+ "solid-js": "catalog:",
+ "react": "18.2.0"
},
"exports": {
"./*": "./emails/templates/*"
@@ -18,5 +17,8 @@
"dev": "email preview emails/templates"
},
"type": "module",
- "license": "MIT"
+ "license": "MIT",
+ "devDependencies": {
+ "@types/react": "18.0.25"
+ }
}
diff --git a/packages/console/resource/package.json b/packages/console/resource/package.json
index 6e874331d248..ba6c014822c8 100644
--- a/packages/console/resource/package.json
+++ b/packages/console/resource/package.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
- "name": "@opencode-ai/console-resource",
+ "name": "@opencoder-ai/console-resource",
"license": "MIT",
"dependencies": {
"@cloudflare/workers-types": "catalog:"
diff --git a/packages/desktop/package.json b/packages/desktop/package.json
index 8e4862b30d16..d826d9c02190 100644
--- a/packages/desktop/package.json
+++ b/packages/desktop/package.json
@@ -1,5 +1,5 @@
{
- "name": "@opencode-ai/desktop",
+ "name": "@opencoder-ai/desktop",
"private": true,
"version": "1.1.65",
"type": "module",
@@ -13,28 +13,28 @@
"tauri": "tauri"
},
"dependencies": {
- "@opencode-ai/app": "workspace:*",
- "@opencode-ai/ui": "workspace:*",
+ "@opencoder-ai/app": "workspace:*",
+ "@opencoder-ai/ui": "workspace:*",
"@solid-primitives/i18n": "2.2.1",
"@solid-primitives/storage": "catalog:",
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-clipboard-manager": "~2",
"@tauri-apps/plugin-deep-link": "~2",
"@tauri-apps/plugin-dialog": "~2",
+ "@tauri-apps/plugin-http": "~2",
+ "@tauri-apps/plugin-notification": "~2",
"@tauri-apps/plugin-opener": "^2",
"@tauri-apps/plugin-os": "~2",
- "@tauri-apps/plugin-notification": "~2",
"@tauri-apps/plugin-process": "~2",
"@tauri-apps/plugin-shell": "~2",
"@tauri-apps/plugin-store": "~2",
"@tauri-apps/plugin-updater": "~2",
- "@tauri-apps/plugin-http": "~2",
"@tauri-apps/plugin-window-state": "~2",
"solid-js": "catalog:",
"@solidjs/meta": "catalog:"
},
"devDependencies": {
- "@actions/artifact": "4.0.0",
+ "@actions/artifact": "5.0.1",
"@tauri-apps/cli": "^2",
"@types/bun": "catalog:",
"@typescript/native-preview": "catalog:",
diff --git a/packages/desktop/scripts/prepare.ts b/packages/desktop/scripts/prepare.ts
index d802f2d89eeb..45a16e17e125 100755
--- a/packages/desktop/scripts/prepare.ts
+++ b/packages/desktop/scripts/prepare.ts
@@ -1,7 +1,7 @@
#!/usr/bin/env bun
import { $ } from "bun"
-import { Script } from "@opencode-ai/script"
+import { Script } from "@opencoder-ai/script"
import { copyBinaryToSidecarFolder, getCurrentSidecar, windowsify } from "./utils"
const pkg = await Bun.file("./package.json").json()
diff --git a/packages/desktop/src/index.tsx b/packages/desktop/src/index.tsx
index ff0a093766ed..e63a8d8f999c 100644
--- a/packages/desktop/src/index.tsx
+++ b/packages/desktop/src/index.tsx
@@ -6,9 +6,9 @@ import {
AppInterface,
PlatformProvider,
Platform,
+ DisplayBackend,
useCommand,
- handleNotificationClick,
-} from "@opencode-ai/app"
+} from "@opencoder-ai/app"
import { open, save } from "@tauri-apps/plugin-dialog"
import { getCurrent, onOpenUrl } from "@tauri-apps/plugin-deep-link"
import { openPath as openerOpenPath } from "@tauri-apps/plugin-opener"
@@ -21,7 +21,7 @@ import { relaunch } from "@tauri-apps/plugin-process"
import { AsyncStorage } from "@solid-primitives/storage"
import { fetch as tauriFetch } from "@tauri-apps/plugin-http"
import { Store } from "@tauri-apps/plugin-store"
-import { Splash } from "@opencode-ai/ui/logo"
+import { Splash } from "@opencoder-ai/ui/logo"
import { createSignal, Show, Accessor, JSX, createResource, onMount, onCleanup } from "solid-js"
import { readImage } from "@tauri-apps/plugin-clipboard-manager"
@@ -336,7 +336,10 @@ const createPlatform = (password: Accessor): Platform => {
void win.show().catch(() => undefined)
void win.unminimize().catch(() => undefined)
void win.setFocus().catch(() => undefined)
- handleNotificationClick(href)
+ if (href) {
+ window.history.pushState(null, "", href)
+ window.dispatchEvent(new PopStateEvent("popstate"))
+ }
notification.close()
}
})
diff --git a/packages/desktop/src/loading.tsx b/packages/desktop/src/loading.tsx
index 23a8055c9d6f..3b5ed3174acb 100644
--- a/packages/desktop/src/loading.tsx
+++ b/packages/desktop/src/loading.tsx
@@ -1,9 +1,9 @@
import { render } from "solid-js/web"
import { MetaProvider } from "@solidjs/meta"
-import "@opencode-ai/app/index.css"
-import { Font } from "@opencode-ai/ui/font"
-import { Splash } from "@opencode-ai/ui/logo"
-import { Progress } from "@opencode-ai/ui/progress"
+import "@opencoder-ai/app/index.css"
+import { Font } from "@opencoder-ai/ui/font"
+import { Splash } from "@opencoder-ai/ui/logo"
+import { Progress } from "@opencoder-ai/ui/progress"
import "./styles.css"
import { createEffect, createMemo, createSignal, onCleanup, onMount } from "solid-js"
import { commands, events, InitStep } from "./bindings"
diff --git a/packages/desktop/vite.config.ts b/packages/desktop/vite.config.ts
index 62c3a099adeb..eb3a3dae5524 100644
--- a/packages/desktop/vite.config.ts
+++ b/packages/desktop/vite.config.ts
@@ -1,5 +1,5 @@
import { defineConfig } from "vite"
-import appPlugin from "@opencode-ai/app/vite"
+import appPlugin from "@opencoder-ai/app/vite"
const host = process.env.TAURI_DEV_HOST
diff --git a/packages/docs/docs.json b/packages/docs/docs.json
index 1bf8b3700b93..2ade74281706 100644
--- a/packages/docs/docs.json
+++ b/packages/docs/docs.json
@@ -1,7 +1,7 @@
{
"$schema": "https://mintlify.com/docs.json",
"theme": "mint",
- "name": "@opencode-ai/docs",
+ "name": "@opencoder-ai/docs",
"colors": {
"primary": "#16A34A",
"light": "#07C983",
diff --git a/packages/enterprise/AGENTS.md b/packages/enterprise/AGENTS.md
new file mode 100644
index 000000000000..03302b0f8a53
--- /dev/null
+++ b/packages/enterprise/AGENTS.md
@@ -0,0 +1,34 @@
+# Enterprise Features
+
+**Package:** `packages/enterprise`
+**Type:** Enterprise-specific functionality
+
+## Overview
+
+Enterprise features including shareable routes, API endpoints, and business logic.
+
+## Structure
+
+```
+packages/enterprise/src/
+├── core/ # Core enterprise logic
+└── routes/ # API and page routes
+ ├── api/ # API endpoints
+ └── share/ # Share functionality
+```
+
+## Commands
+
+```bash
+# Dev
+bun dev
+
+# Build
+bun build
+```
+
+## Key Patterns
+
+- Hono for API routes
+- SST deployment
+- Enterprise-specific business logic
diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json
index bd2fac19f762..fc8e875bf6be 100644
--- a/packages/enterprise/package.json
+++ b/packages/enterprise/package.json
@@ -1,6 +1,6 @@
{
- "name": "@opencode-ai/enterprise",
- "version": "1.1.65",
+ "name": "@opencoder-ai/enterprise",
+ "version": "1.1.63",
"private": true,
"type": "module",
"license": "MIT",
@@ -13,13 +13,13 @@
"shell-prod": "sst shell --target Teams --stage production"
},
"dependencies": {
- "@opencode-ai/util": "workspace:*",
- "@opencode-ai/ui": "workspace:*",
- "aws4fetch": "^1.0.20",
+ "@opencoder-ai/ui": "workspace:*",
+ "@opencoder-ai/util": "workspace:*",
"@pierre/diffs": "catalog:",
+ "@solidjs/meta": "catalog:",
"@solidjs/router": "catalog:",
"@solidjs/start": "catalog:",
- "@solidjs/meta": "catalog:",
+ "aws4fetch": "1.0.20",
"hono": "catalog:",
"hono-openapi": "catalog:",
"js-base64": "3.7.7",
@@ -31,8 +31,8 @@
"devDependencies": {
"@cloudflare/workers-types": "catalog:",
"@tailwindcss/vite": "catalog:",
- "@typescript/native-preview": "catalog:",
"@types/luxon": "catalog:",
+ "@typescript/native-preview": "catalog:",
"tailwindcss": "catalog:",
"typescript": "catalog:",
"vite": "catalog:"
diff --git a/packages/enterprise/src/app.css b/packages/enterprise/src/app.css
index 4af87bca632a..e3d82c978efc 100644
--- a/packages/enterprise/src/app.css
+++ b/packages/enterprise/src/app.css
@@ -1 +1 @@
-@import "@opencode-ai/ui/styles/tailwind";
+@import "@opencoder-ai/ui/styles/tailwind";
diff --git a/packages/enterprise/src/app.tsx b/packages/enterprise/src/app.tsx
index 6f9cdcafb893..ab72ed8c5c5c 100644
--- a/packages/enterprise/src/app.tsx
+++ b/packages/enterprise/src/app.tsx
@@ -1,16 +1,16 @@
import { Router } from "@solidjs/router"
import { FileRoutes } from "@solidjs/start/router"
-import { Font } from "@opencode-ai/ui/font"
+import { Font } from "@opencoder-ai/ui/font"
import { MetaProvider } from "@solidjs/meta"
-import { MarkedProvider } from "@opencode-ai/ui/context/marked"
-import { DialogProvider } from "@opencode-ai/ui/context/dialog"
-import { I18nProvider, type UiI18nParams } from "@opencode-ai/ui/context"
-import { dict as uiEn } from "@opencode-ai/ui/i18n/en"
-import { dict as uiZh } from "@opencode-ai/ui/i18n/zh"
+import { MarkedProvider } from "@opencoder-ai/ui/context/marked"
+import { DialogProvider } from "@opencoder-ai/ui/context/dialog"
+import { I18nProvider, type UiI18nParams } from "@opencoder-ai/ui/context"
+import { dict as uiEn } from "@opencoder-ai/ui/i18n/en"
+import { dict as uiZh } from "@opencoder-ai/ui/i18n/zh"
import { createEffect, createMemo, Suspense, type ParentProps } from "solid-js"
import { getRequestEvent } from "solid-js/web"
import "./app.css"
-import { Favicon } from "@opencode-ai/ui/favicon"
+import { Favicon } from "@opencoder-ai/ui/favicon"
function resolveTemplate(text: string, params?: UiI18nParams) {
if (!params) return text
diff --git a/packages/enterprise/src/core/share.ts b/packages/enterprise/src/core/share.ts
index d7f5c8b8d523..dd2f0d78c7ac 100644
--- a/packages/enterprise/src/core/share.ts
+++ b/packages/enterprise/src/core/share.ts
@@ -1,10 +1,10 @@
-import { FileDiff, Message, Model, Part, Session } from "@opencode-ai/sdk/v2"
-import { fn } from "@opencode-ai/util/fn"
-import { iife } from "@opencode-ai/util/iife"
-import { Identifier } from "@opencode-ai/util/identifier"
+import { FileDiff, Message, Model, Part, Session } from "@opencoder-ai/sdk/v2"
+import { fn } from "@opencoder-ai/util/fn"
+import { iife } from "@opencoder-ai/util/iife"
+import { Identifier } from "@opencoder-ai/util/identifier"
import z from "zod"
import { Storage } from "./storage"
-import { Binary } from "@opencode-ai/util/binary"
+import { Binary } from "@opencoder-ai/util/binary"
export namespace Share {
export const Info = z.object({
diff --git a/packages/enterprise/src/core/storage.ts b/packages/enterprise/src/core/storage.ts
index b8030b4f901a..2644b1f08e31 100644
--- a/packages/enterprise/src/core/storage.ts
+++ b/packages/enterprise/src/core/storage.ts
@@ -1,5 +1,5 @@
import { AwsClient } from "aws4fetch"
-import { lazy } from "@opencode-ai/util/lazy"
+import { lazy } from "@opencoder-ai/util/lazy"
export namespace Storage {
export interface Adapter {
diff --git a/packages/enterprise/src/routes/share/[shareID].tsx b/packages/enterprise/src/routes/share/[shareID].tsx
index a2607891c8a7..07085c5ea929 100644
--- a/packages/enterprise/src/routes/share/[shareID].tsx
+++ b/packages/enterprise/src/routes/share/[shareID].tsx
@@ -1,37 +1,37 @@
-import { FileDiff, Message, Model, Part, Session, SessionStatus, UserMessage } from "@opencode-ai/sdk/v2"
-import { SessionTurn } from "@opencode-ai/ui/session-turn"
-import { SessionReview } from "@opencode-ai/ui/session-review"
-import { DataProvider } from "@opencode-ai/ui/context"
-import { DiffComponentProvider } from "@opencode-ai/ui/context/diff"
-import { CodeComponentProvider } from "@opencode-ai/ui/context/code"
-import { WorkerPoolProvider } from "@opencode-ai/ui/context/worker-pool"
+import { FileDiff, Message, Model, Part, Session, SessionStatus, UserMessage } from "@opencoder-ai/sdk/v2"
+import { SessionTurn } from "@opencoder-ai/ui/session-turn"
+import { SessionReview } from "@opencoder-ai/ui/session-review"
+import { DataProvider } from "@opencoder-ai/ui/context"
+import { DiffComponentProvider } from "@opencoder-ai/ui/context/diff"
+import { CodeComponentProvider } from "@opencoder-ai/ui/context/code"
+import { WorkerPoolProvider } from "@opencoder-ai/ui/context/worker-pool"
import { createAsync, query, useParams } from "@solidjs/router"
import { createEffect, createMemo, ErrorBoundary, For, Match, Show, Switch } from "solid-js"
import { Share } from "~/core/share"
-import { Logo, Mark } from "@opencode-ai/ui/logo"
-import { IconButton } from "@opencode-ai/ui/icon-button"
-import { ProviderIcon } from "@opencode-ai/ui/provider-icon"
-import { createDefaultOptions } from "@opencode-ai/ui/pierre"
-import { iife } from "@opencode-ai/util/iife"
-import { Binary } from "@opencode-ai/util/binary"
-import { NamedError } from "@opencode-ai/util/error"
+import { Logo, Mark } from "@opencoder-ai/ui/logo"
+import { IconButton } from "@opencoder-ai/ui/icon-button"
+import { ProviderIcon } from "@opencoder-ai/ui/provider-icon"
+import { createDefaultOptions } from "@opencoder-ai/ui/pierre"
+import { iife } from "@opencoder-ai/util/iife"
+import { Binary } from "@opencoder-ai/util/binary"
+import { NamedError } from "@opencoder-ai/util/error"
import { DateTime } from "luxon"
import { createStore } from "solid-js/store"
import z from "zod"
import NotFound from "../[...404]"
-import { Tabs } from "@opencode-ai/ui/tabs"
-import { MessageNav } from "@opencode-ai/ui/message-nav"
+import { Tabs } from "@opencoder-ai/ui/tabs"
+import { MessageNav } from "@opencoder-ai/ui/message-nav"
import { preloadMultiFileDiff, PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
-import { Diff as SSRDiff } from "@opencode-ai/ui/diff-ssr"
+import { Diff as SSRDiff } from "@opencoder-ai/ui/diff-ssr"
import { clientOnly } from "@solidjs/start"
-import { type IconName } from "@opencode-ai/ui/icons/provider"
+import { type IconName } from "@opencoder-ai/ui/icons/provider"
import { Meta, Title } from "@solidjs/meta"
import { Base64 } from "js-base64"
-const ClientOnlyDiff = clientOnly(() => import("@opencode-ai/ui/diff").then((m) => ({ default: m.Diff })))
-const ClientOnlyCode = clientOnly(() => import("@opencode-ai/ui/code").then((m) => ({ default: m.Code })))
+const ClientOnlyDiff = clientOnly(() => import("@opencoder-ai/ui/diff").then((m) => ({ default: m.Diff })))
+const ClientOnlyCode = clientOnly(() => import("@opencoder-ai/ui/code").then((m) => ({ default: m.Code })))
const ClientOnlyWorkerPoolProvider = clientOnly(() =>
- import("@opencode-ai/ui/pierre/worker").then((m) => ({
+ import("@opencoder-ai/ui/pierre/worker").then((m) => ({
default: (props: { children: any }) => (
{props.children}
),
@@ -162,12 +162,13 @@ export default function () {
return (
{
+ fallback={(error: unknown) => {
if (SessionDataMissingError.isInstance(error)) {
return
}
console.error(error)
- const details = error instanceof Error ? (error.stack ?? error.message) : String(error)
+ const err = error as Error
+ const details = err?.stack ?? err?.message ?? String(error)
return (
Unable to render this share.
diff --git a/packages/enterprise/test/core/share.test.ts b/packages/enterprise/test/core/share.test.ts
index 9e9c06db3841..56c671ded97b 100644
--- a/packages/enterprise/test/core/share.test.ts
+++ b/packages/enterprise/test/core/share.test.ts
@@ -1,7 +1,7 @@
import { describe, expect, test, afterAll } from "bun:test"
import { Share } from "../../src/core/share"
import { Storage } from "../../src/core/storage"
-import { Identifier } from "@opencode-ai/util/identifier"
+import { Identifier } from "@opencoder-ai/util/identifier"
describe.concurrent("core.share", () => {
test("should create a share", async () => {
diff --git a/packages/function/AGENTS.md b/packages/function/AGENTS.md
new file mode 100644
index 000000000000..395c101c9e50
--- /dev/null
+++ b/packages/function/AGENTS.md
@@ -0,0 +1,21 @@
+# Serverless Utilities
+
+**Package:** `packages/function`
+**Type:** Serverless function utilities
+
+## Overview
+
+Shared utilities and helpers for serverless function development.
+
+## Commands
+
+```bash
+# Build
+bun build
+```
+
+## Key Patterns
+
+- Cloudflare Workers compatible
+- Hono-based handlers
+- Shared function utilities
diff --git a/packages/function/package.json b/packages/function/package.json
index 4c10ab05f891..31a48399fecb 100644
--- a/packages/function/package.json
+++ b/packages/function/package.json
@@ -1,6 +1,6 @@
{
- "name": "@opencode-ai/function",
- "version": "1.1.65",
+ "name": "@opencoder-ai/function",
+ "version": "1.1.63",
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",
diff --git a/packages/opencode/AGENTS.md b/packages/opencode/AGENTS.md
index a68fd7f3e321..5bcab528a6cb 100644
--- a/packages/opencode/AGENTS.md
+++ b/packages/opencode/AGENTS.md
@@ -1,17 +1,24 @@
-# opencode agent guidelines
+# OpenCode CLI - TUI Application
+
+**Package:** `packages/opencode`
+**Type:** Main CLI/TUI application
+
+## Overview
+
+The core OpenCode terminal interface. Built with custom TUI, handles agent orchestration, file operations, and interactive sessions.
## Build/Test Commands
- **Install**: `bun install`
- **Run**: `bun run --conditions=browser ./src/index.ts`
-- **Typecheck**: `bun run typecheck` (npm run typecheck)
-- **Test**: `bun test` (runs all tests)
-- **Single test**: `bun test test/tool/tool.test.ts` (specific test file)
+- **Typecheck**: `bun run typecheck`
+- **Test**: `bun test`
+- **Single test**: `bun test test/tool/tool.test.ts`
## Code Style
- **Runtime**: Bun with TypeScript ESM modules
-- **Imports**: Use relative imports for local modules, named imports preferred
+- **Imports**: Relative imports for local modules, named imports preferred
- **Types**: Zod schemas for validation, TypeScript interfaces for structure
- **Naming**: camelCase for variables/functions, PascalCase for classes/namespaces
- **Error handling**: Use Result patterns, avoid throwing exceptions in tools
@@ -24,4 +31,26 @@
- **Validation**: All inputs validated with Zod schemas
- **Logging**: Use `Log.create({ service: "name" })` pattern
- **Storage**: Use `Storage` namespace for persistence
-- **API Client**: The TypeScript TUI (built with SolidJS + OpenTUI) communicates with the OpenCode server using `@opencode-ai/sdk`. When adding/modifying server endpoints in `packages/opencode/src/server/server.ts`, run `./script/generate.ts` to regenerate the SDK and related files.
+- **SDK Generation**: When modifying server endpoints in `server.ts`, run `./script/generate.ts`
+
+## Structure
+
+```
+packages/opencode/src/
+├── agent/ # Agent definitions and prompts
+├── cli/ # CLI commands
+├── file/ # File operations (has path security TODOs)
+├── permission/ # Permission system (incomplete)
+├── provider/ # LLM providers (legacy code marked for removal)
+├── server/ # Server (too large - needs refactor)
+├── session/ # Session management
+├── tool/ # Tool definitions
+└── bun/ # Bun runtime utilities
+```
+
+## Technical Debt (Priority)
+
+1. **Path security** (`src/file/index.ts`): Symlink escaping, Windows bypass
+2. **Legacy provider code** (`src/provider/provider.ts`): Marked for removal
+3. **Server refactor** (`src/server/server.ts`): Too large, needs splitting
+4. **Permission system** (`src/permission/next.ts`): Incomplete implementation
diff --git a/packages/opencode/package.json b/packages/opencode/package.json
index 82d562bb093b..34e4afb89fe1 100644
--- a/packages/opencode/package.json
+++ b/packages/opencode/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
- "version": "1.1.65",
- "name": "opencode",
+ "version": "1.1.63",
+ "name": "opencoder",
"type": "module",
"license": "MIT",
"private": true,
@@ -26,8 +26,9 @@
},
"devDependencies": {
"@babel/core": "7.28.4",
+ "@cloudflare/workers-types": "catalog:",
"@octokit/webhooks-types": "7.6.1",
- "@opencode-ai/script": "workspace:*",
+ "@opencoder-ai/script": "workspace:*",
"@parcel/watcher-darwin-arm64": "2.5.1",
"@parcel/watcher-darwin-x64": "2.5.1",
"@parcel/watcher-linux-arm64-glibc": "2.5.1",
@@ -45,18 +46,20 @@
"typescript": "catalog:",
"vscode-languageserver-types": "3.17.5",
"why-is-node-running": "3.2.2",
- "zod-to-json-schema": "3.24.5"
+ "zod-to-json-schema": "3.24.5",
+ "@types/pg": "8.16.0"
},
"dependencies": {
"@actions/core": "1.11.1",
"@actions/github": "6.0.1",
"@agentclientprotocol/sdk": "0.14.1",
- "@ai-sdk/amazon-bedrock": "3.0.79",
- "@ai-sdk/anthropic": "2.0.62",
+ "@agni/agent-sdk": "link:@agni/agent-sdk",
+ "@ai-sdk/amazon-bedrock": "3.0.74",
+ "@ai-sdk/anthropic": "2.0.58",
"@ai-sdk/azure": "2.0.91",
"@ai-sdk/cerebras": "1.0.36",
"@ai-sdk/cohere": "2.0.22",
- "@ai-sdk/deepinfra": "1.0.36",
+ "@ai-sdk/deepinfra": "1.0.33",
"@ai-sdk/gateway": "2.0.30",
"@ai-sdk/google": "2.0.52",
"@ai-sdk/google-vertex": "3.0.98",
@@ -79,10 +82,10 @@
"@octokit/graphql": "9.0.2",
"@octokit/rest": "catalog:",
"@openauthjs/openauth": "catalog:",
- "@opencode-ai/plugin": "workspace:*",
- "@opencode-ai/script": "workspace:*",
- "@opencode-ai/sdk": "workspace:*",
- "@opencode-ai/util": "workspace:*",
+ "@opencoder-ai/plugin": "workspace:*",
+ "@opencoder-ai/script": "workspace:*",
+ "@opencoder-ai/sdk": "workspace:*",
+ "@opencoder-ai/util": "workspace:*",
"@openrouter/ai-sdk-provider": "1.5.4",
"@opentui/core": "0.1.79",
"@opentui/solid": "0.1.79",
diff --git a/packages/opencode/script/build.ts b/packages/opencode/script/build.ts
index f0b3fa828a78..b19cc6325c6f 100755
--- a/packages/opencode/script/build.ts
+++ b/packages/opencode/script/build.ts
@@ -13,7 +13,7 @@ const dir = path.resolve(__dirname, "..")
process.chdir(dir)
import pkg from "../package.json"
-import { Script } from "@opencode-ai/script"
+import { Script } from "@opencoder-ai/script"
const modelsUrl = process.env.OPENCODE_MODELS_URL || "https://models.dev"
// Fetch and generate models.dev snapshot
const modelsData = process.env.MODELS_DEV_API_JSON
@@ -113,8 +113,10 @@ await $`rm -rf dist`
const binaries: Record
= {}
if (!skipInstall) {
- await $`bun install --os="*" --cpu="*" @opentui/core@${pkg.dependencies["@opentui/core"]}`
- await $`bun install --os="*" --cpu="*" @parcel/watcher@${pkg.dependencies["@parcel/watcher"]}`
+ // These installs are only to ensure platform artifacts are present for multi-target builds.
+ // Avoid mutating bun.lock during builds (keeps CI and automation worktrees clean).
+ await $`HUSKY=0 bun install --no-save --os="*" --cpu="*" @opentui/core@${pkg.dependencies["@opentui/core"]}`
+ await $`HUSKY=0 bun install --no-save --os="*" --cpu="*" @parcel/watcher@${pkg.dependencies["@parcel/watcher"]}`
}
for (const item of targets) {
const name = [
@@ -149,8 +151,8 @@ for (const item of targets) {
autoloadTsconfig: true,
autoloadPackageJson: true,
target: name.replace(pkg.name, "bun") as any,
- outfile: `dist/${name}/bin/opencode`,
- execArgv: [`--user-agent=opencode/${Script.version}`, "--use-system-ca", "--"],
+ outfile: `dist/${name}/bin/opencoder`,
+ execArgv: [`--user-agent=opencoder/${Script.version}`, "--use-system-ca", "--"],
windows: {},
},
entrypoints: ["./src/index.ts", parserWorker, workerPath],
diff --git a/packages/opencode/script/publish.ts b/packages/opencode/script/publish.ts
index fbc1c83ba6dc..ff28facca959 100755
--- a/packages/opencode/script/publish.ts
+++ b/packages/opencode/script/publish.ts
@@ -1,7 +1,7 @@
#!/usr/bin/env bun
import { $ } from "bun"
import pkg from "../package.json"
-import { Script } from "@opencode-ai/script"
+import { Script } from "@opencoder-ai/script"
import { fileURLToPath } from "url"
const dir = fileURLToPath(new URL("..", import.meta.url))
@@ -25,7 +25,7 @@ await Bun.file(`./dist/${pkg.name}/package.json`).write(
{
name: pkg.name + "-ai",
bin: {
- [pkg.name]: `./bin/${pkg.name}`,
+ opencode: `./bin/opencode`,
},
scripts: {
postinstall: "bun ./postinstall.mjs || node ./postinstall.mjs",
diff --git a/packages/opencode/src/acp/agent.ts b/packages/opencode/src/acp/agent.ts
index ae6f6fcc296a..77ede544494f 100644
--- a/packages/opencode/src/acp/agent.ts
+++ b/packages/opencode/src/acp/agent.ts
@@ -40,7 +40,7 @@ import { Config } from "@/config/config"
import { Todo } from "@/session/todo"
import { z } from "zod"
import { LoadAPIKeyError } from "ai"
-import type { AssistantMessage, Event, OpencodeClient, SessionMessageResponse } from "@opencode-ai/sdk/v2"
+import type { AssistantMessage, Event, OpencodeClient, SessionMessageResponse } from "@opencoder-ai/sdk/v2"
import { applyPatch } from "diff"
type ModeOption = { id: string; name: string; description?: string }
diff --git a/packages/opencode/src/acp/session.ts b/packages/opencode/src/acp/session.ts
index 18aa42313017..0801be8e9909 100644
--- a/packages/opencode/src/acp/session.ts
+++ b/packages/opencode/src/acp/session.ts
@@ -1,7 +1,7 @@
import { RequestError, type McpServer } from "@agentclientprotocol/sdk"
import type { ACPSessionState } from "./types"
import { Log } from "@/util/log"
-import type { OpencodeClient } from "@opencode-ai/sdk/v2"
+import type { OpencodeClient } from "@opencoder-ai/sdk/v2"
const log = Log.create({ service: "acp-session-manager" })
diff --git a/packages/opencode/src/acp/types.ts b/packages/opencode/src/acp/types.ts
index de8ac5081228..7e951d7a7b36 100644
--- a/packages/opencode/src/acp/types.ts
+++ b/packages/opencode/src/acp/types.ts
@@ -1,5 +1,5 @@
import type { McpServer } from "@agentclientprotocol/sdk"
-import type { OpencodeClient } from "@opencode-ai/sdk/v2"
+import type { OpencodeClient } from "@opencoder-ai/sdk/v2"
export interface ACPSessionState {
id: string
diff --git a/packages/opencode/src/bun/index.ts b/packages/opencode/src/bun/index.ts
index bdb7cff78e25..4d61f5267639 100644
--- a/packages/opencode/src/bun/index.ts
+++ b/packages/opencode/src/bun/index.ts
@@ -3,7 +3,7 @@ import { Global } from "../global"
import { Log } from "../util/log"
import path from "path"
import { Filesystem } from "../util/filesystem"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { readableStreamToText } from "bun"
import { Lock } from "../util/lock"
import { PackageRegistry } from "./registry"
diff --git a/packages/opencode/src/cli/cmd/acp.ts b/packages/opencode/src/cli/cmd/acp.ts
index 99a9a81ab9cd..b0a3be9d6d99 100644
--- a/packages/opencode/src/cli/cmd/acp.ts
+++ b/packages/opencode/src/cli/cmd/acp.ts
@@ -4,7 +4,7 @@ import { cmd } from "./cmd"
import { AgentSideConnection, ndJsonStream } from "@agentclientprotocol/sdk"
import { ACP } from "@/acp/agent"
import { Server } from "@/server/server"
-import { createOpencodeClient } from "@opencode-ai/sdk/v2"
+import { createOpencodeClient } from "@opencoder-ai/sdk/v2"
import { withNetworkOptions, resolveNetworkOptions } from "../network"
const log = Log.create({ service: "acp-command" })
diff --git a/packages/opencode/src/cli/cmd/auth.ts b/packages/opencode/src/cli/cmd/auth.ts
index 34e2269d0c16..d5f8ab3e469a 100644
--- a/packages/opencode/src/cli/cmd/auth.ts
+++ b/packages/opencode/src/cli/cmd/auth.ts
@@ -10,7 +10,7 @@ import { Config } from "../../config/config"
import { Global } from "../../global"
import { Plugin } from "../../plugin"
import { Instance } from "../../project/instance"
-import type { Hooks } from "@opencode-ai/plugin"
+import type { Hooks } from "@opencoder-ai/plugin"
type PluginAuth = NonNullable
diff --git a/packages/opencode/src/cli/cmd/debug/agent.ts b/packages/opencode/src/cli/cmd/debug/agent.ts
index fe3003485976..6836ceb2b051 100644
--- a/packages/opencode/src/cli/cmd/debug/agent.ts
+++ b/packages/opencode/src/cli/cmd/debug/agent.ts
@@ -152,6 +152,7 @@ async function createToolContext(agent: Agent.Info) {
messageID,
callID: Identifier.ascending("part"),
agent: agent.name,
+ model,
abort: new AbortController().signal,
messages: [],
metadata: () => {},
diff --git a/packages/opencode/src/cli/cmd/generate.ts b/packages/opencode/src/cli/cmd/generate.ts
index fad4514c81e5..dbfb6283b529 100644
--- a/packages/opencode/src/cli/cmd/generate.ts
+++ b/packages/opencode/src/cli/cmd/generate.ts
@@ -14,7 +14,7 @@ export const GenerateCommand = {
{
lang: "js",
source: [
- `import { createOpencodeClient } from "@opencode-ai/sdk`,
+ `import { createOpencodeClient } from "@opencoder-ai/sdk`,
``,
`const client = createOpencodeClient()`,
`await client.${operation.operationId}({`,
diff --git a/packages/opencode/src/cli/cmd/import.ts b/packages/opencode/src/cli/cmd/import.ts
index 37419f4e2350..2be33024674c 100644
--- a/packages/opencode/src/cli/cmd/import.ts
+++ b/packages/opencode/src/cli/cmd/import.ts
@@ -1,5 +1,5 @@
import type { Argv } from "yargs"
-import type { Session as SDKSession, Message, Part } from "@opencode-ai/sdk/v2"
+import type { Session as SDKSession, Message, Part } from "@opencoder-ai/sdk/v2"
import { Session } from "../../session"
import { cmd } from "./cmd"
import { bootstrap } from "../bootstrap"
diff --git a/packages/opencode/src/cli/cmd/run.ts b/packages/opencode/src/cli/cmd/run.ts
index 0febec3a207c..494b08ff1e88 100644
--- a/packages/opencode/src/cli/cmd/run.ts
+++ b/packages/opencode/src/cli/cmd/run.ts
@@ -6,7 +6,7 @@ import { cmd } from "./cmd"
import { Flag } from "../../flag/flag"
import { bootstrap } from "../bootstrap"
import { EOL } from "os"
-import { createOpencodeClient, type Message, type OpencodeClient, type ToolPart } from "@opencode-ai/sdk/v2"
+import { createOpencodeClient, type Message, type OpencodeClient, type ToolPart } from "@opencoder-ai/sdk/v2"
import { Server } from "../../server/server"
import { Provider } from "../../provider/provider"
import { Agent } from "../../agent/agent"
diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx
index 38dc402758b2..86c682f2857c 100644
--- a/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx
+++ b/packages/opencode/src/cli/cmd/tui/component/dialog-command.tsx
@@ -11,7 +11,7 @@ import {
} from "solid-js"
import { useKeyboard } from "@opentui/solid"
import { useKeybind } from "@tui/context/keybind"
-import type { KeybindsConfig } from "@opencode-ai/sdk/v2"
+import type { KeybindsConfig } from "@/config/config"
type Context = ReturnType
const ctx = createContext()
diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx
index 9682bee4ead2..2698f486124a 100644
--- a/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx
+++ b/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx
@@ -8,7 +8,7 @@ import { DialogPrompt } from "../ui/dialog-prompt"
import { Link } from "../ui/link"
import { useTheme } from "../context/theme"
import { TextAttributes } from "@opentui/core"
-import type { ProviderAuthAuthorization } from "@opencode-ai/sdk/v2"
+import type { ProviderAuthAuthorization } from "@opencoder-ai/sdk/v2"
import { DialogModel } from "./dialog-model"
import { useKeyboard } from "@opentui/solid"
import { Clipboard } from "@tui/util/clipboard"
diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/history.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/history.tsx
index e90503e9f52e..ef1161901235 100644
--- a/packages/opencode/src/cli/cmd/tui/component/prompt/history.tsx
+++ b/packages/opencode/src/cli/cmd/tui/component/prompt/history.tsx
@@ -5,7 +5,7 @@ import { createStore, produce } from "solid-js/store"
import { clone } from "remeda"
import { createSimpleContext } from "../../context/helper"
import { appendFile, writeFile } from "fs/promises"
-import type { AgentPart, FilePart, TextPart } from "@opencode-ai/sdk/v2"
+import type { AgentPart, FilePart, TextPart } from "@opencoder-ai/sdk/v2"
export type PromptInfo = {
input: string
diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx
index cefef208de4a..972ce8836bb9 100644
--- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx
@@ -19,7 +19,7 @@ import { useRenderer } from "@opentui/solid"
import { Editor } from "@tui/util/editor"
import { useExit } from "../../context/exit"
import { Clipboard } from "../../util/clipboard"
-import type { FilePart } from "@opencode-ai/sdk/v2"
+import type { FilePart } from "@opencoder-ai/sdk/v2"
import { TuiEvent } from "../../event"
import { iife } from "@/util/iife"
import { Locale } from "@/util/locale"
diff --git a/packages/opencode/src/cli/cmd/tui/context/keybind.tsx b/packages/opencode/src/cli/cmd/tui/context/keybind.tsx
index 0dbbbc6f9ee1..671f5112becb 100644
--- a/packages/opencode/src/cli/cmd/tui/context/keybind.tsx
+++ b/packages/opencode/src/cli/cmd/tui/context/keybind.tsx
@@ -1,8 +1,9 @@
import { createMemo } from "solid-js"
import { useSync } from "@tui/context/sync"
import { Keybind } from "@/util/keybind"
+import { Config } from "@/config/config"
import { pipe, mapValues } from "remeda"
-import type { KeybindsConfig } from "@opencode-ai/sdk/v2"
+import type { KeybindsConfig } from "@/config/config"
import type { ParsedKey, Renderable } from "@opentui/core"
import { createStore } from "solid-js/store"
import { useKeyboard, useRenderer } from "@opentui/solid"
@@ -13,8 +14,10 @@ export const { use: useKeybind, provider: KeybindProvider } = createSimpleContex
init: () => {
const sync = useSync()
const keybinds = createMemo(() => {
+ const parsed = Config.Keybinds.safeParse(sync.data.config.keybinds ?? {})
+ const values = parsed.success ? parsed.data : Config.Keybinds.parse({})
return pipe(
- sync.data.config.keybinds ?? {},
+ values,
mapValues((value) => Keybind.parse(value)),
)
})
diff --git a/packages/opencode/src/cli/cmd/tui/context/sdk.tsx b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx
index 7fa7e05c3d25..64cb61ed6a84 100644
--- a/packages/opencode/src/cli/cmd/tui/context/sdk.tsx
+++ b/packages/opencode/src/cli/cmd/tui/context/sdk.tsx
@@ -1,4 +1,4 @@
-import { createOpencodeClient, type Event } from "@opencode-ai/sdk/v2"
+import { createOpencodeClient, type Event } from "@opencoder-ai/sdk/v2"
import { createSimpleContext } from "./helper"
import { createGlobalEmitter } from "@solid-primitives/event-bus"
import { batch, onCleanup, onMount } from "solid-js"
diff --git a/packages/opencode/src/cli/cmd/tui/context/sync.tsx b/packages/opencode/src/cli/cmd/tui/context/sync.tsx
index eb8ed2d9bbad..babfcce9ac33 100644
--- a/packages/opencode/src/cli/cmd/tui/context/sync.tsx
+++ b/packages/opencode/src/cli/cmd/tui/context/sync.tsx
@@ -17,17 +17,158 @@ import type {
ProviderListResponse,
ProviderAuthMethod,
VcsInfo,
-} from "@opencode-ai/sdk/v2"
+} from "@opencoder-ai/sdk/v2"
import { createStore, produce, reconcile } from "solid-js/store"
import { useSDK } from "@tui/context/sdk"
-import { Binary } from "@opencode-ai/util/binary"
+import { Binary } from "@opencoder-ai/util/binary"
import { createSimpleContext } from "./helper"
import type { Snapshot } from "@/snapshot"
import { useExit } from "./exit"
import { useArgs } from "./args"
import { batch, onMount } from "solid-js"
import { Log } from "@/util/log"
-import type { Path } from "@opencode-ai/sdk"
+import type { Path } from "@opencoder-ai/sdk"
+import {
+ createAgentClient,
+ type GetMailInboxResponse,
+ type GetMailThreadsByThreadIdMessagesResponse,
+} from "@agni/agent-sdk"
+
+type AgniConfig = {
+ apiKey: string
+ organizationId: string
+ projectId: string
+ baseUrl?: string
+}
+
+type AgniThread = GetMailInboxResponse[number]
+type AgniMessage = GetMailThreadsByThreadIdMessagesResponse[number]
+
+const resolveAgniConfig = (): AgniConfig | null => {
+ const apiKey = process.env.AGNI_API_KEY
+ const organizationId = process.env.AGNI_ORGANIZATION_ID ?? process.env.AGNI_ORG_ID
+ const projectId = process.env.AGNI_PROJECT_ID
+ const baseUrl = process.env.AGNI_BASE_URL
+ if (!apiKey || !organizationId || !projectId) return null
+ return {
+ apiKey,
+ organizationId,
+ projectId,
+ baseUrl,
+ }
+}
+
+const agniConfig = resolveAgniConfig()
+const agniClient = agniConfig
+ ? createAgentClient({
+ apiKey: agniConfig.apiKey,
+ organizationId: agniConfig.organizationId,
+ baseUrl: agniConfig.baseUrl,
+ })
+ : null
+
+const agniRunBySession = new Map()
+
+const resolveAgentHandle = (messages: { info: Message }[], fallback?: string) => {
+ for (let i = messages.length - 1; i >= 0; i -= 1) {
+ const message = messages[i]?.info
+ if (message?.role === "user" && message.agent) {
+ return message.agent
+ }
+ }
+ return fallback ?? "build"
+}
+
+const ensureAgniRun = async (sessionID: string, agentHandle: string) => {
+ if (!agniClient || !agniConfig) return null
+ if (!agentHandle) return null
+ const cached = agniRunBySession.get(sessionID)
+ if (cached) return cached
+ try {
+ const run = await agniClient.agentRuns.ensure({
+ projectId: agniConfig.projectId,
+ harness: "opencode",
+ harnessSessionId: sessionID,
+ agentHandle,
+ status: "running",
+ })
+ if (!run?.runId) {
+ Log.Default.warn("invalid agni run response", {
+ sessionID,
+ agentHandle,
+ run,
+ })
+ return null
+ }
+ agniRunBySession.set(sessionID, run.runId)
+ return run.runId
+ } catch (error) {
+ Log.Default.warn("failed to ensure agni run", {
+ error,
+ sessionID,
+ agentHandle,
+ })
+ }
+ return null
+}
+
+const fetchAgniInbox = async (sessionID: string, agentHandle: string) => {
+ if (!agniClient || !agniConfig) return []
+ const runId = await ensureAgniRun(sessionID, agentHandle)
+ if (!runId) return []
+ try {
+ const threads =
+ (await agniClient.mail.inbox.list({
+ projectId: agniConfig.projectId,
+ runId,
+ limit: 20,
+ })) ?? []
+
+ if (threads.length === 0) return []
+
+ const latestMessages = await Promise.all(
+ threads.map(async (thread) => {
+ try {
+ const messages =
+ (await agniClient.mail.messages.list({
+ threadId: thread.id,
+ limit: 1,
+ })) ?? []
+ return {
+ thread,
+ message: messages[0] ?? null,
+ }
+ } catch (error) {
+ Log.Default.warn("failed to load agni thread messages", {
+ error,
+ threadId: thread.id,
+ })
+ return { thread, message: null }
+ }
+ }),
+ )
+
+ return latestMessages.map(({ thread, message }) => {
+ const createdAt = message?.createdAt ?? thread.updatedAt
+ const createdAtDate = new Date(createdAt)
+ const lastReadAt = thread.lastReadAt ? new Date(thread.lastReadAt) : null
+ const isRead = lastReadAt ? createdAtDate <= lastReadAt : false
+ return {
+ id: thread.id,
+ senderId: message?.senderRun.agent.handle ?? thread.createdByRun.agent.handle ?? "unknown",
+ subject: message?.subject ?? thread.subject ?? "No subject",
+ body: message?.body ?? "",
+ type: "mail",
+ priority: message?.priority ?? 0,
+ isRead,
+ createdAt: createdAtDate,
+ }
+ })
+ } catch (error) {
+ Log.Default.warn("failed to load agni inbox", { error })
+ return []
+ }
+}
export const { use: useSync, provider: SyncProvider } = createSimpleContext({
name: "Sync",
@@ -73,6 +214,18 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
formatter: FormatterStatus[]
vcs: VcsInfo | undefined
path: Path
+ inbox: {
+ [sessionID: string]: Array<{
+ id: string
+ senderId: string
+ subject: string
+ body: string
+ type: string
+ priority: number
+ isRead: boolean
+ createdAt: Date
+ }>
+ }
}>({
provider_next: {
all: [],
@@ -100,6 +253,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
formatter: [],
vcs: undefined,
path: { state: "", config: "", worktree: "", directory: "" },
+ inbox: {},
})
const sdk = useSDK()
@@ -444,9 +598,11 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
const [session, messages, todo, diff] = await Promise.all([
sdk.client.session.get({ sessionID }, { throwOnError: true }),
sdk.client.session.messages({ sessionID, limit: 100 }),
- sdk.client.session.todo({ sessionID }),
+ sdk.client.session.todo.list({ sessionID }),
sdk.client.session.diff({ sessionID }),
])
+ const agentHandle = resolveAgentHandle(messages.data ?? [], store.config.default_agent)
+ const inbox = await fetchAgniInbox(sessionID, agentHandle)
setStore(
produce((draft) => {
const match = Binary.search(draft.session, sessionID, (s) => s.id)
@@ -458,6 +614,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
draft.part[message.info.id] = message.parts
}
draft.session_diff[sessionID] = diff.data ?? []
+ draft.inbox[sessionID] = inbox
}),
)
fullSyncedSessions.add(sessionID)
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx
index 62154cce5636..a6b05493ba7d 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/dialog-fork-from-timeline.tsx
@@ -1,7 +1,7 @@
import { createMemo, onMount } from "solid-js"
import { useSync } from "@tui/context/sync"
import { DialogSelect, type DialogSelectOption } from "@tui/ui/dialog-select"
-import type { TextPart } from "@opencode-ai/sdk/v2"
+import type { TextPart } from "@opencoder-ai/sdk/v2"
import { Locale } from "@/util/locale"
import { useSDK } from "@tui/context/sdk"
import { useRoute } from "@tui/context/route"
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/dialog-timeline.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/dialog-timeline.tsx
index 87248a6a8ba6..8920a5066278 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/dialog-timeline.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/dialog-timeline.tsx
@@ -1,7 +1,7 @@
import { createMemo, onMount } from "solid-js"
import { useSync } from "@tui/context/sync"
import { DialogSelect, type DialogSelectOption } from "@tui/ui/dialog-select"
-import type { TextPart } from "@opencode-ai/sdk/v2"
+import type { TextPart } from "@opencoder-ai/sdk/v2"
import { Locale } from "@/util/locale"
import { DialogMessage } from "./dialog-message"
import { useDialog } from "../../ui/dialog"
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/header.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/header.tsx
index 0c5ea9a85723..725eee9214c5 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/header.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/header.tsx
@@ -4,7 +4,7 @@ import { useSync } from "@tui/context/sync"
import { pipe, sumBy } from "remeda"
import { useTheme } from "@tui/context/theme"
import { SplitBorder } from "@tui/component/border"
-import type { AssistantMessage, Session } from "@opencode-ai/sdk/v2"
+import type { AssistantMessage, Session } from "@opencoder-ai/sdk/v2"
import { useCommandDialog } from "@tui/component/dialog-command"
import { useKeybind } from "../../context/keybind"
import { useTerminalDimensions } from "@opentui/solid"
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
index b843bda1c9db..45450e6538e9 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
@@ -28,7 +28,7 @@ import {
RGBA,
} from "@opentui/core"
import { Prompt, type PromptRef } from "@tui/component/prompt"
-import type { AssistantMessage, Part, ToolPart, UserMessage, TextPart, ReasoningPart } from "@opencode-ai/sdk/v2"
+import type { AssistantMessage, Part, ToolPart, UserMessage, TextPart, ReasoningPart } from "@opencoder-ai/sdk/v2"
import { useLocal } from "@tui/context/local"
import { Locale } from "@/util/locale"
import type { Tool } from "@/tool/tool"
@@ -529,7 +529,7 @@ export function Session() {
{
title: conceal() ? "Disable code concealment" : "Enable code concealment",
value: "session.toggle.conceal",
- keybind: "messages_toggle_conceal" as any,
+ keybind: "messages_toggle_conceal",
category: "Session",
onSelect: (dialog) => {
setConceal((prev) => !prev)
@@ -1846,27 +1846,17 @@ function Task(props: ToolProps) {
const keybind = useKeybind()
const { navigate } = useRoute()
const local = useLocal()
- const sync = useSync()
-
- const tools = createMemo(() => {
- const sessionID = props.metadata.sessionId
- const msgs = sync.data.message[sessionID ?? ""] ?? []
- return msgs.flatMap((msg) =>
- (sync.data.part[msg.id] ?? [])
- .filter((part): part is ToolPart => part.type === "tool")
- .map((part) => ({ tool: part.tool, state: part.state })),
- )
- })
-
- const current = createMemo(() => tools().findLast((x) => x.state.status !== "pending"))
+ const agentType = createMemo(() => props.input.subagent_type ?? props.metadata.subagent_type ?? "unknown")
+ const current = createMemo(() => props.metadata.summary?.findLast((x) => x.state.status !== "pending"))
const isRunning = createMemo(() => props.part.state.status === "running")
+ const color = createMemo(() => local.agent.color(agentType()))
return (
navigate({ type: "session", sessionID: props.metadata.sessionId! })
@@ -1877,7 +1867,7 @@ function Task(props: ToolProps) {
>
- {props.input.description} ({tools().length} toolcalls)
+ {props.input.description ?? props.metadata.description} ({props.metadata.summary?.length ?? 0} toolcalls)
{(item) => {
@@ -1899,8 +1889,20 @@ function Task(props: ToolProps) {
-
- {props.input.subagent_type} Task {props.input.description}
+
+ {Locale.titlecase(agentType())} Task "
+ {props.input.description ?? props.metadata.description}"
@@ -2051,14 +2053,37 @@ function ApplyPatch(props: ToolProps) {
}
function TodoWrite(props: ToolProps) {
+ // Try to get todos from metadata, or parse from output if missing
+ const todos = createMemo(() => {
+ // Priority 1: Use metadata.todos if available
+ if (props.metadata.todos && props.metadata.todos.length > 0) {
+ return props.metadata.todos
+ }
+
+ // Priority 2: Try to parse todos from output JSON
+ if (props.output) {
+ try {
+ const parsed = JSON.parse(props.output)
+ if (Array.isArray(parsed) && parsed.length > 0) {
+ // Validate that it looks like todos (has id, content, status)
+ if (parsed[0]?.id && parsed[0]?.content && parsed[0]?.status) {
+ return parsed
+ }
+ }
+ } catch {
+ // JSON parse failed, continue to fallback
+ }
+ }
+
+ return null
+ })
+
return (
-
+
-
- {(todo) => }
-
+ {(todo) => }
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx
index 9e79c76bf518..06dac33384bb 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx
@@ -4,7 +4,7 @@ import { Portal, useKeyboard, useRenderer, useTerminalDimensions, type JSX } fro
import type { TextareaRenderable } from "@opentui/core"
import { useKeybind } from "../../context/keybind"
import { useTheme, selectedForeground } from "../../context/theme"
-import type { PermissionRequest } from "@opencode-ai/sdk/v2"
+import type { PermissionRequest } from "@opencoder-ai/sdk/v2"
import { useSDK } from "../../context/sdk"
import { SplitBorder } from "../../component/border"
import { useSync } from "../../context/sync"
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx
index 1565a3008185..ab7a6e68c773 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx
@@ -4,7 +4,7 @@ import { useKeyboard } from "@opentui/solid"
import type { TextareaRenderable } from "@opentui/core"
import { useKeybind } from "../../context/keybind"
import { selectedForeground, tint, useTheme } from "../../context/theme"
-import type { QuestionAnswer, QuestionRequest } from "@opencode-ai/sdk/v2"
+import type { QuestionAnswer, QuestionRequest } from "@opencoder-ai/sdk/v2"
import { useSDK } from "../../context/sdk"
import { SplitBorder } from "../../component/border"
import { useTextareaKeybindings } from "../../component/textarea-keybindings"
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx
index 4ffe91558ed7..b2d46d9e7497 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/sidebar.tsx
@@ -4,7 +4,7 @@ import { createStore } from "solid-js/store"
import { useTheme } from "../../context/theme"
import { Locale } from "@/util/locale"
import path from "path"
-import type { AssistantMessage } from "@opencode-ai/sdk/v2"
+import type { AssistantMessage } from "@opencoder-ai/sdk/v2"
import { Global } from "@/global"
import { Installation } from "@/installation"
import { useKeybind } from "../../context/keybind"
@@ -25,6 +25,7 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) {
diff: true,
todo: true,
lsp: true,
+ inbox: true,
})
// Sort MCP servers alphabetically for consistent display order
@@ -221,6 +222,45 @@ export function Sidebar(props: { sessionID: string; overlay?: boolean }) {
+ 0}>
+
+
+ (sync.data.inbox[props.sessionID]?.length ?? 0) > 2 && setExpanded("inbox", !expanded.inbox)
+ }
+ >
+ 2}>
+ {expanded.inbox ? "▼" : "▶"}
+
+
+ Inbox
+ !m.isRead).length ?? 0) > 0}>
+
+ {" "}
+ {sync.data.inbox[props.sessionID]?.filter((m) => !m.isRead).length ?? 0} new
+
+
+
+
+
+
+ {(message) => (
+
+
+ {message.senderId}: {message.subject}
+
+
+ {message.body.slice(0, 80)}
+ {message.body.length > 80 ? "..." : ""}
+
+
+ )}
+
+
+
+
0}>
({}))
json.dependencies = {
...json.dependencies,
- "@opencode-ai/plugin": targetVersion,
+ "@opencoder-ai/plugin": targetVersion,
}
await Bun.write(pkg, JSON.stringify(json, null, 2))
await new Promise((resolve) => setTimeout(resolve, 3000))
@@ -307,15 +307,15 @@ export namespace Config {
const parsed = await pkgFile.json().catch(() => null)
const dependencies = parsed?.dependencies ?? {}
- const depVersion = dependencies["@opencode-ai/plugin"]
+ const depVersion = dependencies["@opencoder-ai/plugin"]
if (!depVersion) return true
const targetVersion = Installation.isLocal() ? "latest" : Installation.VERSION
if (targetVersion === "latest") {
- const isOutdated = await PackageRegistry.isOutdated("@opencode-ai/plugin", depVersion, dir)
+ const isOutdated = await PackageRegistry.isOutdated("@opencoder-ai/plugin", depVersion, dir)
if (!isOutdated) return false
log.info("Cached version is outdated, proceeding with install", {
- pkg: "@opencode-ai/plugin",
+ pkg: "@opencoder-ai/plugin",
cachedVersion: depVersion,
})
return true
@@ -1481,3 +1481,5 @@ export namespace Config {
return state().then((x) => x.directories)
}
}
+
+export type KeybindsConfig = z.infer
diff --git a/packages/opencode/src/config/markdown.ts b/packages/opencode/src/config/markdown.ts
index 4cd17746c54c..de553309d57b 100644
--- a/packages/opencode/src/config/markdown.ts
+++ b/packages/opencode/src/config/markdown.ts
@@ -1,4 +1,4 @@
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import matter from "gray-matter"
import { z } from "zod"
diff --git a/packages/opencode/src/file/ripgrep.ts b/packages/opencode/src/file/ripgrep.ts
index 58f9af7cdbab..5d0293aed04a 100644
--- a/packages/opencode/src/file/ripgrep.ts
+++ b/packages/opencode/src/file/ripgrep.ts
@@ -3,7 +3,7 @@ import path from "path"
import { Global } from "../global"
import fs from "fs/promises"
import z from "zod"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { lazy } from "../util/lazy"
import { $ } from "bun"
diff --git a/packages/opencode/src/ide/index.ts b/packages/opencode/src/ide/index.ts
index 0837b2aa5ff5..bbccb3dc5892 100644
--- a/packages/opencode/src/ide/index.ts
+++ b/packages/opencode/src/ide/index.ts
@@ -2,7 +2,7 @@ import { BusEvent } from "@/bus/bus-event"
import { Bus } from "@/bus"
import { spawn } from "bun"
import z from "zod"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { Log } from "../util/log"
const SUPPORTED_IDES = [
diff --git a/packages/opencode/src/index.ts b/packages/opencode/src/index.ts
index 6dc5e99e91ef..b16b954796c1 100644
--- a/packages/opencode/src/index.ts
+++ b/packages/opencode/src/index.ts
@@ -10,7 +10,7 @@ import { UninstallCommand } from "./cli/cmd/uninstall"
import { ModelsCommand } from "./cli/cmd/models"
import { UI } from "./cli/ui"
import { Installation } from "./installation"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { FormatError } from "./cli/error"
import { ServeCommand } from "./cli/cmd/serve"
import { DebugCommand } from "./cli/cmd/debug"
diff --git a/packages/opencode/src/installation/index.ts b/packages/opencode/src/installation/index.ts
index 47278bd5628e..b693f063f6bc 100644
--- a/packages/opencode/src/installation/index.ts
+++ b/packages/opencode/src/installation/index.ts
@@ -2,7 +2,7 @@ import { BusEvent } from "@/bus/bus-event"
import path from "path"
import { $ } from "bun"
import z from "zod"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { Log } from "../util/log"
import { iife } from "@/util/iife"
import { Flag } from "../flag/flag"
@@ -104,7 +104,7 @@ export namespace Installation {
for (const check of checks) {
const output = await check.command()
const installedName =
- check.name === "brew" || check.name === "choco" || check.name === "scoop" ? "opencode" : "opencode-ai"
+ check.name === "brew" || check.name === "choco" || check.name === "scoop" ? "opencode" : "opencoder-ai"
if (output.includes(installedName)) {
return check.name
}
@@ -132,19 +132,19 @@ export namespace Installation {
let cmd
switch (method) {
case "curl":
- cmd = $`curl -fsSL https://opencode.ai/install | bash`.env({
+ cmd = $`curl -fsSL https://raw.githubusercontent.com/AryaLabsHQ/opencoder/dev/install | bash`.env({
...process.env,
VERSION: target,
})
break
case "npm":
- cmd = $`npm install -g opencode-ai@${target}`
+ cmd = $`npm install -g opencoder-ai@${target}`
break
case "pnpm":
- cmd = $`pnpm install -g opencode-ai@${target}`
+ cmd = $`pnpm install -g opencoder-ai@${target}`
break
case "bun":
- cmd = $`bun install -g opencode-ai@${target}`
+ cmd = $`bun install -g opencoder-ai@${target}`
break
case "brew": {
const formula = await getBrewFormula()
@@ -220,7 +220,7 @@ export namespace Installation {
return reg.endsWith("/") ? reg.slice(0, -1) : reg
})
const channel = CHANNEL
- return fetch(`${registry}/opencode-ai/${channel}`)
+ return fetch(`${registry}/opencoder-ai/${channel}`)
.then((res) => {
if (!res.ok) throw new Error(res.statusText)
return res.json()
@@ -251,7 +251,7 @@ export namespace Installation {
.then((data: any) => data.version)
}
- return fetch("https://api.github.com/repos/anomalyco/opencode/releases/latest")
+ return fetch("https://api.github.com/repos/AryaLabsHQ/opencoder/releases/latest")
.then((res) => {
if (!res.ok) throw new Error(res.statusText)
return res.json()
diff --git a/packages/opencode/src/lsp/client.ts b/packages/opencode/src/lsp/client.ts
index 8704b65acb5b..622bec84d4de 100644
--- a/packages/opencode/src/lsp/client.ts
+++ b/packages/opencode/src/lsp/client.ts
@@ -8,7 +8,7 @@ import { Log } from "../util/log"
import { LANGUAGE_EXTENSIONS } from "./language"
import z from "zod"
import type { LSPServer } from "./server"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { withTimeout } from "../util/timeout"
import { Instance } from "../project/instance"
import { Filesystem } from "../util/filesystem"
diff --git a/packages/opencode/src/mcp/index.ts b/packages/opencode/src/mcp/index.ts
index 3c29fe03d30a..1e561c4f9fa4 100644
--- a/packages/opencode/src/mcp/index.ts
+++ b/packages/opencode/src/mcp/index.ts
@@ -11,7 +11,7 @@ import {
} from "@modelcontextprotocol/sdk/types.js"
import { Config } from "../config/config"
import { Log } from "../util/log"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import z from "zod/v4"
import { Instance } from "../project/instance"
import { Installation } from "../installation"
diff --git a/packages/opencode/src/plugin/codex.ts b/packages/opencode/src/plugin/codex.ts
index 56931b2ed62c..99e8fb328d6c 100644
--- a/packages/opencode/src/plugin/codex.ts
+++ b/packages/opencode/src/plugin/codex.ts
@@ -1,4 +1,4 @@
-import type { Hooks, PluginInput } from "@opencode-ai/plugin"
+import type { Hooks, PluginInput } from "@opencoder-ai/plugin"
import { Log } from "../util/log"
import { Installation } from "../installation"
import { Auth, OAUTH_DUMMY_KEY } from "../auth"
@@ -440,8 +440,8 @@ export async function CodexAuthPlugin(input: PluginInput): Promise {
const tokens = await refreshAccessToken(currentAuth.refresh)
const newAccountId = extractAccountId(tokens) || authWithAccount.accountId
await input.client.auth.set({
- path: { id: "openai" },
- body: {
+ providerID: "openai",
+ auth: {
type: "oauth",
refresh: tokens.refresh_token,
access: tokens.access_token,
@@ -457,7 +457,9 @@ export async function CodexAuthPlugin(input: PluginInput): Promise {
const headers = new Headers()
if (init?.headers) {
if (init.headers instanceof Headers) {
- init.headers.forEach((value, key) => headers.set(key, value))
+ init.headers.forEach((value, key) => {
+ headers.set(key, value)
+ })
} else if (Array.isArray(init.headers)) {
for (const [key, value] of init.headers) {
if (value !== undefined) headers.set(key, String(value))
diff --git a/packages/opencode/src/plugin/copilot.ts b/packages/opencode/src/plugin/copilot.ts
index 39ea0d00d28e..e5214e4c11af 100644
--- a/packages/opencode/src/plugin/copilot.ts
+++ b/packages/opencode/src/plugin/copilot.ts
@@ -1,4 +1,4 @@
-import type { Hooks, PluginInput } from "@opencode-ai/plugin"
+import type { Hooks, PluginInput } from "@opencoder-ai/plugin"
import { Installation } from "@/installation"
import { iife } from "@/util/iife"
@@ -309,15 +309,15 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise {
}
const session = await sdk.session
- .get({
- path: {
- id: incoming.sessionID,
- },
- query: {
+ .get(
+ {
+ sessionID: incoming.sessionID,
directory: input.directory,
},
- throwOnError: true,
- })
+ {
+ throwOnError: true,
+ },
+ )
.catch(() => undefined)
if (!session || !session.data.parentID) return
// mark subagent sessions as agent initiated matching standard that other copilot tools have
diff --git a/packages/opencode/src/plugin/index.ts b/packages/opencode/src/plugin/index.ts
index 24dc695d6350..1c788b5b8fe9 100644
--- a/packages/opencode/src/plugin/index.ts
+++ b/packages/opencode/src/plugin/index.ts
@@ -1,17 +1,17 @@
-import type { Hooks, PluginInput, Plugin as PluginInstance } from "@opencode-ai/plugin"
+import type { PluginInput, Hooks } from "@opencoder-ai/plugin"
+import type { Plugin as PluginFn } from "@opencoder-ai/plugin"
import { Config } from "../config/config"
import { Bus } from "../bus"
import { Log } from "../util/log"
-import { createOpencodeClient } from "@opencode-ai/sdk"
+import { createOpencodeClient } from "@opencoder-ai/sdk/v2"
import { Server } from "../server/server"
import { BunProc } from "../bun"
import { Instance } from "../project/instance"
import { Flag } from "../flag/flag"
import { CodexAuthPlugin } from "./codex"
import { Session } from "../session"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { CopilotAuthPlugin } from "./copilot"
-import { gitlabAuthPlugin as GitlabAuthPlugin } from "@gitlab/opencode-gitlab-auth"
export namespace Plugin {
const log = Log.create({ service: "plugin" })
@@ -19,7 +19,7 @@ export namespace Plugin {
const BUILTIN = ["opencode-anthropic-auth@0.0.13"]
// Built-in plugins that are directly imported (not installed from npm)
- const INTERNAL_PLUGINS: PluginInstance[] = [CodexAuthPlugin, CopilotAuthPlugin, GitlabAuthPlugin]
+ const INTERNAL_PLUGINS: PluginFn[] = [CodexAuthPlugin, CopilotAuthPlugin]
const state = Instance.state(async () => {
const client = createOpencodeClient({
@@ -28,8 +28,10 @@ export namespace Plugin {
// @ts-ignore - fetch type incompatibility
fetch: async (...args) => Server.App().fetch(...args),
})
+
const config = await Config.get()
const hooks: Hooks[] = []
+
const input: PluginInput = {
client,
project: Instance.project,
@@ -80,14 +82,17 @@ export namespace Plugin {
if (!plugin) continue
}
const mod = await import(plugin)
+
// Prevent duplicate initialization when plugins export the same function
// as both a named export and default export (e.g., `export const X` and `export default X`).
// Object.entries(mod) would return both entries pointing to the same function reference.
- const seen = new Set()
- for (const [_name, fn] of Object.entries(mod)) {
- if (seen.has(fn)) continue
- seen.add(fn)
- const init = await fn(input)
+ const seen = new Set()
+ for (const [_name, fn] of Object.entries(mod)) {
+ if (typeof fn !== "function") continue
+ const pluginFn = fn as PluginFn
+ if (seen.has(pluginFn)) continue
+ seen.add(pluginFn)
+ const init = await pluginFn(input)
hooks.push(init)
}
}
@@ -123,7 +128,6 @@ export namespace Plugin {
const hooks = await state().then((x) => x.hooks)
const config = await Config.get()
for (const hook of hooks) {
- // @ts-expect-error this is because we haven't moved plugin to sdk v2
await hook.config?.(config)
}
Bus.subscribeAll(async (input) => {
diff --git a/packages/opencode/src/project/project.ts b/packages/opencode/src/project/project.ts
index c79a62c6c95e..e854b2d083e2 100644
--- a/packages/opencode/src/project/project.ts
+++ b/packages/opencode/src/project/project.ts
@@ -7,7 +7,7 @@ import { Log } from "../util/log"
import { Flag } from "@/flag/flag"
import { Session } from "../session"
import { work } from "../util/queue"
-import { fn } from "@opencode-ai/util/fn"
+import { fn } from "@opencoder-ai/util/fn"
import { BusEvent } from "@/bus/bus-event"
import { iife } from "@/util/iife"
import { GlobalBus } from "@/bus/global"
diff --git a/packages/opencode/src/provider/auth.ts b/packages/opencode/src/provider/auth.ts
index e6681ff08914..45cc383cac6a 100644
--- a/packages/opencode/src/provider/auth.ts
+++ b/packages/opencode/src/provider/auth.ts
@@ -3,8 +3,8 @@ import { Plugin } from "../plugin"
import { map, filter, pipe, fromEntries, mapValues } from "remeda"
import z from "zod"
import { fn } from "@/util/fn"
-import type { AuthOuathResult, Hooks } from "@opencode-ai/plugin"
-import { NamedError } from "@opencode-ai/util/error"
+import type { AuthOuathResult, Hooks } from "@opencoder-ai/plugin"
+import { NamedError } from "@opencoder-ai/util/error"
import { Auth } from "@/auth"
export namespace ProviderAuth {
diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts
index 44bcf8adb3de..2a4f2a618801 100644
--- a/packages/opencode/src/provider/provider.ts
+++ b/packages/opencode/src/provider/provider.ts
@@ -8,7 +8,7 @@ import { Log } from "../util/log"
import { BunProc } from "../bun"
import { Plugin } from "../plugin"
import { ModelsDev } from "./models"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { Auth } from "../auth"
import { Env } from "../env"
import { Instance } from "../project/instance"
diff --git a/packages/opencode/src/pty/index.ts b/packages/opencode/src/pty/index.ts
index a9052a79eb8c..352df39b55b2 100644
--- a/packages/opencode/src/pty/index.ts
+++ b/packages/opencode/src/pty/index.ts
@@ -5,7 +5,7 @@ import z from "zod"
import { Identifier } from "../id/id"
import { Log } from "../util/log"
import { Instance } from "../project/instance"
-import { lazy } from "@opencode-ai/util/lazy"
+import { lazy } from "@opencoder-ai/util/lazy"
import { Shell } from "@/shell/shell"
import { Plugin } from "@/plugin"
diff --git a/packages/opencode/src/server/routes/session.ts b/packages/opencode/src/server/routes/session.ts
index 82e6f3121bf7..4ea546ec63bd 100644
--- a/packages/opencode/src/server/routes/session.ts
+++ b/packages/opencode/src/server/routes/session.ts
@@ -157,7 +157,7 @@ export const SessionRoutes = lazy(() =>
describeRoute({
summary: "Get session todos",
description: "Retrieve the todo list associated with a specific session, showing tasks and action items.",
- operationId: "session.todo",
+ operationId: "session.todo.list",
responses: {
200: {
description: "Todo list",
@@ -182,6 +182,43 @@ export const SessionRoutes = lazy(() =>
return c.json(todos)
},
)
+ .put(
+ "/:sessionID/todo",
+ describeRoute({
+ summary: "Update session todos",
+ description: "Replace the todo list associated with a specific session.",
+ operationId: "session.todo.update",
+ responses: {
+ 200: {
+ description: "Updated todo list",
+ content: {
+ "application/json": {
+ schema: resolver(Todo.Info.array()),
+ },
+ },
+ },
+ ...errors(400, 404),
+ },
+ }),
+ validator(
+ "param",
+ z.object({
+ sessionID: z.string().meta({ description: "Session ID" }),
+ }),
+ ),
+ validator(
+ "json",
+ z.object({
+ todos: Todo.Info.array(),
+ }),
+ ),
+ async (c) => {
+ const sessionID = c.req.valid("param").sessionID
+ const { todos } = c.req.valid("json")
+ await Todo.update({ sessionID, todos })
+ return c.json(todos)
+ },
+ )
.post(
"/",
describeRoute({
diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts
index 9fb5206551b6..be24af2900fb 100644
--- a/packages/opencode/src/server/server.ts
+++ b/packages/opencode/src/server/server.ts
@@ -9,7 +9,7 @@ import { proxy } from "hono/proxy"
import { basicAuth } from "hono/basic-auth"
import z from "zod"
import { Provider } from "../provider/provider"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { LSP } from "../lsp"
import { Format } from "../format"
import { TuiRoutes } from "./routes/tui"
diff --git a/packages/opencode/src/session/index.ts b/packages/opencode/src/session/index.ts
index b0ffaaf70d77..c6c7a44de66b 100644
--- a/packages/opencode/src/session/index.ts
+++ b/packages/opencode/src/session/index.ts
@@ -1,4 +1,4 @@
-import { Slug } from "@opencode-ai/util/slug"
+import { Slug } from "@opencoder-ai/util/slug"
import path from "path"
import { BusEvent } from "@/bus/bus-event"
import { Bus } from "@/bus"
@@ -431,6 +431,7 @@ export namespace Session {
const part = "delta" in input ? input.part : input
const delta = "delta" in input ? input.delta : undefined
await Storage.write(["part", part.messageID, part.id], part)
+
Bus.publish(MessageV2.Event.PartUpdated, {
part,
delta,
diff --git a/packages/opencode/src/session/message-v2.ts b/packages/opencode/src/session/message-v2.ts
index 70763548c6a0..9a960ecae581 100644
--- a/packages/opencode/src/session/message-v2.ts
+++ b/packages/opencode/src/session/message-v2.ts
@@ -1,6 +1,6 @@
import { BusEvent } from "@/bus/bus-event"
import z from "zod"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { APICallError, convertToModelMessages, LoadAPIKeyError, type ModelMessage, type UIMessage } from "ai"
import { Identifier } from "../id/id"
import { LSP } from "../lsp"
@@ -751,91 +751,101 @@ export namespace MessageV2 {
}
export function fromError(e: unknown, ctx: { providerID: string }) {
- switch (true) {
- case e instanceof DOMException && e.name === "AbortError":
- return new MessageV2.AbortedError(
- { message: e.message },
- {
- cause: e,
+ if (e instanceof DOMException && e.name === "AbortError") {
+ return new MessageV2.AbortedError(
+ { message: e.message },
+ {
+ cause: e,
+ },
+ ).toObject()
+ }
+ if (MessageV2.OutputLengthError.isInstance(e)) {
+ return e
+ }
+ if (LoadAPIKeyError.isInstance(e)) {
+ return new MessageV2.AuthError(
+ {
+ providerID: ctx.providerID,
+ message: e.message,
+ },
+ { cause: e },
+ ).toObject()
+ }
+ if ((e as SystemError)?.code === "ECONNRESET") {
+ return new MessageV2.APIError(
+ {
+ message: "Connection reset by server",
+ isRetryable: true,
+ metadata: {
+ code: (e as SystemError).code ?? "",
+ syscall: (e as SystemError).syscall ?? "",
+ message: (e as SystemError).message ?? "",
},
- ).toObject()
- case MessageV2.OutputLengthError.isInstance(e):
- return e
- case LoadAPIKeyError.isInstance(e):
- return new MessageV2.AuthError(
+ },
+ { cause: e },
+ ).toObject()
+ }
+ if (APICallError.isInstance(e)) {
+ const parsed = ProviderError.parseAPICallError({
+ providerID: ctx.providerID,
+ error: e,
+ })
+ if (parsed.type === "context_overflow") {
+ return new MessageV2.ContextOverflowError(
{
- providerID: ctx.providerID,
- message: e.message,
+ message: parsed.message,
+ responseBody: parsed.responseBody,
},
{ cause: e },
).toObject()
- case (e as SystemError)?.code === "ECONNRESET":
- return new MessageV2.APIError(
+ }
+
+ return new MessageV2.APIError(
+ {
+ message: parsed.message,
+ statusCode: parsed.statusCode,
+ isRetryable: parsed.isRetryable,
+ responseHeaders: parsed.responseHeaders,
+ responseBody: parsed.responseBody,
+ metadata: parsed.metadata,
+ },
+ { cause: e },
+ ).toObject()
+ }
+ if (e instanceof Error) {
+ return new NamedError.Unknown({ message: e.toString() }, { cause: e }).toObject()
+ }
+
+ try {
+ const parsed = ProviderError.parseStreamError(e)
+ if (parsed?.type === "context_overflow") {
+ return new MessageV2.ContextOverflowError(
{
- message: "Connection reset by server",
- isRetryable: true,
- metadata: {
- code: (e as SystemError).code ?? "",
- syscall: (e as SystemError).syscall ?? "",
- message: (e as SystemError).message ?? "",
- },
+ message: parsed.message,
+ responseBody: parsed.responseBody,
},
{ cause: e },
).toObject()
- case APICallError.isInstance(e):
- const parsed = ProviderError.parseAPICallError({
- providerID: ctx.providerID,
- error: e,
- })
- if (parsed.type === "context_overflow") {
- return new MessageV2.ContextOverflowError(
- {
- message: parsed.message,
- responseBody: parsed.responseBody,
- },
- { cause: e },
- ).toObject()
- }
-
+ }
+ if (parsed?.type === "api_error") {
return new MessageV2.APIError(
{
message: parsed.message,
- statusCode: parsed.statusCode,
isRetryable: parsed.isRetryable,
- responseHeaders: parsed.responseHeaders,
responseBody: parsed.responseBody,
- metadata: parsed.metadata,
},
{ cause: e },
).toObject()
- case e instanceof Error:
- return new NamedError.Unknown({ message: e.toString() }, { cause: e }).toObject()
- default:
- try {
- const parsed = ProviderError.parseStreamError(e)
- if (parsed) {
- if (parsed.type === "context_overflow") {
- return new MessageV2.ContextOverflowError(
- {
- message: parsed.message,
- responseBody: parsed.responseBody,
- },
- { cause: e },
- ).toObject()
- }
- return new MessageV2.APIError(
- {
- message: parsed.message,
- isRetryable: parsed.isRetryable,
- responseBody: parsed.responseBody,
- },
- {
- cause: e,
- },
- ).toObject()
- }
- } catch {}
- return new NamedError.Unknown({ message: JSON.stringify(e) }, { cause: e }).toObject()
- }
+ }
+ } catch {}
+
+ const message = (() => {
+ try {
+ return JSON.stringify(e)
+ } catch {
+ return Bun.inspect(e)
+ }
+ })()
+ return new NamedError.Unknown({ message }, { cause: e }).toObject()
}
}
diff --git a/packages/opencode/src/session/message.ts b/packages/opencode/src/session/message.ts
index 5c950d0e4028..e9f51d3ef5bf 100644
--- a/packages/opencode/src/session/message.ts
+++ b/packages/opencode/src/session/message.ts
@@ -1,5 +1,5 @@
import z from "zod"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
export namespace Message {
export const OutputLengthError = NamedError.create("MessageOutputLengthError", z.object({}))
diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts
index be813e823fb0..2442d132f3fc 100644
--- a/packages/opencode/src/session/prompt.ts
+++ b/packages/opencode/src/session/prompt.ts
@@ -17,8 +17,8 @@ import { ProviderTransform } from "../provider/transform"
import { SystemPrompt } from "./system"
import { InstructionPrompt } from "./instruction"
import { Plugin } from "../plugin"
-import PROMPT_PLAN from "../session/prompt/plan.txt"
import BUILD_SWITCH from "../session/prompt/build-switch.txt"
+import PROMPT_PLAN from "../session/prompt/plan.txt"
import MAX_STEPS from "../session/prompt/max-steps.txt"
import { defer } from "../util/defer"
import { clone } from "remeda"
@@ -29,12 +29,11 @@ import { ReadTool } from "../tool/read"
import { FileTime } from "../file/time"
import { Flag } from "../flag/flag"
import { ulid } from "ulid"
-import { spawn } from "child_process"
import { Command } from "../command"
import { $, fileURLToPath, pathToFileURL } from "bun"
import { ConfigMarkdown } from "../config/markdown"
import { SessionSummary } from "./summary"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { fn } from "@/util/fn"
import { SessionProcessor } from "./processor"
import { TaskTool } from "@/tool/task"
@@ -411,6 +410,7 @@ export namespace SessionPrompt {
tool: "task",
sessionID,
callID: part.id,
+ agent: task.agent,
},
{ args: taskArgs },
)
@@ -422,6 +422,7 @@ export namespace SessionPrompt {
sessionID: sessionID,
abort,
callID: part.callID,
+ model: { providerID: taskModel.providerID, modelID: taskModel.id },
extra: { bypassAgentCheck: true },
messages: msgs,
async metadata(input) {
@@ -454,6 +455,7 @@ export namespace SessionPrompt {
sessionID,
callID: part.id,
args: taskArgs,
+ agent: task.agent,
},
result,
)
@@ -746,7 +748,8 @@ export namespace SessionPrompt {
abort: options.abortSignal!,
messageID: input.processor.message.id,
callID: options.toolCallId,
- extra: { model: input.model, bypassAgentCheck: input.bypassAgentCheck },
+ model: { providerID: input.model.providerID, modelID: input.model.id },
+ extra: { bypassAgentCheck: input.bypassAgentCheck },
agent: input.agent.name,
messages: input.messages,
metadata: async (val: { title?: string; metadata?: any }) => {
@@ -793,6 +796,7 @@ export namespace SessionPrompt {
tool: item.id,
sessionID: ctx.sessionID,
callID: ctx.callID,
+ agent: input.agent.name,
},
{
args,
@@ -806,6 +810,7 @@ export namespace SessionPrompt {
sessionID: ctx.sessionID,
callID: ctx.callID,
args,
+ agent: input.agent.name,
},
result,
)
@@ -830,6 +835,7 @@ export namespace SessionPrompt {
tool: key,
sessionID: ctx.sessionID,
callID: opts.toolCallId,
+ agent: input.agent.name,
},
{
args,
@@ -852,6 +858,7 @@ export namespace SessionPrompt {
sessionID: ctx.sessionID,
callID: opts.toolCallId,
args,
+ agent: input.agent.name,
},
result,
)
@@ -1135,13 +1142,14 @@ export namespace SessionPrompt {
await ReadTool.init()
.then(async (t) => {
- const model = await Provider.getModel(info.model.providerID, info.model.modelID)
+ const model = info.model ?? (await Provider.defaultModel())
const readCtx: Tool.Context = {
sessionID: input.sessionID,
abort: new AbortController().signal,
agent: input.agent!,
messageID: info.id,
- extra: { bypassCwdCheck: true, model },
+ model,
+ extra: { bypassCwdCheck: true },
messages: [],
metadata: async () => {},
ask: async () => {},
@@ -1198,11 +1206,13 @@ export namespace SessionPrompt {
if (part.mime === "application/x-directory") {
const args = { filePath: filepath }
+ const model = info.model ?? (await Provider.defaultModel())
const listCtx: Tool.Context = {
sessionID: input.sessionID,
abort: new AbortController().signal,
agent: input.agent!,
messageID: info.id,
+ model,
extra: { bypassCwdCheck: true },
messages: [],
metadata: async () => {},
@@ -1568,124 +1578,29 @@ NOTE: At any point in time through this workflow you should feel free to ask the
},
}
await Session.updatePart(part)
- const shell = Shell.preferred()
- const shellName = (
- process.platform === "win32" ? path.win32.basename(shell, ".exe") : path.basename(shell)
- ).toLowerCase()
-
- const invocations: Record = {
- nu: {
- args: ["-c", input.command],
- },
- fish: {
- args: ["-c", input.command],
- },
- zsh: {
- args: [
- "-c",
- "-l",
- `
- [[ -f ~/.zshenv ]] && source ~/.zshenv >/dev/null 2>&1 || true
- [[ -f "\${ZDOTDIR:-$HOME}/.zshrc" ]] && source "\${ZDOTDIR:-$HOME}/.zshrc" >/dev/null 2>&1 || true
- eval ${JSON.stringify(input.command)}
- `,
- ],
- },
- bash: {
- args: [
- "-c",
- "-l",
- `
- shopt -s expand_aliases
- [[ -f ~/.bashrc ]] && source ~/.bashrc >/dev/null 2>&1 || true
- eval ${JSON.stringify(input.command)}
- `,
- ],
- },
- // Windows cmd
- cmd: {
- args: ["/c", input.command],
- },
- // Windows PowerShell
- powershell: {
- args: ["-NoProfile", "-Command", input.command],
- },
- pwsh: {
- args: ["-NoProfile", "-Command", input.command],
- },
- // Fallback: any shell that doesn't match those above
- // - No -l, for max compatibility
- "": {
- args: ["-c", `${input.command}`],
- },
- }
-
- const matchingInvocation = invocations[shellName] ?? invocations[""]
- const args = matchingInvocation?.args
-
- const cwd = Instance.directory
- const shellEnv = await Plugin.trigger("shell.env", { cwd }, { env: {} })
- const proc = spawn(shell, args, {
- cwd,
- detached: process.platform !== "win32",
- stdio: ["ignore", "pipe", "pipe"],
- env: {
- ...process.env,
- ...shellEnv.env,
- TERM: "dumb",
- },
- })
-
- let output = ""
-
- proc.stdout?.on("data", (chunk) => {
- output += chunk.toString()
- if (part.state.status === "running") {
- part.state.metadata = {
- output: output,
- description: "",
- }
- Session.updatePart(part)
- }
- })
- proc.stderr?.on("data", (chunk) => {
- output += chunk.toString()
- if (part.state.status === "running") {
- part.state.metadata = {
- output: output,
- description: "",
+ let currentOutput = ""
+
+ const result = await Shell.execute({
+ command: input.command,
+ cwd: Instance.directory,
+ shell: Shell.preferred(),
+ loadRcFiles: true,
+ abort,
+ onOutput: (output) => {
+ currentOutput = output
+ if (part.state.status === "running") {
+ part.state.metadata = {
+ output,
+ description: "",
+ }
+ Session.updatePart(part)
}
- Session.updatePart(part)
- }
- })
-
- let aborted = false
- let exited = false
-
- const kill = () => Shell.killTree(proc, { exited: () => exited })
-
- if (abort.aborted) {
- aborted = true
- await kill()
- }
-
- const abortHandler = () => {
- aborted = true
- void kill()
- }
-
- abort.addEventListener("abort", abortHandler, { once: true })
-
- await new Promise((resolve) => {
- proc.on("close", () => {
- exited = true
- abort.removeEventListener("abort", abortHandler)
- resolve()
- })
+ },
})
- if (aborted) {
+ let output = currentOutput
+ if (result.aborted) {
output += "\n\n" + ["", "User aborted the command", ""].join("\n")
}
msg.time.completed = Date.now()
diff --git a/packages/opencode/src/session/retry.ts b/packages/opencode/src/session/retry.ts
index 6d057f539f81..2c2038bb99b7 100644
--- a/packages/opencode/src/session/retry.ts
+++ b/packages/opencode/src/session/retry.ts
@@ -1,4 +1,4 @@
-import type { NamedError } from "@opencode-ai/util/error"
+import type { NamedError } from "@opencoder-ai/util/error"
import { MessageV2 } from "./message-v2"
import { iife } from "@/util/iife"
diff --git a/packages/opencode/src/share/share-next.ts b/packages/opencode/src/share/share-next.ts
index a3a229d1a1d5..87fdaf6982ed 100644
--- a/packages/opencode/src/share/share-next.ts
+++ b/packages/opencode/src/share/share-next.ts
@@ -6,7 +6,7 @@ import { Session } from "@/session"
import { MessageV2 } from "@/session/message-v2"
import { Storage } from "@/storage/storage"
import { Log } from "@/util/log"
-import type * as SDK from "@opencode-ai/sdk/v2"
+import type * as SDK from "@opencoder-ai/sdk/v2"
export namespace ShareNext {
const log = Log.create({ service: "share-next" })
diff --git a/packages/opencode/src/shell/shell.ts b/packages/opencode/src/shell/shell.ts
index 2e8d48bfd921..c15c1548e03c 100644
--- a/packages/opencode/src/shell/shell.ts
+++ b/packages/opencode/src/shell/shell.ts
@@ -64,4 +64,132 @@ export namespace Shell {
if (s && !BLACKLIST.has(process.platform === "win32" ? path.win32.basename(s) : path.basename(s))) return s
return fallback()
})
+
+ function getInvocationArgs(shell: string, command: string): string[] {
+ const shellName = (
+ process.platform === "win32" ? path.win32.basename(shell, ".exe") : path.basename(shell)
+ ).toLowerCase()
+
+ const invocations: Record = {
+ nu: ["-c", command],
+ fish: ["-c", command],
+ zsh: [
+ "-c",
+ "-l",
+ `[[ -f ~/.zshenv ]] && source ~/.zshenv >/dev/null 2>&1 || true
+[[ -f "\${ZDOTDIR:-$HOME}/.zshrc" ]] && source "\${ZDOTDIR:-$HOME}/.zshrc" >/dev/null 2>&1 || true
+eval ${JSON.stringify(command)}`,
+ ],
+ bash: [
+ "-c",
+ "-l",
+ `shopt -s expand_aliases
+[[ -f ~/.bashrc ]] && source ~/.bashrc >/dev/null 2>&1 || true
+eval ${JSON.stringify(command)}`,
+ ],
+ cmd: ["/c", command],
+ powershell: ["-NoProfile", "-Command", command],
+ pwsh: ["-NoProfile", "-Command", command],
+ }
+
+ return invocations[shellName] ?? ["-c", command]
+ }
+
+ // ============ Unified Execution ============
+
+ export interface ExecuteOptions {
+ command: string
+ cwd: string
+ shell?: string
+ loadRcFiles?: boolean
+ timeout?: number
+ abort: AbortSignal
+ env?: Record
+ onOutput?: (output: string) => void
+ }
+
+ export interface ExecuteResult {
+ output: string
+ exitCode: number | null
+ timedOut: boolean
+ aborted: boolean
+ }
+
+ export async function execute(options: ExecuteOptions): Promise {
+ const { command, cwd, shell = acceptable(), loadRcFiles = false, timeout, abort, env = {}, onOutput } = options
+
+ const proc = loadRcFiles
+ ? spawn(shell, getInvocationArgs(shell, command), {
+ cwd,
+ env: { ...process.env, TERM: "dumb", ...env },
+ stdio: ["ignore", "pipe", "pipe"],
+ detached: process.platform !== "win32",
+ })
+ : spawn(command, {
+ shell,
+ cwd,
+ env: { ...process.env, TERM: "dumb", ...env },
+ stdio: ["ignore", "pipe", "pipe"],
+ detached: process.platform !== "win32",
+ })
+
+ let output = ""
+ let timedOut = false
+ let aborted = false
+ let exited = false
+
+ const append = (chunk: Buffer) => {
+ output += chunk.toString()
+ onOutput?.(output)
+ }
+
+ proc.stdout?.on("data", append)
+ proc.stderr?.on("data", append)
+
+ const kill = () => killTree(proc, { exited: () => exited })
+
+ if (abort.aborted) {
+ aborted = true
+ await kill()
+ }
+
+ const abortHandler = () => {
+ aborted = true
+ void kill()
+ }
+ abort.addEventListener("abort", abortHandler, { once: true })
+
+ const timeoutTimer = timeout
+ ? setTimeout(() => {
+ timedOut = true
+ void kill()
+ }, timeout + 100)
+ : undefined
+
+ await new Promise((resolve, reject) => {
+ const cleanup = () => {
+ if (timeoutTimer) clearTimeout(timeoutTimer)
+ abort.removeEventListener("abort", abortHandler)
+ }
+
+ proc.once("exit", () => {
+ exited = true
+ cleanup()
+ resolve()
+ })
+
+ proc.once("error", (error) => {
+ exited = true
+ cleanup()
+ reject(error)
+ })
+ })
+
+ return {
+ output,
+ exitCode: proc.exitCode,
+ timedOut,
+ aborted,
+ }
+ }
}
diff --git a/packages/opencode/src/skill/skill.ts b/packages/opencode/src/skill/skill.ts
index 42795b7ebcc3..bc93bceb6ae9 100644
--- a/packages/opencode/src/skill/skill.ts
+++ b/packages/opencode/src/skill/skill.ts
@@ -3,7 +3,7 @@ import path from "path"
import os from "os"
import { Config } from "../config/config"
import { Instance } from "../project/instance"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { ConfigMarkdown } from "../config/markdown"
import { Log } from "../util/log"
import { Global } from "@/global"
diff --git a/packages/opencode/src/storage/storage.ts b/packages/opencode/src/storage/storage.ts
index 18f2d67e7ac0..c5d7edcb17dd 100644
--- a/packages/opencode/src/storage/storage.ts
+++ b/packages/opencode/src/storage/storage.ts
@@ -6,7 +6,7 @@ import { Filesystem } from "../util/filesystem"
import { lazy } from "../util/lazy"
import { Lock } from "../util/lock"
import { $ } from "bun"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import z from "zod"
export namespace Storage {
diff --git a/packages/opencode/src/tool/bash.ts b/packages/opencode/src/tool/bash.ts
index 67559b78c085..c9e8aea8f8f0 100644
--- a/packages/opencode/src/tool/bash.ts
+++ b/packages/opencode/src/tool/bash.ts
@@ -1,5 +1,4 @@
import z from "zod"
-import { spawn } from "child_process"
import { Tool } from "./tool"
import path from "path"
import DESCRIPTION from "./bash.txt"
@@ -19,6 +18,7 @@ import { Truncate } from "./truncation"
import { Plugin } from "@/plugin"
const MAX_METADATA_LENGTH = 30_000
+const MAX_OUTPUT_LENGTH = 30_000
const DEFAULT_TIMEOUT = Flag.OPENCODE_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MS || 2 * 60 * 1000
export const log = Log.create({ service: "bash-tool" })
@@ -53,8 +53,7 @@ const parser = lazy(async () => {
// TODO: we may wanna rename this tool so it works better on other shells
export const BashTool = Tool.define("bash", async () => {
- const shell = Shell.acceptable()
- log.info("bash tool using shell", { shell })
+ log.info("bash tool using shell", { shell: Shell.acceptable() })
return {
description: DESCRIPTION.replaceAll("${directory}", Instance.directory)
@@ -163,20 +162,6 @@ export const BashTool = Tool.define("bash", async () => {
})
}
- const shellEnv = await Plugin.trigger("shell.env", { cwd }, { env: {} })
- const proc = spawn(params.command, {
- shell,
- cwd,
- env: {
- ...process.env,
- ...shellEnv.env,
- },
- stdio: ["ignore", "pipe", "pipe"],
- detached: process.platform !== "win32",
- })
-
- let output = ""
-
// Initialize metadata with empty output
ctx.metadata({
metadata: {
@@ -185,69 +170,40 @@ export const BashTool = Tool.define("bash", async () => {
},
})
- const append = (chunk: Buffer) => {
- output += chunk.toString()
- ctx.metadata({
- metadata: {
- // truncate the metadata to avoid GIANT blobs of data (has nothing to do w/ what agent can access)
- output: output.length > MAX_METADATA_LENGTH ? output.slice(0, MAX_METADATA_LENGTH) + "\n\n..." : output,
- description: params.description,
- },
- })
- }
-
- proc.stdout?.on("data", append)
- proc.stderr?.on("data", append)
-
- let timedOut = false
- let aborted = false
- let exited = false
-
- const kill = () => Shell.killTree(proc, { exited: () => exited })
-
- if (ctx.abort.aborted) {
- aborted = true
- await kill()
- }
-
- const abortHandler = () => {
- aborted = true
- void kill()
- }
-
- ctx.abort.addEventListener("abort", abortHandler, { once: true })
-
- const timeoutTimer = setTimeout(() => {
- timedOut = true
- void kill()
- }, timeout + 100)
-
- await new Promise((resolve, reject) => {
- const cleanup = () => {
- clearTimeout(timeoutTimer)
- ctx.abort.removeEventListener("abort", abortHandler)
- }
-
- proc.once("exit", () => {
- exited = true
- cleanup()
- resolve()
- })
+ let currentOutput = ""
- proc.once("error", (error) => {
- exited = true
- cleanup()
- reject(error)
- })
+ const result = await Shell.execute({
+ command: params.command,
+ cwd,
+ loadRcFiles: true,
+ timeout,
+ abort: ctx.abort,
+ onOutput: (output) => {
+ currentOutput = output
+ if (output.length <= MAX_OUTPUT_LENGTH) {
+ ctx.metadata({
+ metadata: {
+ output,
+ description: params.description,
+ },
+ })
+ }
+ },
})
+ let output = currentOutput
const resultMetadata: string[] = []
- if (timedOut) {
+ if (output.length > MAX_OUTPUT_LENGTH) {
+ output = output.slice(0, MAX_OUTPUT_LENGTH)
+ resultMetadata.push(`bash tool truncated output as it exceeded ${MAX_OUTPUT_LENGTH} char limit`)
+ }
+
+ if (result.timedOut) {
resultMetadata.push(`bash tool terminated command after exceeding timeout ${timeout} ms`)
}
- if (aborted) {
+ if (result.aborted) {
resultMetadata.push("User aborted the command")
}
@@ -259,7 +215,7 @@ export const BashTool = Tool.define("bash", async () => {
title: params.description,
metadata: {
output: output.length > MAX_METADATA_LENGTH ? output.slice(0, MAX_METADATA_LENGTH) + "\n\n..." : output,
- exit: proc.exitCode,
+ exit: result.exitCode,
description: params.description,
},
output,
diff --git a/packages/opencode/src/tool/registry.ts b/packages/opencode/src/tool/registry.ts
index 9a06cb59937b..fd287f018bb6 100644
--- a/packages/opencode/src/tool/registry.ts
+++ b/packages/opencode/src/tool/registry.ts
@@ -16,7 +16,7 @@ import { Tool } from "./tool"
import { Instance } from "../project/instance"
import { Config } from "../config/config"
import path from "path"
-import { type ToolContext as PluginToolContext, type ToolDefinition } from "@opencode-ai/plugin"
+import { type ToolContext as PluginToolContext, type ToolDefinition, type ToolResult } from "@opencoder-ai/plugin"
import z from "zod"
import { Plugin } from "../plugin"
import { WebSearchTool } from "./websearch"
@@ -68,13 +68,20 @@ export namespace ToolRegistry {
...ctx,
directory: Instance.directory,
worktree: Instance.worktree,
+ model: ctx.model,
} as unknown as PluginToolContext
const result = await def.execute(args as any, pluginCtx)
- const out = await Truncate.output(result, {}, initCtx?.agent)
+ const normalized = typeof result === "string" ? { title: "", metadata: {}, output: result } : result
+ const out = await Truncate.output(normalized.output, {}, initCtx?.agent)
return {
- title: "",
- output: out.truncated ? out.content : result,
- metadata: { truncated: out.truncated, outputPath: out.truncated ? out.outputPath : undefined },
+ title: normalized.title,
+ output: out.truncated ? out.content : normalized.output,
+ metadata: {
+ ...normalized.metadata,
+ truncated: out.truncated,
+ outputPath: out.truncated ? out.outputPath : undefined,
+ },
+ attachments: normalized.attachments,
}
},
}),
diff --git a/packages/opencode/src/tool/task.ts b/packages/opencode/src/tool/task.ts
index 8c8cf827abaf..96b4aedc1b6d 100644
--- a/packages/opencode/src/tool/task.ts
+++ b/packages/opencode/src/tool/task.ts
@@ -2,6 +2,7 @@ import { Tool } from "./tool"
import DESCRIPTION from "./task.txt"
import z from "zod"
import { Session } from "../session"
+import { Bus } from "../bus"
import { MessageV2 } from "../session/message-v2"
import { Identifier } from "../id/id"
import { Agent } from "../agent/agent"
@@ -10,6 +11,7 @@ import { iife } from "@/util/iife"
import { defer } from "@/util/defer"
import { Config } from "../config/config"
import { PermissionNext } from "@/permission/next"
+import { Provider } from "../provider/provider"
const parameters = z.object({
description: z.string().describe("A short (3-5 words) description of the task"),
@@ -103,10 +105,18 @@ export const TaskTool = Tool.define("task", async (ctx) => {
const msg = await MessageV2.get({ sessionID: ctx.sessionID, messageID: ctx.messageID })
if (msg.info.role !== "assistant") throw new Error("Not an assistant message")
- const model = agent.model ?? {
+ const messageModel = {
modelID: msg.info.modelID,
providerID: msg.info.providerID,
}
+ const useMessageModel = msg.info.agent === agent.name
+ const defaultModel = await Provider.defaultModel()
+ const model = useMessageModel
+ ? messageModel
+ : (agent.model ?? {
+ modelID: defaultModel.modelID,
+ providerID: defaultModel.providerID,
+ })
ctx.metadata({
title: params.description,
@@ -117,6 +127,31 @@ export const TaskTool = Tool.define("task", async (ctx) => {
})
const messageID = Identifier.ascending("message")
+ const parts: Record = {}
+ const unsub = Bus.subscribe(MessageV2.Event.PartUpdated, async (evt) => {
+ if (evt.properties.part.sessionID !== session.id) return
+ if (evt.properties.part.messageID === messageID) return
+ if (evt.properties.part.type !== "tool") return
+ const part = evt.properties.part
+ parts[part.id] = {
+ id: part.id,
+ tool: part.tool,
+ state: {
+ status: part.state.status,
+ title: part.state.status === "completed" ? part.state.title : undefined,
+ },
+ }
+ ctx.metadata({
+ title: params.description,
+ metadata: {
+ summary: Object.values(parts).sort((a, b) => a.id.localeCompare(b.id)),
+ subagent_type: params.subagent_type,
+ sessionId: session.id,
+ model,
+ description: params.description,
+ },
+ })
+ })
function cancel() {
SessionPrompt.cancel(session.id)
@@ -140,8 +175,22 @@ export const TaskTool = Tool.define("task", async (ctx) => {
...Object.fromEntries((config.experimental?.primary_tools ?? []).map((t) => [t, false])),
},
parts: promptParts,
+ }).finally(() => {
+ unsub()
})
+ const messages = await Session.messages({ sessionID: session.id })
+ const summary = messages
+ .filter((x) => x.info.role === "assistant")
+ .flatMap((msg) => msg.parts.filter((x: any) => x.type === "tool") as MessageV2.ToolPart[])
+ .map((part) => ({
+ id: part.id,
+ tool: part.tool,
+ state: {
+ status: part.state.status,
+ title: part.state.status === "completed" ? part.state.title : undefined,
+ },
+ }))
const text = result.parts.findLast((x) => x.type === "text")?.text ?? ""
const output = [
@@ -155,8 +204,11 @@ export const TaskTool = Tool.define("task", async (ctx) => {
return {
title: params.description,
metadata: {
+ summary,
+ subagent_type: params.subagent_type,
sessionId: session.id,
model,
+ description: params.description,
},
output,
}
diff --git a/packages/opencode/src/tool/tool.ts b/packages/opencode/src/tool/tool.ts
index 3d17ea192d32..e21f9947d91d 100644
--- a/packages/opencode/src/tool/tool.ts
+++ b/packages/opencode/src/tool/tool.ts
@@ -17,6 +17,7 @@ export namespace Tool {
sessionID: string
messageID: string
agent: string
+ model: { providerID: string; modelID: string }
abort: AbortSignal
callID?: string
extra?: { [key: string]: any }
diff --git a/packages/opencode/src/worktree/index.ts b/packages/opencode/src/worktree/index.ts
index 85d7f6d0e8a2..3a5fe0ec49f0 100644
--- a/packages/opencode/src/worktree/index.ts
+++ b/packages/opencode/src/worktree/index.ts
@@ -2,7 +2,7 @@ import { $ } from "bun"
import fs from "fs/promises"
import path from "path"
import z from "zod"
-import { NamedError } from "@opencode-ai/util/error"
+import { NamedError } from "@opencoder-ai/util/error"
import { Global } from "../global"
import { Instance } from "../project/instance"
import { InstanceBootstrap } from "../project/bootstrap"
diff --git a/packages/opencode/test/acp/event-subscription.test.ts b/packages/opencode/test/acp/event-subscription.test.ts
index 8e139ff59732..f8feca71e2ba 100644
--- a/packages/opencode/test/acp/event-subscription.test.ts
+++ b/packages/opencode/test/acp/event-subscription.test.ts
@@ -1,7 +1,7 @@
import { describe, expect, test } from "bun:test"
import { ACP } from "../../src/acp/agent"
import type { AgentSideConnection } from "@agentclientprotocol/sdk"
-import type { Event } from "@opencode-ai/sdk/v2"
+import type { Event } from "@opencoder-ai/sdk/v2"
import { Instance } from "../../src/project/instance"
import { tmpdir } from "../fixture/fixture"
diff --git a/packages/opencode/test/cli/tui/transcript.test.ts b/packages/opencode/test/cli/tui/transcript.test.ts
index 7a5fa6b8f1cf..4b8eb0c77144 100644
--- a/packages/opencode/test/cli/tui/transcript.test.ts
+++ b/packages/opencode/test/cli/tui/transcript.test.ts
@@ -5,7 +5,7 @@ import {
formatPart,
formatTranscript,
} from "../../../src/cli/cmd/tui/util/transcript"
-import type { AssistantMessage, Part, UserMessage } from "@opencode-ai/sdk/v2"
+import type { AssistantMessage, Part, UserMessage } from "@opencoder-ai/sdk/v2"
describe("transcript", () => {
describe("formatAssistantHeader", () => {
diff --git a/packages/opencode/test/memory/abort-leak.test.ts b/packages/opencode/test/memory/abort-leak.test.ts
index b202c9127a8a..b9b19a6e0021 100644
--- a/packages/opencode/test/memory/abort-leak.test.ts
+++ b/packages/opencode/test/memory/abort-leak.test.ts
@@ -2,6 +2,7 @@ import { describe, test, expect } from "bun:test"
import path from "path"
import { Instance } from "../../src/project/instance"
import { WebFetchTool } from "../../src/tool/webfetch"
+import { testModel } from "../tool/fixtures/model"
const projectRoot = path.join(__dirname, "../..")
@@ -14,6 +15,7 @@ const ctx = {
messages: [],
metadata: () => {},
ask: async () => {},
+ model: testModel,
}
const MB = 1024 * 1024
diff --git a/packages/opencode/test/session/retry.test.ts b/packages/opencode/test/session/retry.test.ts
index 6768e72d95a7..8ca9a3be7e00 100644
--- a/packages/opencode/test/session/retry.test.ts
+++ b/packages/opencode/test/session/retry.test.ts
@@ -1,5 +1,5 @@
import { describe, expect, test } from "bun:test"
-import type { NamedError } from "@opencode-ai/util/error"
+import type { NamedError } from "@opencoder-ai/util/error"
import { APICallError } from "ai"
import { SessionRetry } from "../../src/session/retry"
import { MessageV2 } from "../../src/session/message-v2"
diff --git a/packages/opencode/test/tool/apply_patch.test.ts b/packages/opencode/test/tool/apply_patch.test.ts
index a08e235885af..42c3cfae8bf2 100644
--- a/packages/opencode/test/tool/apply_patch.test.ts
+++ b/packages/opencode/test/tool/apply_patch.test.ts
@@ -4,12 +4,14 @@ import * as fs from "fs/promises"
import { ApplyPatchTool } from "../../src/tool/apply_patch"
import { Instance } from "../../src/project/instance"
import { tmpdir } from "../fixture/fixture"
+import { testModel } from "./fixtures/model"
const baseCtx = {
sessionID: "test",
messageID: "",
callID: "",
agent: "build",
+ model: testModel,
abort: AbortSignal.any([]),
messages: [],
metadata: () => {},
diff --git a/packages/opencode/test/tool/bash.test.ts b/packages/opencode/test/tool/bash.test.ts
index fd03b7f9803c..c5e0921860b1 100644
--- a/packages/opencode/test/tool/bash.test.ts
+++ b/packages/opencode/test/tool/bash.test.ts
@@ -5,12 +5,14 @@ import { Instance } from "../../src/project/instance"
import { tmpdir } from "../fixture/fixture"
import type { PermissionNext } from "../../src/permission/next"
import { Truncate } from "../../src/tool/truncation"
+import { testModel } from "./fixtures/model"
const ctx = {
sessionID: "test",
messageID: "",
callID: "",
agent: "build",
+ model: testModel,
abort: AbortSignal.any([]),
messages: [],
metadata: () => {},
diff --git a/packages/opencode/test/tool/external-directory.test.ts b/packages/opencode/test/tool/external-directory.test.ts
index 33c5e2c7397f..331a65845728 100644
--- a/packages/opencode/test/tool/external-directory.test.ts
+++ b/packages/opencode/test/tool/external-directory.test.ts
@@ -4,12 +4,14 @@ import type { Tool } from "../../src/tool/tool"
import { Instance } from "../../src/project/instance"
import { assertExternalDirectory } from "../../src/tool/external-directory"
import type { PermissionNext } from "../../src/permission/next"
+import { testModel } from "./fixtures/model"
const baseCtx: Omit = {
sessionID: "test",
messageID: "",
callID: "",
agent: "build",
+ model: testModel,
abort: AbortSignal.any([]),
messages: [],
metadata: () => {},
diff --git a/packages/opencode/test/tool/fixtures/model.ts b/packages/opencode/test/tool/fixtures/model.ts
new file mode 100644
index 000000000000..c74a45c27c62
--- /dev/null
+++ b/packages/opencode/test/tool/fixtures/model.ts
@@ -0,0 +1,4 @@
+export const testModel = {
+ providerID: "test-provider",
+ modelID: "test-model",
+}
diff --git a/packages/opencode/test/tool/grep.test.ts b/packages/opencode/test/tool/grep.test.ts
index e774580df61c..fb8be41d88c9 100644
--- a/packages/opencode/test/tool/grep.test.ts
+++ b/packages/opencode/test/tool/grep.test.ts
@@ -3,12 +3,14 @@ import path from "path"
import { GrepTool } from "../../src/tool/grep"
import { Instance } from "../../src/project/instance"
import { tmpdir } from "../fixture/fixture"
+import { testModel } from "./fixtures/model"
const ctx = {
sessionID: "test",
messageID: "",
callID: "",
agent: "build",
+ model: testModel,
abort: AbortSignal.any([]),
messages: [],
metadata: () => {},
diff --git a/packages/opencode/test/tool/question.test.ts b/packages/opencode/test/tool/question.test.ts
index 4a436186db61..951877153957 100644
--- a/packages/opencode/test/tool/question.test.ts
+++ b/packages/opencode/test/tool/question.test.ts
@@ -2,12 +2,14 @@ import { describe, expect, test, spyOn, beforeEach, afterEach } from "bun:test"
import { z } from "zod"
import { QuestionTool } from "../../src/tool/question"
import * as QuestionModule from "../../src/question"
+import { testModel } from "./fixtures/model"
const ctx = {
sessionID: "test-session",
messageID: "test-message",
callID: "test-call",
agent: "test-agent",
+ model: testModel,
abort: AbortSignal.any([]),
messages: [],
metadata: () => {},
diff --git a/packages/opencode/test/tool/read.test.ts b/packages/opencode/test/tool/read.test.ts
index 095c7bce2d25..7e1affa56ea6 100644
--- a/packages/opencode/test/tool/read.test.ts
+++ b/packages/opencode/test/tool/read.test.ts
@@ -5,6 +5,7 @@ import { Instance } from "../../src/project/instance"
import { tmpdir } from "../fixture/fixture"
import { PermissionNext } from "../../src/permission/next"
import { Agent } from "../../src/agent/agent"
+import { testModel } from "./fixtures/model"
const FIXTURES_DIR = path.join(import.meta.dir, "fixtures")
@@ -13,6 +14,7 @@ const ctx = {
messageID: "",
callID: "",
agent: "build",
+ model: testModel,
abort: AbortSignal.any([]),
messages: [],
metadata: () => {},
diff --git a/packages/opencode/test/tool/registry.test.ts b/packages/opencode/test/tool/registry.test.ts
index 706a9e12caf9..a5eba09c6a42 100644
--- a/packages/opencode/test/tool/registry.test.ts
+++ b/packages/opencode/test/tool/registry.test.ts
@@ -88,7 +88,7 @@ describe("tool.registry", () => {
JSON.stringify({
name: "custom-tools",
dependencies: {
- "@opencode-ai/plugin": "^0.0.0",
+ "@opencoder-ai/plugin": "^0.0.0",
cowsay: "^1.6.0",
},
}),
diff --git a/packages/opencode/test/tool/skill.test.ts b/packages/opencode/test/tool/skill.test.ts
index d5057ba9e7f4..643d068341ac 100644
--- a/packages/opencode/test/tool/skill.test.ts
+++ b/packages/opencode/test/tool/skill.test.ts
@@ -5,6 +5,7 @@ import type { PermissionNext } from "../../src/permission/next"
import type { Tool } from "../../src/tool/tool"
import { Instance } from "../../src/project/instance"
import { SkillTool } from "../../src/tool/skill"
+import { testModel } from "./fixtures/model"
import { tmpdir } from "../fixture/fixture"
const baseCtx: Omit = {
@@ -15,6 +16,7 @@ const baseCtx: Omit = {
abort: AbortSignal.any([]),
messages: [],
metadata: () => {},
+ model: testModel,
}
describe("tool.skill", () => {
diff --git a/packages/opencode/test/tool/webfetch.test.ts b/packages/opencode/test/tool/webfetch.test.ts
index 10178af8fab7..6c85ef4e5398 100644
--- a/packages/opencode/test/tool/webfetch.test.ts
+++ b/packages/opencode/test/tool/webfetch.test.ts
@@ -10,6 +10,7 @@ const ctx = {
messageID: "message",
callID: "",
agent: "build",
+ model: { providerID: "opencode", modelID: "test" },
abort: AbortSignal.any([]),
messages: [],
metadata: () => {},
diff --git a/packages/plugin/AGENTS.md b/packages/plugin/AGENTS.md
new file mode 100644
index 000000000000..f34bd7f3ca58
--- /dev/null
+++ b/packages/plugin/AGENTS.md
@@ -0,0 +1,21 @@
+# Plugin System
+
+**Package:** `packages/plugin`
+**Type:** Plugin architecture
+
+## Overview
+
+Core plugin system for extending OpenCode functionality.
+
+## Structure
+
+```
+packages/plugin/src/
+└── ... # Plugin infrastructure
+```
+
+## Key Patterns
+
+- Plugin interface definitions
+- Plugin loading and management
+- Extension points
diff --git a/packages/plugin/package.json b/packages/plugin/package.json
index c373083f5873..5f5c4b856b2c 100644
--- a/packages/plugin/package.json
+++ b/packages/plugin/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
- "name": "@opencode-ai/plugin",
- "version": "1.1.65",
+ "name": "@opencoder-ai/plugin",
+ "version": "1.1.63",
"type": "module",
"license": "MIT",
"scripts": {
@@ -16,13 +16,13 @@
"dist"
],
"dependencies": {
- "@opencode-ai/sdk": "workspace:*",
+ "@opencoder-ai/sdk": "workspace:*",
"zod": "catalog:"
},
"devDependencies": {
"@tsconfig/node22": "catalog:",
"@types/node": "catalog:",
- "typescript": "catalog:",
- "@typescript/native-preview": "catalog:"
+ "@typescript/native-preview": "catalog:",
+ "typescript": "catalog:"
}
}
diff --git a/packages/plugin/script/publish.ts b/packages/plugin/script/publish.ts
index 647b56e5e2dd..b0ee7b17dbf9 100755
--- a/packages/plugin/script/publish.ts
+++ b/packages/plugin/script/publish.ts
@@ -1,5 +1,5 @@
#!/usr/bin/env bun
-import { Script } from "@opencode-ai/script"
+import { Script } from "@opencoder-ai/script"
import { $ } from "bun"
const dir = new URL("..", import.meta.url).pathname
diff --git a/packages/plugin/src/index.ts b/packages/plugin/src/index.ts
index bd4ba530498d..e08a366a954d 100644
--- a/packages/plugin/src/index.ts
+++ b/packages/plugin/src/index.ts
@@ -1,16 +1,16 @@
import type {
Event,
- createOpencodeClient,
Project,
Model,
Provider,
- Permission,
+ PermissionRequest,
UserMessage,
Message,
Part,
Auth,
Config,
-} from "@opencode-ai/sdk"
+ OpencodeClient,
+} from "@opencoder-ai/sdk/v2"
import type { BunShell } from "./shell"
import { type ToolDefinition } from "./tool"
@@ -24,7 +24,7 @@ export type ProviderContext = {
}
export type PluginInput = {
- client: ReturnType
+ client: OpencodeClient
project: Project
directory: string
worktree: string
@@ -176,18 +176,21 @@ export interface Hooks {
input: { sessionID: string; agent: string; model: Model; provider: ProviderContext; message: UserMessage },
output: { headers: Record },
) => Promise
- "permission.ask"?: (input: Permission, output: { status: "ask" | "deny" | "allow" }) => Promise
+ "permission.ask"?: (
+ input: PermissionRequest,
+ output: { status: "ask" | "deny" | "allow" | "reject" },
+ ) => Promise
"command.execute.before"?: (
input: { command: string; sessionID: string; arguments: string },
output: { parts: Part[] },
) => Promise
"tool.execute.before"?: (
- input: { tool: string; sessionID: string; callID: string },
+ input: { tool: string; sessionID: string; callID: string; agent?: string },
output: { args: any },
) => Promise
"shell.env"?: (input: { cwd: string }, output: { env: Record }) => Promise
"tool.execute.after"?: (
- input: { tool: string; sessionID: string; callID: string; args: any },
+ input: { tool: string; sessionID: string; callID: string; args: any; agent?: string },
output: {
title: string
output: string
diff --git a/packages/plugin/src/tool.ts b/packages/plugin/src/tool.ts
index 23aa512d9a43..a4b47cc619ca 100644
--- a/packages/plugin/src/tool.ts
+++ b/packages/plugin/src/tool.ts
@@ -1,9 +1,11 @@
import { z } from "zod"
+import type { FilePart } from "@opencoder-ai/sdk"
export type ToolContext = {
sessionID: string
messageID: string
agent: string
+ model?: { providerID: string; modelID: string }
/**
* Current project directory for this session.
* Prefer this over process.cwd() when resolving relative paths.
@@ -26,10 +28,27 @@ type AskInput = {
metadata: { [key: string]: any }
}
+/**
+ * Structured result for plugin tools.
+ *
+ * Return this instead of a plain string to provide rich metadata
+ * that integrates with streaming updates.
+ */
+export interface ToolResult {
+ /** Title displayed in the UI */
+ title: string
+ /** Arbitrary metadata passed to tool.execute.after hooks */
+ metadata: Record
+ /** The text output returned to the model */
+ output: string
+ /** Optional file attachments to include with the result */
+ attachments?: FilePart[]
+}
+
export function tool(input: {
description: string
args: Args
- execute(args: z.infer>, context: ToolContext): Promise
+ execute(args: z.infer>, context: ToolContext): Promise
}) {
return input
}
diff --git a/packages/script/AGENTS.md b/packages/script/AGENTS.md
new file mode 100644
index 000000000000..38964d575ec5
--- /dev/null
+++ b/packages/script/AGENTS.md
@@ -0,0 +1,14 @@
+# Script Utilities
+
+**Package:** `packages/script`
+**Type:** Build and utility scripts
+
+## Overview
+
+Shared build scripts and utilities used across the monorepo.
+
+## Key Patterns
+
+- Build script automation
+- Code generation utilities
+- CI/CD helper scripts
diff --git a/packages/script/package.json b/packages/script/package.json
index 45de3bcb99fb..f5fa940f73bd 100644
--- a/packages/script/package.json
+++ b/packages/script/package.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package",
- "name": "@opencode-ai/script",
+ "name": "@opencoder-ai/script",
"license": "MIT",
"devDependencies": {
"@types/bun": "catalog:"
diff --git a/packages/script/src/index.ts b/packages/script/src/index.ts
index a3f5e7a8e2a4..6de095c4139a 100644
--- a/packages/script/src/index.ts
+++ b/packages/script/src/index.ts
@@ -33,7 +33,7 @@ const IS_PREVIEW = CHANNEL !== "latest"
const VERSION = await (async () => {
if (env.OPENCODE_VERSION) return env.OPENCODE_VERSION
if (IS_PREVIEW) return `0.0.0-${CHANNEL}-${new Date().toISOString().slice(0, 16).replace(/[-:T]/g, "")}`
- const version = await fetch("https://registry.npmjs.org/opencode-ai/latest")
+ const version = await fetch("https://registry.npmjs.org/opencoder-ai/latest")
.then((res) => {
if (!res.ok) throw new Error(res.statusText)
return res.json()
diff --git a/packages/sdk/js/AGENTS.md b/packages/sdk/js/AGENTS.md
new file mode 100644
index 000000000000..34323735acae
--- /dev/null
+++ b/packages/sdk/js/AGENTS.md
@@ -0,0 +1,38 @@
+# JavaScript SDK
+
+**Package:** `packages/sdk/js`
+**Type:** External SDK for programmatic access
+
+## Overview
+
+JavaScript/TypeScript SDK for external programmatic access to OpenCode. Generated from OpenAPI spec.
+
+## Commands
+
+```bash
+# Regenerate SDK
+./packages/sdk/js/script/build.ts
+
+# Test
+cd packages/sdk/js && bun test
+```
+
+## Structure
+
+```
+packages/sdk/js/
+├── src/
+│ ├── index.ts # Public exports
+│ ├── client.ts # Core client
+│ ├── entrypoints/ # Specific entry points
+│ └── __tests__/ # Vitest tests
+├── script/
+│ └── build.ts # SDK generation
+└── vitest.config.ts # Test configuration
+```
+
+## Testing
+
+- Framework: Vitest
+- Config: `vitest.config.ts`
+- Tests in `__tests__/` directory
diff --git a/packages/sdk/js/example/example.ts b/packages/sdk/js/example/example.ts
index 42838a82a7e6..5cffd53c9f40 100644
--- a/packages/sdk/js/example/example.ts
+++ b/packages/sdk/js/example/example.ts
@@ -1,4 +1,4 @@
-import { createOpencodeClient, createOpencodeServer } from "@opencode-ai/sdk"
+import { createOpencodeClient, createOpencodeServer } from "@opencoder-ai/sdk"
import { pathToFileURL } from "bun"
const server = await createOpencodeServer()
diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json
index ff8108b7be57..c40edab9eef7 100644
--- a/packages/sdk/js/package.json
+++ b/packages/sdk/js/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
- "name": "@opencode-ai/sdk",
- "version": "1.1.65",
+ "name": "@opencoder-ai/sdk",
+ "version": "1.1.63",
"type": "module",
"license": "MIT",
"scripts": {
@@ -9,12 +9,30 @@
"build": "./script/build.ts"
},
"exports": {
- ".": "./src/index.ts",
- "./client": "./src/client.ts",
- "./server": "./src/server.ts",
- "./v2": "./src/v2/index.ts",
- "./v2/client": "./src/v2/client.ts",
- "./v2/server": "./src/v2/server.ts"
+ ".": {
+ "types": "./dist/index.d.ts",
+ "default": "./src/index.ts"
+ },
+ "./client": {
+ "types": "./dist/client.d.ts",
+ "default": "./src/client.ts"
+ },
+ "./server": {
+ "types": "./dist/server.d.ts",
+ "default": "./src/server.ts"
+ },
+ "./v2": {
+ "types": "./dist/v2/index.d.ts",
+ "default": "./src/v2/index.ts"
+ },
+ "./v2/client": {
+ "types": "./dist/v2/client.d.ts",
+ "default": "./src/v2/client.ts"
+ },
+ "./v2/server": {
+ "types": "./dist/v2/server.d.ts",
+ "default": "./src/v2/server.ts"
+ }
},
"files": [
"dist"
@@ -23,10 +41,9 @@
"@hey-api/openapi-ts": "0.90.10",
"@tsconfig/node22": "catalog:",
"@types/node": "catalog:",
- "typescript": "catalog:",
- "@typescript/native-preview": "catalog:"
+ "@typescript/native-preview": "catalog:",
+ "typescript": "catalog:"
},
- "dependencies": {},
"publishConfig": {
"directory": "dist"
}
diff --git a/packages/sdk/js/script/publish.ts b/packages/sdk/js/script/publish.ts
index 46dd42b700d1..2fd21da9c3fb 100755
--- a/packages/sdk/js/script/publish.ts
+++ b/packages/sdk/js/script/publish.ts
@@ -1,6 +1,6 @@
#!/usr/bin/env bun
-import { Script } from "@opencode-ai/script"
+import { Script } from "@opencoder-ai/script"
import { $ } from "bun"
const dir = new URL("..", import.meta.url).pathname
diff --git a/packages/sdk/js/src/v2/gen/sdk.gen.ts b/packages/sdk/js/src/v2/gen/sdk.gen.ts
index af79c44a17a7..b745eaa7472d 100644
--- a/packages/sdk/js/src/v2/gen/sdk.gen.ts
+++ b/packages/sdk/js/src/v2/gen/sdk.gen.ts
@@ -132,8 +132,10 @@ import type {
SessionStatusResponses,
SessionSummarizeErrors,
SessionSummarizeResponses,
- SessionTodoErrors,
- SessionTodoResponses,
+ SessionTodoListErrors,
+ SessionTodoListResponses,
+ SessionTodoUpdateErrors,
+ SessionTodoUpdateResponses,
SessionUnrevertErrors,
SessionUnrevertResponses,
SessionUnshareErrors,
@@ -142,6 +144,7 @@ import type {
SessionUpdateResponses,
SubtaskPartInput,
TextPartInput,
+ Todo as Todo2,
ToolIdsErrors,
ToolIdsResponses,
ToolListErrors,
@@ -926,6 +929,75 @@ export class Experimental extends HeyApiClient {
}
}
+export class Todo extends HeyApiClient {
+ /**
+ * Get session todos
+ *
+ * Retrieve the todo list associated with a specific session, showing tasks and action items.
+ */
+ public list(
+ parameters: {
+ sessionID: string
+ directory?: string
+ },
+ options?: Options,
+ ) {
+ const params = buildClientParams(
+ [parameters],
+ [
+ {
+ args: [
+ { in: "path", key: "sessionID" },
+ { in: "query", key: "directory" },
+ ],
+ },
+ ],
+ )
+ return (options?.client ?? this.client).get({
+ url: "/session/{sessionID}/todo",
+ ...options,
+ ...params,
+ })
+ }
+
+ /**
+ * Update session todos
+ *
+ * Replace the todo list associated with a specific session.
+ */
+ public update(
+ parameters: {
+ sessionID: string
+ directory?: string
+ todos?: Array
+ },
+ options?: Options,
+ ) {
+ const params = buildClientParams(
+ [parameters],
+ [
+ {
+ args: [
+ { in: "path", key: "sessionID" },
+ { in: "query", key: "directory" },
+ { in: "body", key: "todos" },
+ ],
+ },
+ ],
+ )
+ return (options?.client ?? this.client).put({
+ url: "/session/{sessionID}/todo",
+ ...options,
+ ...params,
+ headers: {
+ "Content-Type": "application/json",
+ ...options?.headers,
+ ...params.headers,
+ },
+ })
+ }
+}
+
export class Session extends HeyApiClient {
/**
* List sessions
@@ -1152,36 +1224,6 @@ export class Session extends HeyApiClient {
})
}
- /**
- * Get session todos
- *
- * Retrieve the todo list associated with a specific session, showing tasks and action items.
- */
- public todo(
- parameters: {
- sessionID: string
- directory?: string
- },
- options?: Options,
- ) {
- const params = buildClientParams(
- [parameters],
- [
- {
- args: [
- { in: "path", key: "sessionID" },
- { in: "query", key: "directory" },
- ],
- },
- ],
- )
- return (options?.client ?? this.client).get({
- url: "/session/{sessionID}/todo",
- ...options,
- ...params,
- })
- }
-
/**
* Initialize session
*
@@ -1771,6 +1813,11 @@ export class Session extends HeyApiClient {
...params,
})
}
+
+ private _todo?: Todo
+ get todo(): Todo {
+ return (this._todo ??= new Todo({ client: this.client }))
+ }
}
export class Part extends HeyApiClient {
diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts
index b22b7e9af4e1..2a6ed307952e 100644
--- a/packages/sdk/js/src/v2/gen/types.gen.ts
+++ b/packages/sdk/js/src/v2/gen/types.gen.ts
@@ -3118,7 +3118,7 @@ export type SessionChildrenResponses = {
export type SessionChildrenResponse = SessionChildrenResponses[keyof SessionChildrenResponses]
-export type SessionTodoData = {
+export type SessionTodoListData = {
body?: never
path: {
/**
@@ -3132,7 +3132,7 @@ export type SessionTodoData = {
url: "/session/{sessionID}/todo"
}
-export type SessionTodoErrors = {
+export type SessionTodoListErrors = {
/**
* Bad request
*/
@@ -3143,16 +3143,54 @@ export type SessionTodoErrors = {
404: NotFoundError
}
-export type SessionTodoError = SessionTodoErrors[keyof SessionTodoErrors]
+export type SessionTodoListError = SessionTodoListErrors[keyof SessionTodoListErrors]
-export type SessionTodoResponses = {
+export type SessionTodoListResponses = {
/**
* Todo list
*/
200: Array
}
-export type SessionTodoResponse = SessionTodoResponses[keyof SessionTodoResponses]
+export type SessionTodoListResponse = SessionTodoListResponses[keyof SessionTodoListResponses]
+
+export type SessionTodoUpdateData = {
+ body?: {
+ todos: Array
+ }
+ path: {
+ /**
+ * Session ID
+ */
+ sessionID: string
+ }
+ query?: {
+ directory?: string
+ }
+ url: "/session/{sessionID}/todo"
+}
+
+export type SessionTodoUpdateErrors = {
+ /**
+ * Bad request
+ */
+ 400: BadRequestError
+ /**
+ * Not found
+ */
+ 404: NotFoundError
+}
+
+export type SessionTodoUpdateError = SessionTodoUpdateErrors[keyof SessionTodoUpdateErrors]
+
+export type SessionTodoUpdateResponses = {
+ /**
+ * Updated todo list
+ */
+ 200: Array
+}
+
+export type SessionTodoUpdateResponse = SessionTodoUpdateResponses[keyof SessionTodoUpdateResponses]
export type SessionInitData = {
body?: {
diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json
index 70596431bb62..3e6ef2672f6c 100644
--- a/packages/sdk/openapi.json
+++ b/packages/sdk/openapi.json
@@ -36,7 +36,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.global.health({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.global.health({\n ...\n})"
}
]
}
@@ -61,7 +61,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.global.event({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.global.event({\n ...\n})"
}
]
}
@@ -86,7 +86,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.global.config.get({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.global.config.get({\n ...\n})"
}
]
},
@@ -128,7 +128,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.global.config.update({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.global.config.update({\n ...\n})"
}
]
}
@@ -153,7 +153,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.global.dispose({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.global.dispose({\n ...\n})"
}
]
}
@@ -207,7 +207,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.auth.set({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.auth.set({\n ...\n})"
}
]
},
@@ -250,7 +250,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.auth.remove({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.auth.remove({\n ...\n})"
}
]
}
@@ -287,7 +287,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.project.list({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.project.list({\n ...\n})"
}
]
}
@@ -321,7 +321,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.project.current({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.project.current({\n ...\n})"
}
]
}
@@ -420,7 +420,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.project.update({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.project.update({\n ...\n})"
}
]
}
@@ -457,7 +457,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.pty.list({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.pty.list({\n ...\n})"
}
]
},
@@ -534,7 +534,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.pty.create({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.pty.create({\n ...\n})"
}
]
}
@@ -586,7 +586,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.pty.get({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.pty.get({\n ...\n})"
}
]
},
@@ -662,7 +662,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.pty.update({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.pty.update({\n ...\n})"
}
]
},
@@ -712,7 +712,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.pty.remove({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.pty.remove({\n ...\n})"
}
]
}
@@ -764,7 +764,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.pty.connect({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.pty.connect({\n ...\n})"
}
]
}
@@ -798,7 +798,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.config.get({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.config.get({\n ...\n})"
}
]
},
@@ -849,7 +849,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.config.update({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.config.update({\n ...\n})"
}
]
}
@@ -901,7 +901,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.config.providers({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.config.providers({\n ...\n})"
}
]
}
@@ -945,7 +945,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tool.ids({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tool.ids({\n ...\n})"
}
]
}
@@ -1005,7 +1005,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tool.list({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tool.list({\n ...\n})"
}
]
}
@@ -1058,7 +1058,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.worktree.create({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.worktree.create({\n ...\n})"
}
]
},
@@ -1093,7 +1093,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.worktree.list({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.worktree.list({\n ...\n})"
}
]
},
@@ -1144,7 +1144,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.worktree.remove({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.worktree.remove({\n ...\n})"
}
]
}
@@ -1197,7 +1197,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.worktree.reset({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.worktree.reset({\n ...\n})"
}
]
}
@@ -1237,7 +1237,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.resource.list({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.experimental.resource.list({\n ...\n})"
}
]
}
@@ -1307,7 +1307,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.list({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.list({\n ...\n})"
}
]
},
@@ -1370,7 +1370,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.create({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.create({\n ...\n})"
}
]
}
@@ -1420,7 +1420,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.status({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.status({\n ...\n})"
}
]
}
@@ -1484,7 +1484,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.get({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.get({\n ...\n})"
}
]
},
@@ -1545,7 +1545,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.delete({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.delete({\n ...\n})"
}
]
},
@@ -1627,7 +1627,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.update({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.update({\n ...\n})"
}
]
}
@@ -1694,14 +1694,14 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.children({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.children({\n ...\n})"
}
]
}
},
"/session/{sessionID}/todo": {
"get": {
- "operationId": "session.todo",
+ "operationId": "session.todo.list",
"parameters": [
{
"in": "query",
@@ -1760,7 +1760,89 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.todo({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.todo.list({\n ...\n})"
+ }
+ ]
+ },
+ "put": {
+ "operationId": "session.todo.update",
+ "parameters": [
+ {
+ "in": "query",
+ "name": "directory",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "in": "path",
+ "name": "sessionID",
+ "schema": {
+ "type": "string"
+ },
+ "required": true,
+ "description": "Session ID"
+ }
+ ],
+ "summary": "Update session todos",
+ "description": "Replace the todo list associated with a specific session.",
+ "responses": {
+ "200": {
+ "description": "Updated todo list",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Todo"
+ }
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Bad request",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/BadRequestError"
+ }
+ }
+ }
+ },
+ "404": {
+ "description": "Not found",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/NotFoundError"
+ }
+ }
+ }
+ }
+ },
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "todos": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Todo"
+ }
+ }
+ },
+ "required": ["todos"]
+ }
+ }
+ }
+ },
+ "x-codeSamples": [
+ {
+ "lang": "js",
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.todo.update({\n ...\n})"
}
]
}
@@ -1845,7 +1927,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.init({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.init({\n ...\n})"
}
]
}
@@ -1903,7 +1985,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.fork({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.fork({\n ...\n})"
}
]
}
@@ -1965,7 +2047,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.abort({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.abort({\n ...\n})"
}
]
}
@@ -2027,7 +2109,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.share({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.share({\n ...\n})"
}
]
},
@@ -2088,7 +2170,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.unshare({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.unshare({\n ...\n})"
}
]
}
@@ -2142,7 +2224,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.diff({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.diff({\n ...\n})"
}
]
}
@@ -2227,7 +2309,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.summarize({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.summarize({\n ...\n})"
}
]
}
@@ -2312,7 +2394,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.messages({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.messages({\n ...\n})"
}
]
},
@@ -2432,7 +2514,7 @@
"parts": {
"type": "array",
"items": {
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/TextPartInput"
},
@@ -2457,7 +2539,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.prompt({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.prompt({\n ...\n})"
}
]
}
@@ -2541,7 +2623,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.message({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.message({\n ...\n})"
}
]
}
@@ -2621,7 +2703,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.part.delete({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.part.delete({\n ...\n})"
}
]
},
@@ -2708,7 +2790,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.part.update({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.part.update({\n ...\n})"
}
]
}
@@ -2811,7 +2893,7 @@
"parts": {
"type": "array",
"items": {
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/TextPartInput"
},
@@ -2836,7 +2918,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.prompt_async({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.prompt_async({\n ...\n})"
}
]
}
@@ -2936,7 +3018,7 @@
"parts": {
"type": "array",
"items": {
- "anyOf": [
+ "oneOf": [
{
"type": "object",
"properties": {
@@ -2974,7 +3056,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.command({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.command({\n ...\n})"
}
]
}
@@ -3067,7 +3149,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.shell({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.shell({\n ...\n})"
}
]
}
@@ -3149,7 +3231,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.revert({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.revert({\n ...\n})"
}
]
}
@@ -3211,7 +3293,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.unrevert({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.session.unrevert({\n ...\n})"
}
]
}
@@ -3298,7 +3380,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.permission.respond({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.permission.respond({\n ...\n})"
}
]
}
@@ -3379,7 +3461,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.permission.reply({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.permission.reply({\n ...\n})"
}
]
}
@@ -3416,7 +3498,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.permission.list({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.permission.list({\n ...\n})"
}
]
}
@@ -3453,7 +3535,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.question.list({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.question.list({\n ...\n})"
}
]
}
@@ -3519,11 +3601,11 @@
"type": "object",
"properties": {
"answers": {
- "description": "User answers in order of questions (each answer is an array of selected labels)",
"type": "array",
"items": {
"$ref": "#/components/schemas/QuestionAnswer"
- }
+ },
+ "description": "User answers in order of questions (each answer is an array of selected labels)"
}
},
"required": ["answers"]
@@ -3534,7 +3616,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.question.reply({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.question.reply({\n ...\n})"
}
]
}
@@ -3596,7 +3678,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.question.reject({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.question.reject({\n ...\n})"
}
]
}
@@ -3858,7 +3940,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.provider.list({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.provider.list({\n ...\n})"
}
]
}
@@ -3901,7 +3983,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.provider.auth({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.provider.auth({\n ...\n})"
}
]
}
@@ -3958,8 +4040,8 @@
"type": "object",
"properties": {
"method": {
- "description": "Auth method index",
- "type": "number"
+ "type": "number",
+ "description": "Auth method index"
}
},
"required": ["method"]
@@ -3970,7 +4052,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.provider.oauth.authorize({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.provider.oauth.authorize({\n ...\n})"
}
]
}
@@ -4027,8 +4109,8 @@
"type": "object",
"properties": {
"method": {
- "description": "Auth method index",
- "type": "number"
+ "type": "number",
+ "description": "Auth method index"
},
"code": {
"description": "OAuth authorization code",
@@ -4043,7 +4125,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.provider.oauth.callback({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.provider.oauth.callback({\n ...\n})"
}
]
}
@@ -4139,7 +4221,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.find.text({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.find.text({\n ...\n})"
}
]
}
@@ -4209,7 +4291,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.find.files({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.find.files({\n ...\n})"
}
]
}
@@ -4254,7 +4336,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.find.symbols({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.find.symbols({\n ...\n})"
}
]
}
@@ -4299,7 +4381,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.file.list({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.file.list({\n ...\n})"
}
]
}
@@ -4341,7 +4423,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.file.read({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.file.read({\n ...\n})"
}
]
}
@@ -4378,7 +4460,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.file.status({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.file.status({\n ...\n})"
}
]
}
@@ -4418,7 +4500,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.status({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.status({\n ...\n})"
}
]
},
@@ -4473,7 +4555,7 @@
"type": "string"
},
"config": {
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/McpLocalConfig"
},
@@ -4491,7 +4573,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.add({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.add({\n ...\n})"
}
]
}
@@ -4527,8 +4609,8 @@
"type": "object",
"properties": {
"authorizationUrl": {
- "description": "URL to open in browser for authorization",
- "type": "string"
+ "type": "string",
+ "description": "URL to open in browser for authorization"
}
},
"required": ["authorizationUrl"]
@@ -4560,7 +4642,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.auth.start({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.auth.start({\n ...\n})"
}
]
},
@@ -4617,7 +4699,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.auth.remove({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.auth.remove({\n ...\n})"
}
]
}
@@ -4683,8 +4765,8 @@
"type": "object",
"properties": {
"code": {
- "description": "Authorization code from OAuth callback",
- "type": "string"
+ "type": "string",
+ "description": "Authorization code from OAuth callback"
}
},
"required": ["code"]
@@ -4695,7 +4777,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.auth.callback({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.auth.callback({\n ...\n})"
}
]
}
@@ -4757,7 +4839,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.auth.authenticate({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.auth.authenticate({\n ...\n})"
}
]
}
@@ -4798,7 +4880,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.connect({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.connect({\n ...\n})"
}
]
}
@@ -4839,7 +4921,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.disconnect({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.mcp.disconnect({\n ...\n})"
}
]
}
@@ -4898,7 +4980,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.appendPrompt({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.appendPrompt({\n ...\n})"
}
]
}
@@ -4932,7 +5014,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.openHelp({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.openHelp({\n ...\n})"
}
]
}
@@ -4966,7 +5048,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.openSessions({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.openSessions({\n ...\n})"
}
]
}
@@ -5000,7 +5082,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.openThemes({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.openThemes({\n ...\n})"
}
]
}
@@ -5034,7 +5116,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.openModels({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.openModels({\n ...\n})"
}
]
}
@@ -5068,7 +5150,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.submitPrompt({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.submitPrompt({\n ...\n})"
}
]
}
@@ -5102,7 +5184,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.clearPrompt({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.clearPrompt({\n ...\n})"
}
]
}
@@ -5161,7 +5243,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.executeCommand({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.executeCommand({\n ...\n})"
}
]
}
@@ -5222,7 +5304,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.showToast({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.showToast({\n ...\n})"
}
]
}
@@ -5288,7 +5370,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.publish({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.publish({\n ...\n})"
}
]
}
@@ -5346,9 +5428,9 @@
"type": "object",
"properties": {
"sessionID": {
- "description": "Session ID to navigate to",
"type": "string",
- "pattern": "^ses"
+ "pattern": "^ses",
+ "description": "Session ID to navigate to"
}
},
"required": ["sessionID"]
@@ -5359,7 +5441,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.selectSession({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.selectSession({\n ...\n})"
}
]
}
@@ -5400,7 +5482,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.control.next({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.control.next({\n ...\n})"
}
]
}
@@ -5441,7 +5523,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.control.response({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.tui.control.response({\n ...\n})"
}
]
}
@@ -5475,7 +5557,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.instance.dispose({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.instance.dispose({\n ...\n})"
}
]
}
@@ -5509,7 +5591,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.path.get({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.path.get({\n ...\n})"
}
]
}
@@ -5543,7 +5625,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.vcs.get({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.vcs.get({\n ...\n})"
}
]
}
@@ -5580,7 +5662,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.command.list({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.command.list({\n ...\n})"
}
]
}
@@ -5628,17 +5710,17 @@
"type": "object",
"properties": {
"service": {
- "description": "Service name for the log entry",
- "type": "string"
+ "type": "string",
+ "description": "Service name for the log entry"
},
"level": {
- "description": "Log level",
"type": "string",
- "enum": ["debug", "info", "error", "warn"]
+ "enum": ["debug", "info", "error", "warn"],
+ "description": "Log level"
},
"message": {
- "description": "Log message",
- "type": "string"
+ "type": "string",
+ "description": "Log message"
},
"extra": {
"description": "Additional metadata for the log entry",
@@ -5657,7 +5739,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.app.log({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.app.log({\n ...\n})"
}
]
}
@@ -5694,7 +5776,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.app.agents({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.app.agents({\n ...\n})"
}
]
}
@@ -5746,7 +5828,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.app.skills({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.app.skills({\n ...\n})"
}
]
}
@@ -5783,7 +5865,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.lsp.status({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.lsp.status({\n ...\n})"
}
]
}
@@ -5820,7 +5902,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.formatter.status({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.formatter.status({\n ...\n})"
}
]
}
@@ -5854,7 +5936,7 @@
"x-codeSamples": [
{
"lang": "js",
- "source": "import { createOpencodeClient } from \"@opencode-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.event.subscribe({\n ...\n})"
+ "source": "import { createOpencodeClient } from \"@opencoder-ai/sdk\n\nconst client = createOpencodeClient()\nawait client.event.subscribe({\n ...\n})"
}
]
}
@@ -6415,7 +6497,7 @@
"required": ["created"]
},
"error": {
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/ProviderAuthError"
},
@@ -6526,7 +6608,7 @@
]
},
"Message": {
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/UserMessage"
},
@@ -6819,7 +6901,7 @@
"required": ["text", "type", "clientName", "uri"]
},
"FilePartSource": {
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/FileSource"
},
@@ -7009,7 +7091,7 @@
"required": ["status", "input", "error", "time"]
},
"ToolState": {
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/ToolStatePending"
},
@@ -7287,7 +7369,7 @@
"required": ["id", "sessionID", "messageID", "type", "auto"]
},
"Part": {
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/TextPart"
},
@@ -7548,12 +7630,12 @@
"type": "object",
"properties": {
"label": {
- "description": "Display text (1-5 words, concise)",
- "type": "string"
+ "type": "string",
+ "description": "Display text (1-5 words, concise)"
},
"description": {
- "description": "Explanation of choice",
- "type": "string"
+ "type": "string",
+ "description": "Explanation of choice"
}
},
"required": ["label", "description"]
@@ -7562,19 +7644,19 @@
"type": "object",
"properties": {
"question": {
- "description": "Complete question",
- "type": "string"
+ "type": "string",
+ "description": "Complete question"
},
"header": {
- "description": "Very short label (max 30 chars)",
- "type": "string"
+ "type": "string",
+ "description": "Very short label (max 30 chars)"
},
"options": {
- "description": "Available choices",
"type": "array",
"items": {
"$ref": "#/components/schemas/QuestionOption"
- }
+ },
+ "description": "Available choices"
},
"multiple": {
"description": "Allow selecting multiple choices",
@@ -7599,11 +7681,11 @@
"pattern": "^ses.*"
},
"questions": {
- "description": "Questions to ask",
"type": "array",
"items": {
"$ref": "#/components/schemas/QuestionInfo"
- }
+ },
+ "description": "Questions to ask"
},
"tool": {
"type": "object",
@@ -7747,20 +7829,20 @@
"type": "object",
"properties": {
"content": {
- "description": "Brief description of the task",
- "type": "string"
+ "type": "string",
+ "description": "Brief description of the task"
},
"status": {
- "description": "Current status of the task: pending, in_progress, completed, cancelled",
- "type": "string"
+ "type": "string",
+ "description": "Current status of the task: pending, in_progress, completed, cancelled"
},
"priority": {
- "description": "Priority level of the task: high, medium, low",
- "type": "string"
+ "type": "string",
+ "description": "Priority level of the task: high, medium, low"
},
"id": {
- "description": "Unique identifier for the todo item",
- "type": "string"
+ "type": "string",
+ "description": "Unique identifier for the todo item"
}
},
"required": ["content", "status", "priority", "id"]
@@ -7895,9 +7977,9 @@
"type": "object",
"properties": {
"sessionID": {
- "description": "Session ID to navigate to",
"type": "string",
- "pattern": "^ses"
+ "pattern": "^ses",
+ "description": "Session ID to navigate to"
}
},
"required": ["sessionID"]
@@ -8195,7 +8277,7 @@
"type": "string"
},
"error": {
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/ProviderAuthError"
},
@@ -8397,7 +8479,7 @@
"required": ["type", "properties"]
},
"Event": {
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/Event.installation.updated"
},
@@ -8543,473 +8625,473 @@
"type": "object",
"properties": {
"leader": {
- "description": "Leader key for keybind combinations",
"default": "ctrl+x",
+ "description": "Leader key for keybind combinations",
"type": "string"
},
"app_exit": {
- "description": "Exit the application",
"default": "ctrl+c,ctrl+d,q",
+ "description": "Exit the application",
"type": "string"
},
"editor_open": {
- "description": "Open external editor",
"default": "e",
+ "description": "Open external editor",
"type": "string"
},
"theme_list": {
- "description": "List available themes",
"default": "t",
+ "description": "List available themes",
"type": "string"
},
"sidebar_toggle": {
- "description": "Toggle sidebar",
"default": "b",
+ "description": "Toggle sidebar",
"type": "string"
},
"scrollbar_toggle": {
- "description": "Toggle session scrollbar",
"default": "none",
+ "description": "Toggle session scrollbar",
"type": "string"
},
"username_toggle": {
- "description": "Toggle username visibility",
"default": "none",
+ "description": "Toggle username visibility",
"type": "string"
},
"status_view": {
- "description": "View status",
"default": "s",
+ "description": "View status",
"type": "string"
},
"session_export": {
- "description": "Export session to editor",
"default": "x",
+ "description": "Export session to editor",
"type": "string"
},
"session_new": {
- "description": "Create a new session",
"default": "n",
+ "description": "Create a new session",
"type": "string"
},
"session_list": {
- "description": "List all sessions",
"default": "l",
+ "description": "List all sessions",
"type": "string"
},
"session_timeline": {
- "description": "Show session timeline",
"default": "g",
+ "description": "Show session timeline",
"type": "string"
},
"session_fork": {
- "description": "Fork session from message",
"default": "none",
+ "description": "Fork session from message",
"type": "string"
},
"session_rename": {
- "description": "Rename session",
"default": "ctrl+r",
+ "description": "Rename session",
"type": "string"
},
"session_delete": {
- "description": "Delete session",
"default": "ctrl+d",
+ "description": "Delete session",
"type": "string"
},
"stash_delete": {
- "description": "Delete stash entry",
"default": "ctrl+d",
+ "description": "Delete stash entry",
"type": "string"
},
"model_provider_list": {
- "description": "Open provider list from model dialog",
"default": "ctrl+a",
+ "description": "Open provider list from model dialog",
"type": "string"
},
"model_favorite_toggle": {
- "description": "Toggle model favorite status",
"default": "ctrl+f",
+ "description": "Toggle model favorite status",
"type": "string"
},
"session_share": {
- "description": "Share current session",
"default": "none",
+ "description": "Share current session",
"type": "string"
},
"session_unshare": {
- "description": "Unshare current session",
"default": "none",
+ "description": "Unshare current session",
"type": "string"
},
"session_interrupt": {
- "description": "Interrupt current session",
"default": "escape",
+ "description": "Interrupt current session",
"type": "string"
},
"session_compact": {
- "description": "Compact the session",
"default": "c",
+ "description": "Compact the session",
"type": "string"
},
"messages_page_up": {
- "description": "Scroll messages up by one page",
"default": "pageup,ctrl+alt+b",
+ "description": "Scroll messages up by one page",
"type": "string"
},
"messages_page_down": {
- "description": "Scroll messages down by one page",
"default": "pagedown,ctrl+alt+f",
+ "description": "Scroll messages down by one page",
"type": "string"
},
"messages_line_up": {
- "description": "Scroll messages up by one line",
"default": "ctrl+alt+y",
+ "description": "Scroll messages up by one line",
"type": "string"
},
"messages_line_down": {
- "description": "Scroll messages down by one line",
"default": "ctrl+alt+e",
+ "description": "Scroll messages down by one line",
"type": "string"
},
"messages_half_page_up": {
- "description": "Scroll messages up by half page",
"default": "ctrl+alt+u",
+ "description": "Scroll messages up by half page",
"type": "string"
},
"messages_half_page_down": {
- "description": "Scroll messages down by half page",
"default": "ctrl+alt+d",
+ "description": "Scroll messages down by half page",
"type": "string"
},
"messages_first": {
- "description": "Navigate to first message",
"default": "ctrl+g,home",
+ "description": "Navigate to first message",
"type": "string"
},
"messages_last": {
- "description": "Navigate to last message",
"default": "ctrl+alt+g,end",
+ "description": "Navigate to last message",
"type": "string"
},
"messages_next": {
- "description": "Navigate to next message",
"default": "none",
+ "description": "Navigate to next message",
"type": "string"
},
"messages_previous": {
- "description": "Navigate to previous message",
"default": "none",
+ "description": "Navigate to previous message",
"type": "string"
},
"messages_last_user": {
- "description": "Navigate to last user message",
"default": "none",
+ "description": "Navigate to last user message",
"type": "string"
},
"messages_copy": {
- "description": "Copy message",
"default": "y",
+ "description": "Copy message",
"type": "string"
},
"messages_undo": {
- "description": "Undo message",
"default": "u",
+ "description": "Undo message",
"type": "string"
},
"messages_redo": {
- "description": "Redo message",
"default": "r",
+ "description": "Redo message",
"type": "string"
},
"messages_toggle_conceal": {
- "description": "Toggle code block concealment in messages",
"default": "h",
+ "description": "Toggle code block concealment in messages",
"type": "string"
},
"tool_details": {
- "description": "Toggle tool details visibility",
"default": "none",
+ "description": "Toggle tool details visibility",
"type": "string"
},
"model_list": {
- "description": "List available models",
"default": "m",
+ "description": "List available models",
"type": "string"
},
"model_cycle_recent": {
- "description": "Next recently used model",
"default": "f2",
+ "description": "Next recently used model",
"type": "string"
},
"model_cycle_recent_reverse": {
- "description": "Previous recently used model",
"default": "shift+f2",
+ "description": "Previous recently used model",
"type": "string"
},
"model_cycle_favorite": {
- "description": "Next favorite model",
"default": "none",
+ "description": "Next favorite model",
"type": "string"
},
"model_cycle_favorite_reverse": {
- "description": "Previous favorite model",
"default": "none",
+ "description": "Previous favorite model",
"type": "string"
},
"command_list": {
- "description": "List available commands",
"default": "ctrl+p",
+ "description": "List available commands",
"type": "string"
},
"agent_list": {
- "description": "List agents",
"default": "a",
+ "description": "List agents",
"type": "string"
},
"agent_cycle": {
- "description": "Next agent",
"default": "tab",
+ "description": "Next agent",
"type": "string"
},
"agent_cycle_reverse": {
- "description": "Previous agent",
"default": "shift+tab",
+ "description": "Previous agent",
"type": "string"
},
"variant_cycle": {
- "description": "Cycle model variants",
"default": "ctrl+t",
+ "description": "Cycle model variants",
"type": "string"
},
"input_clear": {
- "description": "Clear input field",
"default": "ctrl+c",
+ "description": "Clear input field",
"type": "string"
},
"input_paste": {
- "description": "Paste from clipboard",
"default": "ctrl+v",
+ "description": "Paste from clipboard",
"type": "string"
},
"input_submit": {
- "description": "Submit input",
"default": "return",
+ "description": "Submit input",
"type": "string"
},
"input_newline": {
- "description": "Insert newline in input",
"default": "shift+return,ctrl+return,alt+return,ctrl+j",
+ "description": "Insert newline in input",
"type": "string"
},
"input_move_left": {
- "description": "Move cursor left in input",
"default": "left,ctrl+b",
+ "description": "Move cursor left in input",
"type": "string"
},
"input_move_right": {
- "description": "Move cursor right in input",
"default": "right,ctrl+f",
+ "description": "Move cursor right in input",
"type": "string"
},
"input_move_up": {
- "description": "Move cursor up in input",
"default": "up",
+ "description": "Move cursor up in input",
"type": "string"
},
"input_move_down": {
- "description": "Move cursor down in input",
"default": "down",
+ "description": "Move cursor down in input",
"type": "string"
},
"input_select_left": {
- "description": "Select left in input",
"default": "shift+left",
+ "description": "Select left in input",
"type": "string"
},
"input_select_right": {
- "description": "Select right in input",
"default": "shift+right",
+ "description": "Select right in input",
"type": "string"
},
"input_select_up": {
- "description": "Select up in input",
"default": "shift+up",
+ "description": "Select up in input",
"type": "string"
},
"input_select_down": {
- "description": "Select down in input",
"default": "shift+down",
+ "description": "Select down in input",
"type": "string"
},
"input_line_home": {
- "description": "Move to start of line in input",
"default": "ctrl+a",
+ "description": "Move to start of line in input",
"type": "string"
},
"input_line_end": {
- "description": "Move to end of line in input",
"default": "ctrl+e",
+ "description": "Move to end of line in input",
"type": "string"
},
"input_select_line_home": {
- "description": "Select to start of line in input",
"default": "ctrl+shift+a",
+ "description": "Select to start of line in input",
"type": "string"
},
"input_select_line_end": {
- "description": "Select to end of line in input",
"default": "ctrl+shift+e",
+ "description": "Select to end of line in input",
"type": "string"
},
"input_visual_line_home": {
- "description": "Move to start of visual line in input",
"default": "alt+a",
+ "description": "Move to start of visual line in input",
"type": "string"
},
"input_visual_line_end": {
- "description": "Move to end of visual line in input",
"default": "alt+e",
+ "description": "Move to end of visual line in input",
"type": "string"
},
"input_select_visual_line_home": {
- "description": "Select to start of visual line in input",
"default": "alt+shift+a",
+ "description": "Select to start of visual line in input",
"type": "string"
},
"input_select_visual_line_end": {
- "description": "Select to end of visual line in input",
"default": "alt+shift+e",
+ "description": "Select to end of visual line in input",
"type": "string"
},
"input_buffer_home": {
- "description": "Move to start of buffer in input",
"default": "home",
+ "description": "Move to start of buffer in input",
"type": "string"
},
"input_buffer_end": {
- "description": "Move to end of buffer in input",
"default": "end",
+ "description": "Move to end of buffer in input",
"type": "string"
},
"input_select_buffer_home": {
- "description": "Select to start of buffer in input",
"default": "shift+home",
+ "description": "Select to start of buffer in input",
"type": "string"
},
"input_select_buffer_end": {
- "description": "Select to end of buffer in input",
"default": "shift+end",
+ "description": "Select to end of buffer in input",
"type": "string"
},
"input_delete_line": {
- "description": "Delete line in input",
"default": "ctrl+shift+d",
+ "description": "Delete line in input",
"type": "string"
},
"input_delete_to_line_end": {
- "description": "Delete to end of line in input",
"default": "ctrl+k",
+ "description": "Delete to end of line in input",
"type": "string"
},
"input_delete_to_line_start": {
- "description": "Delete to start of line in input",
"default": "ctrl+u",
+ "description": "Delete to start of line in input",
"type": "string"
},
"input_backspace": {
- "description": "Backspace in input",
"default": "backspace,shift+backspace",
+ "description": "Backspace in input",
"type": "string"
},
"input_delete": {
- "description": "Delete character in input",
"default": "ctrl+d,delete,shift+delete",
+ "description": "Delete character in input",
"type": "string"
},
"input_undo": {
- "description": "Undo in input",
"default": "ctrl+-,super+z",
+ "description": "Undo in input",
"type": "string"
},
"input_redo": {
- "description": "Redo in input",
"default": "ctrl+.,super+shift+z",
+ "description": "Redo in input",
"type": "string"
},
"input_word_forward": {
- "description": "Move word forward in input",
"default": "alt+f,alt+right,ctrl+right",
+ "description": "Move word forward in input",
"type": "string"
},
"input_word_backward": {
- "description": "Move word backward in input",
"default": "alt+b,alt+left,ctrl+left",
+ "description": "Move word backward in input",
"type": "string"
},
"input_select_word_forward": {
- "description": "Select word forward in input",
"default": "alt+shift+f,alt+shift+right",
+ "description": "Select word forward in input",
"type": "string"
},
"input_select_word_backward": {
- "description": "Select word backward in input",
"default": "alt+shift+b,alt+shift+left",
+ "description": "Select word backward in input",
"type": "string"
},
"input_delete_word_forward": {
- "description": "Delete word forward in input",
"default": "alt+d,alt+delete,ctrl+delete",
+ "description": "Delete word forward in input",
"type": "string"
},
"input_delete_word_backward": {
- "description": "Delete word backward in input",
"default": "ctrl+w,ctrl+backspace,alt+backspace",
+ "description": "Delete word backward in input",
"type": "string"
},
"history_previous": {
- "description": "Previous history item",
"default": "up",
+ "description": "Previous history item",
"type": "string"
},
"history_next": {
- "description": "Next history item",
"default": "down",
+ "description": "Next history item",
"type": "string"
},
"session_child_cycle": {
- "description": "Next child session",
"default": "right",
+ "description": "Next child session",
"type": "string"
},
"session_child_cycle_reverse": {
- "description": "Previous child session",
"default": "left",
+ "description": "Previous child session",
"type": "string"
},
"session_parent": {
- "description": "Go to parent session",
"default": "up",
+ "description": "Go to parent session",
"type": "string"
},
"terminal_suspend": {
- "description": "Suspend terminal",
"default": "ctrl+z",
+ "description": "Suspend terminal",
"type": "string"
},
"terminal_title_toggle": {
- "description": "Toggle terminal title",
"default": "none",
+ "description": "Toggle terminal title",
"type": "string"
},
"tips_toggle": {
- "description": "Toggle tips on home screen",
"default": "h",
+ "description": "Toggle tips on home screen",
"type": "string"
},
"display_thinking": {
- "description": "Toggle thinking blocks visibility",
"default": "none",
+ "description": "Toggle thinking blocks visibility",
"type": "string"
}
},
@@ -9225,6 +9307,18 @@
},
"permission": {
"$ref": "#/components/schemas/PermissionConfig"
+ },
+ "reminder": {
+ "description": "Custom reminder text injected into user messages for this agent. Set to false to disable the default reminder.",
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "boolean",
+ "const": false
+ }
+ ]
}
},
"additionalProperties": {}
@@ -9459,15 +9553,15 @@
"description": "Timeout in milliseconds for requests to this provider. Default is 300000 (5 minutes). Set to false to disable timeout.",
"anyOf": [
{
- "description": "Timeout in milliseconds for requests to this provider. Default is 300000 (5 minutes). Set to false to disable timeout.",
"type": "integer",
"exclusiveMinimum": 0,
- "maximum": 9007199254740991
+ "maximum": 9007199254740991,
+ "description": "Timeout in milliseconds for requests to this provider. Default is 300000 (5 minutes). Set to false to disable timeout."
},
{
- "description": "Disable timeout for this provider entirely.",
"type": "boolean",
- "const": false
+ "const": false,
+ "description": "Disable timeout for this provider entirely."
}
]
}
@@ -9481,16 +9575,16 @@
"type": "object",
"properties": {
"type": {
- "description": "Type of MCP server connection",
"type": "string",
- "const": "local"
+ "const": "local",
+ "description": "Type of MCP server connection"
},
"command": {
- "description": "Command and arguments to run the MCP server",
"type": "array",
"items": {
"type": "string"
- }
+ },
+ "description": "Command and arguments to run the MCP server"
},
"environment": {
"description": "Environment variables to set when running the MCP server",
@@ -9538,13 +9632,13 @@
"type": "object",
"properties": {
"type": {
- "description": "Type of MCP server connection",
"type": "string",
- "const": "remote"
+ "const": "remote",
+ "description": "Type of MCP server connection"
},
"url": {
- "description": "URL of the remote MCP server",
- "type": "string"
+ "type": "string",
+ "description": "URL of the remote MCP server"
},
"enabled": {
"description": "Enable or disable the MCP server on startup",
@@ -9618,8 +9712,8 @@
"type": "object",
"properties": {
"enabled": {
- "description": "Enable scroll acceleration",
- "type": "boolean"
+ "type": "boolean",
+ "description": "Enable scroll acceleration"
}
},
"required": ["enabled"]
@@ -9738,12 +9832,12 @@
}
},
"model": {
- "description": "Model to use in the format of provider/model, eg anthropic/claude-2",
- "type": "string"
+ "type": "string",
+ "description": "Model to use in the format of provider/model, eg anthropic/claude-2"
},
"small_model": {
- "description": "Small model to use for tasks like title generation in the format of provider/model",
- "type": "string"
+ "type": "string",
+ "description": "Small model to use for tasks like title generation in the format of provider/model"
},
"default_agent": {
"description": "Default agent to use when none is specified. Must be a primary agent. Falls back to 'build' if not set or if the specified agent is invalid.",
@@ -9817,7 +9911,7 @@
"additionalProperties": {
"anyOf": [
{
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/McpLocalConfig"
},
@@ -10109,7 +10203,7 @@
"required": ["type", "key", "token"]
},
"Auth": {
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/OAuth"
},
@@ -10873,7 +10967,7 @@
"required": ["status", "error"]
},
"MCPStatus": {
- "anyOf": [
+ "oneOf": [
{
"$ref": "#/components/schemas/MCPStatusConnected"
},
@@ -11022,6 +11116,17 @@
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
+ },
+ "reminder": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "boolean",
+ "const": false
+ }
+ ]
}
},
"required": ["name", "mode", "permission", "options"]
diff --git a/packages/slack/AGENTS.md b/packages/slack/AGENTS.md
new file mode 100644
index 000000000000..77e3c6dc971e
--- /dev/null
+++ b/packages/slack/AGENTS.md
@@ -0,0 +1,21 @@
+# Slack Integration
+
+**Package:** `packages/slack`
+**Type:** Slack integration
+
+## Overview
+
+Slack integration for OpenCode, enabling AI-assisted interactions within Slack.
+
+## Commands
+
+```bash
+# Build
+bun build
+```
+
+## Key Patterns
+
+- Slack API integration
+- Bot functionality
+- Event handling
diff --git a/packages/slack/README.md b/packages/slack/README.md
index a12978d8a6ea..9e7a26612ffe 100644
--- a/packages/slack/README.md
+++ b/packages/slack/README.md
@@ -1,4 +1,4 @@
-# @opencode-ai/slack
+# @opencoder-ai/slack
Slack bot integration for opencode that creates threaded conversations.
diff --git a/packages/slack/package.json b/packages/slack/package.json
index 78a5702228f6..40b09844811d 100644
--- a/packages/slack/package.json
+++ b/packages/slack/package.json
@@ -1,6 +1,6 @@
{
- "name": "@opencode-ai/slack",
- "version": "1.1.65",
+ "name": "@opencoder-ai/slack",
+ "version": "1.1.63",
"type": "module",
"license": "MIT",
"scripts": {
@@ -8,12 +8,12 @@
"typecheck": "tsgo --noEmit"
},
"dependencies": {
- "@opencode-ai/sdk": "workspace:*",
+ "@opencoder-ai/sdk": "workspace:*",
"@slack/bolt": "^3.17.1"
},
"devDependencies": {
"@types/node": "catalog:",
- "typescript": "catalog:",
- "@typescript/native-preview": "catalog:"
+ "@typescript/native-preview": "catalog:",
+ "typescript": "catalog:"
}
}
diff --git a/packages/slack/src/index.ts b/packages/slack/src/index.ts
index d07e3dfb4161..4f63ee2cc498 100644
--- a/packages/slack/src/index.ts
+++ b/packages/slack/src/index.ts
@@ -1,5 +1,5 @@
import { App } from "@slack/bolt"
-import { createOpencode, type ToolPart } from "@opencode-ai/sdk"
+import { createOpencode, type ToolPart } from "@opencoder-ai/sdk"
const app = new App({
token: process.env.SLACK_BOT_TOKEN,
diff --git a/packages/ui/AGENTS.md b/packages/ui/AGENTS.md
new file mode 100644
index 000000000000..2efde6e829b5
--- /dev/null
+++ b/packages/ui/AGENTS.md
@@ -0,0 +1,37 @@
+# Shared UI Components
+
+**Package:** `packages/ui`
+**Type:** Component library
+
+## Overview
+
+Shared UI components used across the application. Built with SolidJS, TailwindCSS styling.
+
+## Structure
+
+```
+packages/ui/src/
+├── components/ # UI components
+│ ├── file-icons/
+│ └── provider-icons/
+├── context/ # Context providers
+├── hooks/ # Shared hooks
+├── i18n/ # Internationalization
+├── styles/ # Styles including Tailwind
+├── theme/ # Theme definitions
+└── assets/ # Icons, images, fonts
+```
+
+## Key Patterns
+
+- Components use TailwindCSS via `@tailwindcss/vite`
+- Icons in `assets/icons/`
+- Themes in `theme/themes/`
+- I18n support via `i18n/` directory
+
+## Commands
+
+```bash
+# Build
+bun build
+```
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 5dbbb4605a37..a211702bc73a 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -1,6 +1,6 @@
{
- "name": "@opencode-ai/ui",
- "version": "1.1.65",
+ "name": "@opencoder-ai/ui",
+ "version": "1.1.63",
"type": "module",
"license": "MIT",
"exports": {
@@ -41,8 +41,8 @@
},
"dependencies": {
"@kobalte/core": "catalog:",
- "@opencode-ai/sdk": "workspace:*",
- "@opencode-ai/util": "workspace:*",
+ "@opencoder-ai/sdk": "workspace:*",
+ "@opencoder-ai/util": "workspace:*",
"@pierre/diffs": "catalog:",
"@shikijs/transformers": "3.9.2",
"@solid-primitives/bounds": "0.1.3",
@@ -50,7 +50,7 @@
"@solid-primitives/resize-observer": "2.1.3",
"@solidjs/meta": "catalog:",
"@typescript/native-preview": "catalog:",
- "dompurify": "3.3.1",
+ "dompurify": "catalog:",
"fuzzysort": "catalog:",
"katex": "0.16.27",
"luxon": "catalog:",
diff --git a/packages/ui/src/components/diff.tsx b/packages/ui/src/components/diff.tsx
index 0966db75e036..fd16b1d82adb 100644
--- a/packages/ui/src/components/diff.tsx
+++ b/packages/ui/src/components/diff.tsx
@@ -1,4 +1,4 @@
-import { checksum } from "@opencode-ai/util/encode"
+import { checksum } from "@opencoder-ai/util/encode"
import { FileDiff, type SelectedLineRange, VirtualizedFileDiff } from "@pierre/diffs"
import { createMediaQuery } from "@solid-primitives/media"
import { createEffect, createMemo, createSignal, onCleanup, splitProps } from "solid-js"
diff --git a/packages/ui/src/components/list.tsx b/packages/ui/src/components/list.tsx
index aa2347037ea4..0738f44be268 100644
--- a/packages/ui/src/components/list.tsx
+++ b/packages/ui/src/components/list.tsx
@@ -1,4 +1,4 @@
-import { type FilteredListProps, useFilteredList } from "@opencode-ai/ui/hooks"
+import { type FilteredListProps, useFilteredList } from "@opencoder-ai/ui/hooks"
import { createEffect, createSignal, For, onCleanup, type JSX, on, Show } from "solid-js"
import { createStore } from "solid-js/store"
import { useI18n } from "../context/i18n"
diff --git a/packages/ui/src/components/markdown.tsx b/packages/ui/src/components/markdown.tsx
index 608db818f549..cf895f7b1fa5 100644
--- a/packages/ui/src/components/markdown.tsx
+++ b/packages/ui/src/components/markdown.tsx
@@ -2,7 +2,7 @@ import { useMarked } from "../context/marked"
import { useI18n } from "../context/i18n"
import DOMPurify from "dompurify"
import morphdom from "morphdom"
-import { checksum } from "@opencode-ai/util/encode"
+import { checksum } from "@opencoder-ai/util/encode"
import { ComponentProps, createEffect, createResource, createSignal, onCleanup, splitProps } from "solid-js"
import { isServer } from "solid-js/web"
diff --git a/packages/ui/src/components/message-nav.tsx b/packages/ui/src/components/message-nav.tsx
index d151633faab7..a0d8a2f1ae7a 100644
--- a/packages/ui/src/components/message-nav.tsx
+++ b/packages/ui/src/components/message-nav.tsx
@@ -1,4 +1,4 @@
-import { UserMessage } from "@opencode-ai/sdk/v2"
+import { UserMessage } from "@opencoder-ai/sdk/v2"
import { ComponentProps, For, Match, Show, splitProps, Switch } from "solid-js"
import { DiffChanges } from "./diff-changes"
import { Tooltip } from "@kobalte/core/tooltip"
diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx
index 3f61b3186d30..ca248cbc9cb2 100644
--- a/packages/ui/src/components/message-part.tsx
+++ b/packages/ui/src/components/message-part.tsx
@@ -26,7 +26,7 @@ import {
QuestionRequest,
QuestionAnswer,
QuestionInfo,
-} from "@opencode-ai/sdk/v2"
+} from "@opencoder-ai/sdk/v2"
import { createStore } from "solid-js/store"
import { useData } from "../context"
import { useDiffComponent } from "../context/diff"
@@ -42,9 +42,9 @@ import { Checkbox } from "./checkbox"
import { DiffChanges } from "./diff-changes"
import { Markdown } from "./markdown"
import { ImagePreview } from "./image-preview"
-import { findLast } from "@opencode-ai/util/array"
-import { getDirectory as _getDirectory, getFilename } from "@opencode-ai/util/path"
-import { checksum } from "@opencode-ai/util/encode"
+import { findLast } from "@opencoder-ai/util/array"
+import { getDirectory as _getDirectory, getFilename } from "@opencoder-ai/util/path"
+import { checksum } from "@opencoder-ai/util/encode"
import { Tooltip } from "./tooltip"
import { IconButton } from "./icon-button"
import { createAutoScroll } from "../hooks"
diff --git a/packages/ui/src/components/session-review.tsx b/packages/ui/src/components/session-review.tsx
index fe2475548ea4..e2739f6f1ad3 100644
--- a/packages/ui/src/components/session-review.tsx
+++ b/packages/ui/src/components/session-review.tsx
@@ -8,11 +8,11 @@ import { LineComment, LineCommentEditor } from "./line-comment"
import { StickyAccordionHeader } from "./sticky-accordion-header"
import { useDiffComponent } from "../context/diff"
import { useI18n } from "../context/i18n"
-import { getDirectory, getFilename } from "@opencode-ai/util/path"
-import { checksum } from "@opencode-ai/util/encode"
+import { getDirectory, getFilename } from "@opencoder-ai/util/path"
+import { checksum } from "@opencoder-ai/util/encode"
import { createEffect, createMemo, createSignal, For, Match, Show, Switch, type JSX } from "solid-js"
import { createStore } from "solid-js/store"
-import { type FileContent, type FileDiff } from "@opencode-ai/sdk/v2"
+import { type FileContent, type FileDiff } from "@opencoder-ai/sdk/v2"
import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
import { type SelectedLineRange } from "@pierre/diffs"
import { Dynamic } from "solid-js/web"
diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx
index 9ffa671e6985..e1b54b0c8373 100644
--- a/packages/ui/src/components/session-turn.tsx
+++ b/packages/ui/src/components/session-turn.tsx
@@ -7,11 +7,11 @@ import {
type QuestionRequest,
TextPart,
ToolPart,
-} from "@opencode-ai/sdk/v2/client"
+} from "@opencoder-ai/sdk/v2/client"
import { useData } from "../context"
import { type UiI18nKey, type UiI18nParams, useI18n } from "../context/i18n"
-import { Binary } from "@opencode-ai/util/binary"
+import { Binary } from "@opencoder-ai/util/binary"
import { createEffect, createMemo, createSignal, For, Match, on, onCleanup, ParentProps, Show, Switch } from "solid-js"
import { Message, Part } from "./message-part"
import { Markdown } from "./markdown"
diff --git a/packages/ui/src/context/data.tsx b/packages/ui/src/context/data.tsx
index 51bffa0502ad..117ff4e53cfb 100644
--- a/packages/ui/src/context/data.tsx
+++ b/packages/ui/src/context/data.tsx
@@ -7,7 +7,7 @@ import type {
PermissionRequest,
QuestionRequest,
QuestionAnswer,
-} from "@opencode-ai/sdk/v2"
+} from "@opencoder-ai/sdk/v2"
import { createSimpleContext } from "./helper"
import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
diff --git a/packages/util/AGENTS.md b/packages/util/AGENTS.md
new file mode 100644
index 000000000000..5b91bb45593a
--- /dev/null
+++ b/packages/util/AGENTS.md
@@ -0,0 +1,21 @@
+# Shared Utilities
+
+**Package:** `packages/util`
+**Type:** Shared utility functions
+
+## Overview
+
+Common utility functions used across the monorepo.
+
+## Structure
+
+```
+packages/util/src/
+└── ... # Utility functions
+```
+
+## Key Patterns
+
+- Reusable helper functions
+- Common TypeScript utilities
+- Shared business logic
diff --git a/packages/util/package.json b/packages/util/package.json
index f37bb5c1d174..ef73a0f1e99b 100644
--- a/packages/util/package.json
+++ b/packages/util/package.json
@@ -1,20 +1,24 @@
{
- "name": "@opencode-ai/util",
- "version": "1.1.65",
+ "name": "@opencoder-ai/util",
+ "version": "1.1.63",
"private": true,
"type": "module",
"license": "MIT",
"exports": {
- "./*": "./src/*.ts"
+ "./*": {
+ "types": "./dist/*.d.ts",
+ "default": "./src/*.ts"
+ }
},
"scripts": {
- "typecheck": "tsc --noEmit"
+ "typecheck": "tsc --noEmit",
+ "build": "tsc"
},
"dependencies": {
"zod": "catalog:"
},
"devDependencies": {
- "typescript": "catalog:",
- "@types/bun": "catalog:"
+ "@types/bun": "catalog:",
+ "typescript": "catalog:"
}
}
diff --git a/packages/util/src/error.ts b/packages/util/src/error.ts
index 12c27a0a7799..9ef0dfbf168c 100644
--- a/packages/util/src/error.ts
+++ b/packages/util/src/error.ts
@@ -26,8 +26,8 @@ export abstract class NamedError extends Error {
this.name = name
}
- static isInstance(input: any): input is InstanceType {
- return typeof input === "object" && "name" in input && input.name === name
+ static isInstance(input: unknown): input is { name: Name; data: z.input } {
+ return typeof input === "object" && input !== null && "name" in input && input.name === name
}
schema() {
diff --git a/packages/util/tsconfig.json b/packages/util/tsconfig.json
index 528dcd91d998..2860d0b909d3 100644
--- a/packages/util/tsconfig.json
+++ b/packages/util/tsconfig.json
@@ -7,8 +7,15 @@
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"allowJs": true,
- "noEmit": true,
+ "noEmit": false,
+ "declaration": true,
+ "emitDeclarationOnly": true,
+ "declarationMap": true,
+ "outDir": "dist",
+ "rootDir": "src",
"strict": true,
"isolatedModules": true
- }
+ },
+ "include": ["src"],
+ "exclude": ["dist", "node_modules"]
}
diff --git a/packages/web/AGENTS.md b/packages/web/AGENTS.md
new file mode 100644
index 000000000000..3c9c1af66dcf
--- /dev/null
+++ b/packages/web/AGENTS.md
@@ -0,0 +1,31 @@
+# Web Marketing Site
+
+**Package:** `packages/web`
+**Type:** Marketing site (Astro)
+
+## Overview
+
+Landing page and marketing website built with Astro.
+
+## Structure
+
+```
+packages/web/src/
+└── assets/ # Static assets, images
+```
+
+## Commands
+
+```bash
+# Dev
+bun dev
+
+# Build
+bun build
+```
+
+## Key Patterns
+
+- Astro static site generator
+- TailwindCSS styling
+- Static asset management
diff --git a/packages/web/package.json b/packages/web/package.json
index 7c6698117a79..72bee27b5a2c 100644
--- a/packages/web/package.json
+++ b/packages/web/package.json
@@ -1,5 +1,5 @@
{
- "name": "@opencode-ai/web",
+ "name": "@opencoder-ai/web",
"type": "module",
"license": "MIT",
"version": "1.1.65",
@@ -17,7 +17,7 @@
"@astrojs/solid-js": "5.1.0",
"@astrojs/starlight": "0.34.3",
"@fontsource/ibm-plex-mono": "5.2.5",
- "@shikijs/transformers": "3.20.0",
+ "@shikijs/transformers": "3.9.2",
"@types/luxon": "catalog:",
"ai": "catalog:",
"astro": "5.7.13",
@@ -35,9 +35,9 @@
"vscode-languageserver-types": "3.17.5"
},
"devDependencies": {
- "opencode": "workspace:*",
- "@types/node": "catalog:",
"@astrojs/check": "0.9.6",
+ "@types/node": "catalog:",
+ "opencoder": "workspace:*",
"typescript": "catalog:"
}
}
diff --git a/packages/web/src/content/docs/custom-tools.mdx b/packages/web/src/content/docs/custom-tools.mdx
index 80a19236995b..4b523021dd5b 100644
--- a/packages/web/src/content/docs/custom-tools.mdx
+++ b/packages/web/src/content/docs/custom-tools.mdx
@@ -26,8 +26,8 @@ They can be defined:
The easiest way to create tools is using the `tool()` helper which provides type-safety and validation.
-```ts title=".opencode/tools/database.ts" {1}
-import { tool } from "@opencode-ai/plugin"
+```ts title=".opencode/tool/database.ts" {1}
+import { tool } from "@opencoder-ai/plugin"
export default tool({
description: "Query the project database",
@@ -49,8 +49,8 @@ The **filename** becomes the **tool name**. The above creates a `database` tool.
You can also export multiple tools from a single file. Each export becomes **a separate tool** with the name **`_`**:
-```ts title=".opencode/tools/math.ts"
-import { tool } from "@opencode-ai/plugin"
+```ts title=".opencode/tool/math.ts"
+import { tool } from "@opencoder-ai/plugin"
export const add = tool({
description: "Add two numbers",
@@ -112,8 +112,8 @@ export default {
Tools receive context about the current session:
-```ts title=".opencode/tools/project.ts" {8}
-import { tool } from "@opencode-ai/plugin"
+```ts title=".opencode/tool/project.ts" {8}
+import { tool } from "@opencoder-ai/plugin"
export default tool({
description: "Get project information",
@@ -149,8 +149,8 @@ print(a + b)
Then create the tool definition that invokes it:
-```ts title=".opencode/tools/python-add.ts" {10}
-import { tool } from "@opencode-ai/plugin"
+```ts title=".opencode/tool/python-add.ts" {10}
+import { tool } from "@opencoder-ai/plugin"
import path from "path"
export default tool({
diff --git a/packages/web/src/content/docs/ecosystem.mdx b/packages/web/src/content/docs/ecosystem.mdx
index 85839a2d82b8..f640b2fa6dc0 100644
--- a/packages/web/src/content/docs/ecosystem.mdx
+++ b/packages/web/src/content/docs/ecosystem.mdx
@@ -59,7 +59,7 @@ You can also check out [awesome-opencode](https://github.com/awesome-opencode/aw
| [portal](https://github.com/hosenur/portal) | Mobile-first web UI for OpenCode over Tailscale/VPN |
| [opencode plugin template](https://github.com/zenobi-us/opencode-plugin-template/) | Template for building OpenCode plugins |
| [opencode.nvim](https://github.com/sudo-tee/opencode.nvim) | Neovim frontend for opencode - a terminal-based AI coding agent |
-| [ai-sdk-provider-opencode-sdk](https://github.com/ben-vargas/ai-sdk-provider-opencode-sdk) | Vercel AI SDK provider for using OpenCode via @opencode-ai/sdk |
+| [ai-sdk-provider-opencode-sdk](https://github.com/ben-vargas/ai-sdk-provider-opencode-sdk) | Vercel AI SDK provider for using OpenCode via @opencoder-ai/sdk |
| [OpenChamber](https://github.com/btriapitsyn/openchamber) | Web / Desktop App and VS Code Extension for OpenCode |
| [OpenCode-Obsidian](https://github.com/mtymek/opencode-obsidian) | Obsidian plugin that embeds OpenCode in Obsidian's UI |
| [OpenWork](https://github.com/different-ai/openwork) | An open-source alternative to Claude Cowork, powered by OpenCode |
diff --git a/packages/web/src/content/docs/plugins.mdx b/packages/web/src/content/docs/plugins.mdx
index 411b827d22c2..4884bce902ef 100644
--- a/packages/web/src/content/docs/plugins.mdx
+++ b/packages/web/src/content/docs/plugins.mdx
@@ -128,7 +128,7 @@ The plugin function receives:
For TypeScript plugins, you can import types from the plugin package:
```ts title="my-plugin.ts" {1}
-import type { Plugin } from "@opencode-ai/plugin"
+import type { Plugin } from "@opencoder-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
@@ -279,8 +279,8 @@ export const InjectEnvPlugin = async () => {
Plugins can also add custom tools to opencode:
-```ts title=".opencode/plugins/custom-tools.ts"
-import { type Plugin, tool } from "@opencode-ai/plugin"
+```ts title=".opencode/plugin/custom-tools.ts"
+import { type Plugin, tool } from "@opencoder-ai/plugin"
export const CustomToolsPlugin: Plugin = async (ctx) => {
return {
@@ -335,8 +335,8 @@ Levels: `debug`, `info`, `warn`, `error`. See [SDK documentation](https://openco
Customize the context included when a session is compacted:
-```ts title=".opencode/plugins/compaction.ts"
-import type { Plugin } from "@opencode-ai/plugin"
+```ts title=".opencode/plugin/compaction.ts"
+import type { Plugin } from "@opencoder-ai/plugin"
export const CompactionPlugin: Plugin = async (ctx) => {
return {
@@ -359,8 +359,8 @@ The `experimental.session.compacting` hook fires before the LLM generates a cont
You can also replace the compaction prompt entirely by setting `output.prompt`:
-```ts title=".opencode/plugins/custom-compaction.ts"
-import type { Plugin } from "@opencode-ai/plugin"
+```ts title=".opencode/plugin/custom-compaction.ts"
+import type { Plugin } from "@opencoder-ai/plugin"
export const CustomCompactionPlugin: Plugin = async (ctx) => {
return {
diff --git a/packages/web/src/content/docs/sdk.mdx b/packages/web/src/content/docs/sdk.mdx
index 24546213be51..4703ff43fc0a 100644
--- a/packages/web/src/content/docs/sdk.mdx
+++ b/packages/web/src/content/docs/sdk.mdx
@@ -18,7 +18,7 @@ Use it to build integrations and control opencode programmatically.
Install the SDK from npm:
```bash
-npm install @opencode-ai/sdk
+npm install @opencoder-ai/sdk
```
---
@@ -28,7 +28,7 @@ npm install @opencode-ai/sdk
Create an instance of opencode:
```javascript
-import { createOpencode } from "@opencode-ai/sdk"
+import { createOpencode } from "@opencoder-ai/sdk"
const { client } = await createOpencode()
```
@@ -52,7 +52,7 @@ This starts both a server and a client
You can pass a configuration object to customize behavior. The instance still picks up your `opencode.json`, but you can override or add configuration inline:
```javascript
-import { createOpencode } from "@opencode-ai/sdk"
+import { createOpencode } from "@opencoder-ai/sdk"
const opencode = await createOpencode({
hostname: "127.0.0.1",
@@ -72,7 +72,7 @@ opencode.server.close()
If you already have a running instance of opencode, you can create a client instance to connect to it:
```javascript
-import { createOpencodeClient } from "@opencode-ai/sdk"
+import { createOpencodeClient } from "@opencoder-ai/sdk"
const client = createOpencodeClient({
baseUrl: "http://localhost:4096",
@@ -96,7 +96,7 @@ const client = createOpencodeClient({
The SDK includes TypeScript definitions for all API types. Import them directly:
```typescript
-import type { Session, Message, Part } from "@opencode-ai/sdk"
+import type { Session, Message, Part } from "@opencoder-ai/sdk"
```
All types are generated from the server's OpenAPI specification and available in the types file.
diff --git a/script/changelog.ts b/script/changelog.ts
index 5fc30a228bfb..4f523d38faeb 100755
--- a/script/changelog.ts
+++ b/script/changelog.ts
@@ -1,9 +1,9 @@
#!/usr/bin/env bun
import { $ } from "bun"
-import { createOpencode } from "@opencode-ai/sdk/v2"
+import { createOpencode } from "@opencoder-ai/sdk"
import { parseArgs } from "util"
-import { Script } from "@opencode-ai/script"
+import { Script } from "@opencoder-ai/script"
type Release = {
tag_name: string
diff --git a/script/duplicate-pr.ts b/script/duplicate-pr.ts
index b77737c1d417..81371342d844 100755
--- a/script/duplicate-pr.ts
+++ b/script/duplicate-pr.ts
@@ -2,7 +2,7 @@
import path from "path"
import { pathToFileURL } from "bun"
-import { createOpencode } from "@opencode-ai/sdk"
+import { createOpencode } from "@opencoder-ai/sdk"
import { parseArgs } from "util"
async function main() {
diff --git a/script/publish.ts b/script/publish.ts
index 1294f8d793e1..2b064013fb26 100755
--- a/script/publish.ts
+++ b/script/publish.ts
@@ -1,7 +1,8 @@
#!/usr/bin/env bun
import { $ } from "bun"
-import { Script } from "@opencode-ai/script"
+import { Script } from "@opencoder-ai/script"
+import { buildNotes, getLatestRelease } from "./changelog"
const highlightsTemplate = `