Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
21 changes: 12 additions & 9 deletions packages/opencode/specs/effect/schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,18 @@ Schema at source.
These are the highest-priority next targets. Each is a small, self-contained
schema module with a clear domain.

- [x] `src/account/schema.ts`
- [x] `src/control-plane/schema.ts`
- [x] `src/permission/schema.ts`
- [x] `src/project/schema.ts`
- [x] `src/provider/schema.ts`
- [x] `src/pty/schema.ts`
- [x] `src/question/schema.ts`
- [x] `src/session/schema.ts`
- [x] `src/storage/schema.ts`
- [x] `src/sync/schema.ts`
- [x] `src/tool/schema.ts`
- [x] `src/util/schema.ts`

### Session domain

Expand Down Expand Up @@ -248,15 +251,15 @@ Possible later tightening after the Schema-first migration is stable:
- promote repeated opaque strings and timestamp numbers into branded/newtype
leaf schemas where that adds domain value without changing the wire format

- [ ] `src/session/compaction.ts`
- [ ] `src/session/message-v2.ts`
- [ ] `src/session/message.ts`
- [ ] `src/session/prompt.ts`
- [ ] `src/session/revert.ts`
- [ ] `src/session/session.ts`
- [ ] `src/session/status.ts`
- [ ] `src/session/summary.ts`
- [ ] `src/session/todo.ts`
- [x] `src/session/compaction.ts`
- [x] `src/session/message-v2.ts`
- [x] `src/session/message.ts`
- [x] `src/session/prompt.ts`
- [x] `src/session/revert.ts`
- [x] `src/session/session.ts`
- [x] `src/session/status.ts`
- [x] `src/session/summary.ts`
- [x] `src/session/todo.ts`

### Provider domain

Expand Down
4 changes: 2 additions & 2 deletions packages/opencode/src/acp/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ export class Agent implements ACPAgent {
}

