diff --git a/packages/core/src/tool-output-store.ts b/packages/core/src/tool-output-store.ts index 696ab8a0c4..1030ff22ff 100644 --- a/packages/core/src/tool-output-store.ts +++ b/packages/core/src/tool-output-store.ts @@ -109,7 +109,7 @@ const lineCount = (text: string) => { return count } -export const layer = Layer.effect( +const layer = Layer.effect( Service, Effect.gen(function* () { const fs = yield* FSUtil.Service @@ -192,8 +192,6 @@ export const layer = Layer.effect( }), ) -export const defaultLayer = layer.pipe(Layer.provide(FSUtil.defaultLayer), Layer.provide(Global.defaultLayer)) - export const node = makeLocationNode({ service: Service, layer, deps: [FSUtil.node, Global.node, Config.node] }) export const nodeWithoutConfig = makeLocationNode({ service: Service, layer, deps: [FSUtil.node, Global.node] }) diff --git a/packages/core/src/tool/application-tools.ts b/packages/core/src/tool/application-tools.ts index 3b46c490cb..4d541691b2 100644 --- a/packages/core/src/tool/application-tools.ts +++ b/packages/core/src/tool/application-tools.ts @@ -27,7 +27,7 @@ export interface Interface { export class Service extends Context.Service()("@opencode/ApplicationTools") {} -export const layer = Layer.effect( +const layer = Layer.effect( Service, Effect.gen(function* () { const state = State.create({ diff --git a/packages/core/src/tool/apply-patch.ts b/packages/core/src/tool/apply-patch.ts index c0368f5b16..3d7105a31a 100644 --- a/packages/core/src/tool/apply-patch.ts +++ b/packages/core/src/tool/apply-patch.ts @@ -56,7 +56,7 @@ type Prepared = readonly after: string }) -export const layer = Layer.effectDiscard( +const layer = Layer.effectDiscard( Effect.gen(function* () { const tools = yield* Tools.Service const mutation = yield* LocationMutation.Service diff --git a/packages/core/src/tool/bash.ts b/packages/core/src/tool/bash.ts index 2acd8c5ee7..228818c2dd 100644 --- a/packages/core/src/tool/bash.ts +++ b/packages/core/src/tool/bash.ts @@ -90,7 +90,7 @@ const externalCommandDirectories = (command: string, cwd: string) => { return [...directories] } -export const layer = Layer.effectDiscard( +const layer = Layer.effectDiscard( Effect.gen(function* () { const tools = yield* Tools.Service const mutation = yield* LocationMutation.Service diff --git a/packages/core/src/tool/builtins.ts b/packages/core/src/tool/builtins.ts index da887d3824..a558124378 100644 --- a/packages/core/src/tool/builtins.ts +++ b/packages/core/src/tool/builtins.ts @@ -9,7 +9,6 @@ import { GlobTool } from "./glob" import { GrepTool } from "./grep" import { QuestionTool } from "./question" import { ReadTool } from "./read" -import { ReadToolFileSystem } from "./read-filesystem" import { SkillTool } from "./skill" import { TodoWriteTool } from "./todowrite" import { WebFetchTool } from "./webfetch" @@ -29,21 +28,6 @@ import { WriteTool } from "./write" * repo_clone, repo_overview, plan_exit, and Rune/code mode. Keep MCP and plugin * transforms separate from this static built-in list. */ -export const locationLayer = Layer.mergeAll( - ApplyPatchTool.layer, - BashTool.layer, - EditTool.layer, - GlobTool.layer, - GrepTool.layer, - QuestionTool.layer, - ReadTool.layer.pipe(Layer.provide(ReadToolFileSystem.layer)), - SkillTool.layer, - TodoWriteTool.layer, - WebFetchTool.layer, - WebSearchTool.layer.pipe(Layer.provide(WebSearchTool.defaultConfigLayer)), - WriteTool.layer, -) - export const node = makeLocationNode({ name: "built-in-tools", layer: Layer.empty, diff --git a/packages/core/src/tool/edit.ts b/packages/core/src/tool/edit.ts index 240ca59f83..f0bdb488a0 100644 --- a/packages/core/src/tool/edit.ts +++ b/packages/core/src/tool/edit.ts @@ -87,7 +87,7 @@ export const toModelOutput = (output: Output, oldString: string, newString: stri // TODO: Add snapshots / undo after design exists. // TODO: Add LSP notification and diagnostics after V2 LSP runtime exists. -export const layer = Layer.effectDiscard( +const layer = Layer.effectDiscard( Effect.gen(function* () { const tools = yield* Tools.Service const mutation = yield* LocationMutation.Service diff --git a/packages/core/src/tool/glob.ts b/packages/core/src/tool/glob.ts index 90e666c811..f8bd1869e1 100644 --- a/packages/core/src/tool/glob.ts +++ b/packages/core/src/tool/glob.ts @@ -35,7 +35,7 @@ export const toModelOutput = (output: ModelOutput) => { } /** Glob leaf that defaults its filesystem root to the active Location. */ -export const layer = Layer.effectDiscard( +const layer = Layer.effectDiscard( Effect.gen(function* () { const tools = yield* Tools.Service const ripgrep = yield* Ripgrep.Service diff --git a/packages/core/src/tool/grep.ts b/packages/core/src/tool/grep.ts index 4bd0a1d2da..f455bd4c8a 100644 --- a/packages/core/src/tool/grep.ts +++ b/packages/core/src/tool/grep.ts @@ -50,7 +50,7 @@ export const toModelOutput = (output: ModelOutput) => { } /** Grep leaf that defaults its filesystem root to the active Location. */ -export const layer = Layer.effectDiscard( +const layer = Layer.effectDiscard( Effect.gen(function* () { const tools = yield* Tools.Service const fs = yield* FSUtil.Service diff --git a/packages/core/src/tool/question.ts b/packages/core/src/tool/question.ts index d92a8263cb..e5ae0d7426 100644 --- a/packages/core/src/tool/question.ts +++ b/packages/core/src/tool/question.ts @@ -44,7 +44,7 @@ export const toModelOutput = ( return `User has answered your questions: ${formatted}. You can now continue with the user's answers in mind.` } -export const layer = Layer.effectDiscard( +const layer = Layer.effectDiscard( Effect.gen(function* () { const tools = yield* Tools.Service const question = yield* QuestionV2.Service diff --git a/packages/core/src/tool/read-filesystem.ts b/packages/core/src/tool/read-filesystem.ts index 842e93dd3e..e325a83edd 100644 --- a/packages/core/src/tool/read-filesystem.ts +++ b/packages/core/src/tool/read-filesystem.ts @@ -351,7 +351,7 @@ export const list = Effect.fn("ReadTool.list")(function* (fs: FSUtil.Interface, return new ListPage({ entries: selected, truncated, ...(truncated ? { next: offset + selected.length } : {}) }) }) -export const layer = Layer.effect( +const layer = Layer.effect( Service, Effect.gen(function* () { const fs = yield* FSUtil.Service diff --git a/packages/core/src/tool/read.ts b/packages/core/src/tool/read.ts index 259fdd54ec..6961a86091 100644 --- a/packages/core/src/tool/read.ts +++ b/packages/core/src/tool/read.ts @@ -27,7 +27,7 @@ const LocationInput = Schema.Struct({ const Input = LocationInput const Output = Schema.Union([FileSystem.Content, ReadToolFileSystem.TextPage, ReadToolFileSystem.ListPage]) -export const layer = Layer.effectDiscard( +const layer = Layer.effectDiscard( Effect.gen(function* () { const tools = yield* Tools.Service const reader = yield* ReadToolFileSystem.Service diff --git a/packages/core/src/tool/registry.ts b/packages/core/src/tool/registry.ts index 868ba44672..1c2dfe7ab4 100644 --- a/packages/core/src/tool/registry.ts +++ b/packages/core/src/tool/registry.ts @@ -124,7 +124,7 @@ const registryLayer = Layer.effect( }), ) -export const layer = Layer.effect( +const layer = Layer.effect( Tools.Service, Service.use((registry) => Effect.succeed(Tools.Service.of({ register: registry.register }))), ).pipe(Layer.provideMerge(registryLayer)) @@ -134,11 +134,6 @@ function whollyDisabled(action: string, rules: PermissionV2.Ruleset) { return rule?.resource === "*" && rule.effect === "deny" } -export const defaultLayer = layer.pipe( - Layer.provide(ApplicationTools.layer), - Layer.provide(ToolOutputStore.defaultLayer), -) - export const node = makeLocationNode({ service: Service, layer, diff --git a/packages/core/src/tool/skill.ts b/packages/core/src/tool/skill.ts index f42d731250..1f8b122903 100644 --- a/packages/core/src/tool/skill.ts +++ b/packages/core/src/tool/skill.ts @@ -54,7 +54,7 @@ export const toModelOutput = (skill: SkillV2.Info, files: ReadonlyArray) const unableToLoad = (name: string, error?: unknown) => new ToolFailure({ message: `Unable to load skill ${name}`, error }) -export const layer = Layer.effectDiscard( +const layer = Layer.effectDiscard( Effect.gen(function* () { const tools = yield* Tools.Service const fs = yield* FSUtil.Service diff --git a/packages/core/src/tool/todowrite.ts b/packages/core/src/tool/todowrite.ts index 809ba69e8b..bc1ba1fbb3 100644 --- a/packages/core/src/tool/todowrite.ts +++ b/packages/core/src/tool/todowrite.ts @@ -22,7 +22,7 @@ export type Output = typeof Output.Type export const toModelOutput = (output: Output) => JSON.stringify(output.todos, null, 2) -export const layer = Layer.effectDiscard( +const layer = Layer.effectDiscard( Effect.gen(function* () { const tools = yield* Tools.Service const todos = yield* SessionTodo.Service diff --git a/packages/core/src/tool/webfetch.ts b/packages/core/src/tool/webfetch.ts index 37d4bf4f3f..d3889d6a7a 100644 --- a/packages/core/src/tool/webfetch.ts +++ b/packages/core/src/tool/webfetch.ts @@ -115,7 +115,7 @@ const convert = (content: string, contentType: string, format: Format) => { return content } -export const layer = Layer.effectDiscard( +const layer = Layer.effectDiscard( Effect.gen(function* () { const tools = yield* Tools.Service const http = yield* HttpClient.HttpClient diff --git a/packages/core/src/tool/websearch.ts b/packages/core/src/tool/websearch.ts index 4ec77cdc57..6d62236316 100644 --- a/packages/core/src/tool/websearch.ts +++ b/packages/core/src/tool/websearch.ts @@ -189,7 +189,7 @@ const Output = Schema.Struct({ text: Schema.String, }) -export const layer = Layer.effectDiscard( +const layer = Layer.effectDiscard( Effect.gen(function* () { const tools = yield* Tools.Service const http = yield* HttpClient.HttpClient diff --git a/packages/core/src/tool/write.ts b/packages/core/src/tool/write.ts index 01c9eb4fca..39ad0b20fb 100644 --- a/packages/core/src/tool/write.ts +++ b/packages/core/src/tool/write.ts @@ -44,7 +44,7 @@ export const toModelOutput = (output: Output) => // TODO: Add snapshots / undo after design exists. // TODO: Add LSP notification and diagnostics after V2 LSP runtime exists. -export const layer = Layer.effectDiscard( +const layer = Layer.effectDiscard( Effect.gen(function* () { const tools = yield* Tools.Service const mutation = yield* LocationMutation.Service diff --git a/packages/sdk-next/src/opencode.ts b/packages/sdk-next/src/opencode.ts index 5256548efc..096b46d4b7 100644 --- a/packages/sdk-next/src/opencode.ts +++ b/packages/sdk-next/src/opencode.ts @@ -1,4 +1,6 @@ import { OpenCode } from "@opencode-ai/client/effect" +import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder" +import { LayerNode } from "@opencode-ai/core/effect/layer-node" import { PermissionSaved } from "@opencode-ai/core/permission/saved" import { ApplicationTools } from "@opencode-ai/core/tool/application-tools" import { createEmbeddedRoutes } from "@opencode-ai/server/routes" @@ -9,7 +11,7 @@ export const create = Effect.fn("OpenCode.create")(function* () { const scope = yield* Scope.Scope const memoMap = yield* Layer.makeMemoMap const context = yield* Layer.buildWithMemoMap( - Layer.merge(ApplicationTools.layer, PermissionSaved.defaultLayer), + AppNodeBuilder.build(LayerNode.group([ApplicationTools.node, PermissionSaved.node])), memoMap, scope, )