From e17df09779f2fc70e8e898a1b49f924cfda534df Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Thu, 16 Apr 2026 23:40:18 -0400 Subject: [PATCH 1/2] refactor: use instance state in small services --- packages/opencode/src/mcp/index.ts | 3 +-- packages/opencode/src/project/vcs.ts | 15 +++++---------- packages/opencode/src/provider/provider.ts | 7 ++----- packages/opencode/src/session/instruction.ts | 9 +++++---- packages/opencode/src/session/system.ts | 10 +++++----- 5 files changed, 18 insertions(+), 26 deletions(-) diff --git a/packages/opencode/src/mcp/index.ts b/packages/opencode/src/mcp/index.ts index ba53e7c0b5df..09fcfc756a16 100644 --- a/packages/opencode/src/mcp/index.ts +++ b/packages/opencode/src/mcp/index.ts @@ -14,7 +14,6 @@ import { ConfigMCP } from "../config/mcp" import { Log } from "../util" import { NamedError } from "@opencode-ai/shared/util/error" import z from "zod/v4" -import { Instance } from "../project/instance" import { Installation } from "../installation" import { InstallationVersion } from "../installation/version" import { withTimeout } from "@/util/timeout" @@ -391,7 +390,7 @@ export const layer = Layer.effect( mcp: ConfigMCP.Info & { type: "local" }, ) { const [cmd, ...args] = mcp.command - const cwd = Instance.directory + const cwd = yield* InstanceState.directory const transport = new StdioClientTransport({ stderr: "pipe", command: cmd, diff --git a/packages/opencode/src/project/vcs.ts b/packages/opencode/src/project/vcs.ts index b1375a7b78e0..ba028f7e8e34 100644 --- a/packages/opencode/src/project/vcs.ts +++ b/packages/opencode/src/project/vcs.ts @@ -8,7 +8,6 @@ import { AppFileSystem } from "@opencode-ai/shared/filesystem" import { FileWatcher } from "@/file/watcher" import { Git } from "@/git" import { Log } from "@/util" -import { Instance } from "./instance" import z from "zod" const log = Log.create({ service: "vcs" }) @@ -205,21 +204,17 @@ export const layer: Layer.Layer { const token = apiKey ?? (yield* dep.get("GITLAB_TOKEN")) const providerConfig = (yield* dep.config()).provider?.["gitlab"] + const directory = yield* InstanceState.directory const aiGatewayHeaders = { "User-Agent": `opencode/${InstallationVersion} gitlab-ai-provider/${GITLAB_PROVIDER_VERSION} (${os.platform()} ${os.release()}; ${os.arch()})`, @@ -591,10 +591,7 @@ function custom(dep: CustomDep): Record { auth?.type === "api" ? { "PRIVATE-TOKEN": token } : { Authorization: `Bearer ${token}` } log.info("gitlab model discovery starting", { instanceUrl }) - const result = await discoverWorkflowModels( - { instanceUrl, getHeaders }, - { workingDirectory: Instance.directory }, - ) + const result = await discoverWorkflowModels({ instanceUrl, getHeaders }, { workingDirectory: directory }) if (!result.models.length) { log.info("gitlab model discovery skipped: no models found", { diff --git a/packages/opencode/src/session/instruction.ts b/packages/opencode/src/session/instruction.ts index 768f352d93d9..122644c1fd89 100644 --- a/packages/opencode/src/session/instruction.ts +++ b/packages/opencode/src/session/instruction.ts @@ -8,7 +8,6 @@ import { Flag } from "@/flag/flag" import { AppFileSystem } from "@opencode-ai/shared/filesystem" import { withTransientReadRetry } from "@/util/effect-http-client" import { Global } from "../global" -import { Instance } from "../project/instance" import { Log } from "../util" import type { MessageV2 } from "./message-v2" import type { MessageID } from "./schema" @@ -82,9 +81,10 @@ export const layer: Layer.Layer Effect.succeed([] as string[]))) } if (!Flag.OPENCODE_CONFIG_DIR) { @@ -119,12 +119,13 @@ export const layer: Layer.Layer() // The first project-level match wins so we don't stack AGENTS.md/CLAUDE.md from every ancestor. if (!Flag.OPENCODE_DISABLE_PROJECT_CONFIG) { for (const file of FILES) { - const matches = yield* fs.findUp(file, Instance.directory, Instance.worktree) + const matches = yield* fs.findUp(file, ctx.directory, ctx.worktree) if (matches.length > 0) { matches.forEach((item) => paths.add(path.resolve(item))) break @@ -191,9 +192,9 @@ export const layer: Layer.Layer`, - ` Working directory: ${Instance.directory}`, - ` Workspace root folder: ${Instance.worktree}`, - ` Is directory a git repo: ${project.vcs === "git" ? "yes" : "no"}`, + ` Working directory: ${ctx.directory}`, + ` Workspace root folder: ${ctx.worktree}`, + ` Is directory a git repo: ${ctx.project.vcs === "git" ? "yes" : "no"}`, ` Platform: ${process.platform}`, ` Today's date: ${new Date().toDateString()}`, ``, From 95efe66994430bc72771189c7b7e8b87dc071350 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Fri, 17 Apr 2026 21:56:08 -0400 Subject: [PATCH 2/2] fix: avoid stale system prompt instance context --- packages/opencode/src/session/system.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/opencode/src/session/system.ts b/packages/opencode/src/session/system.ts index 93df6dd8e286..ec60f6eef77f 100644 --- a/packages/opencode/src/session/system.ts +++ b/packages/opencode/src/session/system.ts @@ -1,6 +1,6 @@ import { Context, Effect, Layer } from "effect" -import { InstanceState } from "@/effect" +import { Instance } from "../project/instance" import PROMPT_ANTHROPIC from "./prompt/anthropic.txt" import PROMPT_DEFAULT from "./prompt/default.txt" @@ -43,18 +43,18 @@ export const layer = Layer.effect( Service, Effect.gen(function* () { const skill = yield* Skill.Service - const ctx = yield* InstanceState.context return Service.of({ environment(model) { + const project = Instance.project return [ [ `You are powered by the model named ${model.api.id}. The exact model ID is ${model.providerID}/${model.api.id}`, `Here is some useful information about the environment you are running in:`, ``, - ` Working directory: ${ctx.directory}`, - ` Workspace root folder: ${ctx.worktree}`, - ` Is directory a git repo: ${ctx.project.vcs === "git" ? "yes" : "no"}`, + ` Working directory: ${Instance.directory}`, + ` Workspace root folder: ${Instance.worktree}`, + ` Is directory a git repo: ${project.vcs === "git" ? "yes" : "no"}`, ` Platform: ${process.platform}`, ` Today's date: ${new Date().toDateString()}`, ``,