This repository was archived by the owner on May 15, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Expand file tree
/
Copy pathskillsMessageHandler.ts
More file actions
231 lines (197 loc) · 7.17 KB
/
Copy pathskillsMessageHandler.ts
File metadata and controls
231 lines (197 loc) · 7.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
import * as vscode from "vscode"
import type { SkillMetadata, WebviewMessage } from "@roo-code/types"
import type { ClineProvider } from "./ClineProvider"
import { openFile } from "../../integrations/misc/open-file"
import { t } from "../../i18n"
/**
* Handles the requestSkills message - returns all skills metadata
*/
export async function handleRequestSkills(provider: ClineProvider): Promise<SkillMetadata[]> {
try {
const skillsManager = provider.getSkillsManager()
if (skillsManager) {
const skills = skillsManager.getSkillsMetadata()
await provider.postMessageToWebview({ type: "skills", skills })
return skills
} else {
await provider.postMessageToWebview({ type: "skills", skills: [] })
return []
}
} catch (error) {
provider.log(`Error fetching skills: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`)
await provider.postMessageToWebview({ type: "skills", skills: [] })
return []
}
}
/**
* Handles the createSkill message - creates a new skill
*/
export async function handleCreateSkill(
provider: ClineProvider,
message: WebviewMessage,
): Promise<SkillMetadata[] | undefined> {
try {
const skillName = message.skillName
const source = message.source
const skillDescription = message.skillDescription
// Support new modeSlugs array or fall back to legacy skillMode
const modeSlugs = message.skillModeSlugs ?? (message.skillMode ? [message.skillMode] : undefined)
if (!skillName || !source || !skillDescription) {
throw new Error(t("skills:errors.missing_create_fields"))
}
// Built-in skills cannot be created
if (source === "built-in") {
throw new Error(t("skills:errors.cannot_modify_builtin"))
}
const skillsManager = provider.getSkillsManager()
if (!skillsManager) {
throw new Error(t("skills:errors.manager_unavailable"))
}
const createdPath = await skillsManager.createSkill(skillName, source, skillDescription, modeSlugs)
// Open the created file in the editor
openFile(createdPath)
// Send updated skills list
const skills = skillsManager.getSkillsMetadata()
await provider.postMessageToWebview({ type: "skills", skills })
return skills
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
provider.log(`Error creating skill: ${errorMessage}`)
vscode.window.showErrorMessage(`Failed to create skill: ${errorMessage}`)
return undefined
}
}
/**
* Handles the deleteSkill message - deletes a skill
*/
export async function handleDeleteSkill(
provider: ClineProvider,
message: WebviewMessage,
): Promise<SkillMetadata[] | undefined> {
try {
const skillName = message.skillName
const source = message.source
// Support new skillModeSlugs array or fall back to legacy skillMode
const skillMode = message.skillModeSlugs?.[0] ?? message.skillMode
if (!skillName || !source) {
throw new Error(t("skills:errors.missing_delete_fields"))
}
// Built-in skills cannot be deleted
if (source === "built-in") {
throw new Error(t("skills:errors.cannot_modify_builtin"))
}
const skillsManager = provider.getSkillsManager()
if (!skillsManager) {
throw new Error(t("skills:errors.manager_unavailable"))
}
await skillsManager.deleteSkill(skillName, source, skillMode)
// Send updated skills list
const skills = skillsManager.getSkillsMetadata()
await provider.postMessageToWebview({ type: "skills", skills })
return skills
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
provider.log(`Error deleting skill: ${errorMessage}`)
vscode.window.showErrorMessage(`Failed to delete skill: ${errorMessage}`)
return undefined
}
}
/**
* Handles the moveSkill message - moves a skill to a different mode
*/
export async function handleMoveSkill(
provider: ClineProvider,
message: WebviewMessage,
): Promise<SkillMetadata[] | undefined> {
try {
const skillName = message.skillName
const source = message.source
const currentMode = message.skillMode
const newMode = message.newSkillMode
if (!skillName || !source) {
throw new Error(t("skills:errors.missing_move_fields"))
}
// Built-in skills cannot be moved
if (source === "built-in") {
throw new Error(t("skills:errors.cannot_modify_builtin"))
}
const skillsManager = provider.getSkillsManager()
if (!skillsManager) {
throw new Error(t("skills:errors.manager_unavailable"))
}
await skillsManager.moveSkill(skillName, source, currentMode, newMode)
// Send updated skills list
const skills = skillsManager.getSkillsMetadata()
await provider.postMessageToWebview({ type: "skills", skills })
return skills
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
provider.log(`Error moving skill: ${errorMessage}`)
vscode.window.showErrorMessage(`Failed to move skill: ${errorMessage}`)
return undefined
}
}
/**
* Handles the updateSkillModes message - updates the mode associations for a skill
*/
export async function handleUpdateSkillModes(
provider: ClineProvider,
message: WebviewMessage,
): Promise<SkillMetadata[] | undefined> {
try {
const skillName = message.skillName
const source = message.source
const newModeSlugs = message.newSkillModeSlugs
if (!skillName || !source) {
throw new Error(t("skills:errors.missing_update_modes_fields"))
}
// Built-in skills cannot be modified
if (source === "built-in") {
throw new Error(t("skills:errors.cannot_modify_builtin"))
}
const skillsManager = provider.getSkillsManager()
if (!skillsManager) {
throw new Error(t("skills:errors.manager_unavailable"))
}
await skillsManager.updateSkillModes(skillName, source, newModeSlugs)
// Send updated skills list
const skills = skillsManager.getSkillsMetadata()
await provider.postMessageToWebview({ type: "skills", skills })
return skills
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
provider.log(`Error updating skill modes: ${errorMessage}`)
vscode.window.showErrorMessage(`Failed to update skill modes: ${errorMessage}`)
return undefined
}
}
/**
* Handles the openSkillFile message - opens a skill file in the editor
*/
export async function handleOpenSkillFile(provider: ClineProvider, message: WebviewMessage): Promise<void> {
try {
const skillName = message.skillName
const source = message.source
if (!skillName || !source) {
throw new Error(t("skills:errors.missing_delete_fields"))
}
// Built-in skills cannot be opened as files (they have no file path)
if (source === "built-in") {
throw new Error(t("skills:errors.cannot_open_builtin"))
}
const skillsManager = provider.getSkillsManager()
if (!skillsManager) {
throw new Error(t("skills:errors.manager_unavailable"))
}
// Find skill by name and source (skills may have modeSlugs arrays now)
const skill = skillsManager.findSkillByNameAndSource(skillName, source)
if (!skill) {
throw new Error(t("skills:errors.skill_not_found", { name: skillName }))
}
openFile(skill.path)
} catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error)
provider.log(`Error opening skill file: ${errorMessage}`)
vscode.window.showErrorMessage(`Failed to open skill file: ${errorMessage}`)
}
}