@@ -188,6 +188,54 @@ describe('renderTodoWriteResult', () => {
188188 } ) ;
189189} ) ;
190190
191+ /** Representative fixtures for registry-driven behavioral smoke tests. */
192+ const TOOL_USE_FIXTURES = {
193+ Bash : { input : { command : 'echo hi' , description : 'say hi' } } ,
194+ Read : { input : { file_path : 'README.md' } } ,
195+ Write : { input : { file_path : 'out.txt' , content : 'data' } } ,
196+ Edit : { input : { file_path : 'a.js' , old_string : 'x' , new_string : 'y' } } ,
197+ Glob : { input : { pattern : '*.js' , path : 'src' } } ,
198+ Grep : { input : { pattern : 'TODO' , path : 'lib' } } ,
199+ Task : { input : { subagent_type : 'explore' , description : 'scan' , prompt : 'go' } } ,
200+ TodoWrite : { input : { todos : [ { status : 'pending' , content : 'task' } ] } } ,
201+ AskUserQuestion : { input : { questions : [ { question : 'OK?' } ] } } ,
202+ WebFetch : { input : { url : 'https://example.com' } } ,
203+ WebSearch : { input : { query : 'vitest' } } ,
204+ } ;
205+
206+ const TOOL_RESULT_FIXTURES = {
207+ bash : { exit_code : 0 , stdout : 'ok' } ,
208+ file_read : { file_path : '/a.txt' , num_lines : 10 } ,
209+ file_edit : { file_path : 'b.js' } ,
210+ file_write : { file_path : 'c.txt' } ,
211+ glob : { num_files : 3 } ,
212+ grep : { num_files : 2 , num_lines : 5 } ,
213+ web_search : { query : 'test' , result_count : 1 } ,
214+ web_fetch : { url : 'https://x.com' , status_code : 200 } ,
215+ task : { status : 'completed' , total_duration_ms : 1000 } ,
216+ todo_write : { todos : [ { status : 'pending' , content : 'x' } ] } ,
217+ user_input : { questions : [ { question : 'Q' } ] , answers : { Q : 'A' } } ,
218+ plan : { file_path : 'plan.md' } ,
219+ } ;
220+
221+ describe ( 'registry behavioral smoke tests' , ( ) => {
222+ it ( 'every registered tool_use renderer produces non-empty HTML' , ( ) => {
223+ for ( const name of CORE_TOOL_USE ) {
224+ const html = renderToolUse ( { name, ...TOOL_USE_FIXTURES [ name ] } ) ;
225+ expect ( html , name ) . toContain ( 'tool-call' ) ;
226+ expect ( html . length , name ) . toBeGreaterThan ( 20 ) ;
227+ }
228+ } ) ;
229+
230+ it ( 'every registered tool_result renderer produces non-empty HTML' , ( ) => {
231+ for ( const rt of CORE_TOOL_RESULT ) {
232+ const html = renderToolResult ( { result_type : rt , ...TOOL_RESULT_FIXTURES [ rt ] } ) ;
233+ expect ( html , rt ) . toContain ( 'tool-result' ) ;
234+ expect ( html . length , rt ) . toBeGreaterThan ( 20 ) ;
235+ }
236+ } ) ;
237+ } ) ;
238+
191239describe ( 'renderToolResult fallback' , ( ) => {
192240 it ( 'renders raw result type and JSON payload for unknown result types' , ( ) => {
193241 const html = renderToolResult ( {
0 commit comments