Skip to content

Feat/add toggle for edit rules skills#9506

Open
Yash-Raj-5424 wants to merge 6 commits intoKilo-Org:mainfrom
Yash-Raj-5424:feat/add-toggle-for-edit-rules-skills
Open

Feat/add toggle for edit rules skills#9506
Yash-Raj-5424 wants to merge 6 commits intoKilo-Org:mainfrom
Yash-Raj-5424:feat/add-toggle-for-edit-rules-skills

Conversation

@Yash-Raj-5424
Copy link
Copy Markdown

Add skill editing and enable/disable toggles

Adds UI controls in Agent Behavior settings to enable/disable individual skills and rules, with inline editing capability. Users can now toggle skills on/off and edit SKILL.md content directly from the extension settings panel.

Changes

  • Backend: Added enable/disable state to skills and rules configuration
  • UI: New toggle controls and Skills Edit Modal in AgentBehaviourTab
  • Message handlers: Added editSkill handler to persist skill file changes via CLI

Testing

  • Toggle enable/disable works correctly
  • Skills Edit Modal opens/closes as expected
  • Skill edits persist to disk
  • No console errors in DevTools

Copilot AI review requested due to automatic review settings April 25, 2026 20:20
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds UI and backend plumbing to toggle skills/rules on/off in Agent Behavior settings, plus a modal to edit skill content from the VS Code extension.

Changes:

  • Adds skills.disabled to config and filters disabled skills out of Skill.available().
  • Introduces enabled handling for permission rules at evaluation-time and a UI section to toggle rules.
  • Adds a Skills edit modal and an editSkill message handler to write skill changes to disk.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
