import path from "path" import fs from "fs/promises" import { xdgData, xdgCache, xdgConfig, xdgState } from "xdg-basedir" import os from "os" import { Context, Effect, Layer } from "effect" import { Flock } from "./util/flock" import { Flag } from "./flag/flag" const app = "opencode" const data = path.join(xdgData!, app) const cache = path.join(xdgCache!, app) const config = path.join(xdgConfig!, app) const state = path.join(xdgState!, app) const paths = { get home() { return process.env.OPENCODE_TEST_HOME ?? os.homedir() }, data, bin: path.join(cache, "bin"), log: path.join(data, "log"), cache, config, state, } export const Path = paths Flock.setGlobal({ state }) await Promise.all([ fs.mkdir(Path.data, { recursive: true }), fs.mkdir(Path.config, { recursive: true }), fs.mkdir(Path.state, { recursive: true }), fs.mkdir(Path.log, { recursive: true }), fs.mkdir(Path.bin, { recursive: true }), ]) export class Service extends Context.Service()("@opencode/Global") {} export interface Interface { readonly home: string readonly data: string readonly cache: string readonly config: string readonly state: string readonly bin: string readonly log: string } export function make(input: Partial = {}): Interface { return { home: Path.home, data: Path.data, cache: Path.cache, config: Flag.OPENCODE_CONFIG_DIR ?? Path.config, state: Path.state, bin: Path.bin, log: Path.log, ...input, } } export const layer = Layer.effect( Service, Effect.sync(() => Service.of(make())), ) export const layerWith = (input: Partial) => Layer.effect( Service, Effect.sync(() => Service.of(make(input))), ) export * as Global from "./global"