@@ -51,11 +51,19 @@ function el<T extends HTMLElement>(id: string): T {
5151}
5252
5353function show ( id : string ) : void {
54- el ( id ) . classList . remove ( "hidden" ) ;
54+ el ( id ) ? .classList . remove ( "hidden" ) ;
5555}
5656
5757function hide ( id : string ) : void {
58- el ( id ) . classList . add ( "hidden" ) ;
58+ el ( id ) ?. classList . add ( "hidden" ) ;
59+ }
60+
61+ function escapeHtml ( text : string ) : string {
62+ return text
63+ . replace ( / & / g, "&" )
64+ . replace ( / < / g, "<" )
65+ . replace ( / > / g, ">" )
66+ . replace ( / " / g, """ ) ;
5967}
6068
6169// ── State rendering ───────────────────────────────────────────────────────────
@@ -98,8 +106,8 @@ function renderSkillRows(
98106 const statusClass = isInstalled ? "hs-ai-item-status--ok" : "hs-ai-item-status--none" ;
99107 const statusText = isInstalled ? "installed" : "—" ;
100108 return `<label class="hs-ai-item">
101- <input type="checkbox" class="hs-ai-cb" data-skill="${ s . dirName } " ${ isInstalled ? "" : "checked" } >
102- <span class="hs-ai-item-name" title="${ s . description } ">${ s . name } </span>
109+ <input type="checkbox" class="hs-ai-cb" data-skill="${ escapeHtml ( s . dirName ) } " ${ isInstalled ? "" : "checked" } >
110+ <span class="hs-ai-item-name" title="${ escapeHtml ( s . description ) } ">${ escapeHtml ( s . name ) } </span>
103111 <span class="hs-ai-item-status ${ statusClass } ">${ statusText } </span>
104112 </label>` ;
105113 } )
@@ -122,8 +130,8 @@ function renderMcpRows(
122130 const statusClass = isConfigured ? "hs-ai-item-status--ok" : "hs-ai-item-status--none" ;
123131 const statusText = isConfigured ? "configured" : "—" ;
124132 return `<label class="hs-ai-item">
125- <input type="checkbox" class="hs-ai-cb" data-mcp="${ s . key } " ${ isConfigured ? "" : "checked" } >
126- <span class="hs-ai-item-name" title="${ s . description } ">${ s . label } </span>
133+ <input type="checkbox" class="hs-ai-cb" data-mcp="${ escapeHtml ( s . key ) } " ${ isConfigured ? "" : "checked" } >
134+ <span class="hs-ai-item-name" title="${ escapeHtml ( s . description ) } ">${ escapeHtml ( s . label ) } </span>
127135 <span class="hs-ai-item-status ${ statusClass } ">${ statusText } </span>
128136 </label>` ;
129137 } )
@@ -205,7 +213,8 @@ function handleApply(): void {
205213
206214function handleAiToolsData ( msg : AiToolsDataMessage ) : void {
207215 if ( msg . error ) {
208- el ( "hs-ai-error-msg" ) . textContent = msg . error ;
216+ const errEl = el ( "hs-ai-error-msg" ) ;
217+ if ( errEl ) { errEl . textContent = msg . error ; }
209218 showPanelState ( "error" ) ;
210219 return ;
211220 }
0 commit comments