@@ -23,11 +23,7 @@ import {
2323 getSkillPresentationMeta ,
2424} from '@/lib/skills/catalog'
2525import { buildSkillUseEnvelope } from '@/lib/skills/provider-adapter'
26- import type {
27- SkillCatalogItem ,
28- SkillPresentationLane ,
29- SkillsRuntimeMap ,
30- } from '@/lib/skills/types'
26+ import type { SkillCatalogItem , SkillPresentationLane , SkillsRuntimeMap } from '@/lib/skills/types'
3127import {
3228 SKILLS_RUNTIME_STORAGE_KEY ,
3329 buildCatalogSummary ,
@@ -180,7 +176,7 @@ function PageSkillCard({
180176 { skill . shortDescription }
181177 </ p >
182178
183- < div className = "mt-4 flex flex-wrap gap-2 " >
179+ < div className = "mt-3 flex flex-wrap gap-1.5 " >
184180 { skill . tags . slice ( 0 , 3 ) . map ( ( tag ) => (
185181 < span
186182 key = { tag }
@@ -191,23 +187,27 @@ function PageSkillCard({
191187 ) ) }
192188 </ div >
193189
194- < div className = "mt-4 grid gap-2 sm: grid-cols-2" >
195- < div className = "rounded-2xl border border-[var(--border)] bg-[color-mix(in_srgb,var(--bg)_82%,transparent)] px-3 py-2.5 " >
190+ < div className = "mt-3 grid gap-2 grid-cols-2" >
191+ < div className = "rounded-xl border border-[var(--border)] bg-[color-mix(in_srgb,var(--bg)_82%,transparent)] px-3 py-2" >
196192 < div className = "text-[10px] font-semibold uppercase tracking-[0.16em] text-[var(--text-disabled)]" >
197193 Collection
198194 </ div >
199- < div className = "mt-1 text-[12px] text-[var(--text-primary)]" > { meta . collectionLabel } </ div >
195+ < div className = "mt-0.5 truncate text-[12px] text-[var(--text-primary)]" >
196+ { meta . collectionLabel }
197+ </ div >
200198 </ div >
201- < div className = "rounded-2xl border border-[var(--border)] bg-[color-mix(in_srgb,var(--bg)_82%,transparent)] px-3 py-2.5 " >
199+ < div className = "rounded-xl border border-[var(--border)] bg-[color-mix(in_srgb,var(--bg)_82%,transparent)] px-3 py-2" >
202200 < div className = "text-[10px] font-semibold uppercase tracking-[0.16em] text-[var(--text-disabled)]" >
203201 Update
204202 </ div >
205- < div className = "mt-1 text-[12px] text-[var(--text-primary)]" > { meta . updatedLabel } </ div >
203+ < div className = "mt-0.5 truncate text-[12px] text-[var(--text-primary)]" >
204+ { meta . updatedLabel }
205+ </ div >
206206 </ div >
207207 </ div >
208208
209- < div className = "mt-4 flex items-center gap-3 rounded-2xl border border-[var(--border)] bg-[color-mix(in_srgb,var(--bg)_84%,transparent)] px-3 py-2.5 " >
210- < div className = "flex h-8 w-8 items-center justify-center rounded-full bg-[color-mix(in_srgb,var(--brand)_16%,transparent)] text-[11px ] font-semibold text-[var(--brand)]" >
209+ < div className = "mt-3 flex items-center gap-2.5 rounded-xl border border-[var(--border)] bg-[color-mix(in_srgb,var(--bg)_84%,transparent)] px-3 py-2" >
210+ < div className = "flex h-7 w-7 shrink-0 items-center justify-center rounded-full bg-[color-mix(in_srgb,var(--brand)_16%,transparent)] text-[10px ] font-semibold text-[var(--brand)]" >
211211 { initials }
212212 </ div >
213213 < div className = "min-w-0" >
@@ -220,7 +220,7 @@ function PageSkillCard({
220220 </ div >
221221 </ div >
222222
223- < div className = "mt-4 flex flex-wrap items-center justify-between gap-2" >
223+ < div className = "mt-3 flex flex-wrap items-center justify-between gap-2" >
224224 < button
225225 onClick = { onToggle }
226226 type = "button"
@@ -282,9 +282,13 @@ function PageSkillCard({
282282 </ div >
283283 </ div >
284284
285- < div className = "mt-4 flex flex-wrap items-center justify-between gap-2 text-[11px] text-[var(--text-tertiary)]" >
285+ < div className = "mt-3 flex flex-wrap items-center justify-between gap-2 text-[11px] text-[var(--text-tertiary)]" >
286286 < span > { formatActivityAge ( state ?. lastUsedAt ) } </ span >
287- < span > { state ?. syncState === 'error' ? state . lastError : formatRelativeTimestamp ( state ?. syncedAt ) } </ span >
287+ < span >
288+ { state ?. syncState === 'error'
289+ ? state . lastError
290+ : formatRelativeTimestamp ( state ?. syncedAt ) }
291+ </ span >
288292 </ div >
289293
290294 { busyAction && state ?. syncState === 'running' ? (
@@ -317,7 +321,9 @@ function SettingsSkillCard({
317321 < div className = "min-w-0 flex-1" >
318322 < div className = "flex items-start justify-between gap-3" >
319323 < div >
320- < h4 className = "text-[13px] font-semibold text-[var(--text-primary)]" > { skill . title } </ h4 >
324+ < h4 className = "text-[13px] font-semibold text-[var(--text-primary)]" >
325+ { skill . title }
326+ </ h4 >
321327 < p className = "mt-0.5 text-[10px] text-[var(--text-disabled)]" >
322328 { skill . shortDescription }
323329 </ p >
@@ -403,7 +409,9 @@ function SettingsSkillCard({
403409 </ div >
404410
405411 < div className = "mt-3 space-y-1 text-[10px] text-[var(--text-disabled)]" >
406- < div > { state ?. synced ? formatRelativeTimestamp ( state . syncedAt ) : 'Not yet synced locally' } </ div >
412+ < div >
413+ { state ?. synced ? formatRelativeTimestamp ( state . syncedAt ) : 'Not yet synced locally' }
414+ </ div >
407415 < div >
408416 Install: < code className = "font-mono" > { skill . installCommand } </ code >
409417 </ div >
@@ -568,6 +576,26 @@ export function SkillsInterface({ variant = 'page' }: SkillsInterfaceProps) {
568576 return
569577 }
570578
579+ if ( plan . kind === 'use' && plan . skill ) {
580+ const request = plan . query ?? ''
581+ if ( ! request ) {
582+ setActionNote (
583+ 'Provide a task after the skill slug. Usage: /skill use <slug> <your request>' ,
584+ )
585+ return
586+ }
587+ const envelope = buildSkillUseEnvelope ( { skill : plan . skill , request, modelName } )
588+ await sendGatewayMessage (
589+ envelope . prompt ,
590+ successLabel || `${ plan . skill . title } sent to ${ envelope . provider . label } .` ,
591+ )
592+ updateRuntime ( plan . skill . id , ( previous ) => ( {
593+ ...previous ,
594+ lastUsedAt : Date . now ( ) ,
595+ } ) )
596+ return
597+ }
598+
571599 if ( plan . message ) {
572600 await sendGatewayMessage (
573601 plan . message ,
@@ -578,7 +606,7 @@ export function SkillsInterface({ variant = 'page' }: SkillsInterfaceProps) {
578606 setBusyAction ( null )
579607 }
580608 } ,
581- [ preferTerminal , sendGatewayMessage , updateRuntime ] ,
609+ [ modelName , preferTerminal , sendGatewayMessage , updateRuntime ] ,
582610 )
583611
584612 const handleToggleEnabled = useCallback (
@@ -737,7 +765,12 @@ export function SkillsInterface({ variant = 'page' }: SkillsInterfaceProps) {
737765 < div className = "relative grid gap-4 xl:grid-cols-[minmax(0,1.35fr)_minmax(300px,0.75fr)]" >
738766 < div className = "space-y-4" >
739767 < div className = "inline-flex items-center gap-2 rounded-full border border-[color-mix(in_srgb,var(--brand)_30%,var(--border))] bg-[color-mix(in_srgb,var(--brand)_10%,transparent)] px-3 py-1 text-[11px] font-semibold uppercase tracking-[0.18em] text-[var(--text-secondary)]" >
740- < Icon icon = "lucide:sparkles" width = { 14 } height = { 14 } className = "text-[var(--brand)]" />
768+ < Icon
769+ icon = "lucide:sparkles"
770+ width = { 14 }
771+ height = { 14 }
772+ className = "text-[var(--brand)]"
773+ />
741774 Skills Library
742775 </ div >
743776 < div >
@@ -779,7 +812,9 @@ export function SkillsInterface({ variant = 'page' }: SkillsInterfaceProps) {
779812 < div className = "text-3xl font-semibold text-[var(--text-primary)] sm:text-4xl" >
780813 { SKILLS_CATALOG . length }
781814 </ div >
782- < div className = "text-[12px] text-[var(--text-tertiary)] sm:text-sm" > curated skills</ div >
815+ < div className = "text-[12px] text-[var(--text-tertiary)] sm:text-sm" >
816+ curated skills
817+ </ div >
783818 </ div >
784819 < div className = "text-right text-[11px] text-[var(--text-secondary)] sm:text-[12px]" >
785820 < div > { installedCount } installed</ div >
@@ -871,7 +906,9 @@ export function SkillsInterface({ variant = 'page' }: SkillsInterfaceProps) {
871906 < section className = "space-y-3" >
872907 < div className = "flex flex-wrap items-center justify-between gap-2" >
873908 < div >
874- < h2 className = "text-base font-semibold text-[var(--text-primary)] sm:text-lg" > Skill Catalog</ h2 >
909+ < h2 className = "text-base font-semibold text-[var(--text-primary)] sm:text-lg" >
910+ Skill Catalog
911+ </ h2 >
875912 < p className = "mt-0.5 hidden text-sm text-[var(--text-tertiary)] sm:block" >
876913 Browse curated workflows, inspect sources, and activate the ones you want ready.
877914 </ p >
@@ -906,8 +943,8 @@ export function SkillsInterface({ variant = 'page' }: SkillsInterfaceProps) {
906943 < div >
907944 < h2 className = "text-[20px] font-semibold text-[var(--text-primary)]" > Skills</ h2 >
908945 < p className = "mt-1 text-[12px] text-[var(--text-tertiary)]" >
909- Curated skills from `obra/superpowers` plus `find-skills`, adapted for GPT,
910- Opus, Sonnet, and gateway-driven workflows.
946+ Curated skills from `obra/superpowers` plus `find-skills`, adapted for GPT, Opus,
947+ Sonnet, and gateway-driven workflows.
911948 </ p >
912949 </ div >
913950 < div className = "flex flex-wrap items-center gap-2" >
0 commit comments