Extract error handling, parsing logic, and variable substitution into dedicated modules. This reduces duplication between tui.json and opencode.json parsing and makes the config system easier to extend for future config formats.
74 lines
1.9 KiB
TypeScript
74 lines
1.9 KiB
TypeScript
import { existsSync } from "fs"
|
|
import os from "os"
|
|
import path from "path"
|
|
import { Log, Process } from "../util"
|
|
|
|
const log = Log.create({ service: "config" })
|
|
|
|
const MANAGED_PLIST_DOMAIN = "ai.opencode.managed"
|
|
|
|
// Keys injected by macOS/MDM into the managed plist that are not OpenCode config
|
|
const PLIST_META = new Set([
|
|
"PayloadDisplayName",
|
|
"PayloadIdentifier",
|
|
"PayloadType",
|
|
"PayloadUUID",
|
|
"PayloadVersion",
|
|
"_manualProfile",
|
|
])
|
|
|
|
function systemManagedConfigDir(): string {
|
|
switch (process.platform) {
|
|
case "darwin":
|
|
return "/Library/Application Support/opencode"
|
|
case "win32":
|
|
return path.join(process.env.ProgramData || "C:\\ProgramData", "opencode")
|
|
default:
|
|
return "/etc/opencode"
|
|
}
|
|
}
|
|
|
|
function managedConfigDir() {
|
|
return process.env.OPENCODE_TEST_MANAGED_CONFIG_DIR || systemManagedConfigDir()
|
|
}
|
|
|
|
function parseManagedPlist(json: string): string {
|
|
const raw = JSON.parse(json)
|
|
for (const key of Object.keys(raw)) {
|
|
if (PLIST_META.has(key)) delete raw[key]
|
|
}
|
|
return JSON.stringify(raw)
|
|
}
|
|
|
|
async function readManagedPreferences() {
|
|
if (process.platform !== "darwin") return
|
|
|
|
const user = os.userInfo().username
|
|
const paths = [
|
|
path.join("/Library/Managed Preferences", user, `${MANAGED_PLIST_DOMAIN}.plist`),
|
|
path.join("/Library/Managed Preferences", `${MANAGED_PLIST_DOMAIN}.plist`),
|
|
]
|
|
|
|
for (const plist of paths) {
|
|
if (!existsSync(plist)) continue
|
|
log.info("reading macOS managed preferences", { path: plist })
|
|
const result = await Process.run(["plutil", "-convert", "json", "-o", "-", plist], { nothrow: true })
|
|
if (result.code !== 0) {
|
|
log.warn("failed to convert managed preferences plist", { path: plist })
|
|
continue
|
|
}
|
|
return {
|
|
source: `mobileconfig:${plist}`,
|
|
text: parseManagedPlist(result.stdout.toString()),
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
export const ConfigManaged = {
|
|
managedConfigDir,
|
|
parseManagedPlist,
|
|
readManagedPreferences,
|
|
}
|