@@ -167,6 +167,7 @@ import {
167167 validateCliServerConnectionProfileName ,
168168 type CliServerConnectionStore ,
169169} from "./server-profile" ;
170+ import { addSkill , listSkills , removeSkill , syncSkills , toggleSkill } from "./skills-gateway" ;
170171import {
171172 buildResumeContentTemplate ,
172173 buildDescribeToolCode ,
@@ -2209,6 +2210,129 @@ const toolsCommand = Command.make("tools").pipe(
22092210 Command . withDescription ( "Discover available tools and integrations" ) ,
22102211) ;
22112212
2213+ // ---------------------------------------------------------------------------
2214+ // Skills Gateway — Central skill store & multi-agent sync
2215+ // ---------------------------------------------------------------------------
2216+
2217+ const skillsGlobalOption = Options . boolean ( "global" )
2218+ . pipe ( Options . withDefault ( false ) )
2219+ . pipe (
2220+ Options . withDescription (
2221+ "Manage user-level skills (~/.executor/skills) instead of workspace skills (.executor/skills)" ,
2222+ ) ,
2223+ ) ;
2224+
2225+ const skillsListCommand = Command . make (
2226+ "list" ,
2227+ {
2228+ global : skillsGlobalOption ,
2229+ } ,
2230+ ( { global } ) =>
2231+ Effect . gen ( function * ( ) {
2232+ const skills = yield * listSkills ( { global } ) ;
2233+ if ( skills . length === 0 ) {
2234+ console . log ( "No skills installed." ) ;
2235+ console . log ( "" ) ;
2236+ console . log ( "Install a skill from a local folder or Git repo:" ) ;
2237+ console . log ( ` ${ cliPrefix } skills add <source>` ) ;
2238+ return ;
2239+ }
2240+ console . log ( `Installed skills (${ global ? "global" : "workspace" } ):` ) ;
2241+ console . log ( "" ) ;
2242+ for ( const skill of skills ) {
2243+ const status = skill . enabled ? "enabled" : "disabled" ;
2244+ const targets =
2245+ skill . syncedTargets . length > 0 ? ` (synced to: ${ skill . syncedTargets . join ( ", " ) } )` : "" ;
2246+ console . log ( ` - ${ skill . name } [${ status } ]${ targets } ` ) ;
2247+ if ( skill . description ) {
2248+ console . log ( ` ${ skill . description } ` ) ;
2249+ }
2250+ console . log ( ` Source: ${ skill . source } (${ skill . sourceType } )` ) ;
2251+ }
2252+ } ) ,
2253+ ) . pipe ( Command . withDescription ( "List installed skills" ) ) ;
2254+
2255+ const skillsAddCommand = Command . make (
2256+ "add" ,
2257+ {
2258+ source : Args . string ( "source" ) ,
2259+ name : Options . string ( "name" ) . pipe (
2260+ Options . optional ,
2261+ Options . withDescription ( "Custom name for the skill" ) ,
2262+ ) ,
2263+ global : skillsGlobalOption ,
2264+ } ,
2265+ ( { source, name, global } ) =>
2266+ Effect . gen ( function * ( ) {
2267+ const customName = Option . getOrUndefined ( name ) ;
2268+ console . log ( `Installing skill from ${ source } ...` ) ;
2269+ const result = yield * addSkill ( { source, name : customName , global } ) ;
2270+ console . log ( `Installed skill '${ result . name } ' successfully.` ) ;
2271+ if ( result . syncedTargets . length > 0 ) {
2272+ console . log ( `Synced to agents: ${ result . syncedTargets . join ( ", " ) } ` ) ;
2273+ }
2274+ } ) ,
2275+ ) . pipe ( Command . withDescription ( "Install a skill and sync it to connected agents" ) ) ;
2276+
2277+ const skillsRemoveCommand = Command . make (
2278+ "remove" ,
2279+ {
2280+ name : Args . string ( "name" ) ,
2281+ global : skillsGlobalOption ,
2282+ } ,
2283+ ( { name, global } ) =>
2284+ Effect . gen ( function * ( ) {
2285+ yield * removeSkill ( { name, global } ) ;
2286+ console . log ( `Removed skill '${ name } '.` ) ;
2287+ } ) ,
2288+ ) . pipe ( Command . withDescription ( "Remove an installed skill" ) ) ;
2289+
2290+ const skillsToggleCommand = Command . make (
2291+ "toggle" ,
2292+ {
2293+ name : Args . string ( "name" ) ,
2294+ action : Args . choice ( "action" , [ "enable" , "disable" ] as const ) ,
2295+ global : skillsGlobalOption ,
2296+ } ,
2297+ ( { name, action, global } ) =>
2298+ Effect . gen ( function * ( ) {
2299+ const enabled = action === "enable" ;
2300+ yield * toggleSkill ( { name, enabled, global } ) ;
2301+ console . log ( `Skill '${ name } ' is now ${ action } d.` ) ;
2302+ } ) ,
2303+ ) . pipe ( Command . withDescription ( "Enable or disable a skill to toggle agent loading" ) ) ;
2304+
2305+ const skillsSyncCommand = Command . make (
2306+ "sync" ,
2307+ {
2308+ global : skillsGlobalOption ,
2309+ } ,
2310+ ( { global } ) =>
2311+ Effect . gen ( function * ( ) {
2312+ console . log ( "Syncing skills to connected agents..." ) ;
2313+ const synced = yield * syncSkills ( { global } ) ;
2314+ if ( synced . length === 0 ) {
2315+ console . log ( "No enabled skills or agent target directories found to sync." ) ;
2316+ return ;
2317+ }
2318+ for ( const record of synced ) {
2319+ console . log ( ` - Synced ${ record . skillName } -> ${ record . target } (${ record . destination } )` ) ;
2320+ }
2321+ console . log ( `Sync complete (${ synced . length } target records synced).` ) ;
2322+ } ) ,
2323+ ) . pipe ( Command . withDescription ( "Sync installed skills to detected agent directories" ) ) ;
2324+
2325+ const skillsCommand = Command . make ( "skills" ) . pipe (
2326+ Command . withSubcommands ( [
2327+ skillsListCommand ,
2328+ skillsAddCommand ,
2329+ skillsRemoveCommand ,
2330+ skillsToggleCommand ,
2331+ skillsSyncCommand ,
2332+ ] as const ) ,
2333+ Command . withDescription ( "Manage agent skills and sync them across AI coding assistants" ) ,
2334+ ) ;
2335+
22122336const HEADER_NAME_PATTERN = / ^ [ ! # $ % & ' * + . ^ _ ` | ~ 0 - 9 A - Z a - z - ] + $ / ;
22132337const ENV_NAME_PATTERN = / ^ [ A - Z a - z _ ] [ A - Z a - z 0 - 9 _ ] * $ / ;
22142338
@@ -3299,6 +3423,7 @@ const root = Command.make("executor").pipe(
32993423 callCommand ,
33003424 resumeCommand ,
33013425 toolsCommand ,
3426+ skillsCommand ,
33023427 installCommand ,
33033428 loginCommand ,
33043429 logoutCommand ,
0 commit comments