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
3 changes: 2 additions & 1 deletion packages/opencode/script/seed-e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ const seed = async () => {
const { InstanceBootstrap } = await import("../src/project/bootstrap")
const { Session } = await import("../src/session")
const { Identifier } = await import("../src/id/id")
const { MessageID } = await import("../src/session/schema")
const { Project } = await import("../src/project/project")

await Instance.provide({
directory: dir,
init: InstanceBootstrap,
fn: async () => {
const session = await Session.create({ title })
const messageID = Identifier.descending("message")
const messageID = MessageID.ascending()
const partID = Identifier.descending("part")
const message = {
id: messageID,
Expand Down
3 changes: 2 additions & 1 deletion packages/opencode/src/cli/cmd/debug/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Provider } from "../../../provider/provider"
import { Session } from "../../../session"
import type { MessageV2 } from "../../../session/message-v2"
import { Identifier } from "../../../id/id"
import { MessageID } from "../../../session/schema"
import { ToolRegistry } from "../../../tool/registry"
import { Instance } from "../../../project/instance"
import { PermissionNext } from "../../../permission/next"
Expand Down Expand Up @@ -113,7 +114,7 @@ function parseToolParams(input?: string) {

async function createToolContext(agent: Agent.Info) {
const session = await Session.create({ title: `Debug tool run (${agent.name})` })
const messageID = Identifier.ascending("message")
const messageID = MessageID.ascending()
const model = agent.model ?? (await Provider.defaultModel())
const now = Date.now()
const message: MessageV2.Assistant = {
Expand Down
5 changes: 3 additions & 2 deletions packages/opencode/src/cli/cmd/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { bootstrap } from "../bootstrap"
import { Session } from "../../session"
import type { SessionID } from "../../session/schema"
import { Identifier } from "../../id/id"
import { MessageID } from "../../session/schema"
import { Provider } from "../../provider/provider"
import { Bus } from "../../bus"
import { MessageV2 } from "../../session/message-v2"
Expand Down Expand Up @@ -935,7 +936,7 @@ export const GithubRunCommand = cmd({

const result = await SessionPrompt.prompt({
sessionID: session.id,
messageID: Identifier.ascending("message"),
messageID: MessageID.ascending(),
variant,
model: {
providerID,
Expand Down Expand Up @@ -989,7 +990,7 @@ export const GithubRunCommand = cmd({
console.log("Requesting summary from agent...")
const summary = await SessionPrompt.prompt({
sessionID: session.id,
messageID: Identifier.ascending("message"),
messageID: MessageID.ascending(),
variant,
model: {
providerID,
Expand Down
17 changes: 12 additions & 5 deletions packages/opencode/src/cli/cmd/import.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import type { Argv } from "yargs"
import type { Session as SDKSession, Message, Part } from "@opencode-ai/sdk/v2"
import { Session } from "../../session"
import { SessionID } from "../../session/schema"
import { SessionID, MessageID } from "../../session/schema"
import { WorkspaceID } from "../../control-plane/schema"
import { cmd } from "./cmd"
import { bootstrap } from "../bootstrap"
import { Database } from "../../storage/db"
Expand Down Expand Up @@ -157,7 +158,11 @@ export const ImportCommand = cmd({
...exportData.info,
id: SessionID.make(exportData.info.id),
parentID: exportData.info.parentID ? SessionID.make(exportData.info.parentID) : undefined,
workspaceID: exportData.info.workspaceID ? WorkspaceID.make(exportData.info.workspaceID) : undefined,
projectID: Instance.project.id,
revert: exportData.info.revert
? { ...exportData.info.revert, messageID: MessageID.make(exportData.info.revert.messageID) }
: undefined,
})
Database.use((db) =>
db
Expand All @@ -168,28 +173,30 @@ export const ImportCommand = cmd({
)

for (const msg of exportData.messages) {
const { id: _mid, sessionID: _msid, ...msgData } = msg.info
Database.use((db) =>
db
.insert(MessageTable)
.values({
id: msg.info.id,
id: MessageID.make(msg.info.id),
session_id: row.id,
time_created: msg.info.time?.created ?? Date.now(),
data: msg.info,
data: msgData,
})
.onConflictDoNothing()
.run(),
)

for (const part of msg.parts) {
const { id: _pid, sessionID: _psid, messageID: _pmid, ...partData } = part
Database.use((db) =>
db
.insert(PartTable)
.values({
id: part.id,
message_id: msg.info.id,
message_id: MessageID.make(msg.info.id),
session_id: row.id,
data: part,
data: partData,
})
.onConflictDoNothing()
.run(),
Expand Down
3 changes: 2 additions & 1 deletion packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useSDK } from "@tui/context/sdk"
import { useRoute } from "@tui/context/route"
import { useSync } from "@tui/context/sync"
import { Identifier } from "@/id/id"
import { MessageID } from "@/session/schema"
import { createStore, produce } from "solid-js/store"
import { useKeybind } from "@tui/context/keybind"
import { usePromptHistory, type PromptInfo } from "./history"
Expand Down Expand Up @@ -561,7 +562,7 @@ export function Prompt(props: PromptProps) {
sessionID = res.data.id
}

const messageID = Identifier.ascending("message")
const messageID = MessageID.ascending()
let inputText = store.prompt.input

// Expand pasted text inline before submitting
Expand Down
4 changes: 2 additions & 2 deletions packages/opencode/src/command/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BusEvent } from "@/bus/bus-event"
import { SessionID } from "@/session/schema"
import { SessionID, MessageID } from "@/session/schema"
import z from "zod"
import { Config } from "../config/config"
import { Instance } from "../project/instance"
Expand All @@ -17,7 +17,7 @@ export namespace Command {
name: z.string(),
sessionID: SessionID.zod,
arguments: z.string(),
messageID: Identifier.schema("message"),
messageID: MessageID.zod,
}),
),
}
Expand Down
17 changes: 17 additions & 0 deletions packages/opencode/src/control-plane/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Schema } from "effect"
import z from "zod"

import { withStatics } from "@/util/schema"
import { Identifier } from "@/id/id"

const workspaceIdSchema = Schema.String.pipe(Schema.brand("WorkspaceId"))

export type WorkspaceID = typeof workspaceIdSchema.Type

export const WorkspaceID = workspaceIdSchema.pipe(
withStatics((schema: typeof workspaceIdSchema) => ({
make: (id: string) => schema.makeUnsafe(id),
ascending: (id?: string) => schema.makeUnsafe(Identifier.ascending("workspace", id)),
zod: z.string().startsWith("wrk").pipe(z.custom<WorkspaceID>()),
})),
)
4 changes: 2 additions & 2 deletions packages/opencode/src/control-plane/types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import z from "zod"
import { Identifier } from "@/id/id"
import { ProjectID } from "@/project/schema"
import { WorkspaceID } from "./schema"

export const WorkspaceInfo = z.object({
id: Identifier.schema("workspace"),
id: WorkspaceID.zod,
type: z.string(),
branch: z.string().nullable(),
name: z.string().nullable(),
Expand Down
5 changes: 3 additions & 2 deletions packages/opencode/src/control-plane/workspace-context.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Context } from "../util/context"
import type { WorkspaceID } from "./schema"

interface Context {
workspaceID?: string
workspaceID?: WorkspaceID
}

const context = Context.create<Context>("workspace")

export const WorkspaceContext = {
async provide<R>(input: { workspaceID?: string; fn: () => R }): Promise<R> {
async provide<R>(input: { workspaceID?: WorkspaceID; fn: () => R }): Promise<R> {
return context.provide({ workspaceID: input.workspaceID }, async () => {
return input.fn()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { InstanceBootstrap } from "../../project/bootstrap"
import { SessionRoutes } from "../../server/routes/session"
import { WorkspaceServerRoutes } from "./routes"
import { WorkspaceContext } from "../workspace-context"
import { WorkspaceID } from "../schema"

export namespace WorkspaceServer {
export function App() {
Expand All @@ -20,9 +21,9 @@ export namespace WorkspaceServer {

return new Hono()
.use(async (c, next) => {
const workspaceID = c.req.query("workspace") || c.req.header("x-opencode-workspace")
const rawWorkspaceID = c.req.query("workspace") || c.req.header("x-opencode-workspace")
const raw = c.req.query("directory") || c.req.header("x-opencode-directory")
if (workspaceID == null) {
if (rawWorkspaceID == null) {
throw new Error("workspaceID parameter is required")
}
if (raw == null) {
Expand All @@ -38,7 +39,7 @@ export namespace WorkspaceServer {
})()

return WorkspaceContext.provide({
workspaceID,
workspaceID: WorkspaceID.make(rawWorkspaceID),
async fn() {
return Instance.provide({
directory,
Expand Down
3 changes: 2 additions & 1 deletion packages/opencode/src/control-plane/workspace.sql.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { sqliteTable, text } from "drizzle-orm/sqlite-core"
import { ProjectTable } from "../project/project.sql"
import type { ProjectID } from "../project/schema"
import type { WorkspaceID } from "./schema"

export const WorkspaceTable = sqliteTable("workspace", {
id: text().primaryKey(),
id: text().$type<WorkspaceID>().primaryKey(),
type: text().notNull(),
branch: text(),
name: text(),
Expand Down
10 changes: 5 additions & 5 deletions packages/opencode/src/control-plane/workspace.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import z from "zod"
import { Identifier } from "@/id/id"
import { fn } from "@/util/fn"
import { Database, eq } from "@/storage/db"
import { Project } from "@/project/project"
Expand All @@ -10,6 +9,7 @@ import { ProjectID } from "@/project/schema"
import { WorkspaceTable } from "./workspace.sql"
import { getAdaptor } from "./adaptors"
import { WorkspaceInfo } from "./types"
import { WorkspaceID } from "./schema"
import { parseSSE } from "./sse"

export namespace Workspace {
Expand Down Expand Up @@ -46,15 +46,15 @@ export namespace Workspace {
}

const CreateInput = z.object({
id: Identifier.schema("workspace").optional(),
id: WorkspaceID.zod.optional(),
type: Info.shape.type,
branch: Info.shape.branch,
projectID: ProjectID.zod,
extra: Info.shape.extra,
})

export const create = fn(CreateInput, async (input) => {
const id = Identifier.ascending("workspace", input.id)
const id = WorkspaceID.ascending(input.id)
const adaptor = await getAdaptor(input.type)

const config = await adaptor.configure({ ...input, id, name: null, directory: null })
Expand Down Expand Up @@ -94,13 +94,13 @@ export namespace Workspace {
return rows.map(fromRow).sort((a, b) => a.id.localeCompare(b.id))
}

export const get = fn(Identifier.schema("workspace"), async (id) => {
export const get = fn(WorkspaceID.zod, async (id) => {
const row = Database.use((db) => db.select().from(WorkspaceTable).where(eq(WorkspaceTable.id, id)).get())
if (!row) return
return fromRow(row)
})

export const remove = fn(Identifier.schema("workspace"), async (id) => {
export const remove = fn(WorkspaceID.zod, async (id) => {
const row = Database.use((db) => db.select().from(WorkspaceTable).where(eq(WorkspaceTable.id, id)).get())
if (row) {
const info = fromRow(row)
Expand Down
4 changes: 2 additions & 2 deletions packages/opencode/src/permission/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { BusEvent } from "@/bus/bus-event"
import { Bus } from "@/bus"
import { SessionID } from "@/session/schema"
import { SessionID, MessageID } from "@/session/schema"
import z from "zod"
import { Log } from "../util/log"
import { Identifier } from "../id/id"
Expand All @@ -26,7 +26,7 @@ export namespace Permission {
type: z.string(),
pattern: z.union([z.string(), z.array(z.string())]).optional(),
sessionID: SessionID.zod,
messageID: z.string(),
messageID: MessageID.zod,
callID: z.string().optional(),
message: z.string(),
metadata: z.record(z.string(), z.any()),
Expand Down
4 changes: 2 additions & 2 deletions packages/opencode/src/permission/next.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Bus } from "@/bus"
import { BusEvent } from "@/bus/bus-event"
import { Config } from "@/config/config"
import { Identifier } from "@/id/id"
import { SessionID } from "@/session/schema"
import { SessionID, MessageID } from "@/session/schema"
import { Instance } from "@/project/instance"
import { Database, eq } from "@/storage/db"
import { PermissionTable } from "@/session/session.sql"
Expand Down Expand Up @@ -77,7 +77,7 @@ export namespace PermissionNext {
always: z.string().array(),
tool: z
.object({
messageID: z.string(),
messageID: MessageID.zod,
callID: z.string(),
})
.optional(),
Expand Down
6 changes: 3 additions & 3 deletions packages/opencode/src/question/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Bus } from "@/bus"
import { BusEvent } from "@/bus/bus-event"
import { Identifier } from "@/id/id"
import { SessionID } from "@/session/schema"
import { SessionID, MessageID } from "@/session/schema"
import { Instance } from "@/project/instance"
import { Log } from "@/util/log"
import z from "zod"
Expand Down Expand Up @@ -39,7 +39,7 @@ export namespace Question {
questions: z.array(Info).describe("Questions to ask"),
tool: z
.object({
messageID: z.string(),
messageID: MessageID.zod,
callID: z.string(),
})
.optional(),
Expand Down Expand Up @@ -98,7 +98,7 @@ export namespace Question {
export async function ask(input: {
sessionID: SessionID
questions: Info[]
tool?: { messageID: string; callID: string }
tool?: { messageID: MessageID; callID: string }
}): Promise<Answer[]> {
const s = await state()
const id = Identifier.ascending("question")
Expand Down
14 changes: 7 additions & 7 deletions packages/opencode/src/server/routes/session.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Hono } from "hono"
import { stream } from "hono/streaming"
import { describeRoute, validator, resolver } from "hono-openapi"
import { SessionID } from "@/session/schema"
import { SessionID, MessageID } from "@/session/schema"
import z from "zod"
import { Session } from "../../session"
import { MessageV2 } from "../../session/message-v2"
Expand Down Expand Up @@ -607,7 +607,7 @@ export const SessionRoutes = lazy(() =>
"param",
z.object({
sessionID: SessionID.zod,
messageID: z.string().meta({ description: "Message ID" }),
messageID: MessageID.zod,
}),
),
async (c) => {
Expand Down Expand Up @@ -642,7 +642,7 @@ export const SessionRoutes = lazy(() =>
"param",
z.object({
sessionID: SessionID.zod,
messageID: z.string().meta({ description: "Message ID" }),
messageID: MessageID.zod,
}),
),
async (c) => {
Expand Down Expand Up @@ -676,8 +676,8 @@ export const SessionRoutes = lazy(() =>
"param",
z.object({
sessionID: SessionID.zod,
messageID: z.string().meta({ description: "Message ID" }),
partID: z.string().meta({ description: "Part ID" }),
messageID: MessageID.zod,
partID: z.string(),
}),
),
async (c) => {
Expand Down Expand Up @@ -711,8 +711,8 @@ export const SessionRoutes = lazy(() =>
"param",
z.object({
sessionID: SessionID.zod,
messageID: z.string().meta({ description: "Message ID" }),
partID: z.string().meta({ description: "Part ID" }),
messageID: MessageID.zod,
partID: z.string(),
}),
),
validator("json", MessageV2.Part),
Expand Down
Loading
Loading