diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 4950be084c..2de4bbd308 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -46,8 +46,6 @@ import { Truncate } from "@/tool/truncate" import { decodeDataUrl } from "@/util/data-url" import { Process } from "@/util/process" import { Cause, Effect, Exit, Latch, Layer, Option, Scope, Context, Schema, Types } from "effect" -import { zod } from "@opencode-ai/core/effect-zod" -import { withStatics } from "@opencode-ai/core/schema" import * as EffectLogger from "@opencode-ai/core/effect/logger" import { InstanceState } from "@/effect/instance-state" import { TaskTool, type TaskPromptOps } from "@/tool/task" @@ -2054,14 +2052,12 @@ export const PromptInput = Schema.Struct({ MessageV2.SubtaskPartInput, ]).annotate({ discriminator: "type" }), ), -}).pipe(withStatics((s) => ({ zod: zod(s) }))) +}) export type PromptInput = Schema.Schema.Type export class LoopInput extends Schema.Class("SessionPrompt.LoopInput")({ sessionID: SessionID, -}) { - static readonly zod = zod(this) -} +}) {} export const ShellInput = Schema.Struct({ sessionID: SessionID, @@ -2069,7 +2065,7 @@ export const ShellInput = Schema.Struct({ agent: Schema.String, model: Schema.optional(ModelRef), command: Schema.String, -}).pipe(withStatics((s) => ({ zod: zod(s) }))) +}) export type ShellInput = Schema.Schema.Type export const CommandInput = Schema.Struct({ @@ -2097,7 +2093,7 @@ export const CommandInput = Schema.Struct({ ]).annotate({ discriminator: "type" }), ), ), -}).pipe(withStatics((s) => ({ zod: zod(s) }))) +}) export type CommandInput = Schema.Schema.Type /** @internal Exported for testing */ diff --git a/packages/opencode/src/session/session.ts b/packages/opencode/src/session/session.ts index f50f8750b3..92b4329e6f 100644 --- a/packages/opencode/src/session/session.ts +++ b/packages/opencode/src/session/session.ts @@ -37,8 +37,7 @@ import type { Provider } from "@/provider/provider" import { Permission } from "@/permission" import { Global } from "@opencode-ai/core/global" import { Effect, Layer, Option, Context, Schema, Types } from "effect" -import { zod } from "@opencode-ai/core/effect-zod" -import { NonNegativeInt, optionalOmitUndefined, withStatics } from "@opencode-ai/core/schema" +import { NonNegativeInt, optionalOmitUndefined } from "@opencode-ai/core/schema" const log = Log.create({ service: "session" }) @@ -193,26 +192,20 @@ export const Info = Schema.Struct({ time: Time, permission: optionalOmitUndefined(Permission.Ruleset), revert: optionalOmitUndefined(Revert), -}) - .annotate({ identifier: "Session" }) - .pipe(withStatics((s) => ({ zod: zod(s) }))) +}).annotate({ identifier: "Session" }) export type Info = Types.DeepMutable> export const ProjectInfo = Schema.Struct({ id: ProjectID, name: optionalOmitUndefined(Schema.String), worktree: Schema.String, -}) - .annotate({ identifier: "ProjectSummary" }) - .pipe(withStatics((s) => ({ zod: zod(s) }))) +}).annotate({ identifier: "ProjectSummary" }) export type ProjectInfo = Types.DeepMutable> export const GlobalInfo = Schema.Struct({ ...Info.fields, project: Schema.NullOr(ProjectInfo), -}) - .annotate({ identifier: "GlobalSession" }) - .pipe(withStatics((s) => ({ zod: zod(s) }))) +}).annotate({ identifier: "GlobalSession" }) export type GlobalInfo = Types.DeepMutable> export const CreateInput = Schema.optional( @@ -224,36 +217,34 @@ export const CreateInput = Schema.optional( permission: Schema.optional(Permission.Ruleset), workspaceID: Schema.optional(WorkspaceID), }), -).pipe(withStatics((s) => ({ zod: zod(s) }))) +) export type CreateInput = Types.DeepMutable> export const ForkInput = Schema.Struct({ sessionID: SessionID, messageID: Schema.optional(MessageID), -}).pipe(withStatics((s) => ({ zod: zod(s) }))) +}) export const GetInput = SessionID export const ChildrenInput = SessionID export const RemoveInput = SessionID -export const SetTitleInput = Schema.Struct({ sessionID: SessionID, title: Schema.String }).pipe( - withStatics((s) => ({ zod: zod(s) })), -) +export const SetTitleInput = Schema.Struct({ sessionID: SessionID, title: Schema.String }) export const SetArchivedInput = Schema.Struct({ sessionID: SessionID, time: Schema.optional(ArchivedTimestamp), -}).pipe(withStatics((s) => ({ zod: zod(s) }))) +}) export const SetPermissionInput = Schema.Struct({ sessionID: SessionID, permission: Permission.Ruleset, -}).pipe(withStatics((s) => ({ zod: zod(s) }))) +}) export const SetRevertInput = Schema.Struct({ sessionID: SessionID, revert: Schema.optional(Revert), summary: Schema.optional(Summary), -}).pipe(withStatics((s) => ({ zod: zod(s) }))) +}) export const MessagesInput = Schema.Struct({ sessionID: SessionID, limit: Schema.optional(NonNegativeInt), -}).pipe(withStatics((s) => ({ zod: zod(s) }))) +}) export type ListInput = { directory?: string scope?: "project" diff --git a/packages/opencode/test/server/global-session-list.test.ts b/packages/opencode/test/server/global-session-list.test.ts index 9368089511..04348e5c0d 100644 --- a/packages/opencode/test/server/global-session-list.test.ts +++ b/packages/opencode/test/server/global-session-list.test.ts @@ -1,7 +1,5 @@ import { describe, expect, test } from "bun:test" import { Effect } from "effect" -import z from "zod" -import { Instance } from "../../src/project/instance" import { WithInstance } from "../../src/project/with-instance" import { Project } from "@/project/project" import { Session as SessionNs } from "@/session/session" @@ -19,7 +17,7 @@ const svc = { create(input?: SessionNs.CreateInput) { return run(SessionNs.Service.use((svc) => svc.create(input))) }, - setArchived(input: z.output) { + setArchived(input: typeof SessionNs.SetArchivedInput.Type) { return run(SessionNs.Service.use((svc) => svc.setArchived(input))) }, } diff --git a/packages/opencode/test/session/schema-decoding.test.ts b/packages/opencode/test/session/schema-decoding.test.ts index 4422c5b719..c0201a475f 100644 --- a/packages/opencode/test/session/schema-decoding.test.ts +++ b/packages/opencode/test/session/schema-decoding.test.ts @@ -49,7 +49,6 @@ describe("Session.Info", () => { time: { created: 1, updated: 2 }, } expect(decode(input)).toEqual(input) - expect(Session.Info.zod.parse(input)).toEqual(input) }) test("round-trips every optional field", () => { @@ -80,7 +79,6 @@ describe("Session.Info", () => { }, } expect(decode(input)).toEqual(input) - expect(Session.Info.zod.parse(input)).toEqual(input) }) test("accepts migrated summary diffs without file details", () => { @@ -100,19 +98,16 @@ describe("Session.Info", () => { time: { created: 1, updated: 2 }, } expect(decode(input)).toEqual(input) - expect(Session.Info.zod.parse(input)).toEqual(input) }) test("rejects unbranded session id", () => { const bad = { id: "not-a-session-id" } as unknown expect(() => decode(bad)).toThrow() - expect(() => Session.Info.zod.parse(bad)).toThrow() }) test("rejects missing required fields", () => { const bad = { id: sessionID } as unknown expect(() => decode(bad)).toThrow() - expect(() => Session.Info.zod.parse(bad)).toThrow() }) }) @@ -124,8 +119,6 @@ describe("Session.ProjectInfo", () => { const withName = { ...noName, name: "alpha" } expect(decode(noName)).toEqual(noName) expect(decode(withName)).toEqual(withName) - expect(Session.ProjectInfo.zod.parse(noName)).toEqual(noName) - expect(Session.ProjectInfo.zod.parse(withName)).toEqual(withName) }) }) @@ -144,7 +137,6 @@ describe("Session.GlobalInfo", () => { project: null, } expect(decode(input)).toEqual(input) - expect(Session.GlobalInfo.zod.parse(input)).toEqual(input) }) test("accepts populated project", () => { @@ -159,7 +151,6 @@ describe("Session.GlobalInfo", () => { project: { id: projectID, worktree: "/tmp/wt", name: "alpha" }, } expect(decode(input)).toEqual(input) - expect(Session.GlobalInfo.zod.parse(input)).toEqual(input) }) }) @@ -167,7 +158,6 @@ describe("Session input schemas", () => { test("CreateInput accepts undefined and populated forms", () => { const decode = decodeUnknown(Session.CreateInput) expect(decode(undefined)).toBeUndefined() - expect(Session.CreateInput.zod.parse(undefined)).toBeUndefined() const populated = { parentID: sessionID, @@ -176,23 +166,19 @@ describe("Session input schemas", () => { workspaceID, } expect(decode(populated)).toEqual(populated) - expect(Session.CreateInput.zod.parse(populated)).toEqual(populated) }) test("ForkInput round-trips", () => { const decode = decodeUnknown(Session.ForkInput) const input = { sessionID, messageID } expect(decode(input)).toEqual(input) - expect(Session.ForkInput.zod.parse(input)).toEqual(input) // messageID is optional const bare = { sessionID } expect(decode(bare)).toEqual(bare) - expect(Session.ForkInput.zod.parse(bare)).toEqual(bare) }) test("SetTitleInput rejects missing title", () => { expect(() => decodeUnknown(Session.SetTitleInput)({ sessionID })).toThrow() - expect(() => Session.SetTitleInput.zod.parse({ sessionID })).toThrow() }) test("SetArchivedInput accepts both with and without time", () => { @@ -282,7 +268,6 @@ describe("SessionPrompt input schemas", () => { test("LoopInput is just sessionID", () => { const decode = decodeUnknown(SessionPrompt.LoopInput) expect(decode({ sessionID })).toEqual({ sessionID }) - expect(SessionPrompt.LoopInput.zod.parse({ sessionID } as unknown)).toEqual({ sessionID }) }) test("ShellInput requires agent + command", () => { @@ -290,7 +275,6 @@ describe("SessionPrompt input schemas", () => { const expected = { sessionID, agent: "build", command: "echo hi" } const input: unknown = expected expect(decode(input)).toEqual(expected) - expect(SessionPrompt.ShellInput.zod.parse(input as unknown)).toEqual(expected) expect(() => decode({ sessionID })).toThrow() }) @@ -308,9 +292,6 @@ describe("SessionPrompt input schemas", () => { expect(decoded.parts).toHaveLength(2) expect(decoded.parts[0]).toMatchObject({ type: "text", text: "hello" }) expect(decoded.parts[1]).toMatchObject({ type: "file", mime: "image/png" }) - - const viaZod = SessionPrompt.PromptInput.zod.parse(input) - expect(viaZod.parts).toHaveLength(2) }) test("PromptInput rejects unknown part type", () => { @@ -320,7 +301,6 @@ describe("SessionPrompt input schemas", () => { parts: [{ type: "nonsense", payload: 42 }], } expect(() => decode(bad)).toThrow() - expect(() => SessionPrompt.PromptInput.zod.parse(bad)).toThrow() }) test("CommandInput round-trips core fields", () => { @@ -332,6 +312,5 @@ describe("SessionPrompt input schemas", () => { } const input: unknown = expected expect(decode(input)).toEqual(expected) - expect(SessionPrompt.CommandInput.zod.parse(input)).toEqual(expected) }) })