mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-17 12:56:41 +02:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3c85719fea |
@@ -45,13 +45,13 @@ jobs:
|
||||
|
||||
- name: Check PR guidelines compliance
|
||||
env:
|
||||
OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }}
|
||||
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
OPENCODE_PERMISSION: '{ "bash": { "*": "deny", "gh*": "allow", "gh pr review*": "deny" } }'
|
||||
PR_TITLE: ${{ steps.pr-details.outputs.title }}
|
||||
run: |
|
||||
PR_BODY=$(jq -r .body pr_data.json)
|
||||
opencode run -m opencode/openai-gpt-5.5 --variant medium "A new pull request has been created: '${PR_TITLE}'
|
||||
opencode run -m anthropic/claude-opus-4-5 "A new pull request has been created: '${PR_TITLE}'
|
||||
|
||||
<pr-number>
|
||||
${{ steps.pr-number.outputs.number }}
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
"version": "1.14.25",
|
||||
"dependencies": {
|
||||
"@kobalte/core": "catalog:",
|
||||
"@opencode-ai/core": "workspace:*",
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
"@opencode-ai/shared": "workspace:*",
|
||||
"@opencode-ai/ui": "workspace:*",
|
||||
"@shikijs/transformers": "3.9.2",
|
||||
"@solid-primitives/active-element": "2.1.3",
|
||||
@@ -190,35 +190,6 @@
|
||||
"cloudflare": "5.2.0",
|
||||
},
|
||||
},
|
||||
"packages/core": {
|
||||
"name": "@opencode-ai/core",
|
||||
"version": "1.14.25",
|
||||
"bin": {
|
||||
"opencode": "./bin/opencode",
|
||||
},
|
||||
"dependencies": {
|
||||
"@effect/opentelemetry": "catalog:",
|
||||
"@effect/platform-node": "catalog:",
|
||||
"@npmcli/arborist": "catalog:",
|
||||
"@opentelemetry/api": "1.9.0",
|
||||
"@opentelemetry/context-async-hooks": "2.6.1",
|
||||
"@opentelemetry/exporter-trace-otlp-http": "0.214.0",
|
||||
"@opentelemetry/sdk-trace-base": "2.6.1",
|
||||
"effect": "catalog:",
|
||||
"glob": "13.0.5",
|
||||
"mime-types": "3.0.2",
|
||||
"minimatch": "10.2.5",
|
||||
"semver": "catalog:",
|
||||
"xdg-basedir": "5.1.0",
|
||||
"zod": "catalog:",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/bun": "catalog:",
|
||||
"@types/bun": "catalog:",
|
||||
"@types/npmcli__arborist": "6.3.3",
|
||||
"@types/semver": "catalog:",
|
||||
},
|
||||
},
|
||||
"packages/desktop": {
|
||||
"name": "@opencode-ai/desktop",
|
||||
"version": "1.14.25",
|
||||
@@ -300,7 +271,7 @@
|
||||
"name": "@opencode-ai/enterprise",
|
||||
"version": "1.14.25",
|
||||
"dependencies": {
|
||||
"@opencode-ai/core": "workspace:*",
|
||||
"@opencode-ai/shared": "workspace:*",
|
||||
"@opencode-ai/ui": "workspace:*",
|
||||
"@pierre/diffs": "catalog:",
|
||||
"@solidjs/meta": "catalog:",
|
||||
@@ -455,8 +426,8 @@
|
||||
"@babel/core": "7.28.4",
|
||||
"@effect/language-service": "0.84.2",
|
||||
"@octokit/webhooks-types": "7.6.1",
|
||||
"@opencode-ai/core": "workspace:*",
|
||||
"@opencode-ai/script": "workspace:*",
|
||||
"@opencode-ai/shared": "workspace:*",
|
||||
"@parcel/watcher-darwin-arm64": "2.5.1",
|
||||
"@parcel/watcher-darwin-x64": "2.5.1",
|
||||
"@parcel/watcher-linux-arm64-glibc": "2.5.1",
|
||||
@@ -537,6 +508,30 @@
|
||||
"typescript": "catalog:",
|
||||
},
|
||||
},
|
||||
"packages/shared": {
|
||||
"name": "@opencode-ai/shared",
|
||||
"version": "1.14.25",
|
||||
"bin": {
|
||||
"opencode": "./bin/opencode",
|
||||
},
|
||||
"dependencies": {
|
||||
"@effect/platform-node": "catalog:",
|
||||
"@npmcli/arborist": "catalog:",
|
||||
"effect": "catalog:",
|
||||
"glob": "13.0.5",
|
||||
"mime-types": "3.0.2",
|
||||
"minimatch": "10.2.5",
|
||||
"semver": "catalog:",
|
||||
"xdg-basedir": "5.1.0",
|
||||
"zod": "catalog:",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tsconfig/bun": "catalog:",
|
||||
"@types/bun": "catalog:",
|
||||
"@types/npmcli__arborist": "6.3.3",
|
||||
"@types/semver": "catalog:",
|
||||
},
|
||||
},
|
||||
"packages/slack": {
|
||||
"name": "@opencode-ai/slack",
|
||||
"version": "1.14.25",
|
||||
@@ -577,8 +572,8 @@
|
||||
"version": "1.14.25",
|
||||
"dependencies": {
|
||||
"@kobalte/core": "catalog:",
|
||||
"@opencode-ai/core": "workspace:*",
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
"@opencode-ai/shared": "workspace:*",
|
||||
"@pierre/diffs": "catalog:",
|
||||
"@shikijs/transformers": "3.9.2",
|
||||
"@solid-primitives/bounds": "0.1.3",
|
||||
@@ -668,7 +663,6 @@
|
||||
"solid-js@1.9.10": "patches/solid-js@1.9.10.patch",
|
||||
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch",
|
||||
"@npmcli/agent@4.0.0": "patches/@npmcli%2Fagent@4.0.0.patch",
|
||||
"@ai-sdk/anthropic@3.0.71": "patches/@ai-sdk%2Fanthropic@3.0.71.patch",
|
||||
},
|
||||
"overrides": {
|
||||
"@types/bun": "catalog:",
|
||||
@@ -1560,8 +1554,6 @@
|
||||
|
||||
"@opencode-ai/console-resource": ["@opencode-ai/console-resource@workspace:packages/console/resource"],
|
||||
|
||||
"@opencode-ai/core": ["@opencode-ai/core@workspace:packages/core"],
|
||||
|
||||
"@opencode-ai/desktop": ["@opencode-ai/desktop@workspace:packages/desktop"],
|
||||
|
||||
"@opencode-ai/desktop-electron": ["@opencode-ai/desktop-electron@workspace:packages/desktop-electron"],
|
||||
@@ -1576,6 +1568,8 @@
|
||||
|
||||
"@opencode-ai/sdk": ["@opencode-ai/sdk@workspace:packages/sdk/js"],
|
||||
|
||||
"@opencode-ai/shared": ["@opencode-ai/shared@workspace:packages/shared"],
|
||||
|
||||
"@opencode-ai/slack": ["@opencode-ai/slack@workspace:packages/slack"],
|
||||
|
||||
"@opencode-ai/storybook": ["@opencode-ai/storybook@workspace:packages/storybook"],
|
||||
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"nodeModules": {
|
||||
"x86_64-linux": "sha256-0w22pAViYEcELJpOrIVCjTQ73fnsSaJxb75heAIUdYE=",
|
||||
"aarch64-linux": "sha256-z1fpZ9HQU9n6W5xhKzuUduwQUJa/nrj9WFZdBLL/e/8=",
|
||||
"aarch64-darwin": "sha256-y5AraTdY2uDTltjQFlHjMoMo6FICgQNKSunIOnQAXnY=",
|
||||
"x86_64-darwin": "sha256-KQF6dJNQ587xp5h9ET+tLni9dLNwYnzxg2DX+KWfpoE="
|
||||
"x86_64-linux": "sha256-V1Rt2k7ujkqGw4pDkn++WALTy1fAugvoKLhKvwFKkss=",
|
||||
"aarch64-linux": "sha256-ho0AuGbJ1qw9Hvb3EbGC8f0lWqqgUslvda/wTe32MFo=",
|
||||
"aarch64-darwin": "sha256-hdUyNmp+snwtnBckHXsPMgNFUYS1sYDdngkk+AXVqzc=",
|
||||
"x86_64-darwin": "sha256-P57LpQNF8fplFKQBBIukhOKbIugbViyBUIUjClXohuk="
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,6 @@
|
||||
"@types/node": "catalog:"
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"@ai-sdk/anthropic@3.0.71": "patches/@ai-sdk%2Fanthropic@3.0.71.patch",
|
||||
"@npmcli/agent@4.0.0": "patches/@npmcli%2Fagent@4.0.0.patch",
|
||||
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch",
|
||||
"solid-js@1.9.10": "patches/solid-js@1.9.10.patch"
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"@kobalte/core": "catalog:",
|
||||
"@opencode-ai/sdk": "workspace:*",
|
||||
"@opencode-ai/ui": "workspace:*",
|
||||
"@opencode-ai/core": "workspace:*",
|
||||
"@opencode-ai/shared": "workspace:*",
|
||||
"@shikijs/transformers": "3.9.2",
|
||||
"@solid-primitives/active-element": "2.1.3",
|
||||
"@solid-primitives/audio": "1.4.2",
|
||||
|
||||
@@ -9,7 +9,7 @@ import { createStore } from "solid-js/store"
|
||||
import { useGlobalSDK } from "@/context/global-sdk"
|
||||
import { useGlobalSync } from "@/context/global-sync"
|
||||
import { type LocalProject, getAvatarColors } from "@/context/layout"
|
||||
import { getFilename } from "@opencode-ai/core/util/path"
|
||||
import { getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { Avatar } from "@opencode-ai/ui/avatar"
|
||||
import { useLanguage } from "@/context/language"
|
||||
import { getProjectAvatarSource } from "@/pages/layout/sidebar-items"
|
||||
|
||||
@@ -9,7 +9,7 @@ import { List } from "@opencode-ai/ui/list"
|
||||
import { showToast } from "@opencode-ai/ui/toast"
|
||||
import { extractPromptFromParts } from "@/utils/prompt"
|
||||
import type { TextPart as SDKTextPart } from "@opencode-ai/sdk/v2/client"
|
||||
import { base64Encode } from "@opencode-ai/core/util/encode"
|
||||
import { base64Encode } from "@opencode-ai/shared/util/encode"
|
||||
import { useLanguage } from "@/context/language"
|
||||
|
||||
interface ForkableMessage {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Dialog } from "@opencode-ai/ui/dialog"
|
||||
import { FileIcon } from "@opencode-ai/ui/file-icon"
|
||||
import { List } from "@opencode-ai/ui/list"
|
||||
import type { ListRef } from "@opencode-ai/ui/list"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/core/util/path"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/shared/util/path"
|
||||
import fuzzysort from "fuzzysort"
|
||||
import { createMemo, createResource, createSignal } from "solid-js"
|
||||
import { useGlobalSDK } from "@/context/global-sdk"
|
||||
|
||||
@@ -4,8 +4,8 @@ import { FileIcon } from "@opencode-ai/ui/file-icon"
|
||||
import { Icon } from "@opencode-ai/ui/icon"
|
||||
import { Keybind } from "@opencode-ai/ui/keybind"
|
||||
import { List } from "@opencode-ai/ui/list"
|
||||
import { base64Encode } from "@opencode-ai/core/util/encode"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/core/util/path"
|
||||
import { base64Encode } from "@opencode-ai/shared/util/encode"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { useNavigate } from "@solidjs/router"
|
||||
import { createMemo, createSignal, Match, onCleanup, Show, Switch } from "solid-js"
|
||||
import { formatKeybind, useCommand, type CommandOption } from "@/context/command"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getFilename } from "@opencode-ai/core/util/path"
|
||||
import { getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { type AgentPartInput, type FilePartInput, type Part, type TextPartInput } from "@opencode-ai/sdk/v2/client"
|
||||
import type { FileSelection } from "@/context/file"
|
||||
import { encodeFilePath } from "@/context/file/path"
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Component, For, Show } from "solid-js"
|
||||
import { FileIcon } from "@opencode-ai/ui/file-icon"
|
||||
import { IconButton } from "@opencode-ai/ui/icon-button"
|
||||
import { Tooltip } from "@opencode-ai/ui/tooltip"
|
||||
import { getDirectory, getFilename, getFilenameTruncated } from "@opencode-ai/core/util/path"
|
||||
import { getDirectory, getFilename, getFilenameTruncated } from "@opencode-ai/shared/util/path"
|
||||
import type { ContextItem } from "@/context/prompt"
|
||||
|
||||
type PromptContextItem = ContextItem & { key: string }
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Component, For, Match, Show, Switch } from "solid-js"
|
||||
import { FileIcon } from "@opencode-ai/ui/file-icon"
|
||||
import { Icon } from "@opencode-ai/ui/icon"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/core/util/path"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/shared/util/path"
|
||||
|
||||
export type AtOption =
|
||||
| { type: "agent"; name: string; display: string }
|
||||
|
||||
@@ -74,7 +74,7 @@ beforeAll(async () => {
|
||||
showToast: () => 0,
|
||||
}))
|
||||
|
||||
mock.module("@opencode-ai/core/util/encode", () => ({
|
||||
mock.module("@opencode-ai/shared/util/encode", () => ({
|
||||
base64Encode: (value: string) => value,
|
||||
}))
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Message, Session } from "@opencode-ai/sdk/v2/client"
|
||||
import { showToast } from "@opencode-ai/ui/toast"
|
||||
import { base64Encode } from "@opencode-ai/core/util/encode"
|
||||
import { Binary } from "@opencode-ai/core/util/binary"
|
||||
import { base64Encode } from "@opencode-ai/shared/util/encode"
|
||||
import { Binary } from "@opencode-ai/shared/util/binary"
|
||||
import { useNavigate, useParams } from "@solidjs/router"
|
||||
import { batch, type Accessor } from "solid-js"
|
||||
import type { FileSelection } from "@/context/file"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { createMemo, createEffect, on, onCleanup, For, Show } from "solid-js"
|
||||
import type { JSX } from "solid-js"
|
||||
import { useSync } from "@/context/sync"
|
||||
import { checksum } from "@opencode-ai/core/util/encode"
|
||||
import { findLast } from "@opencode-ai/core/util/array"
|
||||
import { checksum } from "@opencode-ai/shared/util/encode"
|
||||
import { findLast } from "@opencode-ai/shared/util/array"
|
||||
import { same } from "@/utils/same"
|
||||
import { Icon } from "@opencode-ai/ui/icon"
|
||||
import { Accordion } from "@opencode-ai/ui/accordion"
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Keybind } from "@opencode-ai/ui/keybind"
|
||||
import { Spinner } from "@opencode-ai/ui/spinner"
|
||||
import { showToast } from "@opencode-ai/ui/toast"
|
||||
import { Tooltip, TooltipKeybind } from "@opencode-ai/ui/tooltip"
|
||||
import { getFilename } from "@opencode-ai/core/util/path"
|
||||
import { getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { createEffect, createMemo, createSignal, For, onMount, Show } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { Portal } from "solid-js/web"
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useSDK } from "@/context/sdk"
|
||||
import { useLanguage } from "@/context/language"
|
||||
import { Icon } from "@opencode-ai/ui/icon"
|
||||
import { Mark } from "@opencode-ai/ui/logo"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/core/util/path"
|
||||
import { getDirectory, getFilename } from "@opencode-ai/shared/util/path"
|
||||
|
||||
const MAIN_WORKTREE = "main"
|
||||
const CREATE_WORKTREE = "create"
|
||||
|
||||
@@ -5,7 +5,7 @@ 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/core/util/path"
|
||||
import { getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { useFile } from "@/context/file"
|
||||
import { useLanguage } from "@/context/language"
|
||||
import { useCommand } from "@/context/command"
|
||||
|
||||
@@ -3,7 +3,7 @@ import { createStore, produce, reconcile } from "solid-js/store"
|
||||
import { createSimpleContext } from "@opencode-ai/ui/context"
|
||||
import { showToast } from "@opencode-ai/ui/toast"
|
||||
import { useParams } from "@solidjs/router"
|
||||
import { getFilename } from "@opencode-ai/core/util/path"
|
||||
import { getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { useSDK } from "./sdk"
|
||||
import { useSync } from "./sync"
|
||||
import { useLanguage } from "@/context/language"
|
||||
|
||||
@@ -8,7 +8,7 @@ import type {
|
||||
Todo,
|
||||
} from "@opencode-ai/sdk/v2/client"
|
||||
import { showToast } from "@opencode-ai/ui/toast"
|
||||
import { getFilename } from "@opencode-ai/core/util/path"
|
||||
import { getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { batch, createContext, getOwner, onCleanup, onMount, type ParentProps, untrack, useContext } from "solid-js"
|
||||
import { createStore, produce, reconcile } from "solid-js/store"
|
||||
import { useLanguage } from "@/context/language"
|
||||
|
||||
@@ -11,8 +11,8 @@ import type {
|
||||
Todo,
|
||||
} from "@opencode-ai/sdk/v2/client"
|
||||
import { showToast } from "@opencode-ai/ui/toast"
|
||||
import { getFilename } from "@opencode-ai/core/util/path"
|
||||
import { retry } from "@opencode-ai/core/util/retry"
|
||||
import { getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { retry } from "@opencode-ai/shared/util/retry"
|
||||
import { batch } from "solid-js"
|
||||
import { reconcile, type SetStoreFunction, type Store } from "solid-js/store"
|
||||
import type { State, VcsCache } from "./types"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Binary } from "@opencode-ai/core/util/binary"
|
||||
import { Binary } from "@opencode-ai/shared/util/binary"
|
||||
import { produce, reconcile, type SetStoreFunction, type Store } from "solid-js/store"
|
||||
import type {
|
||||
Message,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createSimpleContext } from "@opencode-ai/ui/context"
|
||||
import { base64Encode } from "@opencode-ai/core/util/encode"
|
||||
import { base64Encode } from "@opencode-ai/shared/util/encode"
|
||||
import { useParams } from "@solidjs/router"
|
||||
import { batch, createEffect, createMemo } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
|
||||
@@ -7,8 +7,8 @@ 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/core/util/binary"
|
||||
import { base64Encode } from "@opencode-ai/core/util/encode"
|
||||
import { Binary } from "@opencode-ai/shared/util/binary"
|
||||
import { base64Encode } from "@opencode-ai/shared/util/encode"
|
||||
import { decode64 } from "@/utils/base64"
|
||||
import { EventSessionError } from "@opencode-ai/sdk/v2"
|
||||
import { Persist, persisted } from "@/utils/persist"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import type { PermissionRequest, Session } from "@opencode-ai/sdk/v2/client"
|
||||
import { base64Encode } from "@opencode-ai/core/util/encode"
|
||||
import { base64Encode } from "@opencode-ai/shared/util/encode"
|
||||
import { autoRespondsPermission, isDirectoryAutoAccepting } from "./permission-auto-respond"
|
||||
|
||||
const session = (input: { id: string; parentID?: string }) =>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { base64Encode } from "@opencode-ai/core/util/encode"
|
||||
import { base64Encode } from "@opencode-ai/shared/util/encode"
|
||||
|
||||
export function acceptKey(sessionID: string, directory?: string) {
|
||||
if (!directory) return sessionID
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createSimpleContext } from "@opencode-ai/ui/context"
|
||||
import { checksum } from "@opencode-ai/core/util/encode"
|
||||
import { checksum } from "@opencode-ai/shared/util/encode"
|
||||
import { useParams } from "@solidjs/router"
|
||||
import { batch, createMemo, createRoot, getOwner, onCleanup } from "solid-js"
|
||||
import { createStore, type SetStoreFunction } from "solid-js/store"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { batch, createMemo } from "solid-js"
|
||||
import { createStore, produce, reconcile } from "solid-js/store"
|
||||
import { Binary } from "@opencode-ai/core/util/binary"
|
||||
import { retry } from "@opencode-ai/core/util/retry"
|
||||
import { Binary } from "@opencode-ai/shared/util/binary"
|
||||
import { retry } from "@opencode-ai/shared/util/retry"
|
||||
import { createSimpleContext } from "@opencode-ai/ui/context"
|
||||
import {
|
||||
clearSessionPrefetch,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { DataProvider } from "@opencode-ai/ui/context"
|
||||
import { showToast } from "@opencode-ai/ui/toast"
|
||||
import { base64Encode } from "@opencode-ai/core/util/encode"
|
||||
import { base64Encode } from "@opencode-ai/shared/util/encode"
|
||||
import { useLocation, useNavigate, useParams } from "@solidjs/router"
|
||||
import { createEffect, createMemo, createResource, type ParentProps, Show } from "solid-js"
|
||||
import { useLanguage } from "@/context/language"
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Button } from "@opencode-ai/ui/button"
|
||||
import { Logo } from "@opencode-ai/ui/logo"
|
||||
import { useLayout } from "@/context/layout"
|
||||
import { useNavigate } from "@solidjs/router"
|
||||
import { base64Encode } from "@opencode-ai/core/util/encode"
|
||||
import { base64Encode } from "@opencode-ai/shared/util/encode"
|
||||
import { Icon } from "@opencode-ai/ui/icon"
|
||||
import { usePlatform } from "@/context/platform"
|
||||
import { DateTime } from "luxon"
|
||||
|
||||
@@ -17,7 +17,7 @@ import { useLocation, 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/core/util/encode"
|
||||
import { base64Encode } from "@opencode-ai/shared/util/encode"
|
||||
import { decode64 } from "@/utils/base64"
|
||||
import { ResizeHandle } from "@opencode-ai/ui/resize-handle"
|
||||
import { Button } from "@opencode-ai/ui/button"
|
||||
@@ -25,7 +25,7 @@ import { IconButton } from "@opencode-ai/ui/icon-button"
|
||||
import { Tooltip } 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/core/util/path"
|
||||
import { getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { Session, type Message } from "@opencode-ai/sdk/v2/client"
|
||||
import { usePlatform } from "@/context/platform"
|
||||
import { useSettings } from "@/context/settings"
|
||||
@@ -48,8 +48,8 @@ import {
|
||||
} from "@/context/global-sync/session-prefetch"
|
||||
import { useNotification } from "@/context/notification"
|
||||
import { usePermission } from "@/context/permission"
|
||||
import { Binary } from "@opencode-ai/core/util/binary"
|
||||
import { retry } from "@opencode-ai/core/util/retry"
|
||||
import { Binary } from "@opencode-ai/shared/util/binary"
|
||||
import { retry } from "@opencode-ai/shared/util/retry"
|
||||
import { playSoundById } from "@/utils/sound"
|
||||
import { createAim } from "@/utils/aim"
|
||||
import { setNavigate } from "@/utils/notification-click"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getFilename } from "@opencode-ai/core/util/path"
|
||||
import { getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { type Session } from "@opencode-ai/sdk/v2/client"
|
||||
|
||||
type SessionStore = {
|
||||
|
||||
@@ -4,7 +4,7 @@ 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 { getFilename } from "@opencode-ai/core/util/path"
|
||||
import { getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { A, useParams } from "@solidjs/router"
|
||||
import { type Accessor, createMemo, For, type JSX, Match, Show, Switch } from "solid-js"
|
||||
import { useGlobalSync } from "@/context/global-sync"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createMemo, For, Show, type Accessor, type JSX } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { base64Encode } from "@opencode-ai/core/util/encode"
|
||||
import { base64Encode } from "@opencode-ai/shared/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"
|
||||
|
||||
@@ -3,8 +3,8 @@ 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/core/util/encode"
|
||||
import { getFilename } from "@opencode-ai/core/util/path"
|
||||
import { base64Encode } from "@opencode-ai/shared/util/encode"
|
||||
import { getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { Button } from "@opencode-ai/ui/button"
|
||||
import { Collapsible } from "@opencode-ai/ui/collapsible"
|
||||
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
|
||||
|
||||
@@ -28,7 +28,7 @@ import { createAutoScroll } from "@opencode-ai/ui/hooks"
|
||||
import { previewSelectedLines } from "@opencode-ai/ui/pierre/selection-bridge"
|
||||
import { Button } from "@opencode-ai/ui/button"
|
||||
import { showToast } from "@opencode-ai/ui/toast"
|
||||
import { checksum } from "@opencode-ai/core/util/encode"
|
||||
import { checksum } from "@opencode-ai/shared/util/encode"
|
||||
import { useSearchParams } from "@solidjs/router"
|
||||
import { NewSessionView, SessionHeader } from "@/components/session"
|
||||
import { useComments } from "@/context/comments"
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { FileSearchHandle } from "@opencode-ai/ui/file"
|
||||
import { useFileComponent } from "@opencode-ai/ui/context/file"
|
||||
import { cloneSelectedLineRange, previewSelectedLines } from "@opencode-ai/ui/pierre/selection-bridge"
|
||||
import { createLineCommentController } from "@opencode-ai/ui/line-comment-annotations"
|
||||
import { sampledChecksum } from "@opencode-ai/core/util/encode"
|
||||
import { sampledChecksum } from "@opencode-ai/shared/util/encode"
|
||||
import { DropdownMenu } from "@opencode-ai/ui/dropdown-menu"
|
||||
import { IconButton } from "@opencode-ai/ui/icon-button"
|
||||
import { Tabs } from "@opencode-ai/ui/tabs"
|
||||
|
||||
@@ -15,8 +15,8 @@ import { ScrollView } from "@opencode-ai/ui/scroll-view"
|
||||
import { TextField } from "@opencode-ai/ui/text-field"
|
||||
import type { AssistantMessage, Message as MessageType, Part, TextPart, UserMessage } from "@opencode-ai/sdk/v2"
|
||||
import { showToast } from "@opencode-ai/ui/toast"
|
||||
import { Binary } from "@opencode-ai/core/util/binary"
|
||||
import { getFilename } from "@opencode-ai/core/util/path"
|
||||
import { Binary } from "@opencode-ai/shared/util/binary"
|
||||
import { getFilename } from "@opencode-ai/shared/util/path"
|
||||
import { Popover as KobaltePopover } from "@kobalte/core/popover"
|
||||
import { shouldMarkBoundaryGesture, normalizeWheelDelta } from "@/pages/session/message-gesture"
|
||||
import { SessionContextUsage } from "@/components/session-context-usage"
|
||||
|
||||
@@ -14,7 +14,7 @@ import { useSettings } from "@/context/settings"
|
||||
import { useSync } from "@/context/sync"
|
||||
import { useTerminal } from "@/context/terminal"
|
||||
import { showToast } from "@opencode-ai/ui/toast"
|
||||
import { findLast } from "@opencode-ai/core/util/array"
|
||||
import { findLast } from "@opencode-ai/shared/util/array"
|
||||
import { createSessionTabs } from "@/pages/session/helpers"
|
||||
import { extractPromptFromParts } from "@/utils/prompt"
|
||||
import { UserMessage } from "@opencode-ai/sdk/v2"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { base64Decode } from "@opencode-ai/core/util/encode"
|
||||
import { base64Decode } from "@opencode-ai/shared/util/encode"
|
||||
|
||||
export function decode64(value: string | undefined) {
|
||||
if (value === undefined) return
|
||||
|
||||
@@ -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/core/util/encode"
|
||||
import { checksum } from "@opencode-ai/shared/util/encode"
|
||||
import { createResource, type Accessor } from "solid-js"
|
||||
import type { SetStoreFunction, Store } from "solid-js/store"
|
||||
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
import path from "path"
|
||||
import fs from "fs/promises"
|
||||
import { xdgData, xdgCache, xdgConfig, xdgState } from "xdg-basedir"
|
||||
import os from "os"
|
||||
import { Context, Effect, Layer } from "effect"
|
||||
import { Flock } from "./util/flock"
|
||||
|
||||
const app = "opencode"
|
||||
const data = path.join(xdgData!, app)
|
||||
const cache = path.join(xdgCache!, app)
|
||||
const config = path.join(xdgConfig!, app)
|
||||
const state = path.join(xdgState!, app)
|
||||
|
||||
const paths = {
|
||||
get home() {
|
||||
return process.env.OPENCODE_TEST_HOME ?? os.homedir()
|
||||
},
|
||||
data,
|
||||
bin: path.join(cache, "bin"),
|
||||
log: path.join(data, "log"),
|
||||
cache,
|
||||
config,
|
||||
state,
|
||||
}
|
||||
|
||||
export const Path = paths
|
||||
|
||||
Flock.setGlobal({ state })
|
||||
|
||||
await Promise.all([
|
||||
fs.mkdir(Path.data, { recursive: true }),
|
||||
fs.mkdir(Path.config, { recursive: true }),
|
||||
fs.mkdir(Path.state, { recursive: true }),
|
||||
fs.mkdir(Path.log, { recursive: true }),
|
||||
fs.mkdir(Path.bin, { recursive: true }),
|
||||
])
|
||||
|
||||
export class Service extends Context.Service<Service, Interface>()("@opencode/Global") {}
|
||||
|
||||
export interface Interface {
|
||||
readonly home: string
|
||||
readonly data: string
|
||||
readonly cache: string
|
||||
readonly config: string
|
||||
readonly state: string
|
||||
readonly bin: string
|
||||
readonly log: string
|
||||
}
|
||||
|
||||
export const layer = Layer.effect(
|
||||
Service,
|
||||
Effect.gen(function* () {
|
||||
return Service.of({
|
||||
home: Path.home,
|
||||
data: Path.data,
|
||||
cache: Path.cache,
|
||||
config: Path.config,
|
||||
state: Path.state,
|
||||
bin: Path.bin,
|
||||
log: Path.log,
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
export * as Global from "./global"
|
||||
@@ -13,7 +13,7 @@
|
||||
"shell-prod": "sst shell --target Teams --stage production"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opencode-ai/core": "workspace:*",
|
||||
"@opencode-ai/shared": "workspace:*",
|
||||
"@opencode-ai/ui": "workspace:*",
|
||||
"aws4fetch": "^1.0.20",
|
||||
"@pierre/diffs": "catalog:",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Message, Model, Part, Session, SnapshotFileDiff } from "@opencode-ai/sdk/v2"
|
||||
import { fn } from "@opencode-ai/core/util/fn"
|
||||
import { iife } from "@opencode-ai/core/util/iife"
|
||||
import { fn } from "@opencode-ai/shared/util/fn"
|
||||
import { iife } from "@opencode-ai/shared/util/iife"
|
||||
import z from "zod"
|
||||
import { Storage } from "./storage"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AwsClient } from "aws4fetch"
|
||||
import { lazy } from "@opencode-ai/core/util/lazy"
|
||||
import { lazy } from "@opencode-ai/shared/util/lazy"
|
||||
|
||||
export namespace Storage {
|
||||
export interface Adapter {
|
||||
|
||||
@@ -10,9 +10,9 @@ 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 { iife } from "@opencode-ai/core/util/iife"
|
||||
import { Binary } from "@opencode-ai/core/util/binary"
|
||||
import { NamedError } from "@opencode-ai/core/util/error"
|
||||
import { iife } from "@opencode-ai/shared/util/iife"
|
||||
import { Binary } from "@opencode-ai/shared/util/binary"
|
||||
import { NamedError } from "@opencode-ai/shared/util/error"
|
||||
import { DateTime } from "luxon"
|
||||
import { createStore } from "solid-js/store"
|
||||
import z from "zod"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { Share } from "../../src/core/share"
|
||||
import { Storage } from "../../src/core/storage"
|
||||
import { Identifier } from "@opencode-ai/core/util/identifier"
|
||||
import { Identifier } from "@opencode-ai/shared/util/identifier"
|
||||
|
||||
describe.concurrent("core.share", () => {
|
||||
test("should create a share", async () => {
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"@effect/language-service": "0.84.2",
|
||||
"@octokit/webhooks-types": "7.6.1",
|
||||
"@opencode-ai/script": "workspace:*",
|
||||
"@opencode-ai/core": "workspace:*",
|
||||
"@opencode-ai/shared": "workspace:*",
|
||||
"@parcel/watcher-darwin-arm64": "2.5.1",
|
||||
"@parcel/watcher-darwin-x64": "2.5.1",
|
||||
"@parcel/watcher-linux-arm64-glibc": "2.5.1",
|
||||
|
||||
@@ -139,8 +139,8 @@ Use raw Effect HTTP routes where `HttpApi` does not fit. The goal is deleting Ho
|
||||
| `project` | `bridged` partial | reads only; git-init remains Hono |
|
||||
| `file` | `bridged` partial | list/content/status only |
|
||||
| `mcp` | `bridged` partial | status only |
|
||||
| `workspace` | `bridged` | list, get, enter |
|
||||
| top-level instance reads | `bridged` partial | path and vcs reads; command, agent, skill, lsp, formatter next |
|
||||
| `workspace` | `implemented` | `HttpApi` group exists, but bridge mounting needs verification |
|
||||
| top-level instance reads | `next` | path, vcs, command, agent, skill, lsp, formatter |
|
||||
| experimental JSON routes | `next/later` | console, tool, worktree, resource, global session list |
|
||||
| `session` | `later/special` | large stateful surface plus streaming |
|
||||
| `sync` | `later` | process/control side effects |
|
||||
@@ -150,9 +150,11 @@ Use raw Effect HTTP routes where `HttpApi` does not fit. The goal is deleting Ho
|
||||
|
||||
## Next PRs
|
||||
|
||||
1. Produce a generated route inventory from Hono registrations and update `Current Route Status` with exact paths.
|
||||
2. Continue porting top-level JSON reads.
|
||||
3. Start the Effect OpenAPI/SDK generation path for already-bridged routes.
|
||||
1. Add bridge-level auth and instance-context tests for the current `HttpApi` bridge.
|
||||
2. Produce a generated route inventory from Hono registrations and update `Current Route Status` with exact paths.
|
||||
3. Fix the `workspace` status: mount it if it should be reachable, or remove it from the composed `HttpApi` layer.
|
||||
4. Port the top-level JSON reads.
|
||||
5. Start the Effect OpenAPI/SDK generation path for already-bridged routes.
|
||||
|
||||
## Checklist
|
||||
|
||||
@@ -162,9 +164,9 @@ Use raw Effect HTTP routes where `HttpApi` does not fit. The goal is deleting Ho
|
||||
- [x] Provide auth, instance lookup, and observability in the Effect route layer.
|
||||
- [x] Attach auth middleware in route modules.
|
||||
- [x] Support `auth_token` as a query security scheme.
|
||||
- [x] Add bridge-level auth and instance tests.
|
||||
- [ ] Add bridge-level auth and instance tests.
|
||||
- [ ] Complete exact Hono route inventory.
|
||||
- [x] Resolve implemented-but-unmounted route groups.
|
||||
- [ ] Resolve implemented-but-unmounted route groups.
|
||||
- [ ] Port remaining JSON routes.
|
||||
- [ ] Generate SDK/OpenAPI from Effect routes.
|
||||
- [ ] Flip ported JSON routes to default-on with fallback.
|
||||
|
||||
@@ -34,7 +34,7 @@ import {
|
||||
import { Log } from "../util"
|
||||
import { pathToFileURL } from "url"
|
||||
import { Filesystem } from "../util"
|
||||
import { Hash } from "@opencode-ai/core/util/hash"
|
||||
import { Hash } from "@opencode-ai/shared/util/hash"
|
||||
import { ACPSessionManager } from "./session"
|
||||
import type { ACPConfig } from "./types"
|
||||
import { Provider } from "../provider"
|
||||
@@ -50,7 +50,7 @@ import { Result, Schema } from "effect"
|
||||
import { LoadAPIKeyError } from "ai"
|
||||
import type { AssistantMessage, Event, OpencodeClient, SessionMessageResponse, ToolPart } from "@opencode-ai/sdk/v2"
|
||||
import { applyPatch } from "diff"
|
||||
import { InstallationVersion } from "@opencode-ai/core/installation/version"
|
||||
import { InstallationVersion } from "@/installation/version"
|
||||
|
||||
type ModeOption = { id: string; name: string; description?: string }
|
||||
type ModelOption = { modelId: string; name: string }
|
||||
|
||||
@@ -15,7 +15,7 @@ import PROMPT_SUMMARY from "./prompt/summary.txt"
|
||||
import PROMPT_TITLE from "./prompt/title.txt"
|
||||
import { Permission } from "@/permission"
|
||||
import { mergeDeep, pipe, sortBy, values } from "remeda"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
import path from "path"
|
||||
import { Plugin } from "@/plugin"
|
||||
import { Skill } from "../skill"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import path from "path"
|
||||
import { Effect, Layer, Record, Result, Schema, Context } from "effect"
|
||||
import { zod } from "@/util/effect-zod"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
||||
import { Global } from "../global"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
|
||||
export const OAUTH_DUMMY_KEY = "opencode-oauth-dummy-key"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { cmd } from "./cmd"
|
||||
import * as prompts from "@clack/prompts"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { UI } from "../ui"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "../../global"
|
||||
import { Agent } from "../../agent/agent"
|
||||
import { Provider } from "../../provider"
|
||||
import path from "path"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "../../../global"
|
||||
import { bootstrap } from "../../bootstrap"
|
||||
import { cmd } from "../cmd"
|
||||
import { ConfigCommand } from "./config"
|
||||
@@ -9,7 +9,6 @@ import { ScrapCommand } from "./scrap"
|
||||
import { SkillCommand } from "./skill"
|
||||
import { SnapshotCommand } from "./snapshot"
|
||||
import { AgentCommand } from "./agent"
|
||||
import { StartupCommand } from "./startup"
|
||||
|
||||
export const DebugCommand = cmd({
|
||||
command: "debug",
|
||||
@@ -23,7 +22,6 @@ export const DebugCommand = cmd({
|
||||
.command(ScrapCommand)
|
||||
.command(SkillCommand)
|
||||
.command(SnapshotCommand)
|
||||
.command(StartupCommand)
|
||||
.command(AgentCommand)
|
||||
.command(PathsCommand)
|
||||
.command({
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { EOL } from "os"
|
||||
import { cmd } from "../cmd"
|
||||
|
||||
export const StartupCommand = cmd({
|
||||
command: "startup",
|
||||
describe: "print startup timing",
|
||||
builder: (yargs) => yargs,
|
||||
handler() {
|
||||
process.stdout.write(performance.now().toString() + EOL)
|
||||
},
|
||||
})
|
||||
@@ -11,9 +11,9 @@ import { Config } from "../../config"
|
||||
import { ConfigMCP } from "../../config/mcp"
|
||||
import { Instance } from "../../project/instance"
|
||||
import { Installation } from "../../installation"
|
||||
import { InstallationVersion } from "@opencode-ai/core/installation/version"
|
||||
import { InstallationVersion } from "../../installation/version"
|
||||
import path from "path"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "../../global"
|
||||
import { modify, applyEdits } from "jsonc-parser"
|
||||
import { Filesystem } from "../../util"
|
||||
import { Bus } from "../../bus"
|
||||
|
||||
@@ -2,7 +2,7 @@ import { intro, log, outro, spinner } from "@clack/prompts"
|
||||
import type { Argv } from "yargs"
|
||||
|
||||
import { ConfigPaths } from "../../config"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "../../global"
|
||||
import { installPlugin, patchPluginConfig, readPluginManifest } from "../../plugin/install"
|
||||
import { resolvePluginTarget } from "../../plugin/shared"
|
||||
import { Instance } from "../../project/instance"
|
||||
|
||||
@@ -8,7 +8,7 @@ import { map, pipe, sortBy, values } from "remeda"
|
||||
import path from "path"
|
||||
import os from "os"
|
||||
import { Config } from "../../config"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "../../global"
|
||||
import { Plugin } from "../../plugin"
|
||||
import { Instance } from "../../project/instance"
|
||||
import type { Hooks } from "@opencode-ai/plugin"
|
||||
|
||||
@@ -3,7 +3,7 @@ import path from "path"
|
||||
import { pathToFileURL } from "url"
|
||||
import { UI } from "../ui"
|
||||
import { cmd } from "./cmd"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flag } from "../../flag/flag"
|
||||
import { bootstrap } from "../bootstrap"
|
||||
import { EOL } from "os"
|
||||
import { Filesystem } from "../../util"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Server } from "../../server/server"
|
||||
import { cmd } from "./cmd"
|
||||
import { withNetworkOptions, resolveNetworkOptions } from "../network"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flag } from "../../flag/flag"
|
||||
|
||||
export const ServeCommand = cmd({
|
||||
command: "serve",
|
||||
|
||||
@@ -5,7 +5,7 @@ import { SessionID } from "../../session/schema"
|
||||
import { bootstrap } from "../bootstrap"
|
||||
import { UI } from "../ui"
|
||||
import { Locale } from "../../util"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flag } from "../../flag/flag"
|
||||
import { Filesystem } from "../../util"
|
||||
import { Process } from "../../util"
|
||||
import { EOL } from "os"
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
on,
|
||||
} from "solid-js"
|
||||
import { win32DisableProcessedInput, win32InstallCtrlCGuard } from "./win32"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import semver from "semver"
|
||||
import { DialogProvider, useDialog } from "@tui/ui/dialog"
|
||||
import { DialogProvider as DialogProviderList } from "@tui/component/dialog-provider"
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useProject } from "@tui/context/project"
|
||||
import { useKeybind } from "../context/keybind"
|
||||
import { useTheme } from "../context/theme"
|
||||
import { useSDK } from "../context/sdk"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { DialogSessionRename } from "./dialog-session-rename"
|
||||
import { Keybind } from "@/util"
|
||||
import { createDebouncedSignal } from "../util/signal"
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useProject } from "@tui/context/project"
|
||||
import { createMemo, createSignal, onMount } from "solid-js"
|
||||
import { setTimeout as sleep } from "node:timers/promises"
|
||||
import { errorData, errorMessage } from "@/util/error"
|
||||
import * as Log from "@opencode-ai/core/util/log"
|
||||
import * as Log from "@/util/log"
|
||||
import { useSDK } from "../context/sdk"
|
||||
import { useToast } from "../ui/toast"
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { TextAttributes } from "@opentui/core"
|
||||
import { useKeyboard, useRenderer, useTerminalDimensions } from "@opentui/solid"
|
||||
import * as Clipboard from "@tui/util/clipboard"
|
||||
import { createSignal } from "solid-js"
|
||||
import { InstallationVersion } from "@opencode-ai/core/installation/version"
|
||||
import { InstallationVersion } from "@/installation/version"
|
||||
import { win32FlushInputBuffer } from "../win32"
|
||||
import { getScrollAcceleration } from "../util/scroll"
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import path from "path"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
import { Filesystem } from "@/util"
|
||||
import { onMount } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import path from "path"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
import { Filesystem } from "@/util"
|
||||
import { onMount } from "solid-js"
|
||||
import { createStore, produce, unwrap } from "solid-js/store"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import path from "path"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
import { Filesystem } from "@/util"
|
||||
import { onMount } from "solid-js"
|
||||
import { createStore, produce, unwrap } from "solid-js/store"
|
||||
|
||||
@@ -3,8 +3,8 @@ import { type ParseError as JsoncParseError, applyEdits, modify, parse as parseJ
|
||||
import { unique } from "remeda"
|
||||
import z from "zod"
|
||||
import { TuiInfo, TuiOptions } from "./tui-schema"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { Global } from "@/global"
|
||||
import { Filesystem, Log } from "@/util"
|
||||
import * as ConfigPaths from "@/config/paths"
|
||||
|
||||
|
||||
@@ -7,15 +7,15 @@ import { ConfigParse } from "@/config/parse"
|
||||
import * as ConfigPaths from "@/config/paths"
|
||||
import { migrateTuiConfig } from "./tui-migrate"
|
||||
import { TuiInfo } from "./tui-schema"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { isRecord } from "@/util/record"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
||||
import { Global } from "@/global"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
import { CurrentWorkingDirectory } from "./cwd"
|
||||
import { ConfigPlugin } from "@/config/plugin"
|
||||
import { ConfigKeybinds } from "@/config/keybinds"
|
||||
import { InstallationLocal, InstallationVersion } from "@opencode-ai/core/installation/version"
|
||||
import { makeRuntime } from "@opencode-ai/core/effect/runtime"
|
||||
import { InstallationLocal, InstallationVersion } from "@/installation/version"
|
||||
import { makeRuntime } from "@/effect/runtime"
|
||||
import { Filesystem, Log } from "@/util"
|
||||
import { ConfigVariable } from "@/config/variable"
|
||||
import { Npm } from "@/npm"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createMemo } from "solid-js"
|
||||
import { useProject } from "./project"
|
||||
import { useSync } from "./sync"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
|
||||
export function useDirectory() {
|
||||
const project = useProject()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
import { Filesystem } from "@/util"
|
||||
import { Flock } from "@opencode-ai/core/util/flock"
|
||||
import { Flock } from "@opencode-ai/shared/util/flock"
|
||||
import { rename, rm } from "fs/promises"
|
||||
import { createSignal, type Setter } from "solid-js"
|
||||
import { createStore, unwrap } from "solid-js/store"
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useSync } from "@tui/context/sync"
|
||||
import { useTheme } from "@tui/context/theme"
|
||||
import { uniqueBy } from "remeda"
|
||||
import path from "path"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
import { iife } from "@/util/iife"
|
||||
import { useToast } from "../ui/toast"
|
||||
import { useArgs } from "./args"
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createOpencodeClient } from "@opencode-ai/sdk/v2"
|
||||
import type { GlobalEvent } from "@opencode-ai/sdk/v2"
|
||||
import { createSimpleContext } from "./helper"
|
||||
import { createGlobalEmitter } from "@solid-primitives/event-bus"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { batch, onCleanup, onMount } from "solid-js"
|
||||
|
||||
export type EventSource = {
|
||||
|
||||
@@ -22,7 +22,7 @@ import { createStore, produce, reconcile } from "solid-js/store"
|
||||
import { useProject } from "@tui/context/project"
|
||||
import { useEvent } from "@tui/context/event"
|
||||
import { useSDK } from "@tui/context/sdk"
|
||||
import { Binary } from "@opencode-ai/core/util/binary"
|
||||
import { Binary } from "@opencode-ai/shared/util/binary"
|
||||
import { createSimpleContext } from "./helper"
|
||||
import type { Snapshot } from "@/snapshot"
|
||||
import { useExit } from "./exit"
|
||||
|
||||
@@ -2,7 +2,7 @@ import { CliRenderEvents, SyntaxStyle, RGBA, type TerminalColors } from "@opentu
|
||||
import path from "path"
|
||||
import { createEffect, createMemo, onCleanup, onMount } from "solid-js"
|
||||
import { createSimpleContext } from "./helper"
|
||||
import { Glob } from "@opencode-ai/core/util/glob"
|
||||
import { Glob } from "@opencode-ai/shared/util/glob"
|
||||
import aura from "./theme/aura.json" with { type: "json" }
|
||||
import ayu from "./theme/ayu.json" with { type: "json" }
|
||||
import catppuccin from "./theme/catppuccin.json" with { type: "json" }
|
||||
@@ -39,7 +39,7 @@ import carbonfox from "./theme/carbonfox.json" with { type: "json" }
|
||||
import { useKV } from "./kv"
|
||||
import { useRenderer } from "@opentui/solid"
|
||||
import { createStore, produce } from "solid-js/store"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
import { Filesystem } from "@/util"
|
||||
import { useTuiConfig } from "./tui-config"
|
||||
import { isRecord } from "@/util/record"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from "@opencode-ai/plugin/tui"
|
||||
import { createMemo, Match, Show, Switch } from "solid-js"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
|
||||
const id = "internal:home-footer"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { TuiPlugin, TuiPluginApi, TuiPluginModule } from "@opencode-ai/plugin/tui"
|
||||
import { createMemo, Show } from "solid-js"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
|
||||
const id = "internal:sidebar-footer"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Layer } from "effect"
|
||||
import { TuiConfig } from "./config/tui"
|
||||
import { Npm } from "@/npm"
|
||||
import { Observability } from "@opencode-ai/core/effect/observability"
|
||||
import { Observability } from "@/effect/observability"
|
||||
|
||||
export const CliLayer = Observability.layer.pipe(Layer.merge(TuiConfig.layer), Layer.provide(Npm.defaultLayer))
|
||||
|
||||
@@ -18,7 +18,7 @@ import { DialogSelect, type DialogSelectOption as SelectOption } from "../ui/dia
|
||||
import { Prompt } from "../component/prompt"
|
||||
import { Slot as HostSlot } from "./slots"
|
||||
import type { useToast } from "../ui/toast"
|
||||
import { InstallationVersion } from "@opencode-ai/core/installation/version"
|
||||
import { InstallationVersion } from "@/installation/version"
|
||||
|
||||
type RouteEntry = {
|
||||
key: symbol
|
||||
|
||||
@@ -29,11 +29,11 @@ import { PluginLoader } from "@/plugin/loader"
|
||||
import { PluginMeta } from "@/plugin/meta"
|
||||
import { installPlugin as installModulePlugin, patchPluginConfig, readPluginManifest } from "@/plugin/install"
|
||||
import { hasTheme, upsertTheme } from "../context/theme"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
import { Filesystem } from "@/util"
|
||||
import { Process } from "@/util"
|
||||
import { Flock } from "@opencode-ai/core/util/flock"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flock } from "@opencode-ai/shared/util/flock"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { INTERNAL_TUI_PLUGINS, type InternalTuiPlugin } from "./internal"
|
||||
import { setupSlots, Slot as View } from "./slots"
|
||||
import type { HostPluginApi, HostSlots } from "./slots"
|
||||
|
||||
@@ -64,7 +64,7 @@ import { DialogForkFromTimeline } from "./dialog-fork-from-timeline"
|
||||
import { DialogSessionRename } from "../../component/dialog-session-rename"
|
||||
import { Sidebar } from "./sidebar"
|
||||
import { SubagentFooter } from "./subagent-footer.tsx"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { LANGUAGE_EXTENSIONS } from "@/lsp/language"
|
||||
import parsers from "../../../../../../parsers-config.ts"
|
||||
import * as Clipboard from "../../util/clipboard"
|
||||
@@ -76,7 +76,7 @@ import stripAnsi from "strip-ansi"
|
||||
import { usePromptRef } from "../../context/prompt"
|
||||
import { useExit } from "../../context/exit"
|
||||
import { Filesystem } from "@/util"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
import { PermissionPrompt } from "./permission"
|
||||
import { QuestionPrompt } from "./question"
|
||||
import { DialogExportOptions } from "../../ui/dialog-export-options"
|
||||
|
||||
@@ -14,7 +14,7 @@ import path from "path"
|
||||
import { LANGUAGE_EXTENSIONS } from "@/lsp/language"
|
||||
import { Keybind } from "@/util"
|
||||
import { Locale } from "@/util"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "@/global"
|
||||
import { useDialog } from "../../ui/dialog"
|
||||
import { getScrollAcceleration } from "../../util/scroll"
|
||||
import { useTuiConfig } from "../../context/tui-config"
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useSync } from "@tui/context/sync"
|
||||
import { createMemo, Show } from "solid-js"
|
||||
import { useTheme } from "../../context/theme"
|
||||
import { useTuiConfig } from "../../context/tui-config"
|
||||
import { InstallationChannel, InstallationVersion } from "@opencode-ai/core/installation/version"
|
||||
import { InstallationChannel, InstallationVersion } from "@/installation/version"
|
||||
import { TuiPluginRuntime } from "../../plugin"
|
||||
|
||||
import { getScrollAcceleration } from "../../util/scroll"
|
||||
|
||||
@@ -15,12 +15,7 @@ import type { EventSource } from "./context/sdk"
|
||||
import { win32DisableProcessedInput, win32InstallCtrlCGuard } from "./win32"
|
||||
import { writeHeapSnapshot } from "v8"
|
||||
import { TuiConfig } from "./config/tui"
|
||||
import {
|
||||
OPENCODE_PROCESS_ROLE,
|
||||
OPENCODE_RUN_ID,
|
||||
ensureRunID,
|
||||
sanitizedProcessEnv,
|
||||
} from "@opencode-ai/core/util/opencode-process"
|
||||
import { OPENCODE_PROCESS_ROLE, OPENCODE_RUN_ID, ensureRunID, sanitizedProcessEnv } from "@/util/opencode-process"
|
||||
import { validateSession } from "./validate-session"
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useTheme } from "@tui/context/theme"
|
||||
import { MouseButton, Renderable, RGBA } from "@opentui/core"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { useToast } from "./toast"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import * as Selection from "@tui/util/selection"
|
||||
|
||||
export function Dialog(
|
||||
|
||||
@@ -7,11 +7,11 @@ import { Rpc } from "@/util"
|
||||
import { upgrade } from "@/cli/upgrade"
|
||||
import { Config } from "@/config"
|
||||
import { GlobalBus } from "@/bus/global"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { writeHeapSnapshot } from "node:v8"
|
||||
import { Heap } from "@/cli/heap"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { ensureProcessMetadata } from "@opencode-ai/core/util/opencode-process"
|
||||
import { ensureProcessMetadata } from "@/util/opencode-process"
|
||||
|
||||
ensureProcessMetadata("worker")
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { UI } from "../ui"
|
||||
import * as prompts from "@clack/prompts"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { Installation } from "../../installation"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "../../global"
|
||||
import fs from "fs/promises"
|
||||
import path from "path"
|
||||
import os from "os"
|
||||
|
||||
@@ -3,7 +3,7 @@ import { UI } from "../ui"
|
||||
import * as prompts from "@clack/prompts"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { Installation } from "../../installation"
|
||||
import { InstallationVersion } from "@opencode-ai/core/installation/version"
|
||||
import { InstallationVersion } from "../../installation/version"
|
||||
|
||||
export const UpgradeCommand = {
|
||||
command: "upgrade [target]",
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Server } from "../../server/server"
|
||||
import { UI } from "../ui"
|
||||
import { cmd } from "./cmd"
|
||||
import { withNetworkOptions, resolveNetworkOptions } from "../network"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flag } from "../../flag/flag"
|
||||
import open from "open"
|
||||
import { networkInterfaces } from "os"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { NamedError } from "@opencode-ai/core/util/error"
|
||||
import { NamedError } from "@opencode-ai/shared/util/error"
|
||||
import { errorFormat } from "@/util/error"
|
||||
|
||||
interface ErrorLike {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from "path"
|
||||
import { writeHeapSnapshot } from "node:v8"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { Global } from "@/global"
|
||||
import { Log } from "@/util"
|
||||
|
||||
const log = Log.create({ service: "heap" })
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import z from "zod"
|
||||
import { EOL } from "os"
|
||||
import { NamedError } from "@opencode-ai/core/util/error"
|
||||
import { NamedError } from "@opencode-ai/shared/util/error"
|
||||
import { logo as glyphs } from "./logo"
|
||||
|
||||
const wordmark = [
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Bus } from "@/bus"
|
||||
import { Config } from "@/config"
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Flag } from "@/flag/flag"
|
||||
import { Installation } from "@/installation"
|
||||
import { InstallationVersion } from "@opencode-ai/core/installation/version"
|
||||
import { InstallationVersion } from "@/installation/version"
|
||||
|
||||
export async function upgrade() {
|
||||
const config = await AppRuntime.runPromise(Config.Service.use((cfg) => cfg.getGlobal()))
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
export * as ConfigAgent from "./agent"
|
||||
|
||||
import { Exit, Schema, SchemaGetter } from "effect"
|
||||
import { Schema } from "effect"
|
||||
import z from "zod"
|
||||
import { Bus } from "@/bus"
|
||||
import { zod } from "@/util/effect-zod"
|
||||
import { PositiveInt, withStatics } from "@/util/schema"
|
||||
import { PositiveInt } from "@/util/schema"
|
||||
import { Log } from "../util"
|
||||
import { NamedError } from "@opencode-ai/core/util/error"
|
||||
import { Glob } from "@opencode-ai/core/util/glob"
|
||||
import { NamedError } from "@opencode-ai/shared/util/error"
|
||||
import { Glob } from "@opencode-ai/shared/util/glob"
|
||||
import { configEntryNameFromPath } from "./entry-name"
|
||||
import { InvalidError } from "./error"
|
||||
import * as ConfigMarkdown from "./markdown"
|
||||
import { ConfigModelID } from "./model-id"
|
||||
import { ConfigParse } from "./parse"
|
||||
import { ConfigPermission } from "./permission"
|
||||
|
||||
const log = Log.create({ service: "config" })
|
||||
@@ -76,7 +77,7 @@ const KNOWN_KEYS = new Set([
|
||||
// - Translate the deprecated `tools: { name: boolean }` map into the new
|
||||
// `permission` shape (write-adjacent tools collapse into `permission.edit`).
|
||||
// - Coalesce `steps ?? maxSteps` so downstream can ignore the deprecated alias.
|
||||
const normalize = (agent: Schema.Schema.Type<typeof AgentSchema>): Schema.Schema.Type<typeof AgentSchema> => {
|
||||
const normalize = (agent: z.infer<typeof Info>) => {
|
||||
const options: Record<string, unknown> = { ...agent.options }
|
||||
for (const [key, value] of Object.entries(agent)) {
|
||||
if (!KNOWN_KEYS.has(key)) options[key] = value
|
||||
@@ -97,15 +98,14 @@ const normalize = (agent: Schema.Schema.Type<typeof AgentSchema>): Schema.Schema
|
||||
return { ...agent, options, permission, ...(steps !== undefined ? { steps } : {}) }
|
||||
}
|
||||
|
||||
export const Info = AgentSchema.pipe(
|
||||
Schema.decodeTo(AgentSchema, {
|
||||
decode: SchemaGetter.transform(normalize),
|
||||
encode: SchemaGetter.passthrough({ strict: false }),
|
||||
}),
|
||||
)
|
||||
.annotate({ identifier: "AgentConfig" })
|
||||
.pipe(withStatics((s) => ({ zod: zod(s) })))
|
||||
export type Info = Schema.Schema.Type<typeof Info>
|
||||
export const Info = zod(AgentSchema).transform(normalize).meta({ ref: "AgentConfig" }) as unknown as z.ZodType<
|
||||
Omit<z.infer<ReturnType<typeof zod<typeof AgentSchema>>>, "options" | "permission" | "steps"> & {
|
||||
options?: Record<string, unknown>
|
||||
permission?: ConfigPermission.Info
|
||||
steps?: number
|
||||
}
|
||||
>
|
||||
export type Info = z.infer<typeof Info>
|
||||
|
||||
export async function load(dir: string) {
|
||||
const result: Record<string, Info> = {}
|
||||
@@ -134,7 +134,12 @@ export async function load(dir: string) {
|
||||
...md.data,
|
||||
prompt: md.content.trim(),
|
||||
}
|
||||
result[config.name] = ConfigParse.effectSchema(Info, config, item)
|
||||
const parsed = Info.safeParse(config)
|
||||
if (parsed.success) {
|
||||
result[config.name] = parsed.data
|
||||
continue
|
||||
}
|
||||
throw new InvalidError({ path: item, issues: parsed.error.issues }, { cause: parsed.error })
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -163,10 +168,10 @@ export async function loadMode(dir: string) {
|
||||
...md.data,
|
||||
prompt: md.content.trim(),
|
||||
}
|
||||
const parsed = Schema.decodeUnknownExit(Info)(config, { errors: "all", propertyOrder: "original" })
|
||||
if (Exit.isSuccess(parsed)) {
|
||||
const parsed = Info.safeParse(config)
|
||||
if (parsed.success) {
|
||||
result[config.name] = {
|
||||
...parsed.value,
|
||||
...parsed.data,
|
||||
mode: "primary" as const,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ export * as ConfigCommand from "./command"
|
||||
|
||||
import { Log } from "../util"
|
||||
import { Schema } from "effect"
|
||||
import { NamedError } from "@opencode-ai/core/util/error"
|
||||
import { Glob } from "@opencode-ai/core/util/glob"
|
||||
import { NamedError } from "@opencode-ai/shared/util/error"
|
||||
import { Glob } from "@opencode-ai/shared/util/glob"
|
||||
import { Bus } from "@/bus"
|
||||
import { zod } from "@/util/effect-zod"
|
||||
import { withStatics } from "@/util/schema"
|
||||
|
||||
@@ -4,27 +4,27 @@ import { pathToFileURL } from "url"
|
||||
import os from "os"
|
||||
import z from "zod"
|
||||
import { mergeDeep, pipe } from "remeda"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import { Global } from "../global"
|
||||
import fsNode from "fs/promises"
|
||||
import { NamedError } from "@opencode-ai/core/util/error"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { NamedError } from "@opencode-ai/shared/util/error"
|
||||
import { Flag } from "../flag/flag"
|
||||
import { Auth } from "../auth"
|
||||
import { Env } from "../env"
|
||||
import { applyEdits, modify } from "jsonc-parser"
|
||||
import { Instance, type InstanceContext } from "../project/instance"
|
||||
import { InstallationLocal, InstallationVersion } from "@opencode-ai/core/installation/version"
|
||||
import { InstallationLocal, InstallationVersion } from "@/installation/version"
|
||||
import { existsSync } from "fs"
|
||||
import { GlobalBus } from "@/bus/global"
|
||||
import { Event } from "../server/event"
|
||||
import { Account } from "@/account/account"
|
||||
import { isRecord } from "@/util/record"
|
||||
import type { ConsoleState } from "./console-state"
|
||||
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
||||
import { AppFileSystem } from "@opencode-ai/shared/filesystem"
|
||||
import { InstanceState } from "@/effect"
|
||||
import { Context, Duration, Effect, Exit, Fiber, Layer, Option, Schema } from "effect"
|
||||
import { EffectFlock } from "@opencode-ai/core/util/effect-flock"
|
||||
import { EffectFlock } from "@opencode-ai/shared/util/effect-flock"
|
||||
import { InstanceRef } from "@/effect/instance-ref"
|
||||
import { zod } from "@/util/effect-zod"
|
||||
import { zod, ZodOverride } from "@/util/effect-zod"
|
||||
import { NonNegativeInt, PositiveInt, withStatics, type DeepMutable } from "@/util/schema"
|
||||
import { ConfigAgent } from "./agent"
|
||||
import { ConfigCommand } from "./command"
|
||||
@@ -81,10 +81,12 @@ export const Server = ConfigServer.Server.zod
|
||||
export const Layout = ConfigLayout.Layout.zod
|
||||
export type Layout = ConfigLayout.Layout
|
||||
|
||||
const LogLevelRef = Schema.Literals(["DEBUG", "INFO", "WARN", "ERROR"]).annotate({
|
||||
identifier: "LogLevel",
|
||||
description: "Log level",
|
||||
})
|
||||
// Schemas that still live at the zod layer (have .transform / .preprocess /
|
||||
// .meta not expressible in current Effect Schema) get referenced via a
|
||||
// ZodOverride-annotated Schema.Any. Walker sees the annotation and emits the
|
||||
// exact zod directly, preserving component $refs.
|
||||
const AgentRef = Schema.Any.annotate({ [ZodOverride]: ConfigAgent.Info })
|
||||
const LogLevelRef = Schema.Any.annotate({ [ZodOverride]: Log.Level })
|
||||
|
||||
// The Effect Schema is the canonical source of truth. The `.zod` compatibility
|
||||
// surface is derived so existing Hono validators keep working without a parallel
|
||||
@@ -150,27 +152,27 @@ export const Info = Schema.Struct({
|
||||
mode: Schema.optional(
|
||||
Schema.StructWithRest(
|
||||
Schema.Struct({
|
||||
build: Schema.optional(ConfigAgent.Info),
|
||||
plan: Schema.optional(ConfigAgent.Info),
|
||||
build: Schema.optional(AgentRef),
|
||||
plan: Schema.optional(AgentRef),
|
||||
}),
|
||||
[Schema.Record(Schema.String, ConfigAgent.Info)],
|
||||
[Schema.Record(Schema.String, AgentRef)],
|
||||
),
|
||||
).annotate({ description: "@deprecated Use `agent` field instead." }),
|
||||
agent: Schema.optional(
|
||||
Schema.StructWithRest(
|
||||
Schema.Struct({
|
||||
// primary
|
||||
plan: Schema.optional(ConfigAgent.Info),
|
||||
build: Schema.optional(ConfigAgent.Info),
|
||||
plan: Schema.optional(AgentRef),
|
||||
build: Schema.optional(AgentRef),
|
||||
// subagent
|
||||
general: Schema.optional(ConfigAgent.Info),
|
||||
explore: Schema.optional(ConfigAgent.Info),
|
||||
general: Schema.optional(AgentRef),
|
||||
explore: Schema.optional(AgentRef),
|
||||
// specialized
|
||||
title: Schema.optional(ConfigAgent.Info),
|
||||
summary: Schema.optional(ConfigAgent.Info),
|
||||
compaction: Schema.optional(ConfigAgent.Info),
|
||||
title: Schema.optional(AgentRef),
|
||||
summary: Schema.optional(AgentRef),
|
||||
compaction: Schema.optional(AgentRef),
|
||||
}),
|
||||
[Schema.Record(Schema.String, ConfigAgent.Info)],
|
||||
[Schema.Record(Schema.String, AgentRef)],
|
||||
),
|
||||
).annotate({ description: "Agent configuration, see https://opencode.ai/docs/agents" }),
|
||||
provider: Schema.optional(Schema.Record(Schema.String, ConfigProvider.Info)).annotate({
|
||||
@@ -182,7 +184,7 @@ export const Info = Schema.Struct({
|
||||
Schema.Union([
|
||||
ConfigMCP.Info,
|
||||
// Matches the legacy `{ enabled: false }` form used to disable a server.
|
||||
Schema.Struct({ enabled: Schema.Boolean }),
|
||||
Schema.Any.annotate({ [ZodOverride]: z.object({ enabled: z.boolean() }).strict() }),
|
||||
]),
|
||||
),
|
||||
).annotate({ description: "MCP (Model Context Protocol) server configurations" }),
|
||||
@@ -360,7 +362,7 @@ export const layer = Layer.effect(
|
||||
),
|
||||
)
|
||||
const parsed = ConfigParse.jsonc(expanded, source)
|
||||
const data = ConfigParse.effectSchema(Info, normalizeLoadedConfig(parsed, source), source)
|
||||
const data = ConfigParse.schema(Info.zod, normalizeLoadedConfig(parsed, source), source)
|
||||
if (!("path" in options)) return data
|
||||
|
||||
yield* Effect.promise(() => resolveLoadedPlugins(data, options.path))
|
||||
@@ -752,13 +754,13 @@ export const layer = Layer.effect(
|
||||
|
||||
let next: Info
|
||||
if (!file.endsWith(".jsonc")) {
|
||||
const existing = ConfigParse.effectSchema(Info, ConfigParse.jsonc(before, file), file)
|
||||
const existing = ConfigParse.schema(Info.zod, ConfigParse.jsonc(before, file), file)
|
||||
const merged = mergeDeep(writable(existing), writable(config))
|
||||
yield* fs.writeFileString(file, JSON.stringify(merged, null, 2)).pipe(Effect.orDie)
|
||||
next = merged
|
||||
} else {
|
||||
const updated = patchJsonc(before, writable(config))
|
||||
next = ConfigParse.effectSchema(Info, ConfigParse.jsonc(updated, file), file)
|
||||
next = ConfigParse.schema(Info.zod, ConfigParse.jsonc(updated, file), file)
|
||||
yield* fs.writeFileString(file, updated).pipe(Effect.orDie)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export * as ConfigError from "./error"
|
||||
|
||||
import z from "zod"
|
||||
import { NamedError } from "@opencode-ai/core/util/error"
|
||||
import { NamedError } from "@opencode-ai/shared/util/error"
|
||||
|
||||
export const JsonError = NamedError.create(
|
||||
"ConfigJsonError",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { NamedError } from "@opencode-ai/core/util/error"
|
||||
import { NamedError } from "@opencode-ai/shared/util/error"
|
||||
import matter from "gray-matter"
|
||||
import { z } from "zod"
|
||||
import { Filesystem } from "../util"
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
export * as ConfigParse from "./parse"
|
||||
|
||||
import { type ParseError as JsoncParseError, parse as parseJsoncImpl, printParseErrorCode } from "jsonc-parser"
|
||||
import { Cause, Exit, Schema as EffectSchema, SchemaIssue } from "effect"
|
||||
import z from "zod"
|
||||
import type { DeepMutable } from "@/util/schema"
|
||||
import { InvalidError, JsonError } from "./error"
|
||||
|
||||
type ZodSchema<T> = z.ZodType<T>
|
||||
type Schema<T> = z.ZodType<T>
|
||||
|
||||
export function jsonc(text: string, filepath: string): unknown {
|
||||
const errors: JsoncParseError[] = []
|
||||
@@ -35,7 +33,7 @@ export function jsonc(text: string, filepath: string): unknown {
|
||||
return data
|
||||
}
|
||||
|
||||
export function schema<T>(schema: ZodSchema<T>, data: unknown, source: string): T {
|
||||
export function schema<T>(schema: Schema<T>, data: unknown, source: string): T {
|
||||
const parsed = schema.safeParse(data)
|
||||
if (parsed.success) return parsed.data
|
||||
|
||||
@@ -44,45 +42,3 @@ export function schema<T>(schema: ZodSchema<T>, data: unknown, source: string):
|
||||
issues: parsed.error.issues,
|
||||
})
|
||||
}
|
||||
|
||||
export function effectSchema<S extends EffectSchema.Decoder<unknown, never>>(
|
||||
schema: S,
|
||||
data: unknown,
|
||||
source: string,
|
||||
): DeepMutable<S["Type"]> {
|
||||
const extra = topLevelExtraKeys(schema, data)
|
||||
if (extra.length) {
|
||||
throw new InvalidError({
|
||||
path: source,
|
||||
issues: [
|
||||
{
|
||||
code: "unrecognized_keys",
|
||||
keys: extra,
|
||||
path: [],
|
||||
message: `Unrecognized key${extra.length === 1 ? "" : "s"}: ${extra.join(", ")}`,
|
||||
} as z.core.$ZodIssue,
|
||||
],
|
||||
})
|
||||
}
|
||||
|
||||
const decoded = EffectSchema.decodeUnknownExit(schema)(data, { errors: "all", propertyOrder: "original" })
|
||||
if (Exit.isSuccess(decoded)) return decoded.value as DeepMutable<S["Type"]>
|
||||
const error = Cause.squash(decoded.cause)
|
||||
|
||||
throw new InvalidError(
|
||||
{
|
||||
path: source,
|
||||
issues: EffectSchema.isSchemaError(error)
|
||||
? (SchemaIssue.makeFormatterStandardSchemaV1()(error.issue).issues as z.core.$ZodIssue[])
|
||||
: ([{ code: "custom", message: String(error), path: [] }] as z.core.$ZodIssue[]),
|
||||
},
|
||||
{ cause: error },
|
||||
)
|
||||
}
|
||||
|
||||
function topLevelExtraKeys(schema: EffectSchema.Top, data: unknown) {
|
||||
if (typeof data !== "object" || data === null || Array.isArray(data)) return []
|
||||
if (schema.ast._tag !== "Objects" || schema.ast.indexSignatures.length > 0) return []
|
||||
const known = new Set(schema.ast.propertySignatures.map((item) => String(item.name)))
|
||||
return Object.keys(data).filter((key) => !known.has(key))
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user