@@ -110,6 +110,8 @@ async function writeConfig(dir: string, config: object, name = "opencode.json")
110110
111111const writeConfigEffect = ( dir : string , config : object , name = "opencode.json" ) =>
112112 Effect . promise ( ( ) => writeConfig ( dir , config , name ) )
113+ const mkdirEffect = ( dir : string ) => Effect . promise ( ( ) => fs . mkdir ( dir , { recursive : true } ) )
114+ const writeTextEffect = ( file : string , content : string ) => Effect . promise ( ( ) => Filesystem . write ( file , content ) )
113115
114116function withProcessEnv < A , E , R > ( key : string , value : string , effect : Effect . Effect < A , E , R > ) {
115117 return Effect . acquireUseRelease (
@@ -671,205 +673,156 @@ it.instance("migrates mode field to agent field", () =>
671673 } ) ,
672674)
673675
674- test ( "loads config from .opencode directory" , async ( ) => {
675- await using tmp = await tmpdir ( {
676- init : async ( dir ) => {
677- const opencodeDir = path . join ( dir , ".opencode" )
678- await fs . mkdir ( opencodeDir , { recursive : true } )
679- const agentDir = path . join ( opencodeDir , "agent" )
680- await fs . mkdir ( agentDir , { recursive : true } )
681-
682- await Filesystem . write (
683- path . join ( agentDir , "test.md" ) ,
684- `---
676+ it . instance ( "loads config from .opencode directory" , ( ) =>
677+ Effect . gen ( function * ( ) {
678+ const test = yield * TestInstance
679+ yield * mkdirEffect ( path . join ( test . directory , ".opencode" , "agent" ) )
680+ yield * writeTextEffect (
681+ path . join ( test . directory , ".opencode" , "agent" , "test.md" ) ,
682+ `---
685683model: test/model
686684---
687685Test agent prompt` ,
688- )
689- } ,
690- } )
691- await withTestInstance ( {
692- directory : tmp . path ,
693- fn : async ( ctx ) => {
694- const config = await load ( ctx )
695- expect ( config . agent ?. [ "test" ] ) . toEqual (
696- expect . objectContaining ( {
697- name : "test" ,
698- model : "test/model" ,
699- prompt : "Test agent prompt" ,
700- } ) ,
701- )
702- } ,
703- } )
704- } )
686+ )
705687
706- test ( "agent markdown permission config preserves user key order" , async ( ) => {
707- await using tmp = await tmpdir ( {
708- init : async ( dir ) => {
709- const agentDir = path . join ( dir , ".opencode" , "agent" )
710- await fs . mkdir ( agentDir , { recursive : true } )
688+ const config = yield * Config . Service . use ( ( svc ) => svc . get ( ) )
689+ expect ( config . agent ?. [ "test" ] ) . toEqual (
690+ expect . objectContaining ( {
691+ name : "test" ,
692+ model : "test/model" ,
693+ prompt : "Test agent prompt" ,
694+ } ) ,
695+ )
696+ } ) ,
697+ )
711698
712- await Filesystem . write (
713- path . join ( agentDir , "ordered.md" ) ,
714- `---
699+ it . instance ( "agent markdown permission config preserves user key order" , ( ) =>
700+ Effect . gen ( function * ( ) {
701+ const test = yield * TestInstance
702+ yield * mkdirEffect ( path . join ( test . directory , ".opencode" , "agent" ) )
703+ yield * writeTextEffect (
704+ path . join ( test . directory , ".opencode" , "agent" , "ordered.md" ) ,
705+ `---
715706permission:
716707 bash: allow
717708 "*": deny
718709 edit: ask
719710---
720711Ordered permissions` ,
721- )
722- } ,
723- } )
724- await withTestInstance ( {
725- directory : tmp . path ,
726- fn : async ( ctx ) => {
727- const config = await load ( ctx )
728- expect ( Object . keys ( config . agent ?. ordered ?. permission ?? { } ) ) . toEqual ( [ "bash" , "*" , "edit" ] )
729- } ,
730- } )
731- } )
732-
733- test ( "loads agents from .opencode/agents (plural)" , async ( ) => {
734- await using tmp = await tmpdir ( {
735- init : async ( dir ) => {
736- const opencodeDir = path . join ( dir , ".opencode" )
737- await fs . mkdir ( opencodeDir , { recursive : true } )
712+ )
738713
739- const agentsDir = path . join ( opencodeDir , "agents" )
740- await fs . mkdir ( path . join ( agentsDir , "nested" ) , { recursive : true } )
714+ const config = yield * Config . Service . use ( ( svc ) => svc . get ( ) )
715+ expect ( Object . keys ( config . agent ?. ordered ?. permission ?? { } ) ) . toEqual ( [ "bash" , "*" , "edit" ] )
716+ } ) ,
717+ )
741718
742- await Filesystem . write (
743- path . join ( agentsDir , "helper.md" ) ,
744- `---
719+ it . instance ( "loads agents from .opencode/agents (plural)" , ( ) =>
720+ Effect . gen ( function * ( ) {
721+ const test = yield * TestInstance
722+ yield * mkdirEffect ( path . join ( test . directory , ".opencode" , "agents" , "nested" ) )
723+ yield * writeTextEffect (
724+ path . join ( test . directory , ".opencode" , "agents" , "helper.md" ) ,
725+ `---
745726model: test/model
746727mode: subagent
747728---
748729Helper agent prompt` ,
749- )
730+ )
750731
751- await Filesystem . write (
752- path . join ( agentsDir , "nested" , "child.md" ) ,
753- `---
732+ yield * writeTextEffect (
733+ path . join ( test . directory , ".opencode" , "agents" , "nested" , "child.md" ) ,
734+ `---
754735model: test/model
755736mode: subagent
756737---
757738Nested agent prompt` ,
758- )
759- } ,
760- } )
761-
762- await withTestInstance ( {
763- directory : tmp . path ,
764- fn : async ( ctx ) => {
765- const config = await load ( ctx )
766-
767- expect ( config . agent ?. [ "helper" ] ) . toMatchObject ( {
768- name : "helper" ,
769- model : "test/model" ,
770- mode : "subagent" ,
771- prompt : "Helper agent prompt" ,
772- } )
739+ )
773740
774- expect ( config . agent ?. [ "nested/child" ] ) . toMatchObject ( {
775- name : "nested/child" ,
776- model : "test/model" ,
777- mode : "subagent" ,
778- prompt : "Nested agent prompt" ,
779- } )
780- } ,
781- } )
782- } )
741+ const config = yield * Config . Service . use ( ( svc ) => svc . get ( ) )
783742
784- test ( "loads commands from .opencode/command (singular)" , async ( ) => {
785- await using tmp = await tmpdir ( {
786- init : async ( dir ) => {
787- const opencodeDir = path . join ( dir , ".opencode" )
788- await fs . mkdir ( opencodeDir , { recursive : true } )
743+ expect ( config . agent ?. [ "helper" ] ) . toMatchObject ( {
744+ name : "helper" ,
745+ model : "test/model" ,
746+ mode : "subagent" ,
747+ prompt : "Helper agent prompt" ,
748+ } )
789749
790- const commandDir = path . join ( opencodeDir , "command" )
791- await fs . mkdir ( path . join ( commandDir , "nested" ) , { recursive : true } )
750+ expect ( config . agent ?. [ "nested/child" ] ) . toMatchObject ( {
751+ name : "nested/child" ,
752+ model : "test/model" ,
753+ mode : "subagent" ,
754+ prompt : "Nested agent prompt" ,
755+ } )
756+ } ) ,
757+ )
792758
793- await Filesystem . write (
794- path . join ( commandDir , "hello.md" ) ,
795- `---
759+ it . instance ( "loads commands from .opencode/command (singular)" , ( ) =>
760+ Effect . gen ( function * ( ) {
761+ const test = yield * TestInstance
762+ yield * mkdirEffect ( path . join ( test . directory , ".opencode" , "command" , "nested" ) )
763+ yield * writeTextEffect (
764+ path . join ( test . directory , ".opencode" , "command" , "hello.md" ) ,
765+ `---
796766description: Test command
797767---
798768Hello from singular command` ,
799- )
769+ )
800770
801- await Filesystem . write (
802- path . join ( commandDir , "nested" , "child.md" ) ,
803- `---
771+ yield * writeTextEffect (
772+ path . join ( test . directory , ".opencode" , "command" , "nested" , "child.md" ) ,
773+ `---
804774description: Nested command
805775---
806776Nested command template` ,
807- )
808- } ,
809- } )
810-
811- await withTestInstance ( {
812- directory : tmp . path ,
813- fn : async ( ctx ) => {
814- const config = await load ( ctx )
815-
816- expect ( config . command ?. [ "hello" ] ) . toEqual ( {
817- description : "Test command" ,
818- template : "Hello from singular command" ,
819- } )
777+ )
820778
821- expect ( config . command ?. [ "nested/child" ] ) . toEqual ( {
822- description : "Nested command" ,
823- template : "Nested command template" ,
824- } )
825- } ,
826- } )
827- } )
779+ const config = yield * Config . Service . use ( ( svc ) => svc . get ( ) )
828780
829- test ( "loads commands from .opencode/commands (plural)" , async ( ) => {
830- await using tmp = await tmpdir ( {
831- init : async ( dir ) => {
832- const opencodeDir = path . join ( dir , ".opencode" )
833- await fs . mkdir ( opencodeDir , { recursive : true } )
781+ expect ( config . command ?. [ "hello" ] ) . toEqual ( {
782+ description : "Test command" ,
783+ template : "Hello from singular command" ,
784+ } )
834785
835- const commandsDir = path . join ( opencodeDir , "commands" )
836- await fs . mkdir ( path . join ( commandsDir , "nested" ) , { recursive : true } )
786+ expect ( config . command ?. [ "nested/child" ] ) . toEqual ( {
787+ description : "Nested command" ,
788+ template : "Nested command template" ,
789+ } )
790+ } ) ,
791+ )
837792
838- await Filesystem . write (
839- path . join ( commandsDir , "hello.md" ) ,
840- `---
793+ it . instance ( "loads commands from .opencode/commands (plural)" , ( ) =>
794+ Effect . gen ( function * ( ) {
795+ const test = yield * TestInstance
796+ yield * mkdirEffect ( path . join ( test . directory , ".opencode" , "commands" , "nested" ) )
797+ yield * writeTextEffect (
798+ path . join ( test . directory , ".opencode" , "commands" , "hello.md" ) ,
799+ `---
841800description: Test command
842801---
843802Hello from plural commands` ,
844- )
803+ )
845804
846- await Filesystem . write (
847- path . join ( commandsDir , "nested" , "child.md" ) ,
848- `---
805+ yield * writeTextEffect (
806+ path . join ( test . directory , ".opencode" , "commands" , "nested" , "child.md" ) ,
807+ `---
849808description: Nested command
850809---
851810Nested command template` ,
852- )
853- } ,
854- } )
811+ )
855812
856- await withTestInstance ( {
857- directory : tmp . path ,
858- fn : async ( ctx ) => {
859- const config = await load ( ctx )
813+ const config = yield * Config . Service . use ( ( svc ) => svc . get ( ) )
860814
861- expect ( config . command ?. [ "hello" ] ) . toEqual ( {
862- description : "Test command" ,
863- template : "Hello from plural commands" ,
864- } )
815+ expect ( config . command ?. [ "hello" ] ) . toEqual ( {
816+ description : "Test command" ,
817+ template : "Hello from plural commands" ,
818+ } )
865819
866- expect ( config . command ?. [ "nested/child" ] ) . toEqual ( {
867- description : "Nested command" ,
868- template : "Nested command template" ,
869- } )
870- } ,
871- } )
872- } )
820+ expect ( config . command ?. [ "nested/child" ] ) . toEqual ( {
821+ description : "Nested command" ,
822+ template : "Nested command template" ,
823+ } )
824+ } ) ,
825+ )
873826
874827it . instance ( "updates config and writes to file" , ( ) =>
875828 Effect . gen ( function * ( ) {
0 commit comments