MCPcopy Index your code
hub / github.com/anomalyco/opencode / createThemeInstaller

Function createThemeInstaller

packages/opencode/src/plugin/tui/runtime.ts:245–310  ·  view source on GitHub ↗
(
  meta: ConfigPlugin.Origin,
  root: string,
  spec: string,
  plugin: PluginEntry,
)

Source from the content-addressed store, hash-verified

243}
244
245function createThemeInstaller(
246 meta: ConfigPlugin.Origin,
247 root: string,
248 spec: string,
249 plugin: PluginEntry,
250): TuiTheme["install"] {
251 return async (file) => {
252 const src = Filesystem.resolveFilePath(root, file)
253 const name = path.basename(src, path.extname(src))
254 const source_dir = path.dirname(meta.source)
255 const local_dir =
256 path.basename(source_dir) === ".opencode"
257 ? path.join(source_dir, "themes")
258 : path.join(source_dir, ".opencode", "themes")
259 const dest_dir = meta.scope === "local" ? local_dir : path.join(Global.Path.config, "themes")
260 const dest = path.join(dest_dir, `${name}.json`)
261 const stat = await Filesystem.statAsync(src)
262 const mtime = stat ? Math.floor(typeof stat.mtimeMs === "bigint" ? Number(stat.mtimeMs) : stat.mtimeMs) : undefined
263 const size = stat ? (typeof stat.size === "bigint" ? Number(stat.size) : stat.size) : undefined
264 const info = {
265 src,
266 dest,
267 mtime,
268 size,
269 }
270
271 await Flock.withLock(`tui-theme:${dest}`, async () => {
272 const save = async () => {
273 plugin.themes[name] = info
274 await PluginMeta.setTheme(plugin.id, name, info).catch(() => {})
275 }
276
277 const exists = hasTheme(name)
278 const prev = plugin.themes[name]
279 if (exists) {
280 if (plugin.meta.state !== "updated") {
281 if (!prev && (await Filesystem.exists(dest))) {
282 await save()
283 }
284 return
285 }
286 if (prev?.dest === dest && prev.mtime === mtime && prev.size === size) return
287 }
288
289 const text = await Filesystem.readText(src).catch(() => undefined)
290 if (text === undefined) return
291
292 const fail = Symbol()
293 const data = await Promise.resolve(text)
294 .then((x) => JSON.parse(x))
295 .catch(() => fail)
296 if (data === fail) return
297
298 if (!isTheme(data)) {
299 return
300 }
301
302 if (exists || !(await Filesystem.exists(dest))) {

Callers 2

syncPluginThemesFunction · 0.85
pluginApiFunction · 0.85

Calls 6

hasThemeFunction · 0.90
upsertThemeFunction · 0.90
writeMethod · 0.80
saveFunction · 0.70
isThemeFunction · 0.70
existsMethod · 0.45

Tested by

no test coverage detected