mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-28 14:11:49 -04:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 641e3c4fa5 |
@@ -4,12 +4,13 @@ import fs from "fs/promises"
|
||||
import path from "path"
|
||||
import { Effect } from "effect"
|
||||
import { Git } from "@opencode-ai/core/git"
|
||||
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||
import { AbsolutePath } from "@opencode-ai/core/schema"
|
||||
import { branch, commit, gitRemote } from "./fixture/git"
|
||||
import { tmpdir } from "./fixture/tmpdir"
|
||||
import { testEffect } from "./lib/effect"
|
||||
|
||||
const it = testEffect(Git.defaultLayer)
|
||||
const it = testEffect(LayerNode.buildLayer(Git.node))
|
||||
|
||||
describe("Git", () => {
|
||||
it.live("clones a remote and reads checkout metadata", () =>
|
||||
|
||||
@@ -228,8 +228,7 @@ export const RunCommand = effectCmd({
|
||||
describe: "run in direct interactive split-footer mode",
|
||||
default: false,
|
||||
})
|
||||
.option("yolo", {
|
||||
alias: ["dangerously-skip-permissions"],
|
||||
.option("dangerously-skip-permissions", {
|
||||
type: "boolean",
|
||||
describe: "auto-approve permissions that are not explicitly denied (dangerous!)",
|
||||
default: false,
|
||||
@@ -733,7 +732,7 @@ export const RunCommand = effectCmd({
|
||||
const permission = event.properties
|
||||
if (permission.sessionID !== sessionID) continue
|
||||
|
||||
if (args.yolo) {
|
||||
if (args["dangerously-skip-permissions"]) {
|
||||
await client.permission.reply({
|
||||
requestID: permission.id,
|
||||
reply: "once",
|
||||
|
||||
@@ -103,12 +103,6 @@ export const TuiThreadCommand = cmd({
|
||||
.option("agent", {
|
||||
type: "string",
|
||||
describe: "agent to use",
|
||||
})
|
||||
.option("yolo", {
|
||||
alias: ["dangerously-skip-permissions"],
|
||||
type: "boolean",
|
||||
describe: "auto-approve permissions that are not explicitly denied (dangerous!)",
|
||||
default: false,
|
||||
}),
|
||||
handler: async (args) => {
|
||||
const unguard = win32InstallCtrlCGuard()
|
||||
|
||||
@@ -15,10 +15,6 @@ const enabledByExperimental = (name: string) =>
|
||||
|
||||
export class Service extends ConfigService.Service<Service>()("@opencode/RuntimeFlags", {
|
||||
autoShare: bool("OPENCODE_AUTO_SHARE"),
|
||||
yolo: Config.all({
|
||||
primary: bool("OPENCODE_YOLO"),
|
||||
legacy: bool("OPENCODE_DANGEROUSLY_SKIP_PERMISSIONS"),
|
||||
}).pipe(Config.map((flags) => flags.primary || flags.legacy)),
|
||||
pure: bool("OPENCODE_PURE"),
|
||||
disableDefaultPlugins: bool("OPENCODE_DISABLE_DEFAULT_PLUGINS"),
|
||||
disableEmbeddedWebUi: bool("OPENCODE_DISABLE_EMBEDDED_WEB_UI"),
|
||||
|
||||
@@ -66,7 +66,6 @@ const cli = yargs(args)
|
||||
.middleware(async (opts) => {
|
||||
if (opts.printLogs) process.env.OPENCODE_PRINT_LOGS = "1"
|
||||
if (opts.logLevel) process.env.OPENCODE_LOG_LEVEL = opts.logLevel
|
||||
if (opts.yolo) process.env.OPENCODE_YOLO = "1"
|
||||
if (opts.pure) {
|
||||
process.env.OPENCODE_PURE = "1"
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import os from "os"
|
||||
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
||||
import { EventV2Bridge } from "@/event-v2-bridge"
|
||||
import { EventV2 } from "@opencode-ai/core/event"
|
||||
import { RuntimeFlags } from "@/effect/runtime-flags"
|
||||
|
||||
export const Event = {
|
||||
Asked: EventV2.define({ type: "permission.asked", schema: PermissionV1.Request.fields }),
|
||||
@@ -55,7 +54,6 @@ export const layer = Layer.effect(
|
||||
Service,
|
||||
Effect.gen(function* () {
|
||||
const events = yield* EventV2Bridge.Service
|
||||
const flags = yield* RuntimeFlags.Service
|
||||
const state = yield* InstanceState.make<State>(
|
||||
Effect.fn("Permission.state")(function* (ctx) {
|
||||
void ctx
|
||||
@@ -91,7 +89,6 @@ export const layer = Layer.effect(
|
||||
})
|
||||
}
|
||||
if (rule.action === "allow") continue
|
||||
if (flags.yolo) continue
|
||||
needsAsk = true
|
||||
}
|
||||
|
||||
@@ -226,11 +223,8 @@ export function disabled(tools: string[], ruleset: PermissionV1.Ruleset): Set<st
|
||||
)
|
||||
}
|
||||
|
||||
export const defaultLayer = layer.pipe(
|
||||
Layer.provide(EventV2Bridge.defaultLayer),
|
||||
Layer.provide(RuntimeFlags.defaultLayer),
|
||||
)
|
||||
export const defaultLayer = layer.pipe(Layer.provide(EventV2Bridge.defaultLayer))
|
||||
|
||||
export const node = LayerNode.make(layer, [EventV2Bridge.node, RuntimeFlags.node])
|
||||
export const node = LayerNode.make(layer, [EventV2Bridge.node])
|
||||
|
||||
export * as Permission from "."
|
||||
|
||||
@@ -72,50 +72,47 @@ Positionals:
|
||||
message message to send [array] [default: []]
|
||||
|
||||
Options:
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level
|
||||
[string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--command the command to run, use message for args [string]
|
||||
-c, --continue continue the last session [boolean]
|
||||
-s, --session session id to continue [string]
|
||||
--fork fork the session before continuing (requires
|
||||
--continue or --session) [boolean]
|
||||
--share share the session [boolean]
|
||||
-m, --model model to use in the format of provider/model [string]
|
||||
--agent agent to use [string]
|
||||
--format format: default (formatted) or json (raw JSON events)
|
||||
-h, --help show help [boolean]
|
||||
-v, --version show version number [boolean]
|
||||
--print-logs print logs to stderr [boolean]
|
||||
--log-level log level [string] [choices: "DEBUG", "INFO", "WARN", "ERROR"]
|
||||
--pure run without external plugins [boolean]
|
||||
--command the command to run, use message for args [string]
|
||||
-c, --continue continue the last session [boolean]
|
||||
-s, --session session id to continue [string]
|
||||
--fork fork the session before continuing (requires --continue or
|
||||
--session) [boolean]
|
||||
--share share the session [boolean]
|
||||
-m, --model model to use in the format of provider/model [string]
|
||||
--agent agent to use [string]
|
||||
--format format: default (formatted) or json (raw JSON events)
|
||||
[string] [choices: "default", "json"] [default: "default"]
|
||||
-f, --file file(s) to attach to message [array]
|
||||
--title title for the session (uses truncated prompt if no
|
||||
value provided) [string]
|
||||
--attach attach to a running opencode server (e.g.,
|
||||
http://localhost:4096) [string]
|
||||
-p, --password basic auth password (defaults to
|
||||
OPENCODE_SERVER_PASSWORD) [string]
|
||||
-u, --username basic auth username (defaults to
|
||||
OPENCODE_SERVER_USERNAME or 'opencode') [string]
|
||||
--dir directory to run in, path on remote server if
|
||||
attaching [string]
|
||||
--port port for the local server (defaults to random port if
|
||||
no value provided) [number]
|
||||
--variant model variant (provider-specific reasoning effort,
|
||||
e.g., high, max, minimal) [string]
|
||||
--thinking show thinking blocks [boolean]
|
||||
--replay replay interactive session history on resume and after
|
||||
resize (use --no-replay to disable)
|
||||
[boolean] [default: true]
|
||||
--replay-limit cap visible interactive replay to the newest N
|
||||
messages [number]
|
||||
-i, --interactive run in direct interactive split-footer mode
|
||||
-f, --file file(s) to attach to message [array]
|
||||
--title title for the session (uses truncated prompt if no value
|
||||
provided) [string]
|
||||
--attach attach to a running opencode server (e.g.,
|
||||
http://localhost:4096) [string]
|
||||
-p, --password basic auth password (defaults to OPENCODE_SERVER_PASSWORD)
|
||||
[string]
|
||||
-u, --username basic auth username (defaults to OPENCODE_SERVER_USERNAME or
|
||||
'opencode') [string]
|
||||
--dir directory to run in, path on remote server if attaching
|
||||
[string]
|
||||
--port port for the local server (defaults to random port if no value
|
||||
provided) [number]
|
||||
--variant model variant (provider-specific reasoning effort, e.g., high,
|
||||
max, minimal) [string]
|
||||
--thinking show thinking blocks [boolean]
|
||||
--replay replay interactive session history on resume and after resize
|
||||
(use --no-replay to disable) [boolean] [default: true]
|
||||
--replay-limit cap visible interactive replay to the newest N messages
|
||||
[number]
|
||||
-i, --interactive run in direct interactive split-footer mode
|
||||
[boolean] [default: false]
|
||||
--yolo, --dangerously-skip-permissions auto-approve permissions that are not explicitly
|
||||
denied (dangerous!) [boolean] [default: false]
|
||||
--demo enable direct interactive demo slash commands; pass
|
||||
one as the message to run it immediately
|
||||
[boolean] [default: false]"
|
||||
--dangerously-skip-permissions auto-approve permissions that are not explicitly denied
|
||||
(dangerous!) [boolean] [default: false]
|
||||
--demo enable direct interactive demo slash commands; pass one as the
|
||||
message to run it immediately [boolean] [default: false]"
|
||||
`;
|
||||
|
||||
exports[`opencode CLI help-text snapshots every documented command emits stable help text: opencode debug --help 1`] = `
|
||||
|
||||
@@ -102,8 +102,6 @@ describe("opencode CLI help-text snapshots", () => {
|
||||
const topLevel = yield* opencode.spawn(["--help"], { env: SNAPSHOT_ENV })
|
||||
expect(topLevel.exitCode).toBe(0)
|
||||
expect(topLevel.stderr.endsWith(EOL)).toBe(true)
|
||||
expect(topLevel.stderr).toContain("--yolo")
|
||||
expect(topLevel.stderr).toContain("--dangerously-skip-permissions")
|
||||
|
||||
const argvs: Array<readonly string[]> = [...TOP_LEVEL.map((c) => [c] as const), ...SUBCOMMANDS]
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ describe("RuntimeFlags", () => {
|
||||
const flags = yield* readFlags.pipe(Effect.provide(fromConfig({})))
|
||||
|
||||
expect(flags.autoShare).toBe(false)
|
||||
expect(flags.yolo).toBe(false)
|
||||
}),
|
||||
)
|
||||
|
||||
@@ -24,7 +23,6 @@ describe("RuntimeFlags", () => {
|
||||
Effect.provide(
|
||||
fromConfig({
|
||||
OPENCODE_PURE: "true",
|
||||
OPENCODE_YOLO: "true",
|
||||
OPENCODE_DISABLE_DEFAULT_PLUGINS: "true",
|
||||
OPENCODE_AUTO_SHARE: "true",
|
||||
OPENCODE_DISABLE_EMBEDDED_WEB_UI: "true",
|
||||
@@ -41,7 +39,6 @@ describe("RuntimeFlags", () => {
|
||||
)
|
||||
|
||||
expect(flags.pure).toBe(true)
|
||||
expect(flags.yolo).toBe(true)
|
||||
expect(flags.autoShare).toBe(true)
|
||||
expect(flags.disableDefaultPlugins).toBe(true)
|
||||
expect(flags.disableEmbeddedWebUi).toBe(true)
|
||||
@@ -81,14 +78,6 @@ describe("RuntimeFlags", () => {
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("supports the legacy dangerous permission environment variable", () =>
|
||||
Effect.gen(function* () {
|
||||
const flags = yield* readFlags.pipe(Effect.provide(fromConfig({ OPENCODE_DANGEROUSLY_SKIP_PERMISSIONS: "true" })))
|
||||
|
||||
expect(flags.yolo).toBe(true)
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("enables native LLM via dedicated flag only", () =>
|
||||
Effect.gen(function* () {
|
||||
const explicit = yield* readFlags.pipe(Effect.provide(fromConfig({ OPENCODE_EXPERIMENTAL_NATIVE_LLM: "true" })))
|
||||
|
||||
@@ -11,21 +11,16 @@ import { InstanceStore } from "../../src/project/instance-store"
|
||||
import { TestInstance, tmpdirScoped } from "../fixture/fixture"
|
||||
import { testEffect } from "../lib/effect"
|
||||
import { MessageID, SessionID } from "../../src/session/schema"
|
||||
import { RuntimeFlags } from "../../src/effect/runtime-flags"
|
||||
|
||||
const events = EventV2Bridge.defaultLayer
|
||||
const noopBootstrap = Layer.succeed(InstanceBootstrap.Service, InstanceBootstrap.Service.of({ run: Effect.void }))
|
||||
const makeEnv = (flags: Partial<RuntimeFlags.Info> = {}) => {
|
||||
const runtimeFlags = RuntimeFlags.layer(flags)
|
||||
return Layer.mergeAll(
|
||||
Permission.layer.pipe(Layer.provide(Database.defaultLayer), Layer.provide(events), Layer.provide(runtimeFlags)),
|
||||
events,
|
||||
CrossSpawnSpawner.defaultLayer,
|
||||
InstanceStore.defaultLayer.pipe(Layer.provide(noopBootstrap)),
|
||||
)
|
||||
}
|
||||
const it = testEffect(makeEnv())
|
||||
const yoloIt = testEffect(makeEnv({ yolo: true }))
|
||||
const env = Layer.mergeAll(
|
||||
Permission.layer.pipe(Layer.provide(Database.defaultLayer), Layer.provide(events)),
|
||||
events,
|
||||
CrossSpawnSpawner.defaultLayer,
|
||||
InstanceStore.defaultLayer.pipe(Layer.provide(noopBootstrap)),
|
||||
)
|
||||
const it = testEffect(env)
|
||||
|
||||
const rejectAll = (message?: string) =>
|
||||
Effect.gen(function* () {
|
||||
@@ -618,39 +613,6 @@ it.instance(
|
||||
{ git: true },
|
||||
)
|
||||
|
||||
yoloIt.instance(
|
||||
"ask - resolves ask rules when yolo mode is enabled",
|
||||
() =>
|
||||
ask({
|
||||
sessionID: SessionID.make("session_test"),
|
||||
permission: "bash",
|
||||
patterns: ["ls"],
|
||||
metadata: {},
|
||||
always: [],
|
||||
ruleset: [{ permission: "bash", pattern: "*", action: "ask" }],
|
||||
}),
|
||||
{ git: true },
|
||||
)
|
||||
|
||||
yoloIt.instance(
|
||||
"ask - preserves deny rules when yolo mode is enabled",
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
const err = yield* fail(
|
||||
ask({
|
||||
sessionID: SessionID.make("session_test"),
|
||||
permission: "bash",
|
||||
patterns: ["rm -rf /"],
|
||||
metadata: {},
|
||||
always: [],
|
||||
ruleset: [{ permission: "bash", pattern: "*", action: "deny" }],
|
||||
}),
|
||||
)
|
||||
expect(err).toBeInstanceOf(PermissionV1.DeniedError)
|
||||
}),
|
||||
{ git: true },
|
||||
)
|
||||
|
||||
it.instance(
|
||||
"ask - adds request to pending list",
|
||||
() =>
|
||||
|
||||
@@ -1838,7 +1838,6 @@ function InlineTool(props: {
|
||||
pending: string
|
||||
failure?: string
|
||||
spinner?: boolean
|
||||
separate?: boolean
|
||||
children: JSX.Element
|
||||
part: ToolPart
|
||||
onClick?: () => void
|
||||
@@ -1891,7 +1890,6 @@ function InlineTool(props: {
|
||||
pending={props.pending}
|
||||
failure={props.failure}
|
||||
spinner={props.spinner}
|
||||
separate={props.separate}
|
||||
onMouseOver={() => clickable() && setHover(true)}
|
||||
onMouseOut={() => setHover(false)}
|
||||
onMouseUp={() => {
|
||||
@@ -1921,7 +1919,6 @@ export function InlineToolRow(props: {
|
||||
pending: string
|
||||
failure?: string
|
||||
spinner?: boolean
|
||||
separate?: boolean
|
||||
children: JSX.Element
|
||||
onMouseOver?: () => void
|
||||
onMouseOut?: () => void
|
||||
@@ -1934,12 +1931,8 @@ export function InlineToolRow(props: {
|
||||
onMouseOut={props.onMouseOut}
|
||||
onMouseUp={props.onMouseUp}
|
||||
ref={(el: BoxRenderable) => {
|
||||
if (props.separate) alwaysSeparate.add(el)
|
||||
setPreLayoutSiblingMargin(el, (previous) => {
|
||||
return props.separate ||
|
||||
(previous instanceof BoxRenderable && (previous.height > 1 || alwaysSeparate.has(previous)))
|
||||
? 1
|
||||
: 0
|
||||
return previous instanceof BoxRenderable && (previous.height > 1 || alwaysSeparate.has(previous)) ? 1 : 0
|
||||
})
|
||||
}}
|
||||
>
|
||||
@@ -2288,7 +2281,6 @@ function Task(props: ToolProps) {
|
||||
return (
|
||||
<InlineTool
|
||||
icon={props.part.state.status === "completed" ? "✓" : "│"}
|
||||
separate={true}
|
||||
color={retry() ? theme.error : undefined}
|
||||
spinner={isRunning()}
|
||||
complete={stringValue(props.input.description)}
|
||||
|
||||
@@ -60,19 +60,16 @@ exports[`TUI inline tool wrapping keeps separation after a padded user message 1
|
||||
|
||||
exports[`TUI inline tool wrapping separates after a multi-line task row 1`] = `
|
||||
" ✱ Grep "Task" (2 matches)
|
||||
|
||||
⠙ Explore Task — Inspect active task spacing
|
||||
|
||||
✓ General Task — Confirm completed task spacing
|
||||
↳ 1 toolcall · 501ms
|
||||
|
||||
→ Read src/cli/cmd/tui/routes/session/index.tsx"
|
||||
`;
|
||||
|
||||
exports[`TUI inline tool wrapping separates a task row from a preceding inline detail 1`] = `
|
||||
exports[`TUI inline tool wrapping does not treat task rows differently from other inline rows 1`] = `
|
||||
" → Read src/cli/cmd/tui/routes/session/index.tsx
|
||||
↳ Loaded src/cli/cmd/tui/routes/session/tools.tsx
|
||||
|
||||
✓ Explore Task — Inspect active task spacing
|
||||
↳ 1 toolcall · 501ms"
|
||||
`;
|
||||
|
||||
@@ -112,10 +112,10 @@ function TaskRowsFixture() {
|
||||
<InlineToolRow icon="✱" complete={true} pending="">
|
||||
Grep "Task" (2 matches)
|
||||
</InlineToolRow>
|
||||
<InlineToolRow icon="⠙" complete={true} pending="" separate={true}>
|
||||
<InlineToolRow icon="⠙" complete={true} pending="">
|
||||
Explore Task — Inspect active task spacing
|
||||
</InlineToolRow>
|
||||
<InlineToolRow icon="✓" complete={true} pending="" separate={true}>
|
||||
<InlineToolRow icon="✓" complete={true} pending="">
|
||||
{"General Task — Confirm completed task spacing\n↳ 1 toolcall · 501ms"}
|
||||
</InlineToolRow>
|
||||
<InlineToolRow icon="→" complete={true} pending="">
|
||||
@@ -134,7 +134,7 @@ function LoadedReadBeforeTaskFixture() {
|
||||
<box paddingLeft={3}>
|
||||
<text paddingLeft={3}>↳ Loaded src/cli/cmd/tui/routes/session/tools.tsx</text>
|
||||
</box>
|
||||
<InlineToolRow icon="✓" complete={true} pending="" separate={true}>
|
||||
<InlineToolRow icon="✓" complete={true} pending="">
|
||||
{"Explore Task — Inspect active task spacing\n↳ 1 toolcall · 501ms"}
|
||||
</InlineToolRow>
|
||||
</box>
|
||||
@@ -312,7 +312,7 @@ describe("TUI inline tool wrapping", () => {
|
||||
expect(await renderFrame(() => <TaskRowsFixture />, { width: 72, height: 10 })).toMatchSnapshot()
|
||||
})
|
||||
|
||||
test("separates a task row from a preceding inline detail", async () => {
|
||||
test("does not treat task rows differently from other inline rows", async () => {
|
||||
expect(await renderFrame(() => <LoadedReadBeforeTaskFixture />, { width: 72, height: 8 })).toMatchSnapshot()
|
||||
})
|
||||
|
||||
|
||||
@@ -29,21 +29,19 @@ opencode [project]
|
||||
|
||||
#### Flags
|
||||
|
||||
| Flag | Short | Description |
|
||||
| ------------------------------------------------------------ | ----- | ----------------------------------------------------------------------- |
|
||||
| <nobr><code>{"--continue"}</code></nobr> | `-c` | Continue the last session |
|
||||
| <nobr><code>{"--session"}</code></nobr> | `-s` | Session ID to continue |
|
||||
| <nobr><code>{"--fork"}</code></nobr> | | Fork the session when continuing (use with `--continue` or `--session`) |
|
||||
| <nobr><code>{"--prompt"}</code></nobr> | | Prompt to use |
|
||||
| <nobr><code>{"--model"}</code></nobr> | `-m` | Model to use in the form of provider/model |
|
||||
| <nobr><code>{"--agent"}</code></nobr> | | Agent to use |
|
||||
| <nobr><code>{"--port"}</code></nobr> | | Port to listen on |
|
||||
| <nobr><code>{"--hostname"}</code></nobr> | | Hostname to listen on |
|
||||
| <nobr><code>{"--mdns"}</code></nobr> | | Enable mDNS discovery |
|
||||
| <nobr><code>{"--mdns-domain"}</code></nobr> | | Custom mDNS domain name |
|
||||
| <nobr><code>{"--cors"}</code></nobr> | | Additional browser origin(s) to allow CORS |
|
||||
| <nobr><code>{"--yolo"}</code></nobr> | | Auto-approve permissions not explicitly denied |
|
||||
| <nobr><code>{"--dangerously-skip-permissions"}</code></nobr> | | Legacy alias for `--yolo` |
|
||||
| Flag | Short | Description |
|
||||
| ------------------------------------------- | ----- | ----------------------------------------------------------------------- |
|
||||
| <nobr><code>{"--continue"}</code></nobr> | `-c` | Continue the last session |
|
||||
| <nobr><code>{"--session"}</code></nobr> | `-s` | Session ID to continue |
|
||||
| <nobr><code>{"--fork"}</code></nobr> | | Fork the session when continuing (use with `--continue` or `--session`) |
|
||||
| <nobr><code>{"--prompt"}</code></nobr> | | Prompt to use |
|
||||
| <nobr><code>{"--model"}</code></nobr> | `-m` | Model to use in the form of provider/model |
|
||||
| <nobr><code>{"--agent"}</code></nobr> | | Agent to use |
|
||||
| <nobr><code>{"--port"}</code></nobr> | | Port to listen on |
|
||||
| <nobr><code>{"--hostname"}</code></nobr> | | Hostname to listen on |
|
||||
| <nobr><code>{"--mdns"}</code></nobr> | | Enable mDNS discovery |
|
||||
| <nobr><code>{"--mdns-domain"}</code></nobr> | | Custom mDNS domain name |
|
||||
| <nobr><code>{"--cors"}</code></nobr> | | Additional browser origin(s) to allow CORS |
|
||||
|
||||
---
|
||||
|
||||
@@ -382,8 +380,7 @@ opencode run --attach http://localhost:4096 "Explain async/await in JavaScript"
|
||||
| <nobr><code>{"--port"}</code></nobr> | | Port for the local server (defaults to random port) |
|
||||
| <nobr><code>{"--variant"}</code></nobr> | | Model variant (provider-specific reasoning effort) |
|
||||
| <nobr><code>{"--thinking"}</code></nobr> | | Show thinking blocks |
|
||||
| <nobr><code>{"--yolo"}</code></nobr> | | Auto-approve permissions that are not explicitly denied |
|
||||
| <nobr><code>{"--dangerously-skip-permissions"}</code></nobr> | | Legacy alias for `--yolo` |
|
||||
| <nobr><code>{"--dangerously-skip-permissions"}</code></nobr> | | Auto-approve permissions that are not explicitly denied (dangerous!) |
|
||||
|
||||
---
|
||||
|
||||
@@ -679,35 +676,33 @@ The opencode CLI takes the following global flags.
|
||||
|
||||
OpenCode can be configured using environment variables.
|
||||
|
||||
| Variable | Type | Description |
|
||||
| --------------------------------------- | ------- | ------------------------------------------------- |
|
||||
| `OPENCODE_AUTO_SHARE` | boolean | Automatically share sessions |
|
||||
| `OPENCODE_GIT_BASH_PATH` | string | Path to Git Bash executable on Windows |
|
||||
| `OPENCODE_CONFIG` | string | Path to config file |
|
||||
| `OPENCODE_TUI_CONFIG` | string | Path to TUI config file |
|
||||
| `OPENCODE_CONFIG_DIR` | string | Path to config directory |
|
||||
| `OPENCODE_CONFIG_CONTENT` | string | Inline json config content |
|
||||
| `OPENCODE_DISABLE_AUTOUPDATE` | boolean | Disable automatic update checks |
|
||||
| `OPENCODE_DISABLE_PRUNE` | boolean | Disable pruning of old data |
|
||||
| `OPENCODE_DISABLE_TERMINAL_TITLE` | boolean | Disable automatic terminal title updates |
|
||||
| `OPENCODE_PERMISSION` | string | Inlined json permissions config |
|
||||
| `OPENCODE_YOLO` | boolean | Auto-approve permissions not explicitly denied |
|
||||
| `OPENCODE_DANGEROUSLY_SKIP_PERMISSIONS` | boolean | Legacy alias for `OPENCODE_YOLO` |
|
||||
| `OPENCODE_DISABLE_DEFAULT_PLUGINS` | boolean | Disable default plugins |
|
||||
| `OPENCODE_DISABLE_LSP_DOWNLOAD` | boolean | Disable automatic LSP server downloads |
|
||||
| `OPENCODE_ENABLE_EXPERIMENTAL_MODELS` | boolean | Enable experimental models |
|
||||
| `OPENCODE_DISABLE_AUTOCOMPACT` | boolean | Disable automatic context compaction |
|
||||
| `OPENCODE_DISABLE_CLAUDE_CODE` | boolean | Disable reading from `.claude` (prompt + skills) |
|
||||
| `OPENCODE_DISABLE_CLAUDE_CODE_PROMPT` | boolean | Disable reading `~/.claude/CLAUDE.md` |
|
||||
| `OPENCODE_DISABLE_CLAUDE_CODE_SKILLS` | boolean | Disable loading `.claude/skills` |
|
||||
| `OPENCODE_DISABLE_MODELS_FETCH` | boolean | Disable fetching models from remote sources |
|
||||
| `OPENCODE_DISABLE_MOUSE` | boolean | Disable mouse capture in the TUI |
|
||||
| `OPENCODE_FAKE_VCS` | string | Fake VCS provider for testing purposes |
|
||||
| `OPENCODE_CLIENT` | string | Client identifier (defaults to `cli`) |
|
||||
| `OPENCODE_ENABLE_EXA` | boolean | Enable Exa web search tools |
|
||||
| `OPENCODE_SERVER_PASSWORD` | string | Enable basic auth for `serve`/`web` |
|
||||
| `OPENCODE_SERVER_USERNAME` | string | Override basic auth username (default `opencode`) |
|
||||
| `OPENCODE_MODELS_URL` | string | Custom URL for fetching models configuration |
|
||||
| Variable | Type | Description |
|
||||
| ------------------------------------- | ------- | ------------------------------------------------- |
|
||||
| `OPENCODE_AUTO_SHARE` | boolean | Automatically share sessions |
|
||||
| `OPENCODE_GIT_BASH_PATH` | string | Path to Git Bash executable on Windows |
|
||||
| `OPENCODE_CONFIG` | string | Path to config file |
|
||||
| `OPENCODE_TUI_CONFIG` | string | Path to TUI config file |
|
||||
| `OPENCODE_CONFIG_DIR` | string | Path to config directory |
|
||||
| `OPENCODE_CONFIG_CONTENT` | string | Inline json config content |
|
||||
| `OPENCODE_DISABLE_AUTOUPDATE` | boolean | Disable automatic update checks |
|
||||
| `OPENCODE_DISABLE_PRUNE` | boolean | Disable pruning of old data |
|
||||
| `OPENCODE_DISABLE_TERMINAL_TITLE` | boolean | Disable automatic terminal title updates |
|
||||
| `OPENCODE_PERMISSION` | string | Inlined json permissions config |
|
||||
| `OPENCODE_DISABLE_DEFAULT_PLUGINS` | boolean | Disable default plugins |
|
||||
| `OPENCODE_DISABLE_LSP_DOWNLOAD` | boolean | Disable automatic LSP server downloads |
|
||||
| `OPENCODE_ENABLE_EXPERIMENTAL_MODELS` | boolean | Enable experimental models |
|
||||
| `OPENCODE_DISABLE_AUTOCOMPACT` | boolean | Disable automatic context compaction |
|
||||
| `OPENCODE_DISABLE_CLAUDE_CODE` | boolean | Disable reading from `.claude` (prompt + skills) |
|
||||
| `OPENCODE_DISABLE_CLAUDE_CODE_PROMPT` | boolean | Disable reading `~/.claude/CLAUDE.md` |
|
||||
| `OPENCODE_DISABLE_CLAUDE_CODE_SKILLS` | boolean | Disable loading `.claude/skills` |
|
||||
| `OPENCODE_DISABLE_MODELS_FETCH` | boolean | Disable fetching models from remote sources |
|
||||
| `OPENCODE_DISABLE_MOUSE` | boolean | Disable mouse capture in the TUI |
|
||||
| `OPENCODE_FAKE_VCS` | string | Fake VCS provider for testing purposes |
|
||||
| `OPENCODE_CLIENT` | string | Client identifier (defaults to `cli`) |
|
||||
| `OPENCODE_ENABLE_EXA` | boolean | Enable Exa web search tools |
|
||||
| `OPENCODE_SERVER_PASSWORD` | string | Enable basic auth for `serve`/`web` |
|
||||
| `OPENCODE_SERVER_USERNAME` | string | Override basic auth username (default `opencode`) |
|
||||
| `OPENCODE_MODELS_URL` | string | Custom URL for fetching models configuration |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user