From 2f4213d6472d7f84e4c2fcd5e04bc752b946a1e8 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Sun, 22 Mar 2026 20:18:57 -0400 Subject: [PATCH] effectify Project: add Service/Interface/layer for Effect-native consumers --- packages/opencode/src/project/project.ts | 57 ++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/packages/opencode/src/project/project.ts b/packages/opencode/src/project/project.ts index 9aff537db8..c5901ae378 100644 --- a/packages/opencode/src/project/project.ts +++ b/packages/opencode/src/project/project.ts @@ -454,4 +454,61 @@ export namespace Project { }) return data } + + // --------------------------------------------------------------------------- + // Effect service + // --------------------------------------------------------------------------- + + export interface Interface { + readonly fromDirectory: (directory: string) => Effect.Effect<{ project: Info; sandbox: string }> + readonly discover: (input: Info) => Effect.Effect + readonly list: () => Effect.Effect + readonly get: (id: ProjectID) => Effect.Effect + readonly update: (input: UpdateInput) => Effect.Effect + readonly initGit: (input: { directory: string; project: Info }) => Effect.Effect + readonly setInitialized: (id: ProjectID) => Effect.Effect + readonly sandboxes: (id: ProjectID) => Effect.Effect + readonly addSandbox: (id: ProjectID, directory: string) => Effect.Effect + readonly removeSandbox: (id: ProjectID, directory: string) => Effect.Effect + } + + export class Service extends ServiceMap.Service()("@opencode/Project") {} + + export const layer = Layer.effect( + Service, + Effect.gen(function* () { + return Service.of({ + fromDirectory: Effect.fn("Project.fromDirectory")(function* (directory: string) { + return yield* Effect.promise(() => fromDirectory(directory)) + }), + discover: Effect.fn("Project.discover")(function* (input: Info) { + yield* Effect.promise(() => discover(input)) + }), + list: Effect.fn("Project.list")(function* () { + return list() + }), + get: Effect.fn("Project.get")(function* (id: ProjectID) { + return get(id) + }), + update: Effect.fn("Project.update")(function* (input: UpdateInput) { + return yield* Effect.promise(() => update(input)) + }), + initGit: Effect.fn("Project.initGit")(function* (input: { directory: string; project: Info }) { + return yield* Effect.promise(() => initGit(input)) + }), + setInitialized: Effect.fn("Project.setInitialized")(function* (id: ProjectID) { + setInitialized(id) + }), + sandboxes: Effect.fn("Project.sandboxes")(function* (id: ProjectID) { + return yield* Effect.promise(() => sandboxes(id)) + }), + addSandbox: Effect.fn("Project.addSandbox")(function* (id: ProjectID, directory: string) { + yield* Effect.promise(() => addSandbox(id, directory)) + }), + removeSandbox: Effect.fn("Project.removeSandbox")(function* (id: ProjectID, directory: string) { + yield* Effect.promise(() => removeSandbox(id, directory)) + }), + }) + }), + ) }