summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax <[email protected]>2026-01-31 20:52:54 -0500
committerGitHub <[email protected]>2026-01-31 20:52:54 -0500
commit5b784871f0befb450f0f80848e397e3f9e36b060 (patch)
tree4dfe9000f9b8605f974b702d1467d6f55afee890
parente5f677dfb5fc0e7470f1be1c03de42876d4a48c8 (diff)
downloadopencode-5b784871f0befb450f0f80848e397e3f9e36b060.tar.gz
opencode-5b784871f0befb450f0f80848e397e3f9e36b060.zip
feat: add skill dialog for selecting and inserting skills (#11547)
-rw-r--r--packages/opencode/src/cli/cmd/tui/component/dialog-skill.tsx34
-rw-r--r--packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx3
-rw-r--r--packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx23
3 files changed, 59 insertions, 1 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-skill.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-skill.tsx
new file mode 100644
index 000000000..1ca109f23
--- /dev/null
+++ b/packages/opencode/src/cli/cmd/tui/component/dialog-skill.tsx
@@ -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()} />
+}
diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx
index bd000e2ab..5f66dc822 100644
--- a/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx
+++ b/packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx
@@ -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,
diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx
index caa130322..8576dd576 100644
--- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx
@@ -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()
+ }}
+ />
+ ))
+ },
+ },
]
})