File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -285,6 +285,32 @@ describe('AgentSchema', () => {
285285 const result = AgentSchema . parse ( agent ) ;
286286 expect ( result . permissions ) . toEqual ( [ 'agent.basic' , 'data.read' ] ) ;
287287 } ) ;
288+
289+ it ( 'should enforce snake_case for skill name references' , ( ) => {
290+ expect ( ( ) => AgentSchema . parse ( {
291+ name : 'test_agent' ,
292+ label : 'Test' ,
293+ role : 'Test' ,
294+ instructions : 'Test' ,
295+ skills : [ 'valid_skill' , 'another_skill' ] ,
296+ } ) ) . not . toThrow ( ) ;
297+
298+ expect ( ( ) => AgentSchema . parse ( {
299+ name : 'test_agent' ,
300+ label : 'Test' ,
301+ role : 'Test' ,
302+ instructions : 'Test' ,
303+ skills : [ 'InvalidSkill' ] ,
304+ } ) ) . toThrow ( ) ;
305+
306+ expect ( ( ) => AgentSchema . parse ( {
307+ name : 'test_agent' ,
308+ label : 'Test' ,
309+ role : 'Test' ,
310+ instructions : 'Test' ,
311+ skills : [ 'valid_skill' , 'Invalid-Skill' ] ,
312+ } ) ) . toThrow ( ) ;
313+ } ) ;
288314 } ) ;
289315
290316 describe ( 'Access Control' , ( ) => {
Original file line number Diff line number Diff line change @@ -137,7 +137,7 @@ export const AgentSchema = z.object({
137137 lifecycle : StateMachineSchema . optional ( ) . describe ( 'State machine defining the agent conversation follow and constraints' ) ,
138138
139139 /** Capabilities — Skill-based (primary) */
140- skills : z . array ( z . string ( ) ) . optional ( ) . describe ( 'Skill names to attach (Agent→Skill→Tool architecture)' ) ,
140+ skills : z . array ( z . string ( ) . regex ( / ^ [ a - z _ ] [ a - z 0 - 9 _ ] * $ / ) ) . optional ( ) . describe ( 'Skill names to attach (Agent→Skill→Tool architecture)' ) ,
141141
142142 /** Capabilities — Direct tool references (fallback / legacy) */
143143 tools : z . array ( AIToolSchema ) . optional ( ) . describe ( 'Direct tool references (legacy fallback)' ) ,
Original file line number Diff line number Diff line change @@ -114,6 +114,26 @@ describe('SkillSchema', () => {
114114 } ) ;
115115 expect ( result . instructions ) . toContain ( 'knowledge base' ) ;
116116 } ) ;
117+
118+ it ( 'should enforce snake_case for tool name references' , ( ) => {
119+ expect ( ( ) => SkillSchema . parse ( {
120+ name : 'valid_skill' ,
121+ label : 'Test' ,
122+ tools : [ 'valid_tool' , 'another_tool' ] ,
123+ } ) ) . not . toThrow ( ) ;
124+
125+ expect ( ( ) => SkillSchema . parse ( {
126+ name : 'valid_skill' ,
127+ label : 'Test' ,
128+ tools : [ 'InvalidTool' ] ,
129+ } ) ) . toThrow ( ) ;
130+
131+ expect ( ( ) => SkillSchema . parse ( {
132+ name : 'valid_skill' ,
133+ label : 'Test' ,
134+ tools : [ 'valid_tool' , 'Invalid-Tool' ] ,
135+ } ) ) . toThrow ( ) ;
136+ } ) ;
117137} ) ;
118138
119139describe ( 'defineSkill' , ( ) => {
Original file line number Diff line number Diff line change @@ -71,7 +71,7 @@ export const SkillSchema = z.object({
7171 * References to tool names that belong to this skill.
7272 * Tools must be registered as first-class metadata (type: 'tool').
7373 */
74- tools : z . array ( z . string ( ) ) . describe ( 'Tool names belonging to this skill' ) ,
74+ tools : z . array ( z . string ( ) . regex ( / ^ [ a - z _ ] [ a - z 0 - 9 _ ] * $ / ) ) . describe ( 'Tool names belonging to this skill' ) ,
7575
7676 /**
7777 * Natural language phrases that trigger skill activation.
You can’t perform that action at this time.
0 commit comments