refactor(core): convert opencode tests to nodes (#34453)
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
export * as Observability from "./observability"
|
export * as Observability from "./observability"
|
||||||
|
|
||||||
import { NodeFileSystem } from "@effect/platform-node"
|
import { NodeFileSystem } from "@effect/platform-node"
|
||||||
|
import { LayerNode } from "./effect/layer-node"
|
||||||
import { Effect, Layer, Logger, References } from "effect"
|
import { Effect, Layer, Logger, References } from "effect"
|
||||||
import { FetchHttpClient } from "effect/unstable/http"
|
import { FetchHttpClient } from "effect/unstable/http"
|
||||||
import { OtlpSerialization } from "effect/unstable/observability"
|
import { OtlpSerialization } from "effect/unstable/observability"
|
||||||
@@ -19,3 +20,5 @@ export const layer = Layer.unwrap(
|
|||||||
return Layer.merge(logs, yield* Effect.promise(Otlp.tracingLayer))
|
return Layer.merge(logs, yield* Effect.promise(Otlp.tracingLayer))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const node = LayerNode.make({ name: "observability", layer, deps: [] })
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { McpServer } from "@agentclientprotocol/sdk"
|
import type { McpServer } from "@agentclientprotocol/sdk"
|
||||||
import type { Message, Part } from "@opencode-ai/sdk/v2"
|
import type { Message, Part } from "@opencode-ai/sdk/v2"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||||
import { ModelV2 } from "@opencode-ai/core/model"
|
import { ModelV2 } from "@opencode-ai/core/model"
|
||||||
import { Context, Effect, Layer, Ref } from "effect"
|
import { Context, Effect, Layer, Ref } from "effect"
|
||||||
@@ -202,6 +203,8 @@ export const layer = Layer.effect(
|
|||||||
|
|
||||||
export const defaultLayer = layer
|
export const defaultLayer = layer
|
||||||
|
|
||||||
|
export const node = LayerNode.make({ service: Service, layer, deps: [] })
|
||||||
|
|
||||||
function makeSession(input: StoreInput): Info {
|
function makeSession(input: StoreInput): Info {
|
||||||
return {
|
return {
|
||||||
id: input.id,
|
id: input.id,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { expect } from "bun:test"
|
import { expect } from "bun:test"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { Effect, Layer, Option } from "effect"
|
import { Effect, Layer, Option } from "effect"
|
||||||
import { sql } from "drizzle-orm"
|
import { sql } from "drizzle-orm"
|
||||||
|
|
||||||
@@ -13,9 +14,10 @@ const truncate = Layer.effectDiscard(
|
|||||||
yield* db.run(sql`DELETE FROM account_state`)
|
yield* db.run(sql`DELETE FROM account_state`)
|
||||||
yield* db.run(sql`DELETE FROM account`)
|
yield* db.run(sql`DELETE FROM account`)
|
||||||
}),
|
}),
|
||||||
).pipe(Layer.provide(Database.defaultLayer))
|
)
|
||||||
|
const truncateNode = LayerNode.make({ name: "truncate-account", layer: truncate, deps: [Database.node] })
|
||||||
|
|
||||||
const it = testEffect(Layer.merge(AccountRepo.defaultLayer, truncate))
|
const it = testEffect(LayerNode.compile(LayerNode.group([AccountRepo.node, truncateNode])))
|
||||||
|
|
||||||
it.live("list returns empty when no accounts exist", () =>
|
it.live("list returns empty when no accounts exist", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { describe, expect, it } from "bun:test"
|
import { describe, expect, it } from "bun:test"
|
||||||
import type { AgentSideConnection } from "@agentclientprotocol/sdk"
|
import type { AgentSideConnection } from "@agentclientprotocol/sdk"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import type { Event, Message, OpencodeClient, Part, SessionMessageResponse, ToolPart } from "@opencode-ai/sdk/v2"
|
import type { Event, Message, OpencodeClient, Part, SessionMessageResponse, ToolPart } from "@opencode-ai/sdk/v2"
|
||||||
import { Effect, ManagedRuntime } from "effect"
|
import { Effect, ManagedRuntime } from "effect"
|
||||||
import { ACPEvent } from "@/acp/event"
|
import { ACPEvent } from "@/acp/event"
|
||||||
@@ -30,7 +31,7 @@ const pollUntil = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
function makeSessionService() {
|
function makeSessionService() {
|
||||||
return ManagedRuntime.make(ACPSession.defaultLayer).runSync(
|
return ManagedRuntime.make(LayerNode.compile(ACPSession.node)).runSync(
|
||||||
ACPSession.Service.use((service) => Effect.succeed(service)),
|
ACPSession.Service.use((service) => Effect.succeed(service)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import type {
|
|||||||
SessionUpdate,
|
SessionUpdate,
|
||||||
} from "@agentclientprotocol/sdk"
|
} from "@agentclientprotocol/sdk"
|
||||||
import type { Event, OpencodeClient } from "@opencode-ai/sdk/v2"
|
import type { Event, OpencodeClient } from "@opencode-ai/sdk/v2"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { createTwoFilesPatch } from "diff"
|
import { createTwoFilesPatch } from "diff"
|
||||||
import { Effect, ManagedRuntime } from "effect"
|
import { Effect, ManagedRuntime } from "effect"
|
||||||
import { mkdtemp, rm } from "node:fs/promises"
|
import { mkdtemp, rm } from "node:fs/promises"
|
||||||
@@ -37,7 +38,7 @@ const pollUntil = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
function makeSessionService() {
|
function makeSessionService() {
|
||||||
return ManagedRuntime.make(ACPSession.defaultLayer).runSync(
|
return ManagedRuntime.make(LayerNode.compile(ACPSession.node)).runSync(
|
||||||
ACPSession.Service.use((service) => Effect.succeed(service)),
|
ACPSession.Service.use((service) => Effect.succeed(service)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { describe, expect } from "bun:test"
|
import { describe, expect } from "bun:test"
|
||||||
import type { McpServer } from "@agentclientprotocol/sdk"
|
import type { McpServer } from "@agentclientprotocol/sdk"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||||
import { ModelV2 } from "@opencode-ai/core/model"
|
import { ModelV2 } from "@opencode-ai/core/model"
|
||||||
@@ -7,7 +8,7 @@ import * as ACPError from "@/acp/error"
|
|||||||
import * as ACPSession from "@/acp/session"
|
import * as ACPSession from "@/acp/session"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const sessionTest = testEffect(ACPSession.defaultLayer)
|
const sessionTest = testEffect(LayerNode.compile(ACPSession.node))
|
||||||
|
|
||||||
const model = (providerID: string, modelID: string): ACPSession.SelectedModel => ({
|
const model = (providerID: string, modelID: string): ACPSession.SelectedModel => ({
|
||||||
providerID: ProviderV2.ID.make(providerID),
|
providerID: ProviderV2.ID.make(providerID),
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { expect } from "bun:test"
|
import { expect } from "bun:test"
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
import { Agent } from "../../src/agent/agent"
|
import { Agent } from "../../src/agent/agent"
|
||||||
@@ -6,7 +7,7 @@ import { deriveSubagentSessionPermission } from "../../src/agent/subagent-permis
|
|||||||
import { Permission } from "../../src/permission"
|
import { Permission } from "../../src/permission"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(Agent.defaultLayer)
|
const it = testEffect(LayerNode.compile(Agent.node))
|
||||||
|
|
||||||
function testAgent(input: {
|
function testAgent(input: {
|
||||||
name: string
|
name: string
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import { describe, expect } from "bun:test"
|
import { describe, expect } from "bun:test"
|
||||||
import { Effect, Layer } from "effect"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
|
import { Effect } from "effect"
|
||||||
import { Auth } from "../../src/auth"
|
import { Auth } from "../../src/auth"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const node = CrossSpawnSpawner.defaultLayer
|
const it = testEffect(LayerNode.compile(Auth.node))
|
||||||
|
|
||||||
const it = testEffect(Layer.mergeAll(Auth.defaultLayer, node))
|
|
||||||
|
|
||||||
describe("Auth", () => {
|
describe("Auth", () => {
|
||||||
it.instance("set normalizes trailing slashes in keys", () =>
|
it.instance("set normalizes trailing slashes in keys", () =>
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { describe, expect } from "bun:test"
|
import { describe, expect } from "bun:test"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { Deferred, Effect } from "effect"
|
import { Deferred, Effect } from "effect"
|
||||||
import { BackgroundJob } from "@/background/job"
|
import { BackgroundJob } from "@/background/job"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(BackgroundJob.defaultLayer)
|
const it = testEffect(LayerNode.compile(BackgroundJob.node))
|
||||||
|
|
||||||
describe("background.job", () => {
|
describe("background.job", () => {
|
||||||
it.instance("tracks started jobs through completion", () =>
|
it.instance("tracks started jobs through completion", () =>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { afterEach, expect } from "bun:test"
|
import { afterEach, expect } from "bun:test"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
import { fileURLToPath } from "url"
|
import { fileURLToPath } from "url"
|
||||||
@@ -6,7 +7,7 @@ import { InstanceRef } from "../../src/effect/instance-ref"
|
|||||||
import { disposeAllInstances, TestInstance } from "../fixture/fixture"
|
import { disposeAllInstances, TestInstance } from "../fixture/fixture"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(FSUtil.defaultLayer)
|
const it = testEffect(LayerNode.compile(FSUtil.node))
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
await disposeAllInstances()
|
await disposeAllInstances()
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { expect } from "bun:test"
|
import { expect } from "bun:test"
|
||||||
import { Effect, Layer } from "effect"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
import { Effect } from "effect"
|
||||||
import { Config } from "@/config/config"
|
import { Config } from "@/config/config"
|
||||||
import { Agent as AgentSvc } from "../../src/agent/agent"
|
import { Agent as AgentSvc } from "../../src/agent/agent"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(Layer.mergeAll(Config.defaultLayer, AgentSvc.defaultLayer, CrossSpawnSpawner.defaultLayer))
|
const it = testEffect(LayerNode.compile(LayerNode.group([Config.node, AgentSvc.node])))
|
||||||
|
|
||||||
it.instance(
|
it.instance(
|
||||||
"agent color parsed from project config",
|
"agent color parsed from project config",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { expect } from "bun:test"
|
import { expect } from "bun:test"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { Context, Deferred, Effect, Fiber, Layer, Logger } from "effect"
|
import { Context, Deferred, Effect, Fiber, Layer, Logger } from "effect"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||||
import { AppLayer } from "../../src/effect/app-runtime"
|
import { AppLayer } from "../../src/effect/app-runtime"
|
||||||
@@ -9,7 +10,8 @@ import { attach } from "../../src/effect/run-service"
|
|||||||
import { TestInstance } from "../fixture/fixture"
|
import { TestInstance } from "../fixture/fixture"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(CrossSpawnSpawner.defaultLayer)
|
const observabilityLayer = LayerNode.compile(Observability.node)
|
||||||
|
const it = testEffect(LayerNode.compile(CrossSpawnSpawner.node))
|
||||||
|
|
||||||
function check(loggers: ReadonlySet<Logger.Logger<unknown, any>>) {
|
function check(loggers: ReadonlySet<Logger.Logger<unknown, any>>) {
|
||||||
return {
|
return {
|
||||||
@@ -34,7 +36,7 @@ it.live("makeRuntime installs the observability logger", () =>
|
|||||||
)
|
)
|
||||||
|
|
||||||
const current = yield* Dummy.use((svc) => svc.current()).pipe(
|
const current = yield* Dummy.use((svc) => svc.current()).pipe(
|
||||||
Effect.provide(Layer.provideMerge(layer, Observability.layer)),
|
Effect.provide(Layer.provideMerge(layer, observabilityLayer)),
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(current.size).toBeGreaterThan(0)
|
expect(current.size).toBeGreaterThan(0)
|
||||||
@@ -94,6 +96,6 @@ it.instance(
|
|||||||
|
|
||||||
expect(result.directory).toBe(test.directory)
|
expect(result.directory).toBe(test.directory)
|
||||||
expect(result.size).toBeGreaterThan(0)
|
expect(result.size).toBeGreaterThan(0)
|
||||||
}).pipe(Effect.provide(Observability.layer)),
|
}).pipe(Effect.provide(observabilityLayer)),
|
||||||
{ git: true },
|
{ git: true },
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import { describe, test, expect } from "bun:test"
|
import { describe, test, expect } from "bun:test"
|
||||||
import { Effect, Layer } from "effect"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { NodeFileSystem } from "@effect/platform-node"
|
import { Effect } from "effect"
|
||||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
|
|
||||||
const live = FSUtil.layer.pipe(Layer.provide(NodeFileSystem.layer))
|
const { effect: it } = testEffect(LayerNode.compile(FSUtil.node))
|
||||||
const { effect: it } = testEffect(live)
|
|
||||||
|
|
||||||
describe("FSUtil", () => {
|
describe("FSUtil", () => {
|
||||||
describe("isDir", () => {
|
describe("isDir", () => {
|
||||||
|
|||||||
@@ -1,20 +1,18 @@
|
|||||||
import { describe, expect } from "bun:test"
|
import { describe, expect } from "bun:test"
|
||||||
import { Cause, Effect, Exit, Layer } from "effect"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
|
import { Cause, Effect, Exit } from "effect"
|
||||||
import { Image } from "@/image/image"
|
import { Image } from "@/image/image"
|
||||||
|
import { Config } from "@/config/config"
|
||||||
import { MessageID, PartID, SessionID } from "@/session/schema"
|
import { MessageID, PartID, SessionID } from "@/session/schema"
|
||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
import { TestConfig } from "../fixture/config"
|
import { TestConfig } from "../fixture/config"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(Layer.mergeAll(Image.layer.pipe(Layer.provide(TestConfig.layer()))))
|
const it = testEffect(LayerNode.compile(Image.node, [[Config.node, TestConfig.layer()]]))
|
||||||
const tiny = testEffect(
|
const tiny = testEffect(
|
||||||
Layer.mergeAll(
|
LayerNode.compile(Image.node, [
|
||||||
Image.layer.pipe(
|
[Config.node, TestConfig.layer({ get: () => Effect.succeed({ attachment: { image: { max_base64_bytes: 1 } } }) })],
|
||||||
Layer.provide(
|
]),
|
||||||
TestConfig.layer({ get: () => Effect.succeed({ attachment: { image: { max_base64_bytes: 1 } } }) }),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
function part(mime: string, data: string) {
|
function part(mime: string, data: string) {
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"
|
import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { Effect, Layer } from "effect"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
|
import { Effect } from "effect"
|
||||||
import { LSP } from "@/lsp/lsp"
|
import { LSP } from "@/lsp/lsp"
|
||||||
import * as LSPServer from "@/lsp/server"
|
import * as LSPServer from "@/lsp/server"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
|
||||||
import { TestInstance } from "../fixture/fixture"
|
import { TestInstance } from "../fixture/fixture"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(Layer.mergeAll(LSP.defaultLayer, CrossSpawnSpawner.defaultLayer))
|
const it = testEffect(LayerNode.compile(LSP.node))
|
||||||
|
|
||||||
describe("LSP service lifecycle", () => {
|
describe("LSP service lifecycle", () => {
|
||||||
let spawnSpy: ReturnType<typeof spyOn>
|
let spawnSpy: ReturnType<typeof spyOn>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { describe, expect, mock, beforeEach } from "bun:test"
|
import { describe, expect, mock, beforeEach } from "bun:test"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ beforeEach(() => {
|
|||||||
|
|
||||||
// Import MCP after mocking
|
// Import MCP after mocking
|
||||||
const { MCP } = await import("../../src/mcp/index")
|
const { MCP } = await import("../../src/mcp/index")
|
||||||
const it = testEffect(MCP.defaultLayer)
|
const it = testEffect(LayerNode.compile(MCP.node))
|
||||||
|
|
||||||
describe("mcp.headers", () => {
|
describe("mcp.headers", () => {
|
||||||
it.instance("headers are passed to transports when oauth is enabled (default)", () =>
|
it.instance("headers are passed to transports when oauth is enabled (default)", () =>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import path from "node:path"
|
|||||||
import { pathToFileURL } from "node:url"
|
import { pathToFileURL } from "node:url"
|
||||||
import { expect, mock, beforeEach } from "bun:test"
|
import { expect, mock, beforeEach } from "bun:test"
|
||||||
import { ListRootsRequestSchema, ToolListChangedNotificationSchema } from "@modelcontextprotocol/sdk/types.js"
|
import { ListRootsRequestSchema, ToolListChangedNotificationSchema } from "@modelcontextprotocol/sdk/types.js"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { Cause, Effect, Exit } from "effect"
|
import { Cause, Effect, Exit } from "effect"
|
||||||
import type { MCP as MCPNS } from "../../src/mcp/index"
|
import type { MCP as MCPNS } from "../../src/mcp/index"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
@@ -275,7 +276,7 @@ beforeEach(() => {
|
|||||||
const { MCP } = await import("../../src/mcp/index")
|
const { MCP } = await import("../../src/mcp/index")
|
||||||
const { McpOAuthCallback } = await import("../../src/mcp/oauth-callback")
|
const { McpOAuthCallback } = await import("../../src/mcp/oauth-callback")
|
||||||
|
|
||||||
const it = testEffect(MCP.defaultLayer)
|
const it = testEffect(LayerNode.compile(MCP.node))
|
||||||
|
|
||||||
function statusName(status: Record<string, MCPNS.Status> | MCPNS.Status, server: string) {
|
function statusName(status: Record<string, MCPNS.Status> | MCPNS.Status, server: string) {
|
||||||
if ("status" in status) return status.status
|
if ("status" in status) return status.status
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { describe, test, expect, beforeEach, afterEach } from "bun:test"
|
import { describe, test, expect, beforeEach, afterEach } from "bun:test"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
import * as fs from "fs/promises"
|
import * as fs from "fs/promises"
|
||||||
import * as path from "path"
|
import * as path from "path"
|
||||||
@@ -7,7 +8,7 @@ import { Patch } from "../../src/patch"
|
|||||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(FSUtil.defaultLayer)
|
const it = testEffect(LayerNode.compile(FSUtil.node))
|
||||||
|
|
||||||
describe("Patch namespace", () => {
|
describe("Patch namespace", () => {
|
||||||
let tempDir: string
|
let tempDir: string
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { describe, test, expect } from "bun:test"
|
import { describe, test, expect } from "bun:test"
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
import { Permission } from "../src/permission"
|
import { Permission } from "../src/permission"
|
||||||
import { Config } from "@/config/config"
|
import { Config } from "@/config/config"
|
||||||
import { testEffect } from "./lib/effect"
|
import { testEffect } from "./lib/effect"
|
||||||
|
|
||||||
const it = testEffect(Config.defaultLayer)
|
const it = testEffect(LayerNode.compile(Config.node))
|
||||||
|
|
||||||
const load = Config.use.get()
|
const load = Config.use.get()
|
||||||
|
|
||||||
|
|||||||
@@ -2,16 +2,16 @@ import { afterEach, expect } from "bun:test"
|
|||||||
import { existsSync } from "node:fs"
|
import { existsSync } from "node:fs"
|
||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
import { pathToFileURL } from "node:url"
|
import { pathToFileURL } from "node:url"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||||
import { Cause, Effect, Exit, Fiber, Layer } from "effect"
|
import { Cause, Effect, Exit, Fiber, Layer } from "effect"
|
||||||
import { bootstrap as cliBootstrap } from "../../src/cli/bootstrap"
|
import { bootstrap as cliBootstrap } from "../../src/cli/bootstrap"
|
||||||
import { InstanceLayer } from "../../src/project/instance-layer"
|
|
||||||
import { InstanceStore } from "../../src/project/instance-store"
|
import { InstanceStore } from "../../src/project/instance-store"
|
||||||
import { disposeAllInstances, tmpdirScoped } from "../fixture/fixture"
|
import { disposeAllInstances, tmpdirScoped } from "../fixture/fixture"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
import { waitGlobalBusEvent } from "../server/global-bus"
|
import { waitGlobalBusEvent } from "../server/global-bus"
|
||||||
|
|
||||||
const it = testEffect(Layer.mergeAll(InstanceLayer.layer, CrossSpawnSpawner.defaultLayer))
|
const it = testEffect(LayerNode.compile(LayerNode.group([InstanceStore.node, CrossSpawnSpawner.node])))
|
||||||
|
|
||||||
// InstanceBootstrap must run before any code touches the instance —
|
// InstanceBootstrap must run before any code touches the instance —
|
||||||
// originally tracked by PRs #25389 and #25449, now a permanent
|
// originally tracked by PRs #25389 and #25449, now a permanent
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import { describe, expect } from "bun:test"
|
import { describe, expect } from "bun:test"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||||
import { Deferred, Effect, Fiber, Layer } from "effect"
|
import { Deferred, Effect, Fiber, Layer } from "effect"
|
||||||
import { InstanceRef } from "../../src/effect/instance-ref"
|
import { InstanceRef } from "../../src/effect/instance-ref"
|
||||||
import { registerDisposer } from "../../src/effect/instance-registry"
|
import { registerDisposer } from "../../src/effect/instance-registry"
|
||||||
import { InstanceBootstrap } from "../../src/project/bootstrap-service"
|
import { InstanceBootstrap } from "../../src/project/bootstrap"
|
||||||
import { InstanceStore } from "../../src/project/instance-store"
|
import { InstanceStore } from "../../src/project/instance-store"
|
||||||
import { tmpdirScoped } from "../fixture/fixture"
|
import { tmpdirScoped } from "../fixture/fixture"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
@@ -15,7 +16,9 @@ const noopBootstrap = Layer.succeed(
|
|||||||
)
|
)
|
||||||
|
|
||||||
const it = testEffect(
|
const it = testEffect(
|
||||||
Layer.mergeAll(InstanceStore.defaultLayer, CrossSpawnSpawner.defaultLayer).pipe(Layer.provide(noopBootstrap)),
|
LayerNode.compile(LayerNode.group([InstanceStore.node, CrossSpawnSpawner.node]), [
|
||||||
|
[InstanceBootstrap.node, noopBootstrap],
|
||||||
|
]),
|
||||||
)
|
)
|
||||||
|
|
||||||
const setBootstrap = (run: Effect.Effect<void>) =>
|
const setBootstrap = (run: Effect.Effect<void>) =>
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ import { ProjectV2 } from "@opencode-ai/core/project"
|
|||||||
import { SessionID } from "../../src/session/schema"
|
import { SessionID } from "../../src/session/schema"
|
||||||
import { $ } from "bun"
|
import { $ } from "bun"
|
||||||
import { tmpdirScoped } from "../fixture/fixture"
|
import { tmpdirScoped } from "../fixture/fixture"
|
||||||
import { Effect, Layer } from "effect"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||||
|
import { Effect } from "effect"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(Layer.mergeAll(Project.defaultLayer, CrossSpawnSpawner.defaultLayer, Database.defaultLayer))
|
const it = testEffect(LayerNode.compile(LayerNode.group([Project.node, Database.node, CrossSpawnSpawner.node])))
|
||||||
|
|
||||||
function legacySessionID() {
|
function legacySessionID() {
|
||||||
// Global-session migration covers persisted IDs from before prefixed session IDs.
|
// Global-session migration covers persisted IDs from before prefixed session IDs.
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ import { describe, expect } from "bun:test"
|
|||||||
import { $ } from "bun"
|
import { $ } from "bun"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { eq } from "drizzle-orm"
|
import { eq } from "drizzle-orm"
|
||||||
import { Effect, Layer } from "effect"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||||
|
import { Effect } from "effect"
|
||||||
import { Hash } from "@opencode-ai/core/util/hash"
|
import { Hash } from "@opencode-ai/core/util/hash"
|
||||||
import { AbsolutePath } from "@opencode-ai/core/schema"
|
import { AbsolutePath } from "@opencode-ai/core/schema"
|
||||||
import { Database } from "@opencode-ai/core/database/database"
|
import { Database } from "@opencode-ai/core/database/database"
|
||||||
@@ -13,7 +14,7 @@ import { Project } from "@/project/project"
|
|||||||
import { tmpdirScoped } from "../fixture/fixture"
|
import { tmpdirScoped } from "../fixture/fixture"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(Layer.mergeAll(Project.defaultLayer, Database.defaultLayer, CrossSpawnSpawner.defaultLayer))
|
const it = testEffect(LayerNode.compile(LayerNode.group([Project.node, Database.node, CrossSpawnSpawner.node])))
|
||||||
|
|
||||||
function directories(projectID: ProjectV2.ID) {
|
function directories(projectID: ProjectV2.ID) {
|
||||||
return Database.Service.use(({ db }) =>
|
return Database.Service.use(({ db }) =>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { afterEach, describe, expect } from "bun:test"
|
import { afterEach, describe, expect } from "bun:test"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||||
|
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||||
import { parsePatch } from "diff"
|
import { parsePatch } from "diff"
|
||||||
import { Deferred, Effect, Layer } from "effect"
|
import { Deferred, Effect, Layer } from "effect"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
|
||||||
import fs from "fs/promises"
|
import fs from "fs/promises"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import {
|
import {
|
||||||
@@ -24,11 +25,7 @@ import { testEffect } from "../lib/effect"
|
|||||||
|
|
||||||
const weird = process.platform === "win32" ? "space file.txt" : "tab\tfile.txt"
|
const weird = process.platform === "win32" ? "space file.txt" : "tab\tfile.txt"
|
||||||
|
|
||||||
const layer = Layer.mergeAll(
|
const layer = LayerNode.compile(LayerNode.group([Vcs.node, Git.node, EventV2Bridge.node, FSUtil.node, CrossSpawnSpawner.node]))
|
||||||
Vcs.layer.pipe(Layer.provideMerge(Git.defaultLayer), Layer.provideMerge(EventV2Bridge.defaultLayer)),
|
|
||||||
CrossSpawnSpawner.defaultLayer,
|
|
||||||
FSUtil.defaultLayer,
|
|
||||||
)
|
|
||||||
const it = testEffect(layer)
|
const it = testEffect(layer)
|
||||||
const worktreeIt = testEffect(Layer.mergeAll(layer, testInstanceStoreLayer))
|
const worktreeIt = testEffect(Layer.mergeAll(layer, testInstanceStoreLayer))
|
||||||
|
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import { $ } from "bun"
|
|||||||
import { describe, expect } from "bun:test"
|
import { describe, expect } from "bun:test"
|
||||||
import * as fs from "fs/promises"
|
import * as fs from "fs/promises"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { Effect, Layer } from "effect"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
import { Effect } from "effect"
|
||||||
import { Worktree } from "../../src/worktree"
|
import { Worktree } from "../../src/worktree"
|
||||||
import { TestInstance } from "../fixture/fixture"
|
import { TestInstance } from "../fixture/fixture"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(Layer.mergeAll(Worktree.defaultLayer, CrossSpawnSpawner.defaultLayer))
|
const it = testEffect(LayerNode.compile(Worktree.node))
|
||||||
const wintest = process.platform === "win32" ? it.instance : it.instance.skip
|
const wintest = process.platform === "win32" ? it.instance : it.instance.skip
|
||||||
|
|
||||||
describe("Worktree.remove", () => {
|
describe("Worktree.remove", () => {
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
import { afterEach, describe, expect } from "bun:test"
|
import { afterEach, describe, expect } from "bun:test"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
import { Cause, Deferred, Effect, Exit, Fiber } from "effect"
|
||||||
import { Cause, Deferred, Effect, Exit, Fiber, Layer } from "effect"
|
|
||||||
import { GlobalBus, type GlobalEvent } from "../../src/bus/global"
|
import { GlobalBus, type GlobalEvent } from "../../src/bus/global"
|
||||||
import { Git } from "../../src/git"
|
import { Git } from "../../src/git"
|
||||||
import { Worktree } from "../../src/worktree"
|
import { Worktree } from "../../src/worktree"
|
||||||
import { disposeAllInstances, provideInstance, TestInstance } from "../fixture/fixture"
|
import { disposeAllInstances, provideInstance, TestInstance } from "../fixture/fixture"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(
|
const it = testEffect(LayerNode.compile(LayerNode.group([Worktree.node, FSUtil.node, Git.node])))
|
||||||
Layer.mergeAll(Worktree.defaultLayer, FSUtil.defaultLayer, CrossSpawnSpawner.defaultLayer, Git.defaultLayer),
|
|
||||||
)
|
|
||||||
const wintest = process.platform !== "win32" ? it.instance : it.instance.skip
|
const wintest = process.platform !== "win32" ? it.instance : it.instance.skip
|
||||||
|
|
||||||
function normalize(input: string) {
|
function normalize(input: string) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { afterEach, describe, expect, test } from "bun:test"
|
import { afterEach, describe, expect, test } from "bun:test"
|
||||||
import { Effect, Layer } from "effect"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
|
import { Effect } from "effect"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { unlink } from "fs/promises"
|
import { unlink } from "fs/promises"
|
||||||
import { Global } from "@opencode-ai/core/global"
|
import { Global } from "@opencode-ai/core/global"
|
||||||
@@ -12,7 +13,7 @@ import { testEffect } from "../lib/effect"
|
|||||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||||
import { ModelV2 } from "@opencode-ai/core/model"
|
import { ModelV2 } from "@opencode-ai/core/model"
|
||||||
|
|
||||||
const it = testEffect(Layer.mergeAll(Provider.defaultLayer, Env.defaultLayer))
|
const it = testEffect(LayerNode.compile(LayerNode.group([Provider.node, Env.node])))
|
||||||
|
|
||||||
const originalEnv = new Map<string, string | undefined>()
|
const originalEnv = new Map<string, string | undefined>()
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { expect } from "bun:test"
|
import { expect } from "bun:test"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { Provider } from "../../src/provider/provider"
|
import { Provider } from "../../src/provider/provider"
|
||||||
|
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
@@ -6,7 +7,7 @@ import { testEffect } from "../lib/effect"
|
|||||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||||
|
|
||||||
const DIGITALOCEAN = ProviderV2.ID.make("digitalocean")
|
const DIGITALOCEAN = ProviderV2.ID.make("digitalocean")
|
||||||
const it = testEffect(Provider.defaultLayer)
|
const it = testEffect(LayerNode.compile(Provider.node))
|
||||||
|
|
||||||
const withEnv = <A, E, R>(values: Record<string, string>, effect: Effect.Effect<A, E, R>) =>
|
const withEnv = <A, E, R>(values: Record<string, string>, effect: Effect.Effect<A, E, R>) =>
|
||||||
Effect.acquireUseRelease(
|
Effect.acquireUseRelease(
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { afterEach, expect } from "bun:test"
|
import { afterEach, expect } from "bun:test"
|
||||||
import { createServer, type Server } from "node:http"
|
import { createServer, type Server } from "node:http"
|
||||||
import { streamText } from "ai"
|
import { streamText } from "ai"
|
||||||
import { Effect, Layer } from "effect"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||||
|
import { Effect } from "effect"
|
||||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||||
import { ModelV2 } from "@opencode-ai/core/model"
|
import { ModelV2 } from "@opencode-ai/core/model"
|
||||||
import { disposeAllInstances, provideTmpdirInstance } from "../fixture/fixture"
|
import { disposeAllInstances, provideTmpdirInstance } from "../fixture/fixture"
|
||||||
@@ -17,9 +18,7 @@ afterEach(async () => {
|
|||||||
await disposeAllInstances()
|
await disposeAllInstances()
|
||||||
})
|
})
|
||||||
|
|
||||||
const it = testEffect(
|
const it = testEffect(LayerNode.compile(LayerNode.group([Provider.node, Env.node, Plugin.node, CrossSpawnSpawner.node])))
|
||||||
Layer.mergeAll(Provider.defaultLayer, Env.defaultLayer, Plugin.defaultLayer, CrossSpawnSpawner.defaultLayer),
|
|
||||||
)
|
|
||||||
|
|
||||||
it.live("headerTimeout does not abort delayed SSE body after headers arrive", () =>
|
it.live("headerTimeout does not abort delayed SSE body after headers arrive", () =>
|
||||||
Effect.gen(function* () {
|
Effect.gen(function* () {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { afterEach, expect } from "bun:test"
|
import { afterEach, expect } from "bun:test"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { Cause, Effect, Exit, Fiber, Layer, Queue } from "effect"
|
import { Cause, Effect, Exit, Fiber, Layer, Queue } from "effect"
|
||||||
import { Question } from "../../src/question"
|
import { Question } from "../../src/question"
|
||||||
import { InstanceRef } from "../../src/effect/instance-ref"
|
import { InstanceRef } from "../../src/effect/instance-ref"
|
||||||
@@ -10,13 +11,11 @@ import { testEffect } from "../lib/effect"
|
|||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||||
import { EventV2Bridge } from "../../src/event-v2-bridge"
|
import { EventV2Bridge } from "../../src/event-v2-bridge"
|
||||||
|
|
||||||
const it = testEffect(
|
const questionLayer = LayerNode.compile(LayerNode.group([Question.node, EventV2Bridge.node, CrossSpawnSpawner.node]))
|
||||||
Layer.mergeAll(Question.layer.pipe(Layer.provideMerge(EventV2Bridge.defaultLayer)), CrossSpawnSpawner.defaultLayer),
|
const it = testEffect(questionLayer)
|
||||||
)
|
|
||||||
const lifecycle = testEffect(
|
const lifecycle = testEffect(
|
||||||
Layer.mergeAll(
|
Layer.mergeAll(
|
||||||
Question.layer.pipe(Layer.provideMerge(EventV2Bridge.defaultLayer)),
|
questionLayer,
|
||||||
CrossSpawnSpawner.defaultLayer,
|
|
||||||
testInstanceStoreLayer,
|
testInstanceStoreLayer,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,29 +1,26 @@
|
|||||||
import { describe, expect } from "bun:test"
|
import { describe, expect } from "bun:test"
|
||||||
import { SessionV1 } from "@opencode-ai/core/v1/session"
|
import { SessionV1 } from "@opencode-ai/core/v1/session"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
|
import { SessionProjector } from "@opencode-ai/core/session/projector"
|
||||||
import fs from "fs/promises"
|
import fs from "fs/promises"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { Effect, Layer } from "effect"
|
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||||
|
import { Effect } from "effect"
|
||||||
import { Session } from "@/session/session"
|
import { Session } from "@/session/session"
|
||||||
|
|
||||||
import { SessionRevert } from "../../src/session/revert"
|
import { SessionRevert } from "../../src/session/revert"
|
||||||
import { MessageV2 } from "../../src/session/message-v2"
|
import { MessageV2 } from "../../src/session/message-v2"
|
||||||
import { Snapshot } from "../../src/snapshot"
|
import { Snapshot } from "../../src/snapshot"
|
||||||
import { MessageID, PartID, SessionID } from "../../src/session/schema"
|
import { MessageID, PartID, SessionID } from "../../src/session/schema"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
|
||||||
import { provideTmpdirInstance } from "../fixture/fixture"
|
import { provideTmpdirInstance } from "../fixture/fixture"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||||
import { ModelV2 } from "@opencode-ai/core/model"
|
import { ModelV2 } from "@opencode-ai/core/model"
|
||||||
|
|
||||||
const env = Layer.mergeAll(
|
const it = testEffect(
|
||||||
Session.defaultLayer,
|
LayerNode.compile(LayerNode.group([Session.node, SessionRevert.node, Snapshot.node, SessionProjector.node, CrossSpawnSpawner.node])),
|
||||||
SessionRevert.defaultLayer,
|
|
||||||
Snapshot.defaultLayer,
|
|
||||||
CrossSpawnSpawner.defaultLayer,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const it = testEffect(env)
|
|
||||||
|
|
||||||
const user = Effect.fn("test.user")(function* (sessionID: SessionID, agent = "default") {
|
const user = Effect.fn("test.user")(function* (sessionID: SessionID, agent = "default") {
|
||||||
const session = yield* Session.Service
|
const session = yield* Session.Service
|
||||||
return yield* session.updateMessage({
|
return yield* session.updateMessage({
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { describe, expect, beforeAll, afterAll } from "bun:test"
|
import { describe, expect, beforeAll, afterAll } from "bun:test"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||||
import { Effect, Layer } from "effect"
|
import { Effect } from "effect"
|
||||||
import { Discovery } from "../../src/skill/discovery"
|
import { Discovery } from "../../src/skill/discovery"
|
||||||
import { Global } from "@opencode-ai/core/global"
|
import { Global } from "@opencode-ai/core/global"
|
||||||
import { Filesystem } from "@/util/filesystem"
|
import { Filesystem } from "@/util/filesystem"
|
||||||
@@ -18,7 +19,7 @@ let mutableFiles = ["SKILL.md"]
|
|||||||
|
|
||||||
const fixturePath = path.join(import.meta.dir, "../fixture/skills")
|
const fixturePath = path.join(import.meta.dir, "../fixture/skills")
|
||||||
const cacheDir = path.join(Global.Path.cache, "skills")
|
const cacheDir = path.join(Global.Path.cache, "skills")
|
||||||
const it = testEffect(Layer.mergeAll(Discovery.defaultLayer, FSUtil.defaultLayer))
|
const it = testEffect(LayerNode.compile(LayerNode.group([Discovery.node, FSUtil.node])))
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
await rm(cacheDir, { recursive: true, force: true })
|
await rm(cacheDir, { recursive: true, force: true })
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
import { describe, expect } from "bun:test"
|
import { describe, expect } from "bun:test"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import { Effect } from "effect"
|
import { Effect } from "effect"
|
||||||
@@ -11,7 +12,7 @@ import type { Permission } from "../../src/permission"
|
|||||||
import { SessionID, MessageID } from "../../src/session/schema"
|
import { SessionID, MessageID } from "../../src/session/schema"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(CrossSpawnSpawner.defaultLayer)
|
const it = testEffect(LayerNode.compile(CrossSpawnSpawner.node))
|
||||||
|
|
||||||
const baseCtx: Omit<Tool.Context, "ask"> = {
|
const baseCtx: Omit<Tool.Context, "ask"> = {
|
||||||
sessionID: SessionID.make("ses_test"),
|
sessionID: SessionID.make("ses_test"),
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { describe, expect } from "bun:test"
|
import { describe, expect } from "bun:test"
|
||||||
import { Effect, Fiber, Layer, Queue } from "effect"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
|
import { Effect, Fiber, Queue } from "effect"
|
||||||
import { QuestionTool } from "../../src/tool/question"
|
import { QuestionTool } from "../../src/tool/question"
|
||||||
import { Question } from "../../src/question"
|
import { Question } from "../../src/question"
|
||||||
import { SessionID, MessageID } from "../../src/session/schema"
|
import { SessionID, MessageID } from "../../src/session/schema"
|
||||||
import { Agent } from "../../src/agent/agent"
|
import { Agent } from "../../src/agent/agent"
|
||||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
|
||||||
import { Truncate } from "@/tool/truncate"
|
import { Truncate } from "@/tool/truncate"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
import { EventV2Bridge } from "../../src/event-v2-bridge"
|
import { EventV2Bridge } from "../../src/event-v2-bridge"
|
||||||
@@ -20,14 +20,7 @@ const ctx = {
|
|||||||
ask: () => Effect.void,
|
ask: () => Effect.void,
|
||||||
}
|
}
|
||||||
|
|
||||||
const it = testEffect(
|
const it = testEffect(LayerNode.compile(LayerNode.group([Question.node, EventV2Bridge.node, Truncate.node, Agent.node])))
|
||||||
Layer.mergeAll(
|
|
||||||
Question.layer.pipe(Layer.provideMerge(EventV2Bridge.defaultLayer)),
|
|
||||||
CrossSpawnSpawner.defaultLayer,
|
|
||||||
Truncate.defaultLayer,
|
|
||||||
Agent.defaultLayer,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
const pending = Effect.fn("QuestionToolTest.pending")(function* (question: Question.Interface) {
|
const pending = Effect.fn("QuestionToolTest.pending")(function* (question: Question.Interface) {
|
||||||
const events = yield* EventV2Bridge.Service
|
const events = yield* EventV2Bridge.Service
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { describe, expect } from "bun:test"
|
import { describe, expect } from "bun:test"
|
||||||
import { Cause, Effect, Exit, Layer, Schema } from "effect"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
|
import { Cause, Effect, Exit, Schema } from "effect"
|
||||||
import { Agent } from "../../src/agent/agent"
|
import { Agent } from "../../src/agent/agent"
|
||||||
import { MessageID, SessionID } from "../../src/session/schema"
|
import { MessageID, SessionID } from "../../src/session/schema"
|
||||||
import { Tool } from "@/tool/tool"
|
import { Tool } from "@/tool/tool"
|
||||||
import { Truncate } from "@/tool/truncate"
|
import { Truncate } from "@/tool/truncate"
|
||||||
import { testEffect } from "../lib/effect"
|
import { testEffect } from "../lib/effect"
|
||||||
|
|
||||||
const it = testEffect(Layer.mergeAll(Truncate.defaultLayer, Agent.defaultLayer))
|
const it = testEffect(LayerNode.compile(LayerNode.group([Truncate.node, Agent.node])))
|
||||||
|
|
||||||
const params = Schema.Struct({ input: Schema.String })
|
const params = Schema.Struct({ input: Schema.String })
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { describe, test, expect } from "bun:test"
|
import { describe, test, expect } from "bun:test"
|
||||||
import { ConfigV1 } from "@opencode-ai/core/v1/config/config"
|
import { ConfigV1 } from "@opencode-ai/core/v1/config/config"
|
||||||
import { NodeFileSystem } from "@effect/platform-node"
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
|
import { filesystem } from "@opencode-ai/core/effect/app-node-platform"
|
||||||
import { FSUtil } from "@opencode-ai/core/fs-util"
|
import { FSUtil } from "@opencode-ai/core/fs-util"
|
||||||
import { Effect, FileSystem, Layer } from "effect"
|
import { Effect, FileSystem } from "effect"
|
||||||
import { Truncate } from "@/tool/truncate"
|
import { Truncate } from "@/tool/truncate"
|
||||||
import { Config } from "@/config/config"
|
import { Config } from "@/config/config"
|
||||||
import { Identifier } from "../../src/id/id"
|
import { Identifier } from "../../src/id/id"
|
||||||
@@ -15,15 +16,12 @@ import { TestConfig } from "../fixture/config"
|
|||||||
const FIXTURES_DIR = path.join(import.meta.dir, "fixtures")
|
const FIXTURES_DIR = path.join(import.meta.dir, "fixtures")
|
||||||
const ROOT = path.resolve(import.meta.dir, "..", "..")
|
const ROOT = path.resolve(import.meta.dir, "..", "..")
|
||||||
|
|
||||||
const it = testEffect(Layer.mergeAll(Truncate.defaultLayer, NodeFileSystem.layer, FSUtil.defaultLayer))
|
const it = testEffect(LayerNode.compile(LayerNode.group([Truncate.node, FSUtil.node, filesystem])))
|
||||||
|
|
||||||
const configuredLayer = (cfg: ConfigV1.Info) =>
|
const configuredLayer = (cfg: ConfigV1.Info) =>
|
||||||
Layer.mergeAll(
|
LayerNode.compile(LayerNode.group([Truncate.node, FSUtil.node, filesystem, Config.node]), [
|
||||||
Truncate.defaultLayer,
|
[Config.node, TestConfig.layer({ get: () => Effect.succeed(cfg) })],
|
||||||
NodeFileSystem.layer,
|
])
|
||||||
FSUtil.defaultLayer,
|
|
||||||
TestConfig.layer({ get: () => Effect.succeed(cfg) }),
|
|
||||||
)
|
|
||||||
const configuredIt = (cfg: ConfigV1.Info) => testEffect(configuredLayer(cfg))
|
const configuredIt = (cfg: ConfigV1.Info) => testEffect(configuredLayer(cfg))
|
||||||
|
|
||||||
describe("Truncate", () => {
|
describe("Truncate", () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user