feat(skill): bundled /batch skill with go:embed
This commit is contained in:
35
internal/skill/embed.go
Normal file
35
internal/skill/embed.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package skill
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
)
|
||||
|
||||
//go:embed skills/*.md
|
||||
var bundledFS embed.FS
|
||||
|
||||
// BundledSkills parses and returns all skills embedded in the binary.
|
||||
func BundledSkills() ([]*Skill, error) {
|
||||
entries, err := fs.ReadDir(bundledFS, "skills")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("skill: reading bundled skills: %w", err)
|
||||
}
|
||||
|
||||
skills := make([]*Skill, 0, len(entries))
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
data, err := bundledFS.ReadFile("skills/" + entry.Name())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("skill: reading bundled file %q: %w", entry.Name(), err)
|
||||
}
|
||||
s, err := Parse(data, "bundled")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("skill: parsing bundled file %q: %w", entry.Name(), err)
|
||||
}
|
||||
skills = append(skills, s)
|
||||
}
|
||||
return skills, nil
|
||||
}
|
||||
53
internal/skill/embed_test.go
Normal file
53
internal/skill/embed_test.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package skill
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBundledSkills_NotEmpty(t *testing.T) {
|
||||
skills, err := BundledSkills()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if len(skills) == 0 {
|
||||
t.Error("expected at least one bundled skill")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBundledSkills_BatchExists(t *testing.T) {
|
||||
skills, err := BundledSkills()
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
var batch *Skill
|
||||
for _, s := range skills {
|
||||
if s.Frontmatter.Name == "batch" {
|
||||
batch = s
|
||||
break
|
||||
}
|
||||
}
|
||||
if batch == nil {
|
||||
t.Fatal("batch skill not found in bundled skills")
|
||||
}
|
||||
if batch.Frontmatter.Description == "" {
|
||||
t.Error("batch skill missing description")
|
||||
}
|
||||
if batch.Body == "" {
|
||||
t.Error("batch skill has empty body")
|
||||
}
|
||||
if batch.Source != "bundled" {
|
||||
t.Errorf("batch skill source = %q, want %q", batch.Source, "bundled")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBundledSkills_AllParseClean(t *testing.T) {
|
||||
skills, err := BundledSkills()
|
||||
if err != nil {
|
||||
t.Fatalf("BundledSkills() error: %v", err)
|
||||
}
|
||||
for _, s := range skills {
|
||||
if s.Frontmatter.Name == "" {
|
||||
t.Errorf("bundled skill has empty name: %+v", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
19
internal/skill/skills/batch.md
Normal file
19
internal/skill/skills/batch.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
name: batch
|
||||
description: Decompose work into parallel tasks executed by elfs
|
||||
whenToUse: When a task can be split into independent parallel sub-tasks with no shared write state
|
||||
---
|
||||
Analyze the user's request and decompose it into independent parallel sub-tasks.
|
||||
|
||||
Rules:
|
||||
1. Identify which parts of the work can run independently (no shared write state).
|
||||
2. For each independent unit, write a focused prompt that includes specific file paths.
|
||||
3. Call spawn_elfs with ALL tasks in a single call — do NOT spawn one elf at a time.
|
||||
4. Read-only tasks on disjoint files can always parallelize.
|
||||
5. Write tasks to the same file must be sequenced — group them into one elf.
|
||||
6. Limit batch size to 5-7 tasks for optimal throughput.
|
||||
7. After all elfs complete, synthesize their outputs into a coherent response.
|
||||
8. If any elf failed, report the failure and suggest a retry for that specific sub-task.
|
||||
|
||||
User's request:
|
||||
{{.Args}}
|
||||
Reference in New Issue
Block a user