Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion apps/cli/src/legacy/cli/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ import { OutputFormatFlag } from "../../shared/cli/global-flags.ts";
import { outputLayerFor } from "../../shared/output/output.layer.ts";
import { legacyQuietProgressTextOutputLayer } from "../output/legacy-quiet-progress-text-output.layer.ts";
import { makeGoProxyLayer } from "../../shared/legacy/go-proxy.layer.ts";
import { AiTool } from "../../shared/telemetry/ai-tool.service.ts";
import { aiToolLayer } from "../../shared/telemetry/ai-tool.layer.ts";
import { resolveAgentOutputFormat } from "../../shared/cli/agent-output.ts";
import {
LEGACY_GLOBAL_FLAGS,
LegacyAgentFlag,
Expand Down Expand Up @@ -96,7 +99,7 @@ export const legacyRoot = Command.make("supabase").pipe(
Command.provide(
Layer.unwrap(
Effect.gen(function* () {
const outputFormat = yield* OutputFormatFlag;
const explicitOutputFormat = yield* OutputFormatFlag;
const goOutput = yield* LegacyOutputFlag;
const profile = yield* LegacyProfileFlag;
const debug = yield* LegacyDebugFlag;
Expand All @@ -108,6 +111,10 @@ export const legacyRoot = Command.make("supabase").pipe(
const createTicket = yield* LegacyCreateTicketFlag;
const agent = yield* LegacyAgentFlag;

const aiTool = yield* AiTool.pipe(Effect.provide(aiToolLayer));
const isCodingAgent = agent === "yes" || (agent !== "no" && Option.isSome(aiTool.name));
const outputFormat = resolveAgentOutputFormat(explicitOutputFormat, isCodingAgent);
Comment thread
pamelachia marked this conversation as resolved.
Outdated

// Build args to prepend to every proxy exec call.
// --output: use explicit --output if set, otherwise map from --output-format.
const globalArgs: string[] = [];
Expand Down
10 changes: 8 additions & 2 deletions apps/cli/src/next/cli/root.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { Effect, Layer } from "effect";
import { Effect, Layer, Option } from "effect";
import { CliOutput, Command } from "effect/unstable/cli";
import { OutputFormatFlag } from "../../shared/cli/global-flags.ts";
import { AiTool } from "../../shared/telemetry/ai-tool.service.ts";
import { aiToolLayer } from "../../shared/telemetry/ai-tool.layer.ts";
import { resolveAgentOutputFormat } from "../../shared/cli/agent-output.ts";
import { branchesCommand } from "../commands/branches/branches.command.ts";
import { functionsCommand } from "../commands/functions/functions.command.ts";
import { linkCommand } from "../commands/link/link.command.ts";
Expand Down Expand Up @@ -47,7 +50,10 @@ export const nextRoot = Command.make("supabase").pipe(
Command.provide(
Layer.unwrap(
Effect.gen(function* () {
const outputFormat = yield* OutputFormatFlag;
const explicitOutputFormat = yield* OutputFormatFlag;
const aiTool = yield* AiTool.pipe(Effect.provide(aiToolLayer));
const isCodingAgent = Option.isSome(aiTool.name);
const outputFormat = resolveAgentOutputFormat(explicitOutputFormat, isCodingAgent);
const base = outputLayerFor(outputFormat);
if (outputFormat === "text") return base;
return Layer.merge(base, CliOutput.layer(jsonCliOutputFormatter()));
Expand Down
9 changes: 9 additions & 0 deletions apps/cli/src/shared/cli/agent-output.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Option } from "effect";
import type { OutputFormat } from "../output/types.ts";

export function resolveAgentOutputFormat(
explicit: Option.Option<OutputFormat>,
isCodingAgent: boolean,
): OutputFormat {
return Option.getOrElse(explicit, () => (isCodingAgent ? "json" : "text"));
}
19 changes: 19 additions & 0 deletions apps/cli/src/shared/cli/agent-output.unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Option } from "effect";
import { describe, expect, it } from "vitest";
import { resolveAgentOutputFormat } from "./agent-output.ts";

describe("resolveAgentOutputFormat", () => {
it("defaults a coding agent to json", () => {
expect(resolveAgentOutputFormat(Option.none(), true)).toBe("json");
});

it("defaults a non-agent to text", () => {
expect(resolveAgentOutputFormat(Option.none(), false)).toBe("text");
});

it("honors an explicit format over agent detection", () => {
expect(resolveAgentOutputFormat(Option.some("text"), true)).toBe("text");
expect(resolveAgentOutputFormat(Option.some("stream-json"), false)).toBe("stream-json");
expect(resolveAgentOutputFormat(Option.some("json"), true)).toBe("json");
});
});
3 changes: 1 addition & 2 deletions apps/cli/src/shared/cli/global-flags.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Flag, GlobalFlag } from "effect/unstable/cli";
import type { OutputFormat } from "../output/types.ts";

export const OutputFormatFlag = GlobalFlag.setting("output-format")({
flag: Flag.choice("output-format", ["text", "json", "stream-json"]).pipe(
Flag.withDescription("Output format: text (default), json, or stream-json (NDJSON)"),
Flag.withDefault("text" as OutputFormat),
Flag.optional,
),
});
Loading