Why: Headless runs need the pi tool names, walked context files, prompt includes, and a trust gate before project settings are loaded. Evidence: go test -count=1 ./runtime/tools/ ./runtime/resources/ ./runtime/skills/ Impact: Existing tool names stay registered. Aliases are added only when the underlying tool exists. Refs: feature/pi-headless N4 Co-authored-by: Cursor <cursoragent@cursor.com>
73 lines
2.1 KiB
Go
73 lines
2.1 KiB
Go
package resources
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"agent-native/runtime/skills"
|
|
"agent-native/runtime/tools"
|
|
)
|
|
|
|
func TestContextAndPromptAndTrust(t *testing.T) {
|
|
root := t.TempDir()
|
|
proj := filepath.Join(root, "proj")
|
|
if err := os.MkdirAll(proj, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(root, "AGENTS.md"), []byte("root-agents"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(proj, "SYSTEM.md"), []byte("sys"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
text, err := ContextFiles(proj)
|
|
if err != nil || !strings.Contains(text, "root-agents") || !strings.Contains(text, "sys") {
|
|
t.Fatalf("context: %s %v", text, err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(proj, "greet.md"), []byte("hello {{name}}"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := Expand("say /greet", proj, map[string]string{"name": "Ada"})
|
|
if err != nil || got != "say hello Ada" {
|
|
t.Fatalf("expand: %q %v", got, err)
|
|
}
|
|
if ProjectTrusted(TrustAsk, false, false) {
|
|
t.Fatal("ask is not trusted without approve")
|
|
}
|
|
if !ProjectTrusted(TrustNever, true, false) {
|
|
t.Fatal("approve overrides never")
|
|
}
|
|
if ProjectTrusted(TrustAlways, false, true) {
|
|
t.Fatal("no-approve wins")
|
|
}
|
|
}
|
|
|
|
func TestPiAliasesFilterAndSkillCommand(t *testing.T) {
|
|
reg := tools.WorkspaceTools(t.TempDir())
|
|
reg.RegisterPiAliases()
|
|
if !reg.Has("read") || !reg.Has("ls") || !reg.Has("read_file") {
|
|
t.Fatal("aliases missing")
|
|
}
|
|
if err := reg.Filter(tools.FilterOptions{Exclude: []string{"read"}, NoBuiltin: false}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if reg.Has("read") || !reg.Has("read_file") {
|
|
t.Fatal("exclude should drop only the alias")
|
|
}
|
|
dir := t.TempDir()
|
|
skillDir := filepath.Join(dir, "review")
|
|
if err := os.MkdirAll(skillDir, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(skillDir, "SKILL.md"), []byte("be thorough"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
store := skills.NewStore(dir)
|
|
out, err := store.ExpandCommands("use /skill:review now")
|
|
if err != nil || !strings.Contains(out, "be thorough") {
|
|
t.Fatalf("skill expand: %q %v", out, err)
|
|
}
|
|
}
|