adamelmore 3 tygodni temu
rodzic
commit
c9bbea4266

+ 16 - 13
packages/opencode/src/config/config.ts

@@ -1104,20 +1104,23 @@ export namespace Config {
       mergeDeep(await loadFile(path.join(Global.Path.config, "opencode.jsonc"))),
     )
 
-    await import(path.join(Global.Path.config, "config"), {
-      with: {
-        type: "toml",
-      },
-    })
-      .then(async (mod) => {
-        const { provider, model, ...rest } = mod.default
-        if (provider && model) result.model = `${provider}/${model}`
-        result["$schema"] = "https://opencode.ai/config.json"
-        result = mergeDeep(result, rest)
-        await Bun.write(path.join(Global.Path.config, "config.json"), JSON.stringify(result, null, 2))
-        await fs.unlink(path.join(Global.Path.config, "config"))
+    const legacy = path.join(Global.Path.config, "config")
+    if (existsSync(legacy)) {
+      await import(pathToFileURL(legacy).href, {
+        with: {
+          type: "toml",
+        },
       })
-      .catch(() => {})
+        .then(async (mod) => {
+          const { provider, model, ...rest } = mod.default
+          if (provider && model) result.model = `${provider}/${model}`
+          result["$schema"] = "https://opencode.ai/config.json"
+          result = mergeDeep(result, rest)
+          await Bun.write(path.join(Global.Path.config, "config.json"), JSON.stringify(result, null, 2))
+          await fs.unlink(legacy)
+        })
+        .catch(() => {})
+    }
 
     return result
   })

+ 32 - 14
packages/opencode/src/project/instance.ts

@@ -17,6 +17,10 @@ const cache = new Map<string, Promise<Context>>()
 
 const DISPOSE_TIMEOUT_MS = 10_000
 
+const disposal = {
+  all: undefined as Promise<void> | undefined,
+}
+
 export const Instance = {
   async provide<R>(input: { directory: string; init?: () => Promise<any>; fn: () => R }): Promise<R> {
     let existing = cache.get(input.directory)
@@ -80,20 +84,34 @@ export const Instance = {
     })
   },
   async disposeAll() {
-    Log.Default.info("disposing all instances")
-    for (const [key, value] of cache) {
-      const ctx = await withTimeout(value, DISPOSE_TIMEOUT_MS).catch((error) => {
-        Log.Default.warn("instance dispose timed out", { key, error })
-        return undefined
-      })
-      if (!ctx) {
-        cache.delete(key)
-        continue
+    if (disposal.all) return disposal.all
+
+    disposal.all = iife(async () => {
+      Log.Default.info("disposing all instances")
+      const entries = [...cache.entries()]
+      for (const [key, value] of entries) {
+        if (cache.get(key) !== value) continue
+
+        const ctx = await withTimeout(value, DISPOSE_TIMEOUT_MS).catch((error) => {
+          Log.Default.warn("instance dispose timed out", { key, error })
+          return undefined
+        })
+
+        if (!ctx) {
+          if (cache.get(key) === value) cache.delete(key)
+          continue
+        }
+
+        if (cache.get(key) !== value) continue
+
+        await context.provide(ctx, async () => {
+          await Instance.dispose()
+        })
       }
-      await context.provide(ctx, async () => {
-        await Instance.dispose()
-      })
-    }
-    cache.clear()
+    }).finally(() => {
+      disposal.all = undefined
+    })
+
+    return disposal.all
   },
 }

+ 3 - 1
packages/opencode/src/project/state.ts

@@ -66,9 +66,11 @@ export namespace State {
 
       tasks.push(task)
     }
+    await Promise.all(tasks)
+
     entries.clear()
     recordsByKey.delete(key)
-    await Promise.all(tasks)
+
     disposalFinished = true
     log.info("state disposal completed", { key })
   }