mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-10-25 14:00:40 +00:00
feat(agent): install compact shared skill
This commit is contained in:
@@ -97,7 +97,7 @@ pad server info # How this client is connected to Pad
|
||||
|
||||
### For AI Agents
|
||||
|
||||
**Your agent becomes a project partner.** Install the `/pad` skill once, and your AI coding tool can read, create, and update project items through natural language.
|
||||
**Your agent becomes a project partner.** Install the `/pad` skill once, and your AI coding tool can read, create, and update project items through natural language. Cursor, Codex, Windsurf, and OpenCode receive a compact dispatcher and load detailed guidance by topic with `pad agent guide`, keeping routine turns small.
|
||||
|
||||
```bash
|
||||
pad agent install # Auto-detects your tools and installs the skill
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// This initially records the existing shared Cursor/Codex payload with modest
|
||||
// headroom. Later prompt-reduction changes should lower this budget, not spend it.
|
||||
const agentSkillPromptBudget = 40 * 1024
|
||||
// The compact dispatcher should stay small enough to load eagerly. Detailed
|
||||
// reference material belongs behind `pad agent guide`, not in this payload.
|
||||
const agentSkillPromptBudget = 5 * 1024
|
||||
|
||||
func TestAgentSkillPromptBudget(t *testing.T) {
|
||||
skill, err := os.ReadFile(filepath.Join("..", "..", "skills", "pad", "SKILL.md"))
|
||||
@@ -27,6 +27,11 @@ func TestAgentSkillPromptBudget(t *testing.T) {
|
||||
if len(payload) > agentSkillPromptBudget {
|
||||
t.Fatalf("%s installed skill payload is %d bytes; budget is %d", agent, len(payload), agentSkillPromptBudget)
|
||||
}
|
||||
for _, required := range []string{"pad bootstrap", "issue IDs", "convention_index", "pad agent guide"} {
|
||||
if !contains(string(payload), required) {
|
||||
t.Errorf("%s installed skill is missing core guidance %q", agent, required)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+65
-3
@@ -82,6 +82,68 @@ var SupportedTools = []AgentTool{
|
||||
},
|
||||
}
|
||||
|
||||
// agentsSkillBody is the eager dispatcher installed for tools that share the
|
||||
// .agents skill format. The full, canonical guide stays embedded in Pad and is
|
||||
// available by topic through `pad agent guide`; repeating it here would charge
|
||||
// Cursor and Codex for reference material on every skill load.
|
||||
const agentsSkillBody = `# Pad — Talk to Your Project
|
||||
|
||||
Use Pad when the user discusses project work: issues, tasks, plans, ideas,
|
||||
progress, dependencies, conventions, roles, standups, or retrospectives.
|
||||
|
||||
## Start every invocation
|
||||
|
||||
Run ` + "`pad bootstrap --format json`" + ` before acting. It returns the workspace,
|
||||
user, collections and schemas, always-on conventions, convention index, roles,
|
||||
playbooks, dashboard, and recent activity in one call.
|
||||
|
||||
- If ` + "`pad`" + ` is missing, ask the user to install it or add it to PATH.
|
||||
- If bootstrap fails, run ` + "`pad agent guide context-loading`" + ` and follow that
|
||||
section. Never initialize authentication blindly.
|
||||
- Follow every body in ` + "`conventions`" + `. Before meaningful work, inspect
|
||||
` + "`convention_index`" + ` and load bodies for the matching trigger.
|
||||
- If ` + "`needs_onboarding`" + ` is true, offer setup and wait for consent.
|
||||
- If roles exist and none was chosen in this conversation, ask once; do not block
|
||||
if the user declines.
|
||||
|
||||
## Act safely
|
||||
|
||||
- Use issue IDs such as ` + "`TASK-5`" + `, never slugs.
|
||||
- Read an item before updating it. Send only changed fields and include a comment
|
||||
with status changes.
|
||||
- Read collection schemas instead of guessing field names or terminal statuses.
|
||||
- Confirm each mutation from the returned object before saying it succeeded.
|
||||
- Use active playbooks when intent or an invocation slug matches; never run draft
|
||||
or deprecated playbooks unless the user explicitly asks.
|
||||
- Prefer summary reads and bounded lists. Fetch full bodies only when needed.
|
||||
|
||||
## Common commands
|
||||
|
||||
` + "```bash" + `
|
||||
pad project dashboard --format json
|
||||
pad item show TASK-5 --format json
|
||||
pad item list [collection] --format json
|
||||
pad item create <collection> "Title" [flags]
|
||||
pad item update TASK-5 [flags]
|
||||
pad item comment TASK-5 -m "Message"
|
||||
pad playbook list --format json
|
||||
pad playbook show <slug> --format markdown
|
||||
` + "```" + `
|
||||
|
||||
Use ` + "`pad <group> <command> --help`" + ` for exact flags.
|
||||
|
||||
## Load details only when needed
|
||||
|
||||
` + "```bash" + `
|
||||
pad agent guide # list available topics
|
||||
pad agent guide items # item commands and contracts
|
||||
pad agent guide before-performing-work # convention routing
|
||||
pad agent guide role-awareness # role behavior
|
||||
pad agent guide multi-step-workflows # planning, ideation, retro, onboarding
|
||||
pad agent guide all # explicit full reference
|
||||
` + "```" + `
|
||||
`
|
||||
|
||||
// ResolveTool finds an AgentTool by name or alias. Returns nil if not found.
|
||||
func ResolveTool(nameOrAlias string) *AgentTool {
|
||||
lower := strings.ToLower(nameOrAlias)
|
||||
@@ -206,15 +268,15 @@ func FormatForTool(tool AgentTool, embeddedContent []byte) []byte {
|
||||
return embeddedContent
|
||||
|
||||
case "agents":
|
||||
// Codex/Cursor/Windsurf/OpenCode use name + description frontmatter
|
||||
body := StripFrontmatter(embeddedContent)
|
||||
// Codex/Cursor/Windsurf/OpenCode use a compact eager dispatcher.
|
||||
// Detailed guidance remains available through `pad agent guide`.
|
||||
fm := `---
|
||||
name: pad
|
||||
description: "Talk to your project. Natural-language project management — create items, check status, create plans, brainstorm ideas, and more."
|
||||
---
|
||||
|
||||
`
|
||||
return append([]byte(fm), body...)
|
||||
return []byte(fm + agentsSkillBody)
|
||||
|
||||
case "copilot":
|
||||
// GitHub Copilot uses applyTo frontmatter
|
||||
|
||||
@@ -101,7 +101,7 @@ Body content here.
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("agents has name+description frontmatter", func(t *testing.T) {
|
||||
t.Run("agents has compact dispatcher", func(t *testing.T) {
|
||||
tool := *ResolveTool("agents")
|
||||
got := string(FormatForTool(tool, embedded))
|
||||
if got[:4] != "---\n" {
|
||||
@@ -116,8 +116,11 @@ Body content here.
|
||||
if contains(got, "allowed-tools") {
|
||||
t.Error("Agents format should NOT contain allowed-tools")
|
||||
}
|
||||
if !contains(got, "# Pad Skill") {
|
||||
t.Error("Agents format should contain body")
|
||||
if !contains(got, "pad agent guide") {
|
||||
t.Error("Agents format should point to on-demand guidance")
|
||||
}
|
||||
if contains(got, "Body content here") {
|
||||
t.Error("Agents format should not eagerly copy the full embedded guide")
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user