Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions packages/kilo-vscode/src/KiloProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,9 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
console.error("[Kilo New] handleRemoveSkill failed:", e),
)
break
case "removeMode":
this.handleRemoveMode(message.name).catch((e) => console.error("[Kilo New] handleRemoveMode failed:", e))
break
case "questionReply":
await this.handleQuestionReply(message.requestID, message.answers)
break
Expand Down Expand Up @@ -1158,6 +1161,33 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
this.cachedSkillsMessage = null
}

/**
* Remove a custom mode via the CLI backend (deletes from disk + refreshes state).
* The webview optimistically removes the mode from its list before this runs.
* On failure, re-fetches agents so the webview reverts to the authoritative state.
*/
private async handleRemoveMode(name: string): Promise<void> {
if (!this.client) return
try {
const dir = this.getWorkspaceDirectory()
const result = await this.client.kilocode.removeAgent({ name, directory: dir })
if (result.error) {
console.error("[Kilo New] KiloProvider: removeAgent returned error:", result.error)
this.cachedAgentsMessage = null
await this.fetchAndSendAgents()
return
}
} catch (error) {
console.error("[Kilo New] KiloProvider: Failed to remove mode:", error)
this.cachedAgentsMessage = null
await this.fetchAndSendAgents()
return
}
// Invalidate cache so next requestAgents fetches fresh data
this.cachedAgentsMessage = null
await this.fetchAndSendAgents()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Removed mode leaves stale config references behind

This only refreshes agentsLoaded. If the deleted mode is still referenced by config.default_agent or config.agent, the webview keeps showing it from stale config state and the backend can start throwing default agent "<name>" not found when the next prompt falls back to the default agent. Refresh or clear the config after a successful removal as well.

}

/**
* Fetch backend config and send to webview.
*/
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useDialog } from "@kilocode/kilo-ui/context/dialog"
import { useConfig } from "../../context/config"
import { useSession } from "../../context/session"
import { useLanguage } from "../../context/language"
import type { AgentConfig, SkillInfo } from "../../types/messages"
import type { AgentConfig, AgentInfo, SkillInfo } from "../../types/messages"

type SubtabId = "agents" | "mcpServers" | "rules" | "workflows" | "skills"

Expand Down Expand Up @@ -195,6 +195,36 @@ const AgentBehaviourTab: Component = () => {
))
}

const removableModes = createMemo(() => session.agents().filter((a) => !a.native))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Delete button is shown for modes this API cannot remove

This filter treats every non-native agent as removable, but Agent.remove() only deletes markdown-backed agents or legacy .kilocodemodes entries. Modes declared directly in kilo.json/opencode.json are also native: false, so the UI will offer a remove action that always comes back with no agent file found on disk.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm willing to accept this for now, we need to iterate on this screen anyways. it's good enough for supporting the marketplace


const confirmRemoveMode = (agent: AgentInfo) => {
dialog.show(() => (
<Dialog title={language.t("settings.agentBehaviour.removeMode.title")} fit>
<div class="dialog-confirm-body">
<span>{language.t("settings.agentBehaviour.removeMode.confirm", { name: agent.name })}</span>
<div class="dialog-confirm-actions">
<Button variant="ghost" size="large" onClick={() => dialog.close()}>
{language.t("common.cancel")}
</Button>
<Button
variant="primary"
size="large"
onClick={() => {
dialog.close()
// Delay optimistic removal until after dialog close animation (100ms)
// to prevent the reactive list re-render from firing click handlers
// on shifted list items while the dialog overlay is still present.
setTimeout(() => session.removeMode(agent.name), 150)
}}
>
{language.t("settings.agentBehaviour.removeMode.button")}
</Button>
</div>
</div>
</Dialog>
))
}

