fix(tui): gate Zed context on terminal env (#28517)

This commit is contained in:
Kit Langton
2026-05-20 16:52:33 -04:00
committed by GitHub
parent 09603ed52f
commit 43c24d8d0f
4 changed files with 48 additions and 8 deletions
@@ -195,6 +195,10 @@ export function resolveZedDbPath() {
return candidates.find((item) => isFile(item)) return candidates.find((item) => isFile(item))
} }
export function isZedTerminal() {
return process.env.ZED_TERM === "true" || process.env.TERM_PROGRAM?.toLowerCase() === "zed"
}
function isFile(item: string) { function isFile(item: string) {
try { try {
return Filesystem.stat(item)?.isFile() === true return Filesystem.stat(item)?.isFile() === true
@@ -6,7 +6,7 @@ import { createStore } from "solid-js/store"
import { Option, Schema, SchemaGetter } from "effect" import { Option, Schema, SchemaGetter } from "effect"
import { isRecord } from "@/util/record" import { isRecord } from "@/util/record"
import { createSimpleContext } from "./helper" import { createSimpleContext } from "./helper"
import { resolveZedDbPath, resolveZedSelection } from "./editor-zed" import { isZedTerminal, resolveZedDbPath, resolveZedSelection } from "./editor-zed"
const MCP_PROTOCOL_VERSION = "2025-11-25" const MCP_PROTOCOL_VERSION = "2025-11-25"
@@ -173,6 +173,12 @@ export const { use: useEditorContext, provider: EditorContextProvider } = create
const connection = resolveEditorConnection(directory) const connection = resolveEditorConnection(directory)
if (!connection) { if (!connection) {
if (!isZedTerminal()) {
setStore("status", "disabled")
scheduleReconnect()
return
}
const dbPath = resolveZedDbPath() const dbPath = resolveZedDbPath()
if (!dbPath) { if (!dbPath) {
setStore("status", "disabled") setStore("status", "disabled")
@@ -311,7 +317,7 @@ export const { use: useEditorContext, provider: EditorContextProvider } = create
return { return {
enabled() { enabled() {
return Boolean(resolveEditorConnection(directory) || resolveZedDbPath()) return Boolean(resolveEditorConnection(directory) || (isZedTerminal() && resolveZedDbPath()))
}, },
connected() { connected() {
return store.status === "connected" return store.status === "connected"
@@ -48,12 +48,14 @@ export const Service =
} }
static get defaultLayer() { static get defaultLayer() {
const tag = this
return Layer.effect( return Layer.effect(
this, tag,
Config.all(fields).pipe( Effect.gen(function* () {
const config = yield* Config.all(fields)
// oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- Config.all preserves the field shape, but its conditional return type also supports iterable inputs. // oxlint-disable-next-line typescript-eslint/no-unsafe-type-assertion -- Config.all preserves the field shape, but its conditional return type also supports iterable inputs.
Effect.map((config) => this.of(config as Shape<Fields>)), return tag.of(config as Shape<Fields>)
), }),
) )
} }
} }
@@ -2,10 +2,25 @@ import { Database } from "bun:sqlite"
import { mkdir, symlink } from "node:fs/promises" import { mkdir, symlink } from "node:fs/promises"
import os from "node:os" import os from "node:os"
import path from "node:path" import path from "node:path"
import { expect, spyOn, test } from "bun:test" import { afterEach, expect, spyOn, test } from "bun:test"
import { offsetToPosition, resolveZedDbPath, resolveZedSelection } from "../../../src/cli/cmd/tui/context/editor-zed" import {
isZedTerminal,
offsetToPosition,
resolveZedDbPath,
resolveZedSelection,
} from "../../../src/cli/cmd/tui/context/editor-zed"
import { tmpdir } from "../../fixture/fixture" import { tmpdir } from "../../fixture/fixture"
const originalZedTerm = process.env.ZED_TERM
const originalTermProgram = process.env.TERM_PROGRAM
afterEach(() => {
if (originalZedTerm === undefined) delete process.env.ZED_TERM
else process.env.ZED_TERM = originalZedTerm
if (originalTermProgram === undefined) delete process.env.TERM_PROGRAM
else process.env.TERM_PROGRAM = originalTermProgram
})
type ZedFixtureOptions = { type ZedFixtureOptions = {
workspacePaths?: string | null workspacePaths?: string | null
itemKind?: string itemKind?: string
@@ -85,6 +100,19 @@ test("resolveZedDbPath skips candidates that cannot be stated", async () => {
} }
}) })
test("isZedTerminal only returns true for Zed terminal environments", () => {
delete process.env.ZED_TERM
delete process.env.TERM_PROGRAM
expect(isZedTerminal()).toBeFalse()
process.env.ZED_TERM = "true"
expect(isZedTerminal()).toBeTrue()
process.env.ZED_TERM = "false"
process.env.TERM_PROGRAM = "zed"
expect(isZedTerminal()).toBeTrue()
})
test("resolveZedSelection returns active editor selection", async () => { test("resolveZedSelection returns active editor selection", async () => {
await using tmp = await tmpdir() await using tmp = await tmpdir()
const fixture = await writeZedFixture(tmp.path) const fixture = await writeZedFixture(tmp.path)