From 028bd95123c50836d008c73373450f267234cb79 Mon Sep 17 00:00:00 2001 From: wgu9 <145739220+wgu9@users.noreply.github.com> Date: Sun, 14 Jun 2026 07:30:01 -0700 Subject: [PATCH] fix: silence plugin spinner outside TTY --- packages/opencode/src/cli/cmd/plug.ts | 12 ++++++++++- packages/opencode/test/plugin/install.test.ts | 20 ++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/opencode/src/cli/cmd/plug.ts b/packages/opencode/src/cli/cmd/plug.ts index 1529e9b71df3..d7d0dd12bdd2 100644 --- a/packages/opencode/src/cli/cmd/plug.ts +++ b/packages/opencode/src/cli/cmd/plug.ts @@ -44,8 +44,18 @@ export type PlugCtx = { directory: string } +const noopSpinner: Spin = { + start() {}, + stop() {}, +} + +export function createPlugSpinner(isTTY = Boolean(process.stdout.isTTY)): Spin { + if (!isTTY) return noopSpinner + return spinner() +} + const defaultPlugDeps: PlugDeps = { - spinner: () => spinner(), + spinner: () => createPlugSpinner(), log: { error: (msg) => log.error(msg), info: (msg) => log.info(msg), diff --git a/packages/opencode/test/plugin/install.test.ts b/packages/opencode/test/plugin/install.test.ts index 6dc9175be42a..8ad56909517f 100644 --- a/packages/opencode/test/plugin/install.test.ts +++ b/packages/opencode/test/plugin/install.test.ts @@ -3,7 +3,7 @@ import fs from "fs/promises" import path from "path" import { parse as parseJsonc } from "jsonc-parser" import { Filesystem } from "@/util/filesystem" -import { createPlugTask, type PlugCtx, type PlugDeps } from "../../src/cli/cmd/plug" +import { createPlugSpinner, createPlugTask, type PlugCtx, type PlugDeps } from "../../src/cli/cmd/plug" import { tmpdir } from "../fixture/fixture" function deps(global: string, target: string | Error): PlugDeps { @@ -109,6 +109,24 @@ async function read(file: string) { } describe("plugin.install.task", () => { + test("uses a quiet spinner for non-TTY output", () => { + const writes: string[] = [] + const original = process.stdout.write + process.stdout.write = ((chunk: string | Uint8Array) => { + writes.push(String(chunk)) + return true + }) as typeof process.stdout.write + try { + const spin = createPlugSpinner(false) + spin.start("Installing plugin package...") + spin.stop("Plugin package ready") + } finally { + process.stdout.write = original + } + + expect(writes).toEqual([]) + }) + test("writes both server and tui config entries", async () => { await using tmp = await tmpdir() const target = await plugin(tmp.path, ["server", "tui"])