Skip to content

Commit b6af4d0

Browse files
authored
refactor(config): pass instance context to containsPath (#21882)
1 parent 577139c commit b6af4d0

2 files changed

Lines changed: 25 additions & 19 deletions

File tree

packages/opencode/src/config/config.ts

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import { Duration, Effect, Layer, Option, ServiceMap } from "effect"
4141
import { Flock } from "@/util/flock"
4242
import { isPathPluginSpec, parsePluginSpecifier, resolvePathPluginTarget } from "@/plugin/shared"
4343
import { Npm } from "@/npm"
44+
import { InstanceRef } from "@/effect/instance-ref"
4445

4546
export namespace Config {
4647
const ModelId = z.string().meta({ $ref: "https://models.dev/model-schema.json#/$defs/Model" })
@@ -1327,27 +1328,31 @@ export namespace Config {
13271328
const consoleManagedProviders = new Set<string>()
13281329
let activeOrgName: string | undefined
13291330

1330-
const scope = (source: string): PluginScope => {
1331+
const scope = Effect.fnUntraced(function* (source: string) {
13311332
if (source.startsWith("http://") || source.startsWith("https://")) return "global"
13321333
if (source === "OPENCODE_CONFIG_CONTENT") return "local"
1333-
if (Instance.containsPath(source)) return "local"
1334+
if (yield* InstanceRef.use((ctx) => Effect.succeed(Instance.containsPath(source, ctx)))) return "local"
13341335
return "global"
1335-
}
1336+
})
13361337

1337-
const track = (source: string, list: PluginSpec[] | undefined, kind?: PluginScope) => {
1338+
const track = Effect.fnUntraced(function* (
1339+
source: string,
1340+
list: PluginSpec[] | undefined,
1341+
kind?: PluginScope,
1342+
) {
13381343
if (!list?.length) return
1339-
const hit = kind ?? scope(source)
1344+
const hit = kind ?? (yield* scope(source))
13401345
const plugins = deduplicatePluginOrigins([
13411346
...(result.plugin_origins ?? []),
13421347
...list.map((spec) => ({ spec, source, scope: hit })),
13431348
])
13441349
result.plugin = plugins.map((item) => item.spec)
13451350
result.plugin_origins = plugins
1346-
}
1351+
})
13471352

13481353
const merge = (source: string, next: Info, kind?: PluginScope) => {
13491354
result = mergeConfigConcatArrays(result, next)
1350-
track(source, next.plugin, kind)
1355+
return track(source, next.plugin, kind)
13511356
}
13521357

13531358
for (const [key, value] of Object.entries(auth)) {
@@ -1367,24 +1372,24 @@ export namespace Config {
13671372
dir: path.dirname(source),
13681373
source,
13691374
})
1370-
merge(source, next, "global")
1375+
yield* merge(source, next, "global")
13711376
log.debug("loaded remote config from well-known", { url })
13721377
}
13731378
}
13741379

13751380
const global = yield* getGlobal()
1376-
merge(Global.Path.config, global, "global")
1381+
yield* merge(Global.Path.config, global, "global")
13771382

13781383
if (Flag.OPENCODE_CONFIG) {
1379-
merge(Flag.OPENCODE_CONFIG, yield* loadFile(Flag.OPENCODE_CONFIG))
1384+
yield* merge(Flag.OPENCODE_CONFIG, yield* loadFile(Flag.OPENCODE_CONFIG))
13801385
log.debug("loaded custom config", { path: Flag.OPENCODE_CONFIG })
13811386
}
13821387

13831388
if (!Flag.OPENCODE_DISABLE_PROJECT_CONFIG) {
13841389
for (const file of yield* Effect.promise(() =>
13851390
ConfigPaths.projectFiles("opencode", ctx.directory, ctx.worktree),
13861391
)) {
1387-
merge(file, yield* loadFile(file), "local")
1392+
yield* merge(file, yield* loadFile(file), "local")
13881393
}
13891394
}
13901395

@@ -1405,7 +1410,7 @@ export namespace Config {
14051410
for (const file of ["opencode.json", "opencode.jsonc"]) {
14061411
const source = path.join(dir, file)
14071412
log.debug(`loading config from ${source}`)
1408-
merge(source, yield* loadFile(source))
1413+
yield* merge(source, yield* loadFile(source))
14091414
result.agent ??= {}
14101415
result.mode ??= {}
14111416
result.plugin ??= []
@@ -1424,7 +1429,7 @@ export namespace Config {
14241429
result.agent = mergeDeep(result.agent, yield* Effect.promise(() => loadAgent(dir)))
14251430
result.agent = mergeDeep(result.agent, yield* Effect.promise(() => loadMode(dir)))
14261431
const list = yield* Effect.promise(() => loadPlugin(dir))
1427-
track(dir, list)
1432+
yield* track(dir, list)
14281433
}
14291434

14301435
if (process.env.OPENCODE_CONFIG_CONTENT) {
@@ -1433,7 +1438,7 @@ export namespace Config {
14331438
dir: ctx.directory,
14341439
source,
14351440
})
1436-
merge(source, next, "local")
1441+
yield* merge(source, next, "local")
14371442
log.debug("loaded custom config from OPENCODE_CONFIG_CONTENT")
14381443
}
14391444

@@ -1462,7 +1467,7 @@ export namespace Config {
14621467
for (const providerID of Object.keys(next.provider ?? {})) {
14631468
consoleManagedProviders.add(providerID)
14641469
}
1465-
merge(source, next, "global")
1470+
yield* merge(source, next, "global")
14661471
}
14671472
}).pipe(
14681473
Effect.catch((err) => {
@@ -1477,7 +1482,7 @@ export namespace Config {
14771482
if (existsSync(managedDir)) {
14781483
for (const file of ["opencode.json", "opencode.jsonc"]) {
14791484
const source = path.join(managedDir, file)
1480-
merge(source, yield* loadFile(source), "global")
1485+
yield* merge(source, yield* loadFile(source), "global")
14811486
}
14821487
}
14831488

packages/opencode/src/project/instance.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,13 @@ export const Instance = {
9090
* Returns true if path is inside Instance.directory OR Instance.worktree.
9191
* Paths within the worktree but outside the working directory should not trigger external_directory permission.
9292
*/
93-
containsPath(filepath: string) {
94-
if (Filesystem.contains(Instance.directory, filepath)) return true
93+
containsPath(filepath: string, ctx?: InstanceContext) {
94+
const instance = ctx ?? Instance
95+
if (Filesystem.contains(instance.directory, filepath)) return true
9596
// Non-git projects set worktree to "/" which would match ANY absolute path.
9697
// Skip worktree check in this case to preserve external_directory permissions.
9798
if (Instance.worktree === "/") return false
98-
return Filesystem.contains(Instance.worktree, filepath)
99+
return Filesystem.contains(instance.worktree, filepath)
99100
},
100101
/**
101102
* Captures the current instance ALS context and returns a wrapper that

0 commit comments

Comments
 (0)