From ba0755d9331d45f023ffa663de0537d24142c94f Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Fri, 28 Aug 2026 14:56:27 -0400 Subject: [PATCH] refactor(core): reuse platform contract types (#45666) --- packages/core/src/image/photon.ts | 9 ++--- packages/core/src/persistent-pty/index.ts | 35 +++---------------- .../core/src/session/instruction-entry.ts | 11 ++---- packages/core/src/session/instructions.ts | 5 +-- packages/core/src/session/runner/llm.ts | 9 ++--- 5 files changed, 12 insertions(+), 57 deletions(-) diff --git a/packages/core/src/image/photon.ts b/packages/core/src/image/photon.ts index aa314bb95ff..610362bf7c3 100644 --- a/packages/core/src/image/photon.ts +++ b/packages/core/src/image/photon.ts @@ -3,7 +3,7 @@ import { Effect } from "effect" import path from "node:path" import { fileURLToPath } from "node:url" import { FileSystem } from "../filesystem.js" -import { DecodeError, ResizerUnavailableError, SizeError } from "../image.js" +import { DecodeError, ResizerUnavailableError, SizeError, type Limits } from "../image.js" const JPEG_QUALITIES = [80, 85, 70, 55, 40] @@ -33,12 +33,7 @@ export const make = Effect.gen(function* () { return Effect.fn("Image.Photon.normalize")(function* ( resource: string, content: FileSystem.Content & { readonly encoding: "base64" }, - limits: { - readonly autoResize: boolean - readonly maxWidth: number - readonly maxHeight: number - readonly maxBase64Bytes: number - }, + limits: Readonly, ) { const photon = yield* loadPhoton const decoded = yield* Effect.try({ diff --git a/packages/core/src/persistent-pty/index.ts b/packages/core/src/persistent-pty/index.ts index 95d54cd0c36..0f316b69cb7 100644 --- a/packages/core/src/persistent-pty/index.ts +++ b/packages/core/src/persistent-pty/index.ts @@ -4,7 +4,7 @@ import os from "node:os" import path from "node:path" import { Context, Effect, Layer, Schema } from "effect" import { makeGlobalNode } from "@opencode-ai/util/effect/app-node" -import { Added, Handoff, ReadLines, Removed, type ReadResult } from "@opencode-ai/schema/persistent-pty" +import { Added, Handoff, PersistentPty, ReadLines, Removed, type ReadResult } from "@opencode-ai/schema/persistent-pty" import { Session } from "@opencode-ai/schema/session" import { Bus } from "../bus.js" import { Pty } from "@opencode-ai/schema/pty" @@ -26,19 +26,9 @@ export { Handoff } from "@opencode-ai/schema/persistent-pty" export const Options = Schema.Struct({ handoff: Schema.optional(Handoff) }) export type Options = typeof Options.Type -export type Info = Pty.Info & { - readonly sessionID: Session.ID - readonly foregroundProcess: string | null - readonly size: { readonly cols: number; readonly rows: number } - readonly output: { readonly head: number; readonly tail: number } -} +export type Info = PersistentPty.Info -export type Snapshot = { - readonly info: Info - readonly text: string - readonly checkpoint: Uint8Array - readonly cursor: { readonly x: number; readonly y: number } -} +export type Snapshot = PersistentPty.Snapshot export type Attachment = { readonly info: Info @@ -161,15 +151,7 @@ export const configured = (options: Options = {}) => const create = Effect.fn("PersistentPty.create")(function* ( sessionID: Session.ID, - input: { - readonly command?: string - readonly args: readonly string[] - readonly cwd?: string - readonly title: string - readonly env: Readonly> - readonly cols?: number - readonly rows?: number - }, + input: Parameters[1], ) { const response = yield* request( daemon, @@ -338,14 +320,7 @@ export const configured = (options: Options = {}) => const attach = Effect.fn("PersistentPty.attach")(function* ( id: Pty.ID, - input: { - readonly cursor: number - readonly attachmentID: string - readonly role: Role - readonly takeover?: boolean - readonly onEvent: (event: StreamEvent) => void - readonly onEnd: () => void - }, + input: Parameters[1], ) { yield* get(id) const attachment = yield* daemon diff --git a/packages/core/src/session/instruction-entry.ts b/packages/core/src/session/instruction-entry.ts index 21c652d88ad..8a7ed643909 100644 --- a/packages/core/src/session/instruction-entry.ts +++ b/packages/core/src/session/instruction-entry.ts @@ -131,11 +131,7 @@ const layer = Layer.effect( return (yield* rows(sessionID, false)).map((row) => ({ key: row.key, value: row.value })) }) - const put = Effect.fn("InstructionEntry.put")(function* (input: { - readonly sessionID: SessionSchema.ID - readonly key: Key - readonly value: Schema.Json - }) { + const put = Effect.fn("InstructionEntry.put")(function* (input: Parameters[0]) { const actualBytes = Buffer.byteLength(JSON.stringify(input.value), "utf8") if (actualBytes > MaxValueBytes) yield* new ValueTooLargeError({ @@ -159,10 +155,7 @@ const layer = Layer.effect( .pipe(Effect.orDie) }) - const remove = Effect.fn("InstructionEntry.remove")(function* (input: { - readonly sessionID: SessionSchema.ID - readonly key: Key - }) { + const remove = Effect.fn("InstructionEntry.remove")(function* (input: Parameters[0]) { yield* db .update(InstructionEntryTable) .set({ value: null, removed: true, time_updated: Date.now() }) diff --git a/packages/core/src/session/instructions.ts b/packages/core/src/session/instructions.ts index 4a51988bec8..c74b34691c8 100644 --- a/packages/core/src/session/instructions.ts +++ b/packages/core/src/session/instructions.ts @@ -43,10 +43,7 @@ const layer = Layer.effect( // are re-discovered and re-injected instead of staying silently lost. const inFlight = yield* Ref.make>>(new Map()) - const load = Effect.fn("SessionInstructions.load")(function* (input: { - readonly sessionID: SessionSchema.ID - readonly paths: ReadonlyArray - }) { + const load = Effect.fn("SessionInstructions.load")(function* (input: Parameters[0]) { const claimed = yield* Ref.modify(inFlight, (map) => { const existing = map.get(input.sessionID) ?? new Set() const newlyClaimed = input.paths.filter((path) => !existing.has(path)) diff --git a/packages/core/src/session/runner/llm.ts b/packages/core/src/session/runner/llm.ts index 069ebe92a7d..2d10ab75464 100644 --- a/packages/core/src/session/runner/llm.ts +++ b/packages/core/src/session/runner/llm.ts @@ -15,7 +15,7 @@ import { SessionMessage } from "../message.js" import { SessionSchema } from "../schema.js" import { SessionStore } from "../store.js" import { SessionTitle } from "../title.js" -import { DrainResult, Service, type Continuation } from "./index.js" +import { DrainResult, Service, type Interface } from "./index.js" import { Snapshot } from "../../snapshot.js" import { makeLocationNode } from "@opencode-ai/util/effect/app-node" import { llmClient } from "../../effect/app-node-platform.js" @@ -44,12 +44,7 @@ const layer = Layer.effect( // Title generation starts once input is visible and must not delay model execution. const titles = yield* FiberMap.make() - const drain = Effect.fn("SessionRunner.drain")(function* (input: { - readonly sessionID: SessionSchema.ID - readonly force: boolean - readonly continuation?: Continuation - readonly promotable?: SessionInbox.Promotable - }) { + const drain = Effect.fn("SessionRunner.drain")(function* (input: Parameters[0]) { const sessionID = input.sessionID let force = input.force let continuing = input.continuation !== undefined