if (part.tool === "todowrite") {
const parsedTodos = z.array(Todo.Info).safeParse(JSON.parse(part.state.output))
const parsedTodos = z.array(Todo.Info.zod).safeParse(JSON.parse(part.state.output))
if (parsedTodos.success) {
await this.connection
.sessionUpdate({
Expand Down Expand Up @@ -901,7 +901,7 @@ export class Agent implements ACPAgent {
}

if (part.tool === "todowrite") {
const parsedTodos = z.array(Todo.Info).safeParse(JSON.parse(part.state.output))
const parsedTodos = z.array(Todo.Info.zod).safeParse(JSON.parse(part.state.output))
if (parsedTodos.success) {
await this.connection
.sessionUpdate({
Expand Down
5 changes: 3 additions & 2 deletions packages/opencode/src/cli/cmd/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { ShareNext } from "../../share"
import { EOL } from "os"
import { Filesystem } from "../../util"
import { AppRuntime } from "@/effect/app-runtime"
import { Schema } from "effect"

/** Discriminated union returned by the ShareNext API (GET /api/shares/:id/data) */
export type ShareData =
Expand Down Expand Up @@ -154,10 +155,10 @@ export const ImportCommand = cmd({
return
}

const info = Session.Info.parse({
const info = Schema.decodeUnknownSync(Session.Info)({
...exportData.info,
projectID: Instance.project.id,
})
}) as Session.Info
const row = Session.toRow(info)
Database.use((db) =>
db
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ export const ExperimentalRoutes = lazy(() =>
description: "List of sessions",
content: {
"application/json": {
schema: resolver(Session.GlobalInfo.array()),
schema: resolver(Session.GlobalInfo.zod.array()),
},
},
},
Expand Down
72 changes: 33 additions & 39 deletions packages/opencode/src/server/routes/instance/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { PermissionID } from "@/permission/schema"
import { ModelID, ProviderID } from "@/provider/schema"
import { errors } from "../../error"
import { lazy } from "@/util/lazy"
import { zodObject } from "@/util/effect-zod"
import { Bus } from "@/bus"
import { NamedError } from "@opencode-ai/shared/util/error"
import { jsonRequest, runRequest } from "./trace"
Expand All @@ -42,7 +43,7 @@ export const SessionRoutes = lazy(() =>
description: "List of sessions",
content: {
"application/json": {
schema: resolver(Session.Info.array()),
schema: resolver(Session.Info.zod.array()),
},
},
},
Expand Down Expand Up @@ -87,7 +88,7 @@ export const SessionRoutes = lazy(() =>
description: "Get session status",
content: {
"application/json": {
schema: resolver(z.record(z.string(), SessionStatus.Info)),
schema: resolver(z.record(z.string(), SessionStatus.Info.zod)),
},
},
},
Expand All @@ -112,7 +113,7 @@ export const SessionRoutes = lazy(() =>
description: "Get session",
content: {
"application/json": {
schema: resolver(Session.Info),
schema: resolver(Session.Info.zod),
},
},
},
Expand All @@ -122,7 +123,7 @@ export const SessionRoutes = lazy(() =>
validator(
"param",
z.object({
sessionID: Session.GetInput,
sessionID: Session.GetInput.zod,
}),
),
async (c) => {
Expand All @@ -145,7 +146,7 @@ export const SessionRoutes = lazy(() =>
description: "List of children",
content: {
"application/json": {
schema: resolver(Session.Info.array()),
schema: resolver(Session.Info.zod.array()),
},
},
},
Expand All @@ -155,7 +156,7 @@ export const SessionRoutes = lazy(() =>
validator(
"param",
z.object({
sessionID: Session.ChildrenInput,
sessionID: Session.ChildrenInput.zod,
}),
),
async (c) => {
Expand All @@ -177,7 +178,7 @@ export const SessionRoutes = lazy(() =>
description: "Todo list",
content: {
"application/json": {
schema: resolver(Todo.Info.array()),
schema: resolver(Todo.Info.zod.array()),
},
},
},
Expand Down Expand Up @@ -210,13 +211,13 @@ export const SessionRoutes = lazy(() =>
description: "Successfully created session",
content: {
"application/json": {
schema: resolver(Session.Info),
schema: resolver(Session.Info.zod),
},
},
},
},
}),
validator("json", Session.CreateInput),
validator("json", Session.CreateInput.zod),
async (c) =>
jsonRequest("SessionRoutes.create", c, function* () {
const body = c.req.valid("json") ?? {}
Expand Down Expand Up @@ -245,7 +246,7 @@ export const SessionRoutes = lazy(() =>
validator(
"param",
z.object({
sessionID: Session.RemoveInput,
sessionID: Session.RemoveInput.zod,
}),
),
async (c) =>
Expand All @@ -267,7 +268,7 @@ export const SessionRoutes = lazy(() =>
description: "Successfully updated session",
content: {
"application/json": {
schema: resolver(Session.Info),
schema: resolver(Session.Info.zod),
},
},
},
Expand Down Expand Up @@ -375,7 +376,7 @@ export const SessionRoutes = lazy(() =>
description: "200",
content: {
"application/json": {
schema: resolver(Session.Info),
schema: resolver(Session.Info.zod),
},
},
},
Expand All @@ -384,14 +385,14 @@ export const SessionRoutes = lazy(() =>
validator(
"param",
z.object({
sessionID: Session.ForkInput.shape.sessionID,
sessionID: SessionID.zod,
}),
),
validator("json", Session.ForkInput.omit({ sessionID: true })),
validator("json", zodObject(Session.ForkInput).omit({ sessionID: true })),
async (c) =>
jsonRequest("SessionRoutes.fork", c, function* () {
const sessionID = c.req.valid("param").sessionID
const body = c.req.valid("json")
const body = c.req.valid("json") as { messageID?: MessageID }
const svc = yield* Session.Service
return yield* svc.fork({ ...body, sessionID })
}),
Expand Down Expand Up @@ -438,7 +439,7 @@ export const SessionRoutes = lazy(() =>
description: "Successfully shared session",
content: {
"application/json": {
schema: resolver(Session.Info),
schema: resolver(Session.Info.zod),
},
},
},
Expand Down Expand Up @@ -480,18 +481,13 @@ export const SessionRoutes = lazy(() =>
validator(
"param",
z.object({
sessionID: SessionSummary.DiffInput.shape.sessionID,
}),
),
validator(
"query",
z.object({
messageID: SessionSummary.DiffInput.shape.messageID,
sessionID: SessionID.zod,
}),
),
validator("query", zodObject(SessionSummary.DiffInput).omit({ sessionID: true })),
async (c) =>
jsonRequest("SessionRoutes.diff", c, function* () {
const query = c.req.valid("query")
const query = c.req.valid("query") as Omit<SessionSummary.DiffInput, "sessionID">
const params = c.req.valid("param")
const summary = yield* SessionSummary.Service
return yield* summary.diff({
Expand All @@ -511,7 +507,7 @@ export const SessionRoutes = lazy(() =>
description: "Successfully unshared session",
content: {
"application/json": {
schema: resolver(Session.Info),
schema: resolver(Session.Info.zod),
},
},
},
Expand Down Expand Up @@ -872,7 +868,7 @@ export const SessionRoutes = lazy(() =>
sessionID: SessionID.zod,
}),
),
validator("json", SessionPrompt.PromptInput.omit({ sessionID: true })),
validator("json", zodObject(SessionPrompt.PromptInput).omit({ sessionID: true })),
async (c) => {
c.status(200)
c.header("Content-Type", "application/json")
Expand Down Expand Up @@ -910,7 +906,7 @@ export const SessionRoutes = lazy(() =>
sessionID: SessionID.zod,
}),
),
validator("json", SessionPrompt.PromptInput.omit({ sessionID: true })),
validator("json", zodObject(SessionPrompt.PromptInput).omit({ sessionID: true })),
async (c) => {
const sessionID = c.req.valid("param").sessionID
const body = c.req.valid("json")
Expand Down Expand Up @@ -960,11 +956,11 @@ export const SessionRoutes = lazy(() =>
sessionID: SessionID.zod,
}),
),
validator("json", SessionPrompt.CommandInput.omit({ sessionID: true })),
validator("json", zodObject(SessionPrompt.CommandInput).omit({ sessionID: true })),
async (c) =>
jsonRequest("SessionRoutes.command", c, function* () {
const sessionID = c.req.valid("param").sessionID
const body = c.req.valid("json")
const body = c.req.valid("json") as Omit<SessionPrompt.CommandInput, "sessionID">
const svc = yield* SessionPrompt.Service
return yield* svc.command({ ...body, sessionID })
}),
Expand Down Expand Up @@ -993,11 +989,11 @@ export const SessionRoutes = lazy(() =>
sessionID: SessionID.zod,
}),
),
validator("json", SessionPrompt.ShellInput.omit({ sessionID: true })),
validator("json", zodObject(SessionPrompt.ShellInput).omit({ sessionID: true })),
async (c) =>
jsonRequest("SessionRoutes.shell", c, function* () {
const sessionID = c.req.valid("param").sessionID
const body = c.req.valid("json")
const body = c.req.valid("json") as Omit<SessionPrompt.ShellInput, "sessionID">
const svc = yield* SessionPrompt.Service
return yield* svc.shell({ ...body, sessionID })
}),
Expand All @@ -1013,7 +1009,7 @@ export const SessionRoutes = lazy(() =>
description: "Updated session",
content: {
"application/json": {
schema: resolver(Session.Info),
schema: resolver(Session.Info.zod),
},
},
},
Expand All @@ -1026,16 +1022,14 @@ export const SessionRoutes = lazy(() =>
sessionID: SessionID.zod,
}),
),
validator("json", SessionRevert.RevertInput.omit({ sessionID: true })),
validator("json", zodObject(SessionRevert.RevertInput).omit({ sessionID: true })),
async (c) => {
const sessionID = c.req.valid("param").sessionID
log.info("revert", c.req.valid("json"))
const body = c.req.valid("json") as Omit<SessionRevert.RevertInput, "sessionID">
log.info("revert", body)
return jsonRequest("SessionRoutes.revert", c, function* () {
const svc = yield* SessionRevert.Service
return yield* svc.revert({
sessionID,
...c.req.valid("json"),
})
return yield* svc.revert({ sessionID, ...body })
})
},
)
Expand All @@ -1050,7 +1044,7 @@ export const SessionRoutes = lazy(() =>
description: "Updated session",
content: {
"application/json": {
schema: resolver(Session.Info),
schema: resolver(Session.Info.zod),
},
},
},
Expand Down
Loading
Loading