feat: add skill dialog for selecting and inserting skills (#11547)

This commit is contained in:
Dax
2026-01-31 20:52:54 -05:00
committed by GitHub
parent e5f677dfb5
commit 5b784871f0
3 changed files with 59 additions and 1 deletions

View File

@@ -0,0 +1,34 @@
import { DialogSelect, type DialogSelectOption } from "@tui/ui/dialog-select"
import { createResource, createMemo } from "solid-js"
import { useDialog } from "@tui/ui/dialog"
import { useSDK } from "@tui/context/sdk"
export type DialogSkillProps = {
onSelect: (skill: string) => void
}
export function DialogSkill(props: DialogSkillProps) {
const dialog = useDialog()
const sdk = useSDK()
const [skills] = createResource(async () => {
const result = await sdk.client.app.skills()
return result.data ?? []
})
const options = createMemo<DialogSelectOption<string>[]>(() => {
const list = skills() ?? []
return list.map((skill) => ({
title: skill.name,
description: skill.description,
value: skill.name,
category: "Skills",
onSelect: () => {
props.onSelect(skill.name)
dialog.clear()
},
}))
})
return <DialogSelect title="Skills" placeholder="Search skills..." options={options()} />
}

View File

@@ -345,7 +345,8 @@ export function Autocomplete(props: {
const results: AutocompleteOption[] = [...command.slashes()]
for (const serverCommand of sync.data.command) {
const label = serverCommand.source === "mcp" ? ":mcp" : serverCommand.source === "skill" ? ":skill" : ""
if (serverCommand.source === "skill") continue
const label = serverCommand.source === "mcp" ? ":mcp" : ""
results.push({
display: "/" + serverCommand.name + label,
description: serverCommand.description,

View File

@@ -31,6 +31,7 @@ import { DialogAlert } from "../../ui/dialog-alert"
import { useToast } from "../../ui/toast"
import { useKV } from "../../context/kv"
import { useTextareaKeybindings } from "../textarea-keybindings"
import { DialogSkill } from "../dialog-skill"
export type PromptProps = {
sessionID?: string
@@ -315,6 +316,28 @@ export function Prompt(props: PromptProps) {
input.cursorOffset = Bun.stringWidth(content)
},
},
{
title: "Skills",
value: "prompt.skills",
category: "Prompt",
slash: {
name: "skills",
},
onSelect: () => {
dialog.replace(() => (
<DialogSkill
onSelect={(skill) => {
input.setText(`/${skill} `)
setStore("prompt", {
input: `/${skill} `,
parts: [],
})
input.gotoBufferEnd()
}}
/>
))
},
},
]
})