Add global skill system for self-accumulated knowledge

Introduce a cross-group skill system that lets the bot distill reusable
knowledge into markdown docs and load them on demand, keeping day-to-day
context pollution low.

- SkillStore manages data/skills/*.md files with name/description
  frontmatter and an in-memory index cache (rebuilt on init/reload)
- Only the skill index (name + one-line description) is injected via the
  new {skills} system-prompt placeholder; bodies load on demand
- New tools: loadSkill / saveSkill (upsert, iterate = load+overwrite) /
  deleteSkill, gated by PluginConfig.skillsEnabled
- Skill names validated against ^[A-Za-z0-9_-]+$ to prevent traversal
- Wire SkillStore.init into onEnable and refresh on /jgpt reload; add
  /jgpt skills listing command
- Bump version to 1.12.0; update README

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
2026-06-20 23:37:44 +08:00
co-authored by Claude Opus 4.8
parent 538fe563a0
commit 4307019ee8
9 changed files with 416 additions and 8 deletions
+15
View File
@@ -21,9 +21,24 @@ object PluginCommands : CompositeCommand(
PluginConfig.reload()
PluginData.reload()
LargeLanguageModels.reload()
SkillStore.reload()
sendMessage("OK")
}
@SubCommand
suspend fun CommandSender.skills() {
val all = SkillStore.all
if (all.isEmpty()) {
sendMessage("暂无技能")
return
}
val response = buildString {
appendLine("当前技能(共 ${all.size} 个):")
all.forEach { appendLine("- ${it.name}: ${it.description}") }
}
sendMessage(response.trim())
}
@SubCommand
suspend fun CommandSender.enable(contact: Contact) {
when (contact) {