feat(core): always-on INSTRUCTIONS.md in skill directories
A skill directory may hold INSTRUCTIONS.md, with or without SKILL.md. Its body (frontmatter cut) goes into every system prompt in <skill_instructions>, re-read on every run: 16 KB per file, 64 KB in total, truncation marked with the file's path. /skills marks skills with instructions and lists instruction-only dirs.
This commit is contained in:
@@ -226,9 +226,15 @@ public sealed class ChatCommands(TelegramSender sender, ChatTimeZoneService? zon
|
||||
private static string Skills(ChatContext chat)
|
||||
{
|
||||
var skills = SkillCatalog.Load(chat.Session.Cwd);
|
||||
var instructions = SkillCatalog.LoadInstructions(chat.Session.Cwd);
|
||||
var where = $"`{Path.GetRelativePath(chat.Session.Cwd, SkillCatalog.Directory(chat.Session.Cwd))}/<name>/SKILL.md`";
|
||||
if (skills.Count == 0) return $"No skills yet. Ask me to write one, or put it in {where}.";
|
||||
return $"**Skills** ({where})\n" + string.Join('\n', skills.Select(s => $"• **{s.Name}** – {s.Description}"));
|
||||
if (skills.Count == 0 && instructions.Count == 0) return $"No skills yet. Ask me to write one, or put it in {where}.";
|
||||
|
||||
static string Mark(SkillInstructions i) => i.Truncated ? " (+ INSTRUCTIONS.md, truncated in the prompt)" : " (+ INSTRUCTIONS.md)";
|
||||
var byDir = instructions.ToDictionary(i => Path.GetDirectoryName(i.Path)!, StringComparer.Ordinal);
|
||||
var lines = skills.Select(s => $"• **{s.Name}** – {s.Description}" + (byDir.Remove(Path.GetDirectoryName(s.Path)!, out var i) ? Mark(i) : ""))
|
||||
.Concat(byDir.Values.Select(i => $"• **{i.Name}** – INSTRUCTIONS.md only" + (i.Truncated ? " (truncated in the prompt)" : "")));
|
||||
return $"**Skills** ({where})\n" + string.Join('\n', lines);
|
||||
}
|
||||
|
||||
private string Jobs(ChatContext chat)
|
||||
|
||||
Reference in New Issue
Block a user