refactor: isolate legacy flags

This commit is contained in:
Dax Raad 2026-07-20 21:42:02 -04:00
commit 43c08387f1
65 changed files with 282 additions and 147 deletions

View file

@ -100,6 +100,52 @@ const provider = {
}
describe("Config", () => {
it.live("loads explicit file and content overrides in priority order", () =>
Effect.acquireRelease(
Effect.promise(() => tmpdir()),
(tmp) => Effect.promise(() => tmp[Symbol.asyncDispose]()),
).pipe(
Effect.flatMap((tmp) => {
const global = path.join(tmp.path, "global")
const project = path.join(tmp.path, "project")
const explicit = path.join(tmp.path, "custom.json")
return Effect.promise(async () => {
await fs.mkdir(global, { recursive: true })
await fs.mkdir(project, { recursive: true })
await fs.writeFile(path.join(global, "opencode.json"), JSON.stringify({ shell: "global" }))
await fs.writeFile(explicit, JSON.stringify({ shell: "explicit" }))
await fs.writeFile(path.join(project, "opencode.json"), JSON.stringify({ shell: "project" }))
}).pipe(
Effect.andThen(
Effect.gen(function* () {
const config = yield* Config.Service
const entries = yield* config.entries()
expect(
entries.flatMap((entry) =>
entry.type === "document" && entry.info.shell ? [entry.info.shell] : [],
),
).toEqual(["global", "explicit", "project", "content"])
expect(Config.latest(entries, "shell")).toBe("content")
}).pipe(
Effect.provide(
testLayer(
project,
global,
project,
undefined,
undefined,
emptyCredentialNode,
emptyWellknownNode,
{ file: explicit, content: JSON.stringify({ shell: "content" }) },
),
),
),
),
)
}),
),
)
it.live("skips project configuration when project discovery is disabled", () =>
Effect.acquireRelease(
Effect.promise(() => tmpdir()),

View file

@ -8,14 +8,11 @@ import { fileLogger } from "../../src/observability/logging"
import { resource } from "../../src/observability/otlp"
const otelResourceAttributes = process.env.OTEL_RESOURCE_ATTRIBUTES
const opencodeClient = process.env.OPENCODE_CLIENT
afterEach(() => {
if (otelResourceAttributes === undefined) delete process.env.OTEL_RESOURCE_ATTRIBUTES
else process.env.OTEL_RESOURCE_ATTRIBUTES = otelResourceAttributes
if (opencodeClient === undefined) delete process.env.OPENCODE_CLIENT
else process.env.OPENCODE_CLIENT = opencodeClient
})
describe("resource", () => {
@ -39,16 +36,15 @@ describe("resource", () => {
})
test("keeps built-in attributes when env values conflict", () => {
process.env.OPENCODE_CLIENT = "cli"
process.env.OTEL_RESOURCE_ATTRIBUTES =
"opencode.client=web,service.instance.id=override,service.namespace=anomalyco"
expect(resource().attributes).toMatchObject({
expect(resource("cli").attributes).toMatchObject({
"opencode.client": "cli",
"service.namespace": "anomalyco",
})
expect(resource().attributes["service.instance.id"]).not.toBe("override")
expect(resource().attributes["opencode.run"]).toMatch(/^[0-9a-f]{8}$/)
expect(resource("cli").attributes["service.instance.id"]).not.toBe("override")
expect(resource("cli").attributes["opencode.run"]).toMatch(/^[0-9a-f]{8}$/)
})
})

View file

@ -56,7 +56,7 @@ const locations = Layer.effect(
() =>
// The test only needs the compaction location service used by SessionV2.compact.
// oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion
SessionCompaction.layer.pipe(
SessionCompaction.layer().pipe(
Layer.provide(client),
Layer.provide(config),
Layer.provide(models),

View file

@ -18,7 +18,6 @@ import { SessionStore } from "@opencode-ai/core/session/store"
import { SessionV2 } from "@opencode-ai/core/session"
import { Project } from "@opencode-ai/core/project"
import { ProjectTable } from "@opencode-ai/core/project/sql"
import { Flag } from "@opencode-ai/core/flag/flag"
import { InstallationVersion } from "@opencode-ai/core/installation/version"
import { AbsolutePath } from "@opencode-ai/core/schema"
import { Money } from "@opencode-ai/schema/money"
@ -190,7 +189,7 @@ it.effect("manual compaction summarizes short context instead of no-op", () =>
"User-Agent": `opencode/${InstallationVersion}`,
"x-opencode-project": Project.ID.global,
"x-opencode-session": sessionID,
"x-opencode-client": Flag.OPENCODE_CLIENT,
"x-opencode-client": "cli",
})
expect(requests[0]?.generation).toBeUndefined()
expect(JSON.stringify(requests[0]?.messages)).toContain("Manual compaction should include this short conversation.")

View file

@ -22,7 +22,6 @@ import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder"
import { LayerNodePlatform } from "@opencode-ai/core/effect/app-node-platform"
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
import { EventV2 } from "@opencode-ai/core/event"
import { Flag } from "@opencode-ai/core/flag/flag"
import { InstallationVersion } from "@opencode-ai/core/installation/version"
import { PermissionV2 } from "@opencode-ai/core/permission"
import { EventTable } from "@opencode-ai/core/event/sql"
@ -3183,7 +3182,7 @@ describe("SessionRunnerLLM", () => {
"User-Agent": `opencode/${InstallationVersion}`,
"x-opencode-project": Project.ID.global,
"x-opencode-session": sessionID,
"x-opencode-client": Flag.OPENCODE_CLIENT,
"x-opencode-client": "cli",
})
}),
)

View file

@ -17,7 +17,6 @@ import { SessionTitle } from "@opencode-ai/core/session/title"
import { SessionV2 } from "@opencode-ai/core/session"
import { Project } from "@opencode-ai/core/project"
import { ProjectTable } from "@opencode-ai/core/project/sql"
import { Flag } from "@opencode-ai/core/flag/flag"
import { InstallationVersion } from "@opencode-ai/core/installation/version"
import { AbsolutePath } from "@opencode-ai/core/schema"
import { Money } from "@opencode-ai/schema/money"
@ -153,7 +152,7 @@ it.effect("generates a title from the sole user message and renames the session"
"User-Agent": `opencode/${InstallationVersion}`,
"x-opencode-project": Project.ID.global,
"x-opencode-session": sessionID,
"x-opencode-client": Flag.OPENCODE_CLIENT,
"x-opencode-client": "cli",
})
expect(JSON.stringify(requests[0]?.messages)).toContain("Help me debug the failing build")
const renamed = yield* store.get(sessionID)