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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/docs/assets/images/upgrade-no-indicator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/docs/configure/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Configuration is loaded from multiple sources, with later sources overriding ear
| `default_agent` | `string` | Default agent to use on startup |
| `logLevel` | `string` | Log level: `DEBUG`, `INFO`, `WARN`, `ERROR` |
| `share` | `string` | Session sharing: `"manual"`, `"auto"`, `"disabled"` |
| `autoupdate` | `boolean \| "notify"` | Auto-update behavior |
| `autoupdate` | `boolean \| "notify"` | Auto-update behavior: `true` (default) auto-upgrades, `"notify"` shows an indicator without upgrading, `false` disables auto-upgrade but still shows the update indicator |
| `provider` | `object` | Provider configurations (see [Providers](providers.md)) |
| `mcp` | `object` | MCP server configurations (see [MCP Servers](mcp-servers.md)) |
| `formatter` | `object \| false` | Formatter settings (see [Formatters](formatters.md)) |
Expand Down
11 changes: 10 additions & 1 deletion docs/docs/reference/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,23 @@ Disable auto-update if it causes problems:
export ALTIMATE_CLI_DISABLE_AUTOUPDATE=true
```

Or set to notification only:
Or set to notification only in your config:

```json
{
"autoupdate": "notify"
}
```

Both options still show an upgrade indicator in the footer when a new version is available. To upgrade manually, run:

```bash
altimate upgrade
```

!!! note
When an update is available, you'll see `↑ <version> update available · altimate upgrade` in the bottom-right corner of the TUI.

### Context Too Large

If conversations hit context limits:
Expand Down
2 changes: 1 addition & 1 deletion docs/docs/usage/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Configuration can be controlled via environment variables:

| Variable | Description |
| -------------------------------------- | ------------------------------------ |
| `ALTIMATE_CLI_DISABLE_AUTOUPDATE` | Disable automatic updates |
| `ALTIMATE_CLI_DISABLE_AUTOUPDATE` | Disable automatic updates (still shows upgrade indicator) |
| `ALTIMATE_CLI_DISABLE_LSP_DOWNLOAD` | Don't auto-download LSP servers |
| `ALTIMATE_CLI_DISABLE_AUTOCOMPACT` | Disable automatic context compaction |
| `ALTIMATE_CLI_DISABLE_DEFAULT_PLUGINS` | Skip loading default plugins |
Expand Down
39 changes: 35 additions & 4 deletions packages/opencode/src/cli/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,55 @@ import { Bus } from "@/bus"
import { Config } from "@/config/config"
import { Flag } from "@/flag/flag"
import { Installation } from "@/installation"
// altimate_change start — robust upgrade notification
import semver from "semver"
import { Log } from "@/util/log"

const log = Log.create({ service: "upgrade" })

export async function upgrade() {
const config = await Config.global()
const method = await Installation.method()
const latest = await Installation.latest(method).catch(() => {})
const latest = await Installation.latest(method).catch((err) => {
log.warn("failed to fetch latest version", { error: String(err), method })
return undefined
})
if (!latest) return
if (Installation.VERSION === latest) return

// Prevent downgrade: if current version is already >= latest, skip
if (
Installation.VERSION !== "local" &&
semver.valid(Installation.VERSION) &&
semver.valid(latest) &&
semver.gte(Installation.VERSION, latest)
) {
return
}

const notify = () => Bus.publish(Installation.Event.UpdateAvailable, { version: latest })

// Always notify when update is available, regardless of autoupdate setting
if (config.autoupdate === false || Flag.OPENCODE_DISABLE_AUTOUPDATE) {
await notify()
return
}
if (config.autoupdate === "notify") {
await Bus.publish(Installation.Event.UpdateAvailable, { version: latest })
await notify()
return
}

// Can't auto-upgrade for unknown or unsupported methods — notify instead
if (method === "unknown" || method === "yarn") {
await notify()
return
}

if (method === "unknown") return
await Installation.upgrade(method, latest)
.then(() => Bus.publish(Installation.Event.Updated, { version: latest }))
.catch(() => {})
.catch(async (err) => {
log.warn("auto-upgrade failed, notifying instead", { error: String(err), method, target: latest })
await notify()
})
}
// altimate_change end
4 changes: 3 additions & 1 deletion packages/opencode/src/flag/flag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ export namespace Flag {
export declare const OPENCODE_TUI_CONFIG: string | undefined
export declare const OPENCODE_CONFIG_DIR: string | undefined
export const OPENCODE_CONFIG_CONTENT = process.env["OPENCODE_CONFIG_CONTENT"]
export const OPENCODE_DISABLE_AUTOUPDATE = truthy("OPENCODE_DISABLE_AUTOUPDATE")
// altimate_change start — support ALTIMATE_CLI_DISABLE_AUTOUPDATE env var (documented name)
export const OPENCODE_DISABLE_AUTOUPDATE = altTruthy("ALTIMATE_CLI_DISABLE_AUTOUPDATE", "OPENCODE_DISABLE_AUTOUPDATE")
// altimate_change end
export const OPENCODE_DISABLE_PRUNE = truthy("OPENCODE_DISABLE_PRUNE")
// altimate_change start - global opt-out for Altimate Memory
export const ALTIMATE_DISABLE_MEMORY = altTruthy("ALTIMATE_DISABLE_MEMORY", "OPENCODE_DISABLE_MEMORY")
Expand Down
2 changes: 2 additions & 0 deletions packages/opencode/test/altimate/training-import.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ function setupMocks(opts: {
context: opts.currentCount ?? 0,
rule: opts.currentCount ?? 0,
pattern: opts.currentCount ?? 0,
context: opts.currentCount ?? 0,
rule: opts.currentCount ?? 0,
}))
saveSpy = spyOn(TrainingStore, "save").mockImplementation(async () => {
if (opts.saveShouldFail) throw new Error("store write failed")
Expand Down
Loading
Loading