const renderAgentsSubtab = () => (
<div>
{/* Default agent */}
Expand Down Expand Up @@ -345,6 +375,48 @@ const AgentBehaviourTab: Component = () => {
</SettingsRow>
</Card>
</Show>

{/* Available modes (non-native only, with remove button) */}
<Show when={removableModes().length > 0}>
<h4 style={{ "margin-top": "16px", "margin-bottom": "8px" }}>
{language.t("settings.agentBehaviour.availableModes")}
</h4>
<Card>
<For each={removableModes()}>
{(agent, index) => (
<div
style={{
display: "flex",
"align-items": "center",
"justify-content": "space-between",
padding: "8px 0",
"border-bottom": index() < removableModes().length - 1 ? "1px solid var(--border-weak-base)" : "none",
}}
>
<div style={{ flex: 1, "min-width": 0 }}>
<div data-slot="settings-row-label-title" style={{ "margin-bottom": "0" }}>
{agent.name}
</div>
<Show when={agent.description}>
<div data-slot="settings-row-label-subtitle" style={{ "margin-top": "4px" }}>
{agent.description}
</div>
</Show>
</div>
<IconButton
size="small"
variant="ghost"
icon="close"
onClick={(e: MouseEvent) => {
e.stopPropagation()
confirmRemoveMode(agent)
}}
/>
</div>
)}
</For>
</Card>
</Show>
</div>
)

Expand Down
18 changes: 18 additions & 0 deletions packages/kilo-vscode/webview-ui/src/context/session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ interface SessionContextValue {

// Agent/mode selection (per-session)
agents: Accessor<AgentInfo[]>
removeMode: (name: string) => void
selectedAgent: Accessor<string>
selectAgent: (name: string) => void
getSessionAgent: (sessionID: string) => string
Expand Down Expand Up @@ -213,6 +214,22 @@ export const SessionProvider: ParentComponent = (props) => {
// Skills loaded from the CLI backend
const [skills, setSkills] = createSignal<SkillInfo[]>([])

const removeMode = (name: string) => {
setAgents((prev) => prev.filter((a) => a.name !== name))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Removed mode can stay selected in session state

removeMode() only updates the agents list. If the user deletes the mode currently stored in agentSelections or pendingAgentSelection, selectedAgentName() keeps returning that stale value, and the next sendMessage() still forwards it to the backend. Agent.get(input.agent) then resolves undefined in session/prompt.ts, which turns this into a runtime failure instead of falling back to the new default mode.


// Clear stale selections so selectedAgentName() falls back to the default
if (pendingAgentSelection() === name) {
setPendingAgentSelection(null)
}
for (const sid of Object.keys(store.agentSelections)) {
if (store.agentSelections[sid] === name) {
setStore("agentSelections", sid, undefined as unknown as string)
}
}

vscode.postMessage({ type: "removeMode", name })
}

// Pending agent selection for before a session exists
const [pendingAgentSelection, setPendingAgentSelection] = createSignal<string | null>(null)

Expand Down Expand Up @@ -1314,6 +1331,7 @@ export const SessionProvider: ParentComponent = (props) => {
skills,
refreshSkills,
removeSkill,
removeMode,
selectedAgent: selectedAgentName,
selectAgent,
getSessionAgent: (sessionID: string) => store.agentSelections[sessionID] ?? defaultAgent(),
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/ar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "المهارات المكتشفة",
"settings.agentBehaviour.noSkillsFound":
"لم يتم العثور على مهارات. أضف مسارات مجلدات أو عناوين URL أدناه لإتاحة المهارات.",
"settings.agentBehaviour.availableModes": "الأوضاع المخصصة المتاحة",
"settings.agentBehaviour.noModesFound": "لم يتم العثور على أوضاع.",
"settings.agentBehaviour.removeMode.title": "إزالة الوضع",
"settings.agentBehaviour.removeMode.confirm":
'هل تريد إزالة الوضع "{{name}}"؟ سيؤدي هذا إلى تعطيل الوضع عن طريق تحديث الإعدادات.',
"settings.agentBehaviour.removeMode.button": "إزالة",
"settings.agentBehaviour.skillPaths": "مسارات مجلدات المهارات",
"settings.agentBehaviour.skillUrls": "عناوين URL للمهارات",
"settings.agentBehaviour.removeSkill.title": "إزالة المهارة",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/br.ts
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "Habilidades descobertas",
"settings.agentBehaviour.noSkillsFound":
"Nenhuma habilidade encontrada. Adicione caminhos de pastas ou URLs abaixo para disponibilizar habilidades.",
"settings.agentBehaviour.availableModes": "Modos personalizados disponíveis",
"settings.agentBehaviour.noModesFound": "Nenhum modo encontrado.",
"settings.agentBehaviour.removeMode.title": "Remover modo",
"settings.agentBehaviour.removeMode.confirm":
'Remover o modo "{{name}}"? Isso desativará o modo atualizando sua configuração.',
"settings.agentBehaviour.removeMode.button": "Remover",
"settings.agentBehaviour.skillPaths": "Caminhos de pastas de habilidades",
"settings.agentBehaviour.skillUrls": "URLs de habilidades",
"settings.agentBehaviour.removeSkill.title": "Remover habilidade",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/bs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "Otkrivene vještine",
"settings.agentBehaviour.noSkillsFound":
"Nisu pronađene vještine. Dodajte putanje mapa ili URL-ove ispod kako biste učinili vještine dostupnim.",
"settings.agentBehaviour.availableModes": "Dostupni prilagođeni modovi",
"settings.agentBehaviour.noModesFound": "Nisu pronađeni modovi.",
"settings.agentBehaviour.removeMode.title": "Ukloni mod",
"settings.agentBehaviour.removeMode.confirm":
'Ukloniti mod "{{name}}"? Ovo će onemogućiti mod ažuriranjem vaše konfiguracije.',
"settings.agentBehaviour.removeMode.button": "Ukloni",
"settings.agentBehaviour.skillPaths": "Putanje mapa vještina",
"settings.agentBehaviour.skillUrls": "URL-ovi vještina",
"settings.agentBehaviour.removeSkill.title": "Ukloni vještinu",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/da.ts
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "Opdagede skills",
"settings.agentBehaviour.noSkillsFound":
"Ingen skills fundet. Tilføj skill-mappestier eller URL'er nedenfor for at gøre skills tilgængelige.",
"settings.agentBehaviour.availableModes": "Tilgængelige brugerdefinerede tilstande",
"settings.agentBehaviour.noModesFound": "Ingen tilstande fundet.",
"settings.agentBehaviour.removeMode.title": "Fjern tilstand",
"settings.agentBehaviour.removeMode.confirm":
'Vil du fjerne tilstanden "{{name}}"? Dette vil deaktivere tilstanden ved at opdatere din konfiguration.',
"settings.agentBehaviour.removeMode.button": "Fjern",
"settings.agentBehaviour.skillPaths": "Skill-mappestier",
"settings.agentBehaviour.skillUrls": "Skill-URL'er",
"settings.agentBehaviour.removeSkill.title": "Fjern færdighed",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -972,6 +972,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "Erkannte Skills",
"settings.agentBehaviour.noSkillsFound":
"Keine Skills gefunden. Fügen Sie unten Skill-Ordnerpfade oder URLs hinzu, um Skills verfügbar zu machen.",
"settings.agentBehaviour.availableModes": "Verfügbare benutzerdefinierte Modi",
"settings.agentBehaviour.noModesFound": "Keine Modi gefunden.",
"settings.agentBehaviour.removeMode.title": "Modus entfernen",
"settings.agentBehaviour.removeMode.confirm":
'Modus "{{name}}" entfernen? Dadurch wird der Modus durch Aktualisierung Ihrer Konfiguration deaktiviert.',
"settings.agentBehaviour.removeMode.button": "Entfernen",
"settings.agentBehaviour.skillPaths": "Skill-Ordnerpfade",
"settings.agentBehaviour.skillUrls": "Skill-URLs",
"settings.agentBehaviour.removeSkill.title": "Skill entfernen",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "Discovered Skills",
"settings.agentBehaviour.noSkillsFound":
"No skills discovered. Add skill folder paths or URLs below to make skills available.",
"settings.agentBehaviour.availableModes": "Available Custom Modes",
"settings.agentBehaviour.noModesFound": "No modes found.",
"settings.agentBehaviour.removeMode.title": "Remove mode",
"settings.agentBehaviour.removeMode.confirm":
'Remove mode "{{name}}"? This will disable the mode by updating your config.',
"settings.agentBehaviour.removeMode.button": "Remove",
"settings.agentBehaviour.skillPaths": "Skill Folder Paths",
"settings.agentBehaviour.skillUrls": "Skill URLs",
"settings.agentBehaviour.removeSkill.title": "Remove skill",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -964,6 +964,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "Habilidades descubiertas",
"settings.agentBehaviour.noSkillsFound":
"No se encontraron habilidades. Agregue rutas de carpetas o URLs abajo para hacer disponibles las habilidades.",
"settings.agentBehaviour.availableModes": "Modos personalizados disponibles",
"settings.agentBehaviour.noModesFound": "No se encontraron modos.",
"settings.agentBehaviour.removeMode.title": "Eliminar modo",
"settings.agentBehaviour.removeMode.confirm":
'¿Eliminar el modo "{{name}}"? Esto desactivará el modo actualizando su configuración.',
"settings.agentBehaviour.removeMode.button": "Eliminar",
"settings.agentBehaviour.skillPaths": "Rutas de carpetas de habilidades",
"settings.agentBehaviour.skillUrls": "URLs de habilidades",
"settings.agentBehaviour.removeSkill.title": "Eliminar habilidad",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "Compétences découvertes",
"settings.agentBehaviour.noSkillsFound":
"Aucune compétence découverte. Ajoutez des chemins de dossiers ou des URLs ci-dessous pour rendre les compétences disponibles.",
"settings.agentBehaviour.availableModes": "Modes personnalisés disponibles",
"settings.agentBehaviour.noModesFound": "Aucun mode trouvé.",
"settings.agentBehaviour.removeMode.title": "Supprimer le mode",
"settings.agentBehaviour.removeMode.confirm":
'Supprimer le mode "{{name}}" ? Cela désactivera le mode en mettant à jour votre configuration.',
"settings.agentBehaviour.removeMode.button": "Supprimer",
"settings.agentBehaviour.skillPaths": "Chemins des dossiers de compétences",
"settings.agentBehaviour.skillUrls": "URLs de compétences",
"settings.agentBehaviour.removeSkill.title": "Supprimer la compétence",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "検出されたスキル",
"settings.agentBehaviour.noSkillsFound":
"スキルが見つかりません。スキルを利用可能にするには、以下にスキルフォルダパスまたはURLを追加してください。",
"settings.agentBehaviour.availableModes": "利用可能なカスタムモード",
"settings.agentBehaviour.noModesFound": "モードが見つかりません。",
"settings.agentBehaviour.removeMode.title": "モードを削除",
"settings.agentBehaviour.removeMode.confirm":
'モード "{{name}}" を削除しますか?設定を更新してモードを無効にします。',
"settings.agentBehaviour.removeMode.button": "削除",
"settings.agentBehaviour.skillPaths": "スキルフォルダパス",
"settings.agentBehaviour.skillUrls": "スキルURL",
"settings.agentBehaviour.removeSkill.title": "スキルを削除",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/ko.ts
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "검색된 스킬",
"settings.agentBehaviour.noSkillsFound":
"스킬을 찾을 수 없습니다. 스킬을 사용하려면 아래에 스킬 폴더 경로 또는 URL을 추가하세요.",
"settings.agentBehaviour.availableModes": "사용 가능한 사용자 정의 모드",
"settings.agentBehaviour.noModesFound": "모드를 찾을 수 없습니다.",
"settings.agentBehaviour.removeMode.title": "모드 제거",
"settings.agentBehaviour.removeMode.confirm":
'모드 "{{name}}"을(를) 제거하시겠습니까? 구성을 업데이트하여 모드를 비활성화합니다.',
"settings.agentBehaviour.removeMode.button": "제거",
"settings.agentBehaviour.skillPaths": "스킬 폴더 경로",
"settings.agentBehaviour.skillUrls": "스킬 URL",
"settings.agentBehaviour.removeSkill.title": "스킬 제거",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/no.ts
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "Oppdagede ferdigheter",
"settings.agentBehaviour.noSkillsFound":
"Ingen ferdigheter funnet. Legg til ferdighetsmappestier eller URLer nedenfor for å gjøre ferdigheter tilgjengelige.",
"settings.agentBehaviour.availableModes": "Tilgjengelige egendefinerte moduser",
"settings.agentBehaviour.noModesFound": "Ingen moduser funnet.",
"settings.agentBehaviour.removeMode.title": "Fjern modus",
"settings.agentBehaviour.removeMode.confirm":
'Vil du fjerne modusen "{{name}}"? Dette vil deaktivere modusen ved å oppdatere konfigurasjonen din.',
"settings.agentBehaviour.removeMode.button": "Fjern",
"settings.agentBehaviour.skillPaths": "Ferdighetsmappe-stier",
"settings.agentBehaviour.skillUrls": "Ferdighets-URLer",
"settings.agentBehaviour.removeSkill.title": "Fjern ferdighet",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "Wykryte umiejętności",
"settings.agentBehaviour.noSkillsFound":
"Nie znaleziono umiejętności. Dodaj ścieżki folderów lub adresy URL poniżej, aby udostępnić umiejętności.",
"settings.agentBehaviour.availableModes": "Dostępne tryby niestandardowe",
"settings.agentBehaviour.noModesFound": "Nie znaleziono trybów.",
"settings.agentBehaviour.removeMode.title": "Usuń tryb",
"settings.agentBehaviour.removeMode.confirm":
'Usunąć tryb "{{name}}"? Spowoduje to wyłączenie trybu poprzez aktualizację konfiguracji.',
"settings.agentBehaviour.removeMode.button": "Usuń",
"settings.agentBehaviour.skillPaths": "Ścieżki folderów umiejętności",
"settings.agentBehaviour.skillUrls": "Adresy URL umiejętności",
"settings.agentBehaviour.removeSkill.title": "Usuń umiejętność",
Expand Down
6 changes: 6 additions & 0 deletions packages/kilo-vscode/webview-ui/src/i18n/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,12 @@ export const dict = {
"settings.agentBehaviour.discoveredSkills": "Обнаруженные навыки",
"settings.agentBehaviour.noSkillsFound":
"Навыки не обнаружены. Добавьте пути к папкам навыков или URL-адреса ниже, чтобы сделать навыки доступными.",
"settings.agentBehaviour.availableModes": "Доступные пользовательские режимы",
"settings.agentBehaviour.noModesFound": "Режимы не найдены.",
"settings.agentBehaviour.removeMode.title": "Удалить режим",
"settings.agentBehaviour.removeMode.confirm":
'Удалить режим "{{name}}"? Это отключит режим, обновив вашу конфигурацию.',
"settings.agentBehaviour.removeMode.button": "Удалить",
"settings.agentBehaviour.skillPaths": "Пути папок навыков",
"settings.agentBehaviour.skillUrls": "URL навыков",
"settings.agentBehaviour.removeSkill.title": "Удалить навык",
Expand Down
Loading
Loading