packages/opencode/src/skill/index.ts Adds enabled field to skill schema and filters disabled skills from available() based on config.
packages/opencode/src/permission/index.ts Extends internal PermissionRule schema with an enabled flag defaulting to true.
packages/opencode/src/permission/evaluate.ts Filters out rules with enabled === false before matching.
packages/opencode/src/config/skills.ts Adds skills.disabled list to config schema.
packages/opencode/src/config/permission.ts Adds permission.disabled list to config schema.
packages/kilo-vscode/webview-ui/src/types/messages.ts Extends config/message types for skill disabling and skill edit result messaging.
packages/kilo-vscode/webview-ui/src/components/settings/SkillEditModal.tsx New modal UI for editing a skill’s name/content and saving via webview message.
packages/kilo-vscode/webview-ui/src/components/settings/AgentBehaviourTab.tsx Adds skill toggles + edit button, and a new “Permission Rules” toggle section.
packages/kilo-vscode/src/KiloProvider.ts Handles editSkill messages by locating a skill and writing updated content to disk.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 43 to 46
.object({
__originalKeys: z.string().array().optional(),
disabled: z.array(z.string()).optional().describe("Patterns of disabled rules"),
read: Rule.optional(),
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

permission.disabled is being added to the config schema, but the .transform(transform) currently returns a plain Record<string, Rule>. That means disabled will be preserved in the output object and later treated like a permission ruleset entry (e.g. Permission.fromConfig will iterate it), which will generate invalid rules and can break/alter permission enforcement. Update the transform (and/or downstream consumers) to explicitly omit disabled from the permission map, or change the output type to include disabled separately and ensure fromConfig ignores it.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed: Excluded disabled field from permission map in transform function to prevent it from being treated as a permission rule, which would break permission enforcement.

Comment thread packages/opencode/src/skill/index.ts Outdated
Comment on lines 10 to 14
export function evaluate(permission: string, pattern: string, ...rulesets: Rule[][]): Rule {
const rules = rulesets.flat()
const rules = rulesets.flat().filter((rule) => rule.enabled !== false)
const match = rules.findLast(
(rule) => Wildcard.match(permission, rule.permission) && Wildcard.match(pattern, rule.pattern),
)
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

evaluate() now filters out rules where enabled === false, but there are existing permission tests for evaluate semantics and none cover this new behavior. Add a unit test proving that a disabled matching rule is ignored and the next-most-recent enabled match wins.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed: Added the unit tests.
The tests confirm:

  • Disabled matching rules are ignored, allowing the next enabled match to win
  • Disabled rules don't block fallthrough to other rules or defaults

This ensures the new enabled field behavior is covered and prevents regressions.

Comment thread packages/kilo-vscode/webview-ui/src/components/settings/SkillEditModal.tsx Outdated
Comment on lines +192 to +203
const disabledRulePatterns = () => config().permission?.disabled ?? []

const toggleRuleEnabled = (pattern: string) => {
const disabled = [...disabledRulePatterns()]
const index = disabled.indexOf(pattern)
if (index >= 0) {
disabled.splice(index, 1)
} else {
disabled.push(pattern)
}
updateConfig({ permission: { ...config().permission, disabled } })
}
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

The new rules toggle writes to config().permission.disabled, but permission is currently a map of tool permissions (string/object) and this repo's permission config conversion (Permission.fromConfig) iterates all entries. Persisting a disabled: string[] field inside permission will be treated as a permission rule entry and can break permission evaluation. If you want rule toggles, store disabled rules in a dedicated top-level config field (or a sibling object) and ensure the backend applies it when building the Ruleset.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed: Moved disabled permission patterns from config().permission.disabled to a dedicated top-level config().disabled_permissions field. This ensures disabled patterns are treated as metadata rather than permission rules, preventing Permission.fromConfig() from iterating over them and generating invalid rules that would break permission enforcement. Updated Permission.fromConfig() to accept and apply disabled patterns, marking matching rules with enabled: false.

Comment on lines +2331 to +2336
const skillUri = vscode.Uri.file(skill.location)
const skillContent = Buffer.from(content, "utf8")

// Write the updated skill content
await vscode.workspace.fs.writeFile(skillUri, skillContent)

Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

handleEditSkill overwrites the entire SKILL.md file with content only. In the backend, Skill.Info.content is the markdown body without YAML frontmatter, so this will strip name/description frontmatter and make the skill fail to load on next refresh. Preserve/rewrite the full file including frontmatter (and apply the edited name if renames are supported), and reject editing for built-in skills (location === "builtin") before calling vscode.Uri.file(...).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed: Updated skill editing handler to preserve YAML frontmatter. The handler now:

  • Rejects editing for built-in skills (location === "builtin")
  • Reads the original file and extracts frontmatter between --- delimiters
  • Updates the skill name in frontmatter if it was renamed
  • Reconstructs the complete file with preserved frontmatter + new content
  • Prevents skill loading failures caused by missing metadata

Comment on lines +2302 to +2303
private async handleEditSkill(originalName: string, name: string, content: string): Promise<void> {
if (!this.client || this.connectionState !== "connected") {
Copy link

Copilot AI Apr 25, 2026

Choose a reason for hiding this comment

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

handleEditSkill accepts a name parameter but never uses it, while the UI allows editing the skill name. This will lead to a confusing UX where renames appear to succeed but are not persisted. Either disable name editing in the modal or implement renaming (including updating frontmatter and/or folder naming rules).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed: Disabled skill name editing in the modal to prevent confusing UX. The name field is now read-only since skill renaming requires folder/file renames which are not yet implemented. The backend no longer attempts to update the frontmatter name. Renaming can be added as a future enhancement.

Comment thread packages/kilo-vscode/src/KiloProvider.ts Outdated
await vscode.workspace.fs.writeFile(skillUri, skillContent)

// Send success message
this.postMessage({
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: Skill cache is left stale after a direct file write

This handler writes SKILL.md through vscode.workspace.fs, but the CLI keeps skills in Skill.state/InstanceState and session.refreshSkills() reads back through app.skills(). Without disposing or refreshing the backend instance before returning success, the settings UI and the runtime can keep serving the old in-memory skill content until the server is restarted.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed: Added explicit documentation of skill cache invalidation flow. After successful skill edit:

  • Webview calls session.refreshSkills() in the onSave handler
  • This triggers app.skills() API call which re-reads from disk
  • CLI backend skill cache is invalidated on the next query
  • Both UI and runtime serve updated content without requiring server restart

@kilo-code-bot
Copy link
Copy Markdown
Contributor

kilo-code-bot Bot commented Apr 25, 2026

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0

Fix these issues in Kilo Cloud

Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/src/KiloProvider.ts 2338 After writing SKILL.md, the extension still does not invalidate or refresh the CLI skill/command caches, so session.refreshSkills() can continue serving stale in-memory skill content.
Resolved Since Previous Review
File Line Resolution
packages/kilo-vscode/src/KiloProvider.ts 2316 Switched from this.client.skill.all() to this.client.app.skills(), resolving the broken SDK call in handleEditSkill().
Other Observations (not in diff)

No additional observations outside the diff.

Files Reviewed (2 files)
  • packages/kilo-vscode/src/KiloProvider.ts - 1 unresolved issue, 1 fixed issue
  • packages/kilo-vscode/webview-ui/src/components/settings/SkillEditModal.tsx - 0 issues

Co-authored-by: kilo-code-bot[bot] <240665456+kilo-code-bot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants