fix: proper OpenCode v1.1.1 permission migration (#490)
* fix: implement proper version-aware permission format for OpenCode v1.1.1 - Rewrite permission-compat.ts with runtime version detection - createAgentToolRestrictions() returns correct format per version - v1.1.1+ uses permission format, older uses tools format - Add migrateToolsToPermission/migratePermissionToTools helpers - Update test suite for new API 🤖 Generated with assistance of OhMyOpenCode https://github.com/code-yeongyu/oh-my-opencode * fix: update all agents to use createAgentToolRestrictions() - Replace hardcoded tools: { X: false } format with version-aware utility - All agents now use createAgentToolRestrictions([...]) - Ensures compatibility with both old and new OpenCode versions 🤖 Generated with assistance of OhMyOpenCode https://github.com/code-yeongyu/oh-my-opencode * fix: add runtime migration for user agent configs in config-handler Migrate tools/permission format in user/project/plugin agent configs based on detected OpenCode version at load time. 🤖 Generated with [OhMyOpenCode](https://github.com/code-yeongyu/oh-my-opencode)
This commit is contained in:
@@ -1,72 +1,78 @@
|
||||
import { supportsNewPermissionSystem as checkNewPermissionSystem } from "./opencode-version"
|
||||
import { supportsNewPermissionSystem } from "./opencode-version"
|
||||
|
||||
export type PermissionValue = "ask" | "allow" | "deny"
|
||||
export type BashPermission = PermissionValue | Record<string, PermissionValue>
|
||||
|
||||
export interface StandardPermission {
|
||||
edit?: PermissionValue
|
||||
bash?: BashPermission
|
||||
webfetch?: PermissionValue
|
||||
doom_loop?: PermissionValue
|
||||
external_directory?: PermissionValue
|
||||
export interface LegacyToolsFormat {
|
||||
tools: Record<string, boolean>
|
||||
}
|
||||
|
||||
export interface ToolsConfig {
|
||||
[toolName: string]: boolean
|
||||
export interface NewPermissionFormat {
|
||||
permission: Record<string, PermissionValue>
|
||||
}
|
||||
|
||||
export interface AgentPermissionConfig {
|
||||
permission?: StandardPermission
|
||||
tools?: ToolsConfig
|
||||
export type VersionAwareRestrictions = LegacyToolsFormat | NewPermissionFormat
|
||||
|
||||
export function createAgentToolRestrictions(
|
||||
denyTools: string[]
|
||||
): VersionAwareRestrictions {
|
||||
if (supportsNewPermissionSystem()) {
|
||||
return {
|
||||
permission: Object.fromEntries(
|
||||
denyTools.map((tool) => [tool, "deny" as const])
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
tools: Object.fromEntries(denyTools.map((tool) => [tool, false])),
|
||||
}
|
||||
}
|
||||
|
||||
export { checkNewPermissionSystem as supportsNewPermissionSystemFromCompat }
|
||||
|
||||
export function createToolDenyList(toolNames: string[]): ToolsConfig {
|
||||
return Object.fromEntries(toolNames.map((name) => [name, false]))
|
||||
}
|
||||
|
||||
export function permissionValueToBoolean(value: PermissionValue): boolean {
|
||||
return value === "allow"
|
||||
}
|
||||
|
||||
export function booleanToPermissionValue(value: boolean): PermissionValue {
|
||||
return value ? "allow" : "deny"
|
||||
}
|
||||
|
||||
export function convertToolsToPermission(
|
||||
tools: ToolsConfig
|
||||
export function migrateToolsToPermission(
|
||||
tools: Record<string, boolean>
|
||||
): Record<string, PermissionValue> {
|
||||
return Object.fromEntries(
|
||||
Object.entries(tools).map(([key, value]) => [
|
||||
key,
|
||||
booleanToPermissionValue(value),
|
||||
value ? ("allow" as const) : ("deny" as const),
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
export function convertPermissionToTools(
|
||||
export function migratePermissionToTools(
|
||||
permission: Record<string, PermissionValue>
|
||||
): ToolsConfig {
|
||||
): Record<string, boolean> {
|
||||
return Object.fromEntries(
|
||||
Object.entries(permission)
|
||||
.filter(([, value]) => value !== "ask")
|
||||
.map(([key, value]) => [key, permissionValueToBoolean(value)])
|
||||
.map(([key, value]) => [key, value === "allow"])
|
||||
)
|
||||
}
|
||||
|
||||
export function createAgentRestrictions(config: {
|
||||
denyTools?: string[]
|
||||
permission?: StandardPermission
|
||||
}): AgentPermissionConfig {
|
||||
const result: AgentPermissionConfig = {}
|
||||
export function migrateAgentConfig(
|
||||
config: Record<string, unknown>
|
||||
): Record<string, unknown> {
|
||||
const result = { ...config }
|
||||
|
||||
if (config.denyTools && config.denyTools.length > 0) {
|
||||
result.tools = createToolDenyList(config.denyTools)
|
||||
}
|
||||
|
||||
if (config.permission) {
|
||||
result.permission = config.permission
|
||||
if (supportsNewPermissionSystem()) {
|
||||
if (result.tools && typeof result.tools === "object") {
|
||||
const existingPermission =
|
||||
(result.permission as Record<string, PermissionValue>) || {}
|
||||
const migratedPermission = migrateToolsToPermission(
|
||||
result.tools as Record<string, boolean>
|
||||
)
|
||||
result.permission = { ...migratedPermission, ...existingPermission }
|
||||
delete result.tools
|
||||
}
|
||||
} else {
|
||||
if (result.permission && typeof result.permission === "object") {
|
||||
const existingTools = (result.tools as Record<string, boolean>) || {}
|
||||
const migratedTools = migratePermissionToTools(
|
||||
result.permission as Record<string, PermissionValue>
|
||||
)
|
||||
result.tools = { ...migratedTools, ...existingTools }
|
||||
delete result.permission
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user