Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
988 changes: 289 additions & 699 deletions bun.lock

Large diffs are not rendered by default.

24 changes: 24 additions & 0 deletions docs/docs/configure/permissions.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,30 @@ export ALTIMATE_CLI_PERMISSION='{"bash":"deny","write":"deny"}'
altimate
```

## Yolo Mode

Auto-approve all permission prompts without asking. Useful for CI/CD pipelines, benchmarks, scripted workflows, and trusted environments.

**CLI flag (works with any subcommand):**

```bash
altimate-code --yolo run "build all dbt models"
altimate-code --yolo # launches TUI in yolo mode
```

**Environment variable:**

```bash
export ALTIMATE_CLI_YOLO=true
altimate-code run "analyze my queries"
```

The fallback `OPENCODE_YOLO` env var is also supported. When both are set, `ALTIMATE_CLI_YOLO` takes precedence — setting it to `false` disables yolo even if `OPENCODE_YOLO=true`.

**Safety:** Explicit `deny` rules in your config are still enforced. Deny rules throw an error *before* any permission prompt is created, so yolo mode never sees them. If you've denied `rm *` or `DROP *`, those remain blocked even with `--yolo`.

When yolo mode is active in the TUI, a `△ YOLO` indicator appears in the footer status bar.

## Recommended Configurations

### Data Engineering (Default — Balanced)
Expand Down
6 changes: 0 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,20 +77,14 @@
"@types/pg": "8.18.0",
"@typescript/native-preview": "catalog:",
"husky": "9.1.7",
"mssql": "12.2.0",
"mysql2": "3.20.0",
"pg": "8.20.0",
"prettier": "3.6.2",
"semver": "^7.6.0",
"turbo": "2.8.13"
},
"dependencies": {
"@databricks/sql": "1.13.0",
"@google-cloud/bigquery": "8.1.1",
"@opencode-ai/plugin": "workspace:*",
"@opencode-ai/script": "workspace:*",
"@opencode-ai/sdk": "workspace:*",
"snowflake-sdk": "2.3.5",
"typescript": "catalog:"
},
"repository": {
Expand Down
4 changes: 0 additions & 4 deletions packages/opencode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@
"@typescript/native-preview": "catalog:",
"drizzle-kit": "1.0.0-beta.16-ea816b6",
"drizzle-orm": "1.0.0-beta.16-ea816b6",
"mssql": "12.2.0",
"mysql2": "3.20.0",
"pg": "8.20.0",
"typescript": "catalog:",
"vscode-languageserver-types": "3.17.5",
"why-is-node-running": "3.2.2",
Expand Down Expand Up @@ -126,7 +123,6 @@
"partial-json": "0.1.7",
"remeda": "catalog:",
"semver": "^7.6.3",
"snowflake-sdk": "2.3.5",
"solid-js": "catalog:",
"strip-ansi": "7.1.2",
"tree-sitter-bash": "0.25.0",
Expand Down
14 changes: 14 additions & 0 deletions packages/opencode/src/acp/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ import { z } from "zod"
import { LoadAPIKeyError } from "ai"
import type { AssistantMessage, Event, OpencodeClient, SessionMessageResponse, ToolPart } from "@opencode-ai/sdk/v2"
import { applyPatch } from "diff"
// altimate_change start - yolo mode
import { Flag } from "@/flag/flag"
// altimate_change end

type ModeOption = { id: string; name: string; description?: string }
type ModelOption = { modelId: string; name: string }
Expand Down Expand Up @@ -188,6 +191,17 @@ export namespace ACP {
const session = this.sessionManager.tryGet(permission.sessionID)
if (!session) return

// altimate_change start - yolo mode: auto-approve without asking ACP client
if (Flag.ALTIMATE_CLI_YOLO) {
await this.sdk.permission.reply({
requestID: permission.id,
reply: "once",
directory: session.cwd,
})
return
}
// altimate_change end

const prev = this.permissionQueues.get(permission.sessionID) ?? Promise.resolve()
const next = prev
.then(async () => {
Expand Down
33 changes: 24 additions & 9 deletions packages/opencode/src/cli/cmd/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -664,15 +664,30 @@ You are speaking to a non-technical business executive. Follow these rules stric
if (event.type === "permission.asked") {
const permission = event.properties
if (permission.sessionID !== sessionID) continue
UI.println(
UI.Style.TEXT_WARNING_BOLD + "!",
UI.Style.TEXT_NORMAL +
`permission requested: ${permission.permission} (${permission.patterns.join(", ")}); auto-rejecting`,
)
await sdk.permission.reply({
requestID: permission.id,
reply: "reject",
})
// altimate_change start - yolo mode: auto-approve instead of auto-reject
const yolo = args.yolo || Flag.ALTIMATE_CLI_YOLO
if (yolo) {
UI.println(
UI.Style.TEXT_WARNING_BOLD + "!",
UI.Style.TEXT_NORMAL +
`yolo mode: auto-approved ${permission.permission} (${permission.patterns.join(", ")})`,
)
await sdk.permission.reply({
requestID: permission.id,
reply: "once",
})
} else {
UI.println(
UI.Style.TEXT_WARNING_BOLD + "!",
UI.Style.TEXT_NORMAL +
`permission requested: ${permission.permission} (${permission.patterns.join(", ")}); auto-rejecting`,
)
await sdk.permission.reply({
requestID: permission.id,
reply: "reject",
})
}
// altimate_change end
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions packages/opencode/src/cli/cmd/tui/context/sync.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ import { useExit } from "./exit"
import { useArgs } from "./args"
import { batch, onMount } from "solid-js"
import { Log } from "@/util/log"
// altimate_change start - yolo mode
import { Flag } from "@/flag/flag"
// altimate_change end
import type { Path } from "@opencode-ai/sdk"
import type { Workspace } from "@opencode-ai/sdk/v2"

Expand Down Expand Up @@ -136,6 +139,22 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({

case "permission.asked": {
const request = event.properties
// altimate_change start - yolo mode: auto-approve without showing prompt
if (Flag.ALTIMATE_CLI_YOLO) {
sdk.client.permission
.reply({
requestID: request.id,
reply: "once",
})
.catch((e) => {
Log.Default.error("yolo mode auto-approve failed", {
error: e instanceof Error ? e.message : String(e),
requestID: request.id,
})
})
break
}
// altimate_change end
const requests = store.permission[request.sessionID]
if (!requests) {
setStore("permission", request.sessionID, [request])
Expand Down
10 changes: 10 additions & 0 deletions packages/opencode/src/cli/cmd/tui/routes/session/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { useDirectory } from "../../context/directory"
import { useConnected } from "../../component/dialog-model"
import { createStore } from "solid-js/store"
import { useRoute } from "../../context/route"
// altimate_change start - yolo mode visual indicator
import { Flag } from "@/flag/flag"
// altimate_change end

export function Footer() {
const { theme } = useTheme()
Expand Down Expand Up @@ -60,6 +63,13 @@ export function Footer() {
</text>
</Match>
<Match when={connected()}>
{/* altimate_change start - yolo mode visual indicator */}
<Show when={Flag.ALTIMATE_CLI_YOLO}>
<text fg={theme.warning}>
<span style={{ fg: theme.warning }}>△</span> YOLO
</text>
</Show>
{/* altimate_change end */}
<Show when={permissions().length > 0}>
<text fg={theme.warning}>
<span style={{ fg: theme.warning }}>△</span> {permissions().length} Permission
Expand Down
22 changes: 22 additions & 0 deletions packages/opencode/src/flag/flag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ export namespace Flag {
// altimate_change start - opt-in for session-end auto-extraction
export const ALTIMATE_MEMORY_AUTO_EXTRACT = altTruthy("ALTIMATE_MEMORY_AUTO_EXTRACT", "OPENCODE_MEMORY_AUTO_EXTRACT")
// altimate_change end
// altimate_change start - yolo mode: auto-approve all permission prompts
// Declared here, defined via dynamic getter below (must evaluate at access time
// because --yolo CLI flag sets the env var in middleware after module load)
export declare const ALTIMATE_CLI_YOLO: boolean
// altimate_change end
Comment on lines +39 to +43

This comment was marked as outdated.

// altimate_change start - opt-out for AI Teammate training system
export const ALTIMATE_DISABLE_TRAINING = altTruthy("ALTIMATE_DISABLE_TRAINING", "OPENCODE_DISABLE_TRAINING")
// altimate_change end
Expand Down Expand Up @@ -139,6 +144,23 @@ Object.defineProperty(Flag, "OPENCODE_CLIENT", {
configurable: false,
})

// altimate_change start - yolo mode: dynamic getter (set at runtime via --yolo flag)
// ALTIMATE_CLI_YOLO is authoritative when defined; only falls back to OPENCODE_YOLO when undefined
Object.defineProperty(Flag, "ALTIMATE_CLI_YOLO", {
get() {
const alt = process.env["ALTIMATE_CLI_YOLO"]
if (alt !== undefined) {
const v = alt.toLowerCase()
return v === "true" || v === "1"
}
const oc = process.env["OPENCODE_YOLO"]?.toLowerCase()
return oc === "true" || oc === "1"
},
enumerable: true,
configurable: false,
})
// altimate_change end

// altimate_change start - ALTIMATE_CLI_CLIENT with OPENCODE_CLIENT fallback
Object.defineProperty(Flag, "ALTIMATE_CLI_CLIENT", {
get() {
Expand Down
13 changes: 13 additions & 0 deletions packages/opencode/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ let cli = yargs(hideBin(process.argv))
type: "string",
choices: ["DEBUG", "INFO", "WARN", "ERROR"],
})
// altimate_change start - yolo mode as global flag
.option("yolo", {
describe: "auto-approve all permission prompts (explicit deny rules still enforced)",
type: "boolean",
default: false,
})
// altimate_change end
.middleware(async (opts) => {
await Log.init({
print: process.argv.includes("--print-logs"),
Expand All @@ -96,6 +103,12 @@ let cli = yargs(hideBin(process.argv))
process.env.DATAPILOT = "1"
// altimate_change end

// altimate_change start - propagate --yolo flag to env var so Flag.ALTIMATE_CLI_YOLO picks it up
if ("yolo" in opts && opts.yolo) {
process.env.ALTIMATE_CLI_YOLO = "true"
}
// altimate_change end

// altimate_change start - telemetry init
// Initialize telemetry early so events from MCP, engine, auth are captured.
// init() is idempotent — safe to call again later in session prompt.
Expand Down
Loading
Loading