summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorKit Langton <[email protected]>2026-04-10 19:46:52 -0400
committerGitHub <[email protected]>2026-04-10 19:46:52 -0400
commitcf27a733971ebde73d3c986dfc8ace0336b0234b (patch)
tree1cabe02d82f88d5a438e0ae7502be025a7a8932b
parentf2c492a8e6efd3fb20d8d494345cd41d72aa4351 (diff)
downloadopencode-cf27a733971ebde73d3c986dfc8ace0336b0234b.tar.gz
opencode-cf27a733971ebde73d3c986dfc8ace0336b0234b.zip
feat: add AppRuntime for unified service composition (#21953)
-rw-r--r--packages/opencode/src/bus/index.ts2
-rw-r--r--packages/opencode/src/effect/app-runtime.ts100
-rw-r--r--packages/opencode/src/mcp/auth.ts2
-rw-r--r--packages/opencode/src/project/vcs.ts2
-rw-r--r--packages/opencode/src/pty/index.ts2
-rw-r--r--packages/opencode/src/session/prompt.ts2
-rw-r--r--packages/opencode/src/worktree/index.ts2
7 files changed, 107 insertions, 5 deletions
diff --git a/packages/opencode/src/bus/index.ts b/packages/opencode/src/bus/index.ts
index 6db4eb04f..87b08d610 100644
--- a/packages/opencode/src/bus/index.ts
+++ b/packages/opencode/src/bus/index.ts
@@ -169,6 +169,8 @@ export namespace Bus {
}),
)
+ export const defaultLayer = layer
+
const { runPromise, runSync } = makeRuntime(Service, layer)
// runSync is safe here because the subscribe chain (InstanceState.get, PubSub.subscribe,
diff --git a/packages/opencode/src/effect/app-runtime.ts b/packages/opencode/src/effect/app-runtime.ts
new file mode 100644
index 000000000..674ca1a2a
--- /dev/null
+++ b/packages/opencode/src/effect/app-runtime.ts
@@ -0,0 +1,100 @@
+import { Layer, ManagedRuntime } from "effect"
+import { memoMap } from "./run-service"
+import { Observability } from "./oltp"
+
+import { AppFileSystem } from "@/filesystem"
+import { Bus } from "@/bus"
+import { Auth } from "@/auth"
+import { Account } from "@/account"
+import { Config } from "@/config/config"
+import { Git } from "@/git"
+import { Ripgrep } from "@/file/ripgrep"
+import { FileTime } from "@/file/time"
+import { File } from "@/file"
+import { FileWatcher } from "@/file/watcher"
+import { Storage } from "@/storage/storage"
+import { Snapshot } from "@/snapshot"
+import { Plugin } from "@/plugin"
+import { Provider } from "@/provider/provider"
+import { ProviderAuth } from "@/provider/auth"
+import { Agent } from "@/agent/agent"
+import { Skill } from "@/skill"
+import { Discovery } from "@/skill/discovery"
+import { Question } from "@/question"
+import { Permission } from "@/permission"
+import { Todo } from "@/session/todo"
+import { Session } from "@/session"
+import { SessionStatus } from "@/session/status"
+import { SessionRunState } from "@/session/run-state"
+import { SessionProcessor } from "@/session/processor"
+import { SessionCompaction } from "@/session/compaction"
+import { SessionRevert } from "@/session/revert"
+import { SessionSummary } from "@/session/summary"
+import { SessionPrompt } from "@/session/prompt"
+import { Instruction } from "@/session/instruction"
+import { LLM } from "@/session/llm"
+import { LSP } from "@/lsp"
+import { MCP } from "@/mcp"
+import { McpAuth } from "@/mcp/auth"
+import { Command } from "@/command"
+import { Truncate } from "@/tool/truncate"
+import { ToolRegistry } from "@/tool/registry"
+import { Format } from "@/format"
+import { Project } from "@/project/project"
+import { Vcs } from "@/project/vcs"
+import { Worktree } from "@/worktree"
+import { Pty } from "@/pty"
+import { Installation } from "@/installation"
+import { ShareNext } from "@/share/share-next"
+import { SessionShare } from "@/share/session"
+
+export const AppLayer = Layer.mergeAll(
+ Observability.layer,
+ AppFileSystem.defaultLayer,
+ Bus.defaultLayer,
+ Auth.defaultLayer,
+ Account.defaultLayer,
+ Config.defaultLayer,
+ Git.defaultLayer,
+ Ripgrep.defaultLayer,
+ FileTime.defaultLayer,
+ File.defaultLayer,
+ FileWatcher.defaultLayer,
+ Storage.defaultLayer,
+ Snapshot.defaultLayer,
+ Plugin.defaultLayer,
+ Provider.defaultLayer,
+ ProviderAuth.defaultLayer,
+ Agent.defaultLayer,
+ Skill.defaultLayer,
+ Discovery.defaultLayer,
+ Question.defaultLayer,
+ Permission.defaultLayer,
+ Todo.defaultLayer,
+ Session.defaultLayer,
+ SessionStatus.defaultLayer,
+ SessionRunState.defaultLayer,
+ SessionProcessor.defaultLayer,
+ SessionCompaction.defaultLayer,
+ SessionRevert.defaultLayer,
+ SessionSummary.defaultLayer,
+ SessionPrompt.defaultLayer,
+ Instruction.defaultLayer,
+ LLM.defaultLayer,
+ LSP.defaultLayer,
+ MCP.defaultLayer,
+ McpAuth.defaultLayer,
+ Command.defaultLayer,
+ Truncate.defaultLayer,
+ ToolRegistry.defaultLayer,
+ Format.defaultLayer,
+ Project.defaultLayer,
+ Vcs.defaultLayer,
+ Worktree.defaultLayer,
+ Pty.defaultLayer,
+ Installation.defaultLayer,
+ ShareNext.defaultLayer,
+ SessionShare.defaultLayer,
+)
+
+export const AppRuntime = ManagedRuntime.make(AppLayer, { memoMap })
diff --git a/packages/opencode/src/mcp/auth.ts b/packages/opencode/src/mcp/auth.ts
index 773ca0a6f..e9c3db8a9 100644
--- a/packages/opencode/src/mcp/auth.ts
+++ b/packages/opencode/src/mcp/auth.ts
@@ -141,7 +141,7 @@ export namespace McpAuth {
}),
)
- const defaultLayer = layer.pipe(Layer.provide(AppFileSystem.defaultLayer))
+ export const defaultLayer = layer.pipe(Layer.provide(AppFileSystem.defaultLayer))
const { runPromise } = makeRuntime(Service, defaultLayer)
diff --git a/packages/opencode/src/project/vcs.ts b/packages/opencode/src/project/vcs.ts
index d31dff6a9..0e430d41b 100644
--- a/packages/opencode/src/project/vcs.ts
+++ b/packages/opencode/src/project/vcs.ts
@@ -226,7 +226,7 @@ export namespace Vcs {
}),
)
- const defaultLayer = layer.pipe(
+ export const defaultLayer = layer.pipe(
Layer.provide(Git.defaultLayer),
Layer.provide(AppFileSystem.defaultLayer),
Layer.provide(Bus.layer),
diff --git a/packages/opencode/src/pty/index.ts b/packages/opencode/src/pty/index.ts
index 7695b9ce6..ff44de73b 100644
--- a/packages/opencode/src/pty/index.ts
+++ b/packages/opencode/src/pty/index.ts
@@ -359,7 +359,7 @@ export namespace Pty {
}),
)
- const defaultLayer = layer.pipe(Layer.provide(Bus.layer), Layer.provide(Plugin.defaultLayer))
+ export const defaultLayer = layer.pipe(Layer.provide(Bus.layer), Layer.provide(Plugin.defaultLayer))
const { runPromise } = makeRuntime(Service, defaultLayer)
diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts
index 66740cd40..fe54a25ab 100644
--- a/packages/opencode/src/session/prompt.ts
+++ b/packages/opencode/src/session/prompt.ts
@@ -1672,7 +1672,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the
}),
)
- const defaultLayer = Layer.suspend(() =>
+ export const defaultLayer = Layer.suspend(() =>
layer.pipe(
Layer.provide(SessionRunState.defaultLayer),
Layer.provide(SessionStatus.defaultLayer),
diff --git a/packages/opencode/src/worktree/index.ts b/packages/opencode/src/worktree/index.ts
index e0e7dab4c..dc1548300 100644
--- a/packages/opencode/src/worktree/index.ts
+++ b/packages/opencode/src/worktree/index.ts
@@ -590,7 +590,7 @@ export namespace Worktree {
}),
)
- const defaultLayer = layer.pipe(
+ export const defaultLayer = layer.pipe(
Layer.provide(Git.defaultLayer),
Layer.provide(CrossSpawnSpawner.defaultLayer),
Layer.provide(Project.defaultLayer),