oh-my-opencode/src/shared/opencode-version.ts
YeonGyu-Kim 4a82ff40fb
Consolidate duplicate patterns and simplify codebase (#1317)
* refactor(shared): unify binary downloader and session path storage

- Create binary-downloader.ts for common download/extract logic
- Create session-injected-paths.ts for unified path tracking
- Refactor comment-checker, ast-grep, grep downloaders to use shared util
- Consolidate directory injector types into shared module

* feat(shared): implement unified model resolution pipeline

- Create ModelResolutionPipeline for centralized model selection
- Refactor model-resolver to use pipeline
- Update delegate-task and config-handler to use unified logic
- Ensure consistent model resolution across all agent types

* refactor(agents): simplify agent utils and metadata management

- Extract helper functions for config merging and env context
- Register prompt metadata for all agents
- Simplify agent variant detection logic

* cleanup: inline utilities and remove unused exports

- Remove case-insensitive.ts (inline with native JS)
- Simplify opencode-version helpers
- Remove unused getModelLimit, createCompactionContextInjector exports
- Inline transcript entry creation in claude-code-hooks
- Update tests accordingly

---------

Co-authored-by: justsisyphus <justsisyphus@users.noreply.github.com>
2026-01-31 15:46:14 +09:00

75 lines
2.1 KiB
TypeScript

import { execSync } from "child_process"
/**
* Minimum OpenCode version required for this plugin.
* This plugin only supports OpenCode 1.1.1+ which uses the permission system.
*/
export const MINIMUM_OPENCODE_VERSION = "1.1.1"
/**
* OpenCode version that introduced native AGENTS.md injection.
* PR #10678 merged on Jan 26, 2026 - OpenCode now dynamically resolves
* AGENTS.md files from subdirectories as the agent explores them.
* When this version is detected, the directory-agents-injector hook
* is auto-disabled to prevent duplicate AGENTS.md loading.
*/
export const OPENCODE_NATIVE_AGENTS_INJECTION_VERSION = "1.1.37"
const NOT_CACHED = Symbol("NOT_CACHED")
let cachedVersion: string | null | typeof NOT_CACHED = NOT_CACHED
export function parseVersion(version: string): number[] {
const cleaned = version.replace(/^v/, "").split("-")[0]
return cleaned.split(".").map((n) => parseInt(n, 10) || 0)
}
export function compareVersions(a: string, b: string): -1 | 0 | 1 {
const partsA = parseVersion(a)
const partsB = parseVersion(b)
const maxLen = Math.max(partsA.length, partsB.length)
for (let i = 0; i < maxLen; i++) {
const numA = partsA[i] ?? 0
const numB = partsB[i] ?? 0
if (numA < numB) return -1
if (numA > numB) return 1
}
return 0
}
export function getOpenCodeVersion(): string | null {
if (cachedVersion !== NOT_CACHED) {
return cachedVersion
}
try {
const result = execSync("opencode --version", {
encoding: "utf-8",
timeout: 5000,
stdio: ["pipe", "pipe", "pipe"],
}).trim()
const versionMatch = result.match(/(\d+\.\d+\.\d+(?:-[\w.]+)?)/)
cachedVersion = versionMatch?.[1] ?? null
return cachedVersion
} catch {
cachedVersion = null
return null
}
}
export function isOpenCodeVersionAtLeast(version: string): boolean {
const current = getOpenCodeVersion()
if (!current) return true
return compareVersions(current, version) >= 0
}
export function resetVersionCache(): void {
cachedVersion = NOT_CACHED
}
export function setVersionCache(version: string | null): void {
cachedVersion = version
}