1+ import { afterEach , describe , expect } from "bun:test"
2+ import { Database } from "@opencode-ai/core/database/database"
3+ import { Effect , Layer } from "effect"
4+ import { Agent } from "@/agent/agent"
5+ import { BackgroundJob } from "@/background/job"
6+ import { EventV2Bridge } from "@/event-v2-bridge"
7+ import { Config } from "@/config/config"
8+ import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
9+ import { Ripgrep } from "@opencode-ai/core/ripgrep"
10+ import { Session } from "@/session/session"
11+ import { SessionRunState } from "@/session/run-state"
12+ import { SessionStatus } from "@/session/status"
13+ import { Truncate } from "@/tool/truncate"
14+ import { ToolRegistry } from "@/tool/registry"
15+ import { RuntimeFlags } from "@/effect/runtime-flags"
16+ import { InstanceState } from "@/effect/instance-state"
17+ import { disposeAllInstances } from "../fixture/fixture"
18+ import { testEffect } from "../lib/effect"
19+
20+ afterEach ( async ( ) => {
21+ await disposeAllInstances ( )
22+ } )
23+
24+ const layer = Layer . mergeAll (
25+ Agent . defaultLayer ,
26+ BackgroundJob . defaultLayer ,
27+ EventV2Bridge . defaultLayer ,
28+ Config . defaultLayer ,
29+ CrossSpawnSpawner . defaultLayer ,
30+ Session . defaultLayer ,
31+ SessionRunState . defaultLayer ,
32+ SessionStatus . defaultLayer ,
33+ Truncate . defaultLayer ,
34+ ToolRegistry . defaultLayer ,
35+ Database . defaultLayer ,
36+ RuntimeFlags . layer ( { } ) ,
37+ ) . pipe ( Layer . provide ( Ripgrep . defaultLayer ) )
38+
39+ const it = testEffect ( layer )
40+
41+ describe ( "session project inheritance" , ( ) => {
42+ it . instance ( "subagent inherits parent projectID and directory" , ( ) =>
43+ Effect . gen ( function * ( ) {
44+ const sessions = yield * Session . Service
45+ const parent = yield * sessions . create ( { title : "Parent" } )
46+ const child = yield * sessions . create ( { parentID : parent . id , title : "Child" } )
47+
48+ expect ( child . projectID ) . toBe ( parent . projectID )
49+ expect ( child . directory ) . toBe ( parent . directory )
50+ } ) ,
51+ )
52+
53+ it . instance ( "fork inherits original projectID and directory" , ( ) =>
54+ Effect . gen ( function * ( ) {
55+ const sessions = yield * Session . Service
56+ const original = yield * sessions . create ( { title : "Original" } )
57+ const forked = yield * sessions . fork ( { sessionID : original . id } )
58+
59+ expect ( forked . projectID ) . toBe ( original . projectID )
60+ expect ( forked . directory ) . toBe ( original . directory )
61+ } ) ,
62+ )
63+
64+ it . instance ( "session without parentID falls back to the instance project" , ( ) =>
65+ Effect . gen ( function * ( ) {
66+ const sessions = yield * Session . Service
67+ const session = yield * sessions . create ( { title : "Standalone" } )
68+ const ctx = yield * InstanceState . context
69+
70+ expect ( session . projectID ) . toBe ( ctx . project . id )
71+ expect ( session . directory ) . toBe ( ctx . directory )
72+ } ) ,
73+ )
74+ } )
0 commit comments