diff options
| author | Adam <[email protected]> | 2026-01-16 15:31:03 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2026-01-20 07:33:44 -0600 |
| commit | 924fc9ed803d4dfa89faed65579a5a85cd7666c0 (patch) | |
| tree | ceaa1080079e4b876ff65c925bd83a8977096062 /packages | |
| parent | df094a10ff1f1a95f66abc6bdccfa69080480afa (diff) | |
| download | opencode-924fc9ed803d4dfa89faed65579a5a85cd7666c0.tar.gz opencode-924fc9ed803d4dfa89faed65579a5a85cd7666c0.zip | |
wip(app): settings
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/app/src/components/prompt-input.tsx | 1 | ||||
| -rw-r--r-- | packages/app/src/components/settings-permissions.tsx | 151 | ||||
| -rw-r--r-- | packages/app/src/context/global-sync.tsx | 219 | ||||
| -rw-r--r-- | packages/opencode/src/config/config.ts | 108 | ||||
| -rw-r--r-- | packages/opencode/src/file/watcher.ts | 23 | ||||
| -rw-r--r-- | packages/opencode/src/server/event.ts | 7 | ||||
| -rw-r--r-- | packages/opencode/src/server/server.ts | 5 | ||||
| -rw-r--r-- | packages/sdk/js/src/v2/gen/sdk.gen.ts | 39 | ||||
| -rw-r--r-- | packages/sdk/js/src/v2/gen/types.gen.ts | 41 |
9 files changed, 490 insertions, 104 deletions
diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index 56bbdc8cb..072ef0bdd 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -255,7 +255,6 @@ export const PromptInput: Component<PromptInputProps> = (props) => { createEffect(() => { params.id - editorRef.focus() if (params.id) return const interval = setInterval(() => { setStore("placeholder", (prev) => (prev + 1) % PLACEHOLDERS.length) diff --git a/packages/app/src/components/settings-permissions.tsx b/packages/app/src/components/settings-permissions.tsx index 67c3bfb62..f5ee76650 100644 --- a/packages/app/src/components/settings-permissions.tsx +++ b/packages/app/src/components/settings-permissions.tsx @@ -1,12 +1,153 @@ -import { Component } from "solid-js" +import { Select } from "@opencode-ai/ui/select" +import { showToast } from "@opencode-ai/ui/toast" +import { Component, For, createMemo, type JSX } from "solid-js" +import { useGlobalSync } from "@/context/global-sync" + +type PermissionAction = "allow" | "ask" | "deny" + +type PermissionObject = Record<string, PermissionAction> +type PermissionValue = PermissionAction | PermissionObject | string[] | undefined +type PermissionMap = Record<string, PermissionValue> + +type PermissionItem = { + id: string + title: string + description: string +} + +const ACTIONS: Array<{ value: PermissionAction; label: string }> = [ + { value: "allow", label: "Allow" }, + { value: "ask", label: "Ask" }, + { value: "deny", label: "Deny" }, +] + +const ITEMS: PermissionItem[] = [ + { id: "read", title: "Read", description: "Reading a file (matches the file path)" }, + { id: "edit", title: "Edit", description: "Modify files, including edits, writes, patches, and multi-edits" }, + { id: "glob", title: "Glob", description: "Match files using glob patterns" }, + { id: "grep", title: "Grep", description: "Search file contents using regular expressions" }, + { id: "list", title: "List", description: "List files within a directory" }, + { id: "bash", title: "Bash", description: "Run shell commands" }, + { id: "task", title: "Task", description: "Launch sub-agents" }, + { id: "skill", title: "Skill", description: "Load a skill by name" }, + { id: "lsp", title: "LSP", description: "Run language server queries" }, + { id: "todoread", title: "Todo Read", description: "Read the todo list" }, + { id: "todowrite", title: "Todo Write", description: "Update the todo list" }, + { id: "webfetch", title: "Web Fetch", description: "Fetch content from a URL" }, + { id: "websearch", title: "Web Search", description: "Search the web" }, + { id: "codesearch", title: "Code Search", description: "Search code on the web" }, + { id: "external_directory", title: "External Directory", description: "Access files outside the project directory" }, + { id: "doom_loop", title: "Doom Loop", description: "Detect repeated tool calls with identical input" }, +] + +const VALID_ACTIONS = new Set<PermissionAction>(["allow", "ask", "deny"]) + +function toMap(value: unknown): PermissionMap { + if (value && typeof value === "object" && !Array.isArray(value)) return value as PermissionMap + + const action = getAction(value) + if (action) return { "*": action } + + return {} +} + +function getAction(value: unknown): PermissionAction | undefined { + if (typeof value === "string" && VALID_ACTIONS.has(value as PermissionAction)) return value as PermissionAction + return +} + +function getRuleDefault(value: unknown): PermissionAction | undefined { + const action = getAction(value) + if (action) return action + + if (!value || typeof value !== "object" || Array.isArray(value)) return + + return getAction((value as Record<string, unknown>)["*"]) +} export const SettingsPermissions: Component = () => { + const globalSync = useGlobalSync() + + const permission = createMemo(() => { + return toMap(globalSync.data.config.permission) + }) + + const actionFor = (id: string): PermissionAction => { + const value = permission()[id] + const direct = getRuleDefault(value) + if (direct) return direct + + const wildcard = getRuleDefault(permission()["*"]) + if (wildcard) return wildcard + + return "allow" + } + + const setPermission = async (id: string, action: PermissionAction) => { + const before = globalSync.data.config.permission + const map = toMap(before) + const existing = map[id] + + const nextValue = + existing && typeof existing === "object" && !Array.isArray(existing) ? { ...existing, "*": action } : action + + globalSync.set("config", "permission", { ...map, [id]: nextValue }) + globalSync.updateConfig({ permission: { [id]: nextValue } }).catch((err: unknown) => { + globalSync.set("config", "permission", before) + const message = err instanceof Error ? err.message : String(err) + showToast({ title: "Failed to update permissions", description: message }) + }) + } + + return ( + <div class="flex flex-col h-full overflow-y-auto no-scrollbar"> + <div class="sticky top-0 z-10 bg-background-base border-b border-border-weak-base"> + <div class="flex flex-col gap-1 p-8 max-w-[720px]"> + <h2 class="text-16-medium text-text-strong">Permissions</h2> + <p class="text-14-regular text-text-weak">Control what tools the server can use by default.</p> + </div> + </div> + + <div class="flex flex-col gap-6 p-8 pt-6 max-w-[720px]"> + <div class="flex flex-col gap-2"> + <h3 class="text-14-medium text-text-strong">Appearance</h3> + <div class="border border-border-weak-base rounded-lg overflow-hidden"> + <For each={ITEMS}> + {(item) => ( + <SettingsRow title={item.title} description={item.description}> + <Select + options={ACTIONS} + current={ACTIONS.find((o) => o.value === actionFor(item.id))} + value={(o) => o.value} + label={(o) => o.label} + onSelect={(option) => option && setPermission(item.id, option.value)} + variant="secondary" + size="small" + /> + </SettingsRow> + )} + </For> + </div> + </div> + </div> + </div> + ) +} + +interface SettingsRowProps { + title: string + description: string + children: JSX.Element +} + +const SettingsRow: Component<SettingsRowProps> = (props) => { return ( - <div class="flex flex-col h-full overflow-y-auto"> - <div class="flex flex-col gap-6 p-6 max-w-[600px]"> - <h2 class="text-16-medium text-text-strong">Permissions</h2> - <p class="text-14-regular text-text-weak">Permission settings will be configurable here.</p> + <div class="flex items-center justify-between gap-4 px-4 py-3 border-b border-border-weak-base last:border-none"> + <div class="flex flex-col gap-0.5"> + <span class="text-14-medium text-text-strong">{props.title}</span> + <span class="text-12-regular text-text-weak">{props.description}</span> </div> + <div class="flex-shrink-0">{props.children}</div> </div> ) } diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx index 96f8c63ea..b13855906 100644 --- a/packages/app/src/context/global-sync.tsx +++ b/packages/app/src/context/global-sync.tsx @@ -101,12 +101,29 @@ function createGlobalSync() { project: Project[] provider: ProviderListResponse provider_auth: ProviderAuthResponse + config: Config + reload: undefined | "pending" | "complete" }>({ ready: false, path: { state: "", config: "", worktree: "", directory: "", home: "" }, project: [], provider: { all: [], connected: [], default: {} }, provider_auth: {}, + config: {}, + reload: undefined, + }) + let bootstrapQueue: string[] = [] + + createEffect(async () => { + if (globalStore.reload !== "complete") return + if (bootstrapQueue.length) { + for (const directory of bootstrapQueue) { + bootstrapInstance(directory) + } + bootstrap() + } + bootstrapQueue = [] + setGlobalStore("reload", undefined) }) const children: Record<string, [Store<State>, SetStoreFunction<State>]> = {} @@ -205,6 +222,8 @@ function createGlobalSync() { throwOnError: true, }) + setStore("status", "loading") + createEffect(() => { if (!cache.ready()) return const cached = cache.store.value @@ -230,91 +249,99 @@ function createGlobalSync() { agent: () => sdk.app.agents().then((x) => setStore("agent", x.data ?? [])), config: () => sdk.config.get().then((x) => setStore("config", x.data!)), } - await Promise.all(Object.values(blockingRequests).map((p) => retry(p).catch((e) => setGlobalStore("error", e)))) - .then(() => { - if (store.status !== "complete") setStore("status", "partial") - // non-blocking - Promise.all([ - sdk.path.get().then((x) => setStore("path", x.data!)), - sdk.command.list().then((x) => setStore("command", x.data ?? [])), - sdk.session.status().then((x) => setStore("session_status", x.data!)), - loadSessions(directory), - sdk.mcp.status().then((x) => setStore("mcp", x.data!)), - sdk.lsp.status().then((x) => setStore("lsp", x.data!)), - sdk.vcs.get().then((x) => { - const next = x.data ?? store.vcs - setStore("vcs", next) - if (next?.branch) cache.setStore("value", next) - }), - sdk.permission.list().then((x) => { - const grouped: Record<string, PermissionRequest[]> = {} - for (const perm of x.data ?? []) { - if (!perm?.id || !perm.sessionID) continue - const existing = grouped[perm.sessionID] - if (existing) { - existing.push(perm) - continue - } - grouped[perm.sessionID] = [perm] - } - - batch(() => { - for (const sessionID of Object.keys(store.permission)) { - if (grouped[sessionID]) continue - setStore("permission", sessionID, []) - } - for (const [sessionID, permissions] of Object.entries(grouped)) { - setStore( - "permission", - sessionID, - reconcile( - permissions - .filter((p) => !!p?.id) - .slice() - .sort((a, b) => a.id.localeCompare(b.id)), - { key: "id" }, - ), - ) - } - }) - }), - sdk.question.list().then((x) => { - const grouped: Record<string, QuestionRequest[]> = {} - for (const question of x.data ?? []) { - if (!question?.id || !question.sessionID) continue - const existing = grouped[question.sessionID] - if (existing) { - existing.push(question) - continue - } - grouped[question.sessionID] = [question] - } - - batch(() => { - for (const sessionID of Object.keys(store.question)) { - if (grouped[sessionID]) continue - setStore("question", sessionID, []) - } - for (const [sessionID, questions] of Object.entries(grouped)) { - setStore( - "question", - sessionID, - reconcile( - questions - .filter((q) => !!q?.id) - .slice() - .sort((a, b) => a.id.localeCompare(b.id)), - { key: "id" }, - ), - ) - } - }) - }), - ]).then(() => { - setStore("status", "complete") + + try { + await Promise.all(Object.values(blockingRequests).map((p) => retry(p))) + } catch (err) { + console.error("Failed to bootstrap instance", err) + const project = getFilename(directory) + const message = err instanceof Error ? err.message : String(err) + showToast({ title: `Failed to reload ${project}`, description: message }) + setStore("status", "partial") + return + } + + if (store.status !== "complete") setStore("status", "partial") + + Promise.all([ + sdk.path.get().then((x) => setStore("path", x.data!)), + sdk.command.list().then((x) => setStore("command", x.data ?? [])), + sdk.session.status().then((x) => setStore("session_status", x.data!)), + loadSessions(directory), + sdk.mcp.status().then((x) => setStore("mcp", x.data!)), + sdk.lsp.status().then((x) => setStore("lsp", x.data!)), + sdk.vcs.get().then((x) => { + const next = x.data ?? store.vcs + setStore("vcs", next) + if (next?.branch) cache.setStore("value", next) + }), + sdk.permission.list().then((x) => { + const grouped: Record<string, PermissionRequest[]> = {} + for (const perm of x.data ?? []) { + if (!perm?.id || !perm.sessionID) continue + const existing = grouped[perm.sessionID] + if (existing) { + existing.push(perm) + continue + } + grouped[perm.sessionID] = [perm] + } + + batch(() => { + for (const sessionID of Object.keys(store.permission)) { + if (grouped[sessionID]) continue + setStore("permission", sessionID, []) + } + for (const [sessionID, permissions] of Object.entries(grouped)) { + setStore( + "permission", + sessionID, + reconcile( + permissions + .filter((p) => !!p?.id) + .slice() + .sort((a, b) => a.id.localeCompare(b.id)), + { key: "id" }, + ), + ) + } }) - }) - .catch((e) => setGlobalStore("error", e)) + }), + sdk.question.list().then((x) => { + const grouped: Record<string, QuestionRequest[]> = {} + for (const question of x.data ?? []) { + if (!question?.id || !question.sessionID) continue + const existing = grouped[question.sessionID] + if (existing) { + existing.push(question) + continue + } + grouped[question.sessionID] = [question] + } + + batch(() => { + for (const sessionID of Object.keys(store.question)) { + if (grouped[sessionID]) continue + setStore("question", sessionID, []) + } + for (const [sessionID, questions] of Object.entries(grouped)) { + setStore( + "question", + sessionID, + reconcile( + questions + .filter((q) => !!q?.id) + .slice() + .sort((a, b) => a.id.localeCompare(b.id)), + { key: "id" }, + ), + ) + } + }) + }), + ]).then(() => { + setStore("status", "complete") + }) } const unsub = globalSDK.event.listen((e) => { @@ -324,6 +351,7 @@ function createGlobalSync() { if (directory === "global") { switch (event?.type) { case "global.disposed": { + if (globalStore.reload) return bootstrap() break } @@ -345,9 +373,16 @@ function createGlobalSync() { return } - const [store, setStore] = child(directory) + const existing = children[directory] + if (!existing) return + + const [store, setStore] = existing switch (event.type) { case "server.instance.disposed": { + if (globalStore.reload) { + bootstrapQueue.push(directory) + return + } bootstrapInstance(directory) break } @@ -592,6 +627,11 @@ function createGlobalSync() { }), ), retry(() => + globalSDK.client.global.configGet().then((x) => { + setGlobalStore("config", x.data!) + }), + ), + retry(() => globalSDK.client.project.list().then(async (x) => { const projects = (x.data ?? []) .filter((p) => !!p?.id) @@ -631,6 +671,7 @@ function createGlobalSync() { return { data: globalStore, + set: setGlobalStore, get ready() { return globalStore.ready }, @@ -639,6 +680,14 @@ function createGlobalSync() { }, child, bootstrap, + updateConfig: async (config: Config) => { + setGlobalStore("reload", "pending") + const response = await globalSDK.client.global.configUpdate({ config }) + setTimeout(() => { + setGlobalStore("reload", "complete") + }, 1000) + return response + }, project: { loadSessions, }, diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index ddb3af4b0..b2142e29b 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -12,7 +12,13 @@ import { lazy } from "../util/lazy" import { NamedError } from "@opencode-ai/util/error" import { Flag } from "../flag/flag" import { Auth } from "../auth" -import { type ParseError as JsoncParseError, parse as parseJsonc, printParseErrorCode } from "jsonc-parser" +import { + type ParseError as JsoncParseError, + applyEdits, + modify, + parse as parseJsonc, + printParseErrorCode, +} from "jsonc-parser" import { Instance } from "../project/instance" import { LSPServer } from "../lsp/server" import { BunProc } from "@/bun" @@ -20,6 +26,8 @@ import { Installation } from "@/installation" import { ConfigMarkdown } from "./markdown" import { existsSync } from "fs" import { Bus } from "@/bus" +import { GlobalBus } from "@/bus/global" +import { Event } from "../server/event" export namespace Config { const log = Log.create({ service: "config" }) @@ -1242,6 +1250,10 @@ export namespace Config { return state().then((x) => x.config) } + export async function getGlobal() { + return global() + } + export async function update(config: Info) { const filepath = path.join(Instance.directory, "config.json") const existing = await loadFile(filepath) @@ -1249,6 +1261,100 @@ export namespace Config { await Instance.dispose() } + function globalConfigFile() { + const candidates = ["opencode.jsonc", "opencode.json", "config.json"].map((file) => + path.join(Global.Path.config, file), + ) + for (const file of candidates) { + if (existsSync(file)) return file + } + return candidates[0] + } + + function isRecord(value: unknown): value is Record<string, unknown> { + return !!value && typeof value === "object" && !Array.isArray(value) + } + + function patchJsonc(input: string, patch: unknown, path: string[] = []): string { + if (!isRecord(patch)) { + const edits = modify(input, path, patch, { + formattingOptions: { + insertSpaces: true, + tabSize: 2, + }, + }) + return applyEdits(input, edits) + } + + return Object.entries(patch).reduce((result, [key, value]) => { + if (value === undefined) return result + return patchJsonc(result, value, [...path, key]) + }, input) + } + + function parseConfig(text: string, filepath: string): Info { + const errors: JsoncParseError[] = [] + const data = parseJsonc(text, errors, { allowTrailingComma: true }) + if (errors.length) { + const lines = text.split("\n") + const errorDetails = errors + .map((e) => { + const beforeOffset = text.substring(0, e.offset).split("\n") + const line = beforeOffset.length + const column = beforeOffset[beforeOffset.length - 1].length + 1 + const problemLine = lines[line - 1] + + const error = `${printParseErrorCode(e.error)} at line ${line}, column ${column}` + if (!problemLine) return error + + return `${error}\n Line ${line}: ${problemLine}\n${"".padStart(column + 9)}^` + }) + .join("\n") + + throw new JsonError({ + path: filepath, + message: `\n--- JSONC Input ---\n${text}\n--- Errors ---\n${errorDetails}\n--- End ---`, + }) + } + + const parsed = Info.safeParse(data) + if (parsed.success) return parsed.data + + throw new InvalidError({ + path: filepath, + issues: parsed.error.issues, + }) + } + + export async function updateGlobal(config: Info) { + const filepath = globalConfigFile() + const before = await Bun.file(filepath) + .text() + .catch((err) => { + if (err.code === "ENOENT") return "{}" + throw new JsonError({ path: filepath }, { cause: err }) + }) + + if (!filepath.endsWith(".jsonc")) { + const existing = parseConfig(before, filepath) + await Bun.write(filepath, JSON.stringify(mergeDeep(existing, config), null, 2)) + } else { + const next = patchJsonc(before, config) + parseConfig(next, filepath) + await Bun.write(filepath, next) + } + + global.reset() + await Instance.disposeAll() + GlobalBus.emit("event", { + directory: "global", + payload: { + type: Event.Disposed.type, + properties: {}, + }, + }) + } + export async function directories() { return state().then((x) => x.directories) } diff --git a/packages/opencode/src/file/watcher.ts b/packages/opencode/src/file/watcher.ts index 44f8a0a3a..c4a474777 100644 --- a/packages/opencode/src/file/watcher.ts +++ b/packages/opencode/src/file/watcher.ts @@ -32,11 +32,16 @@ export namespace FileWatcher { ), } - const watcher = lazy(() => { - const binding = require( - `@parcel/watcher-${process.platform}-${process.arch}${process.platform === "linux" ? `-${OPENCODE_LIBC || "glibc"}` : ""}`, - ) - return createWrapper(binding) as typeof import("@parcel/watcher") + const watcher = lazy((): typeof import("@parcel/watcher") | undefined => { + try { + const binding = require( + `@parcel/watcher-${process.platform}-${process.arch}${process.platform === "linux" ? `-${OPENCODE_LIBC || "glibc"}` : ""}`, + ) + return createWrapper(binding) as typeof import("@parcel/watcher") + } catch (error) { + log.error("failed to load watcher binding", { error }) + return + } }) const state = Instance.state( @@ -54,6 +59,10 @@ export namespace FileWatcher { return {} } log.info("watcher backend", { platform: process.platform, backend }) + + const w = watcher() + if (!w) return {} + const subscribe: ParcelWatcher.SubscribeCallback = (err, evts) => { if (err) return for (const evt of evts) { @@ -67,7 +76,7 @@ export namespace FileWatcher { const cfgIgnores = cfg.watcher?.ignore ?? [] if (Flag.OPENCODE_EXPERIMENTAL_FILEWATCHER) { - const pending = watcher().subscribe(Instance.directory, subscribe, { + const pending = w.subscribe(Instance.directory, subscribe, { ignore: [...FileIgnore.PATTERNS, ...cfgIgnores], backend, }) @@ -89,7 +98,7 @@ export namespace FileWatcher { if (vcsDir && !cfgIgnores.includes(".git") && !cfgIgnores.includes(vcsDir)) { const gitDirContents = await readdir(vcsDir).catch(() => []) const ignoreList = gitDirContents.filter((entry) => entry !== "HEAD") - const pending = watcher().subscribe(vcsDir, subscribe, { + const pending = w.subscribe(vcsDir, subscribe, { ignore: ignoreList, backend, }) diff --git a/packages/opencode/src/server/event.ts b/packages/opencode/src/server/event.ts new file mode 100644 index 000000000..49325b2bb --- /dev/null +++ b/packages/opencode/src/server/event.ts @@ -0,0 +1,7 @@ +import { BusEvent } from "@/bus/bus-event" +import z from "zod" + +export const Event = { + Connected: BusEvent.define("server.connected", z.object({})), + Disposed: BusEvent.define("global.disposed", z.object({})), +} diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts index 28dec7f40..15b7f829b 100644 --- a/packages/opencode/src/server/server.ts +++ b/packages/opencode/src/server/server.ts @@ -54,11 +54,6 @@ export namespace Server { return _url ?? new URL("http://localhost:4096") } - export const Event = { - Connected: BusEvent.define("server.connected", z.object({})), - Disposed: BusEvent.define("global.disposed", z.object({})), - } - const app = new Hono() export const App: () => Hono = lazy( () => diff --git a/packages/sdk/js/src/v2/gen/sdk.gen.ts b/packages/sdk/js/src/v2/gen/sdk.gen.ts index 706d0f9c2..139940ef6 100644 --- a/packages/sdk/js/src/v2/gen/sdk.gen.ts +++ b/packages/sdk/js/src/v2/gen/sdk.gen.ts @@ -32,6 +32,9 @@ import type { FindSymbolsResponses, FindTextResponses, FormatterStatusResponses, + GlobalConfigGetResponses, + GlobalConfigUpdateErrors, + GlobalConfigUpdateResponses, GlobalDisposeResponses, GlobalEventResponses, GlobalHealthResponses, @@ -249,6 +252,42 @@ export class Global extends HeyApiClient { ...options, }) } + + /** + * Get global configuration + * + * Retrieve the global OpenCode configuration settings and preferences. + */ + public configGet<ThrowOnError extends boolean = false>(options?: Options<never, ThrowOnError>) { + return (options?.client ?? this.client).get<GlobalConfigGetResponses, unknown, ThrowOnError>({ + url: "/global/config", + ...options, + }) + } + + /** + * Update global configuration + * + * Update global OpenCode configuration settings and preferences. + */ + public configUpdate<ThrowOnError extends boolean = false>( + parameters?: { + config?: Config2 + }, + options?: Options<never, ThrowOnError>, + ) { + const params = buildClientParams([parameters], [{ args: [{ key: "config", map: "body" }] }]) + return (options?.client ?? this.client).patch<GlobalConfigUpdateResponses, GlobalConfigUpdateErrors, ThrowOnError>({ + url: "/global/config", + ...options, + ...params, + headers: { + "Content-Type": "application/json", + ...options?.headers, + ...params.headers, + }, + }) + } } export class Project 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 b7e72fbad..736af471f 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -2189,6 +2189,47 @@ export type GlobalDisposeResponses = { export type GlobalDisposeResponse = GlobalDisposeResponses[keyof GlobalDisposeResponses] +export type GlobalConfigGetData = { + body?: never + path?: never + query?: never + url: "/global/config" +} + +export type GlobalConfigGetResponses = { + /** + * Global config + */ + 200: Config +} + +export type GlobalConfigGetResponse = GlobalConfigGetResponses[keyof GlobalConfigGetResponses] + +export type GlobalConfigUpdateData = { + body?: Config + path?: never + query?: never + url: "/global/config" +} + +export type GlobalConfigUpdateErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type GlobalConfigUpdateError = GlobalConfigUpdateErrors[keyof GlobalConfigUpdateErrors] + +export type GlobalConfigUpdateResponses = { + /** + * Successfully updated global config + */ + 200: Config +} + +export type GlobalConfigUpdateResponse = GlobalConfigUpdateResponses[keyof GlobalConfigUpdateResponses] + export type ProjectListData = { body?: never path?: never |
