@@ -11,7 +11,7 @@ import { makeRuntime } from "@/effect/run-service"
1111import { Flag } from "@/flag/flag"
1212import { Global } from "@/global"
1313import { Permission } from "@/permission"
14- import { Filesystem } from "@/util /filesystem"
14+ import { AppFileSystem } from "@/filesystem"
1515import { Config } from "../config/config"
1616import { ConfigMarkdown } from "../config/markdown"
1717import { Glob } from "../util/glob"
@@ -139,28 +139,20 @@ export namespace Skill {
139139 config : Config . Interface ,
140140 discovery : Discovery . Interface ,
141141 bus : Bus . Interface ,
142+ fsys : AppFileSystem . Interface ,
142143 directory : string ,
143144 worktree : string ,
144145 ) {
145146 if ( ! Flag . OPENCODE_DISABLE_EXTERNAL_SKILLS ) {
146147 for ( const dir of EXTERNAL_DIRS ) {
147148 const root = path . join ( Global . Path . home , dir )
148- const isDir = yield * Effect . promise ( ( ) => Filesystem . isDir ( root ) )
149- if ( ! isDir ) continue
149+ if ( ! ( yield * fsys . isDir ( root ) ) ) continue
150150 yield * scan ( state , bus , root , EXTERNAL_SKILL_PATTERN , { dot : true , scope : "global" } )
151151 }
152152
153- const upDirs = yield * Effect . promise ( async ( ) => {
154- const dirs : string [ ] = [ ]
155- for await ( const root of Filesystem . up ( {
156- targets : EXTERNAL_DIRS ,
157- start : directory ,
158- stop : worktree ,
159- } ) ) {
160- dirs . push ( root )
161- }
162- return dirs
163- } )
153+ const upDirs = yield * fsys
154+ . up ( { targets : EXTERNAL_DIRS , start : directory , stop : worktree } )
155+ . pipe ( Effect . catch ( ( ) => Effect . succeed ( [ ] as string [ ] ) ) )
164156
165157 for ( const root of upDirs ) {
166158 yield * scan ( state , bus , root , EXTERNAL_SKILL_PATTERN , { dot : true , scope : "project" } )
@@ -176,8 +168,7 @@ export namespace Skill {
176168 for ( const item of cfg . skills ?. paths ?? [ ] ) {
177169 const expanded = item . startsWith ( "~/" ) ? path . join ( os . homedir ( ) , item . slice ( 2 ) ) : item
178170 const dir = path . isAbsolute ( expanded ) ? expanded : path . join ( directory , expanded )
179- const isDir = yield * Effect . promise ( ( ) => Filesystem . isDir ( dir ) )
180- if ( ! isDir ) {
171+ if ( ! ( yield * fsys . isDir ( dir ) ) ) {
181172 log . warn ( "skill path not found" , { path : dir } )
182173 continue
183174 }
@@ -198,50 +189,52 @@ export namespace Skill {
198189
199190 export class Service extends ServiceMap . Service < Service , Interface > ( ) ( "@opencode/Skill" ) { }
200191
201- export const layer : Layer . Layer < Service , never , Discovery . Service | Config . Service | Bus . Service > = Layer . effect (
202- Service ,
203- Effect . gen ( function * ( ) {
204- const discovery = yield * Discovery . Service
205- const config = yield * Config . Service
206- const bus = yield * Bus . Service
207- const state = yield * InstanceState . make (
208- Effect . fn ( "Skill.state" ) ( function * ( ctx ) {
209- const s : State = { skills : { } , dirs : new Set ( ) }
210- yield * loadSkills ( s , config , discovery , bus , ctx . directory , ctx . worktree )
211- return s
212- } ) ,
213- )
214-
215- const get = Effect . fn ( "Skill.get" ) ( function * ( name : string ) {
216- const s = yield * InstanceState . get ( state )
217- return s . skills [ name ]
218- } )
219-
220- const all = Effect . fn ( "Skill.all" ) ( function * ( ) {
221- const s = yield * InstanceState . get ( state )
222- return Object . values ( s . skills )
223- } )
224-
225- const dirs = Effect . fn ( "Skill.dirs" ) ( function * ( ) {
226- const s = yield * InstanceState . get ( state )
227- return Array . from ( s . dirs )
228- } )
229-
230- const available = Effect . fn ( "Skill.available" ) ( function * ( agent ?: Agent . Info ) {
231- const s = yield * InstanceState . get ( state )
232- const list = Object . values ( s . skills ) . toSorted ( ( a , b ) => a . name . localeCompare ( b . name ) )
233- if ( ! agent ) return list
234- return list . filter ( ( skill ) => Permission . evaluate ( "skill" , skill . name , agent . permission ) . action !== "deny" )
235- } )
236-
237- return Service . of ( { get, all, dirs, available } )
238- } ) ,
239- )
192+ export const layer = Layer . effect (
193+ Service ,
194+ Effect . gen ( function * ( ) {
195+ const discovery = yield * Discovery . Service
196+ const config = yield * Config . Service
197+ const bus = yield * Bus . Service
198+ const fsys = yield * AppFileSystem . Service
199+ const state = yield * InstanceState . make (
200+ Effect . fn ( "Skill.state" ) ( function * ( ctx ) {
201+ const s : State = { skills : { } , dirs : new Set ( ) }
202+ yield * loadSkills ( s , config , discovery , bus , fsys , ctx . directory , ctx . worktree )
203+ return s
204+ } ) ,
205+ )
206+
207+ const get = Effect . fn ( "Skill.get" ) ( function * ( name : string ) {
208+ const s = yield * InstanceState . get ( state )
209+ return s . skills [ name ]
210+ } )
211+
212+ const all = Effect . fn ( "Skill.all" ) ( function * ( ) {
213+ const s = yield * InstanceState . get ( state )
214+ return Object . values ( s . skills )
215+ } )
216+
217+ const dirs = Effect . fn ( "Skill.dirs" ) ( function * ( ) {
218+ const s = yield * InstanceState . get ( state )
219+ return Array . from ( s . dirs )
220+ } )
221+
222+ const available = Effect . fn ( "Skill.available" ) ( function * ( agent ?: Agent . Info ) {
223+ const s = yield * InstanceState . get ( state )
224+ const list = Object . values ( s . skills ) . toSorted ( ( a , b ) => a . name . localeCompare ( b . name ) )
225+ if ( ! agent ) return list
226+ return list . filter ( ( skill ) => Permission . evaluate ( "skill" , skill . name , agent . permission ) . action !== "deny" )
227+ } )
228+
229+ return Service . of ( { get, all, dirs, available } )
230+ } ) ,
231+ )
240232
241- export const defaultLayer : Layer . Layer < Service > = layer . pipe (
233+ export const defaultLayer = layer . pipe (
242234 Layer . provide ( Discovery . defaultLayer ) ,
243235 Layer . provide ( Config . defaultLayer ) ,
244236 Layer . provide ( Bus . layer ) ,
237+ Layer . provide ( AppFileSystem . defaultLayer ) ,
245238 )
246239
247240 export function fmt ( list : Info [ ] , opts : { verbose : boolean } ) {
0 commit comments