Flatten tools 9P, restore SKILLS_PROMPT, remove role/tool discovery
- Flatten agent/tools/ to serve tools directly (no capability subdirs) - Restore SKILLS_PROMPT.md with proactive skill discovery - Remove discover_role.sh and discover_tool.sh - Remove help endpoint from roles and tools - Update all SKILL.md files to use flat tool paths - Clear agent prompt in anvillm-agent.json
This commit is contained in:
parent
57cd96fc6c
commit
9643a9a034
|
|
@ -0,0 +1,25 @@
|
|||
# Proactive Skill Discovery
|
||||
|
||||
**BEFORE responding to ANY user request**, identify relevant capabilities and load skills using execute_code:
|
||||
|
||||
1. Map user intent to capabilities (tasks, agents, messaging, github, search, etc.)
|
||||
2. Discover skills for each capability:
|
||||
```bash
|
||||
bash <(9p read agent/tools/discover_skill.sh) <keyword>
|
||||
```
|
||||
3. Load relevant skill files:
|
||||
```bash
|
||||
9p read agent/skills/<capability>/<skill-name>/SKILL.md
|
||||
```
|
||||
|
||||
**Common capability mappings:**
|
||||
- Task/project management → `tasks`, `workflow`
|
||||
- Agent operations → `agents`, `sessions`, `messaging`
|
||||
- GitHub/Git → `github`, `vcs`
|
||||
- Web search → `search`, `web`
|
||||
- Documentation → `documentation`, `notes`
|
||||
- Knowledge management → `knowledge`, `learning`
|
||||
|
||||
## After Discovery
|
||||
|
||||
Follow the instructions in the loaded SKILL.md. If no skill found, fall back to shell via execute_code.
|
||||
|
|
@ -30,41 +30,29 @@ If a step succeeded, do not announce it — the tool output is the confirmation.
|
|||
- One-line status: `Created bd-abc.` not a paragraph about what was created
|
||||
- No preamble, no postamble
|
||||
|
||||
# MANDATORY DISCOVERY PROTOCOL - FAILURE TO FOLLOW = BROKEN AGENT
|
||||
# Proactive Skill Discovery
|
||||
|
||||
## YOU MUST DISCOVER SKILLS/ROLES FIRST - NO EXCEPTIONS
|
||||
**BEFORE responding to ANY user request**, identify relevant capabilities and load skills using execute_code:
|
||||
|
||||
**IMPORTANT:** All discovery commands must be run via `execute_code` tool.
|
||||
|
||||
BEFORE attempting ANY task:
|
||||
|
||||
**ROLE ASSIGNMENT**: IF the prompt contains "you are a", "you're a", "act as", or "be a" — your FIRST tool call MUST be `discover_role.sh <keyword>`. Do not respond. Do not check inbox. Do not take any other action. Run role discovery first.
|
||||
1. Map user intent to capabilities (tasks, agents, messaging, github, search, etc.)
|
||||
2. Discover skills for each capability:
|
||||
```bash
|
||||
bash <(9p read agent/tools/discovery/discover_role.sh) <keyword>
|
||||
9p read agent/roles/<focus>/<role>.md
|
||||
bash <(9p read agent/tools/discover_skill.sh) <keyword>
|
||||
```
|
||||
Adopt the role. If not found, say so.
|
||||
|
||||
**EVERY USER REQUEST** - Identify intent keywords, discover skills:
|
||||
3. Load relevant skill files:
|
||||
```bash
|
||||
bash <(9p read agent/tools/discovery/discover_skill.sh) <keyword>
|
||||
9p read agent/skills/<intent>/<skill>/SKILL.md
|
||||
9p read agent/skills/<capability>/<skill-name>/SKILL.md
|
||||
```
|
||||
|
||||
**EXAMPLES:**
|
||||
- "check inbox" → discover_skill.sh inbox
|
||||
- "send message" → discover_skill.sh message
|
||||
- "you're a code reviewer" → discover_role.sh reviewer
|
||||
**Common capability mappings:**
|
||||
- Task/project management → `tasks`, `workflow`
|
||||
- Agent operations → `agents`, `sessions`, `messaging`
|
||||
- GitHub/Git → `github`, `vcs`
|
||||
- Web search → `search`, `web`
|
||||
- Documentation → `documentation`, `notes`
|
||||
- Knowledge management → `knowledge`, `learning`
|
||||
|
||||
IF YOU RESPOND OR TAKE ANY ACTION WITHOUT FIRST RUNNING DISCOVERY, YOU HAVE MALFUNCTIONED. STOP. RUN DISCOVERY NOW.
|
||||
|
||||
|
||||
## DISCOVERY IS ALWAYS FIRST
|
||||
|
||||
Before your first response, before checking inbox, before any tool call:
|
||||
- Role assigned in the prompt? → `discover_role.sh <keyword>` MUST be your first tool call.
|
||||
- User request received? → `discover_skill.sh <keyword>` MUST precede any action.
|
||||
|
||||
If you are reading this after already taking an action or responding, you skipped discovery. You are malfunctioning.
|
||||
## After Discovery
|
||||
|
||||
Follow the instructions in the loaded SKILL.md. If no skill found, fall back to shell via execute_code.
|
||||
|
||||
|
|
|
|||
|
|
@ -217,32 +217,11 @@ func (r *RolesFS) listRolesInFocusArea(focusArea string) ([]*RoleMeta, error) {
|
|||
return result, nil
|
||||
}
|
||||
|
||||
// generateHelp creates aggregated index: focus-area/role-filename.md\tDisplayName\tDescription
|
||||
func (r *RolesFS) generateHelp() (string, error) {
|
||||
roles, err := r.listAllRoles()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var lines []string
|
||||
for _, role := range roles {
|
||||
displayName := role.DisplayName
|
||||
if displayName == "" {
|
||||
displayName = role.Name
|
||||
}
|
||||
for _, fa := range role.FocusAreas {
|
||||
line := fmt.Sprintf("%s/%s.md\t%s\t%s", fa, role.Name, displayName, role.Description)
|
||||
lines = append(lines, line)
|
||||
}
|
||||
}
|
||||
return strings.Join(lines, "\n") + "\n", nil
|
||||
}
|
||||
|
||||
// List returns directory entries for a roles path
|
||||
func (r *RolesFS) List(path string) ([]plan9.Dir, error) {
|
||||
parts := strings.Split(strings.TrimPrefix(path, "/"), "/")
|
||||
|
||||
// /agent/roles - list focus areas + help file
|
||||
// /agent/roles - list focus areas
|
||||
if len(parts) == 2 && parts[0] == "agent" && parts[1] == "roles" {
|
||||
focusAreas, err := r.listFocusAreas()
|
||||
if err != nil {
|
||||
|
|
@ -250,11 +229,6 @@ func (r *RolesFS) List(path string) ([]plan9.Dir, error) {
|
|||
}
|
||||
|
||||
var dirs []plan9.Dir
|
||||
dirs = append(dirs, plan9.Dir{
|
||||
Name: "help",
|
||||
Qid: plan9.Qid{Type: plan9.QTFILE},
|
||||
Mode: 0444,
|
||||
})
|
||||
for _, fa := range focusAreas {
|
||||
dirs = append(dirs, plan9.Dir{
|
||||
Name: fa,
|
||||
|
|
@ -291,15 +265,6 @@ func (r *RolesFS) List(path string) ([]plan9.Dir, error) {
|
|||
func (r *RolesFS) Read(path string) ([]byte, error) {
|
||||
parts := strings.Split(strings.TrimPrefix(path, "/"), "/")
|
||||
|
||||
// /agent/roles/help
|
||||
if len(parts) == 3 && parts[0] == "agent" && parts[1] == "roles" && parts[2] == "help" {
|
||||
help, err := r.generateHelp()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []byte(help), nil
|
||||
}
|
||||
|
||||
// /agent/roles/<focus-area>/<role-name>.md
|
||||
if len(parts) != 4 || parts[0] != "agent" || parts[1] != "roles" {
|
||||
return nil, fmt.Errorf("not found")
|
||||
|
|
|
|||
|
|
@ -481,26 +481,24 @@ func (s *Server) walk(cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
|||
}
|
||||
}
|
||||
} else if path == "/tools" {
|
||||
// Inside tools directory - list capabilities + help
|
||||
// Inside tools directory - list tools flat
|
||||
if s.tools != nil {
|
||||
caps, _ := s.tools.listCapabilities()
|
||||
// help file
|
||||
qid = plan9.Qid{Type: QTFile, Path: qidToolsBase}
|
||||
if name == "help" {
|
||||
newPath = "/tools/help"
|
||||
} else if slices.Contains(caps, name) {
|
||||
qid = plan9.Qid{Type: QTDir, Path: qidToolsBase + hashID(name)}
|
||||
newPath = "/tools/" + name
|
||||
} else {
|
||||
tools, _ := s.tools.listAllTools()
|
||||
found := false
|
||||
for _, tool := range tools {
|
||||
if tool.Name == name {
|
||||
qid = plan9.Qid{Type: QTFile, Path: qidToolsBase + hashID(name)}
|
||||
newPath = "/tools/" + name
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return errFcall(fc, "not found")
|
||||
}
|
||||
} else {
|
||||
return errFcall(fc, "not found")
|
||||
}
|
||||
} else if strings.HasPrefix(path, "/tools/") && strings.Count(path, "/") == 2 {
|
||||
// Inside tools/<capability> - tool files
|
||||
qid = plan9.Qid{Type: QTFile, Path: qidToolsBase + hashID(path+name)}
|
||||
newPath = path + "/" + name
|
||||
} else if path == "/skills" {
|
||||
// Inside skills directory - list intents + help
|
||||
if s.skills != nil {
|
||||
|
|
@ -526,13 +524,10 @@ func (s *Server) walk(cs *connState, fc *plan9.Fcall) *plan9.Fcall {
|
|||
qid = plan9.Qid{Type: QTFile, Path: qidSkillsBase + hashID(path+name)}
|
||||
newPath = path + "/" + name
|
||||
} else if path == "/roles" {
|
||||
// Inside roles directory - list focus areas + help
|
||||
// Inside roles directory - list focus areas
|
||||
if s.roles != nil {
|
||||
focusAreas, _ := s.roles.listFocusAreas()
|
||||
qid = plan9.Qid{Type: QTFile, Path: qidRolesBase}
|
||||
if name == "help" {
|
||||
newPath = "/roles/help"
|
||||
} else if slices.Contains(focusAreas, name) {
|
||||
if slices.Contains(focusAreas, name) {
|
||||
qid = plan9.Qid{Type: QTDir, Path: qidRolesBase + hashID(name)}
|
||||
newPath = "/roles/" + name
|
||||
} else {
|
||||
|
|
@ -1122,28 +1117,11 @@ func (s *Server) readDir(path string, offset uint64, count uint32) []byte {
|
|||
}
|
||||
} else if path == "/tools" {
|
||||
if s.tools != nil {
|
||||
// Add help file
|
||||
dirs = append(dirs, plan9.Dir{
|
||||
Qid: plan9.Qid{Type: QTFile, Path: qidToolsBase},
|
||||
Mode: 0444, Name: "help", Uid: "q", Gid: "q", Muid: "q",
|
||||
})
|
||||
// Add capability directories
|
||||
caps, _ := s.tools.listCapabilities()
|
||||
for _, cap := range caps {
|
||||
dirs = append(dirs, plan9.Dir{
|
||||
Qid: plan9.Qid{Type: QTDir, Path: qidToolsBase + hashID(cap)},
|
||||
Mode: plan9.DMDIR | 0555, Name: cap, Uid: "q", Gid: "q", Muid: "q",
|
||||
})
|
||||
}
|
||||
}
|
||||
} else if strings.HasPrefix(path, "/tools/") && strings.Count(path, "/") == 2 {
|
||||
// Inside tools/<capability> - list tools
|
||||
capability := strings.TrimPrefix(path, "/tools/")
|
||||
if s.tools != nil {
|
||||
tools, _ := s.tools.listToolsInCapability(capability)
|
||||
// List tools flat
|
||||
tools, _ := s.tools.listAllTools()
|
||||
for _, tool := range tools {
|
||||
dirs = append(dirs, plan9.Dir{
|
||||
Qid: plan9.Qid{Type: QTFile, Path: qidToolsBase + hashID(path+tool.Name)},
|
||||
Qid: plan9.Qid{Type: QTFile, Path: qidToolsBase + hashID(tool.Name)},
|
||||
Mode: 0444, Name: tool.Name, Uid: "q", Gid: "q", Muid: "q",
|
||||
})
|
||||
}
|
||||
|
|
@ -1189,11 +1167,6 @@ func (s *Server) readDir(path string, offset uint64, count uint32) []byte {
|
|||
}
|
||||
} else if path == "/roles" {
|
||||
if s.roles != nil {
|
||||
// Add help file
|
||||
dirs = append(dirs, plan9.Dir{
|
||||
Qid: plan9.Qid{Type: QTFile, Path: qidRolesBase},
|
||||
Mode: 0444, Name: "help", Uid: "q", Gid: "q", Muid: "q",
|
||||
})
|
||||
// Add focus area directories
|
||||
focusAreas, _ := s.roles.listFocusAreas()
|
||||
for _, fa := range focusAreas {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"9fans.net/go/plan9"
|
||||
|
|
@ -145,96 +143,12 @@ func (t *ToolsFS) listAllTools() ([]*ToolMeta, error) {
|
|||
return tools, nil
|
||||
}
|
||||
|
||||
// listCapabilities returns unique capability names from all tools
|
||||
func (t *ToolsFS) listCapabilities() ([]string, error) {
|
||||
tools, err := t.listAllTools()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
capSet := make(map[string]bool)
|
||||
for _, tool := range tools {
|
||||
for _, cap := range tool.Capabilities {
|
||||
capSet[cap] = true
|
||||
}
|
||||
}
|
||||
|
||||
var caps []string
|
||||
for cap := range capSet {
|
||||
caps = append(caps, cap)
|
||||
}
|
||||
return caps, nil
|
||||
}
|
||||
|
||||
// listToolsInCapability returns tools that have the given capability
|
||||
func (t *ToolsFS) listToolsInCapability(capability string) ([]*ToolMeta, error) {
|
||||
tools, err := t.listAllTools()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []*ToolMeta
|
||||
for _, tool := range tools {
|
||||
if slices.Contains(tool.Capabilities, capability) {
|
||||
result = append(result, tool)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// generateHelp creates aggregated one-liner index of all tools
|
||||
func (t *ToolsFS) generateHelp() (string, error) {
|
||||
tools, err := t.listAllTools()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
seen := make(map[string]bool)
|
||||
var lines []string
|
||||
for _, tool := range tools {
|
||||
key := tool.Name + "\t" + tool.Description
|
||||
if seen[key] {
|
||||
continue
|
||||
}
|
||||
seen[key] = true
|
||||
lines = append(lines, key)
|
||||
}
|
||||
sort.Strings(lines)
|
||||
return strings.Join(lines, "\n") + "\n", nil
|
||||
}
|
||||
|
||||
func (t *ToolsFS) List(path string) ([]plan9.Dir, error) {
|
||||
parts := strings.Split(strings.TrimPrefix(path, "/"), "/")
|
||||
|
||||
// /tools - list capabilities + help file
|
||||
// /tools - list all tools flat
|
||||
if len(parts) == 2 && parts[0] == "agent" && parts[1] == "tools" {
|
||||
caps, err := t.listCapabilities()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var dirs []plan9.Dir
|
||||
// Add help file
|
||||
dirs = append(dirs, plan9.Dir{
|
||||
Name: "help",
|
||||
Qid: plan9.Qid{Type: plan9.QTFILE},
|
||||
Mode: 0444,
|
||||
})
|
||||
// Add capability directories
|
||||
for _, cap := range caps {
|
||||
dirs = append(dirs, plan9.Dir{
|
||||
Name: cap,
|
||||
Qid: plan9.Qid{Type: plan9.QTDIR},
|
||||
Mode: plan9.DMDIR | 0555,
|
||||
})
|
||||
}
|
||||
return dirs, nil
|
||||
}
|
||||
|
||||
// /tools/<capability> - list tools in that capability
|
||||
if len(parts) == 3 && parts[0] == "agent" && parts[1] == "tools" {
|
||||
capability := parts[2]
|
||||
tools, err := t.listToolsInCapability(capability)
|
||||
tools, err := t.listAllTools()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -256,22 +170,12 @@ func (t *ToolsFS) List(path string) ([]plan9.Dir, error) {
|
|||
func (t *ToolsFS) Read(path string) ([]byte, error) {
|
||||
parts := strings.Split(strings.TrimPrefix(path, "/"), "/")
|
||||
|
||||
// /tools/help - aggregated index
|
||||
if len(parts) == 2 && parts[0] == "tools" && parts[1] == "help" {
|
||||
help, err := t.generateHelp()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []byte(help), nil
|
||||
}
|
||||
|
||||
// /tools/<capability>/<tool.sh> - read tool script
|
||||
if len(parts) != 3 || parts[0] != "tools" {
|
||||
// /tools/<tool.sh> - read tool script
|
||||
if len(parts) != 2 || parts[0] != "tools" {
|
||||
return nil, fmt.Errorf("not found")
|
||||
}
|
||||
|
||||
capability := parts[1]
|
||||
filename := parts[2]
|
||||
filename := parts[1]
|
||||
|
||||
if !strings.HasSuffix(filename, ".sh") {
|
||||
return nil, fmt.Errorf("not a shell script")
|
||||
|
|
@ -283,8 +187,7 @@ func (t *ToolsFS) Read(path string) ([]byte, error) {
|
|||
return nil, fmt.Errorf("invalid filename")
|
||||
}
|
||||
|
||||
// Verify tool has this capability
|
||||
tools, err := t.listToolsInCapability(capability)
|
||||
tools, err := t.listAllTools()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -307,5 +210,5 @@ func (t *ToolsFS) Read(path string) ([]byte, error) {
|
|||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("tool not found in capability")
|
||||
return nil, fmt.Errorf("tool not found")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,42 @@
|
|||
{
|
||||
"name": "anvillm-agent",
|
||||
"description": "Agent for AnviLLM multi-agent workflows with mailbox communication",
|
||||
"prompt": "# MANDATORY DISCOVERY PROTOCOL - FAILURE TO FOLLOW = BROKEN AGENT\n\n## YOU MUST DISCOVER SKILLS/ROLES FIRST - NO EXCEPTIONS\n\n**IMPORTANT:** All discovery commands must be run via `execute_code` tool.\n\nBEFORE attempting ANY task:\n\n**ROLE ASSIGNMENT**: IF the prompt contains \"you are a\", \"you're a\", \"act as\", or \"be a\" — your FIRST tool call MUST be `discover_role.sh <keyword>`. Do not respond. Do not check inbox. Do not take any other action. Run role discovery first.\n```bash\nbash <(9p read agent/tools/discovery/discover_role.sh) <keyword>\n9p read agent/roles/<focus>/<role>.md\n```\nAdopt the role. If not found, say so.\n\n**EVERY USER REQUEST** - Identify intent keywords, discover skills:\n```bash\nbash <(9p read agent/tools/discovery/discover_skill.sh) <keyword>\n9p read agent/skills/<intent>/<skill>/SKILL.md\n```\n\n**EXAMPLES:**\n- \"check inbox\" → discover_skill.sh inbox\n- \"send message\" → discover_skill.sh message\n- \"you're a code reviewer\" → discover_role.sh reviewer\n\nIF YOU RESPOND OR TAKE ANY ACTION WITHOUT FIRST RUNNING DISCOVERY, YOU HAVE MALFUNCTIONED. STOP. RUN DISCOVERY NOW.\n\n\n## DISCOVERY IS ALWAYS FIRST\n\nBefore your first response, before checking inbox, before any tool call:\n- Role assigned in the prompt? → `discover_role.sh <keyword>` MUST be your first tool call.\n- User request received? → `discover_skill.sh <keyword>` MUST precede any action.\n\nIf you are reading this after already taking an action or responding, you skipped discovery. You are malfunctioning.",
|
||||
"tools": ["*"],
|
||||
"allowedTools": ["*"],
|
||||
"prompt": "",
|
||||
"tools": [
|
||||
"code",
|
||||
"read",
|
||||
"write",
|
||||
"glob",
|
||||
"grep",
|
||||
"introspect",
|
||||
"report",
|
||||
"thinking",
|
||||
"todo",
|
||||
"aws",
|
||||
"subagent",
|
||||
"web_fetch",
|
||||
"@anvilmcp/execute_code"
|
||||
],
|
||||
"allowedTools": [
|
||||
"code",
|
||||
"read",
|
||||
"write",
|
||||
"glob",
|
||||
"grep",
|
||||
"introspect",
|
||||
"report",
|
||||
"thinking",
|
||||
"todo",
|
||||
"aws",
|
||||
"subagent",
|
||||
"web_fetch",
|
||||
"@anvilmcp/execute_code"
|
||||
],
|
||||
"toolsSettings": {
|
||||
"shell": {
|
||||
"autoAllowReadonly": true
|
||||
}
|
||||
},
|
||||
"includeMcpJson": true,
|
||||
"hooks": {
|
||||
"agentSpawn": [
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
"mcpServers": {
|
||||
"anvilmcp": {
|
||||
"command": "anvilmcp",
|
||||
"autoApproveTools": ["execute_code"],
|
||||
"args": [],
|
||||
"env": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +0,0 @@
|
|||
#!/bin/bash
|
||||
# capabilities: discovery
|
||||
# description: Discover available roles by focus area and keyword
|
||||
set -euo pipefail
|
||||
|
||||
# Usage: discover_role <keyword>
|
||||
# Returns: focus-area/role-name pairs matching keyword
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Usage: discover_role <keyword>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
keyword="$1"
|
||||
|
||||
9p read agent/roles/help 2>/dev/null | grep -i "$keyword" | sort -u || echo "No roles found matching: $keyword"
|
||||
|
|
@ -15,21 +15,21 @@ Discover agents:
|
|||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/agents/list_sessions.sh) | grep "$(pwd)"
|
||||
code: bash <(9p read agent/tools/list_sessions.sh) | grep "$(pwd)"
|
||||
```
|
||||
|
||||
Send message:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/messaging/send_message.sh) <FROM> <TO> <TYPE> <SUBJECT> <BODY>
|
||||
code: bash <(9p read agent/tools/send_message.sh) <FROM> <TO> <TYPE> <SUBJECT> <BODY>
|
||||
```
|
||||
|
||||
Check inbox:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/messaging/read_inbox.sh) <AGENT_ID>
|
||||
code: bash <(9p read agent/tools/read_inbox.sh) <AGENT_ID>
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
|
|
|||
|
|
@ -16,35 +16,35 @@ List sessions:
|
|||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/agents/list_sessions.sh)
|
||||
code: bash <(9p read agent/tools/list_sessions.sh)
|
||||
```
|
||||
|
||||
Create session:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/agents/create_session.sh) <backend> <cwd> [sandbox=<sandbox>] [model=<model>]
|
||||
code: bash <(9p read agent/tools/create_session.sh) <backend> <cwd> [sandbox=<sandbox>] [model=<model>]
|
||||
```
|
||||
|
||||
Control session:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/agents/control_session.sh) <session-id> <command>
|
||||
code: bash <(9p read agent/tools/control_session.sh) <session-id> <command>
|
||||
```
|
||||
|
||||
Spawn agent:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: default
|
||||
code: bash <(9p read agent/tools/agents/spawn_agent.sh) <agent-id> [cwd-path] [initial-context-prompt]
|
||||
code: bash <(9p read agent/tools/spawn_agent.sh) <agent-id> [cwd-path] [initial-context-prompt]
|
||||
```
|
||||
|
||||
Kill agent:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/agents/kill_agent.sh) [cwd-path]
|
||||
code: bash <(9p read agent/tools/kill_agent.sh) [cwd-path]
|
||||
```
|
||||
|
||||
## Backends
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@ Find your project's beads mount:
|
|||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: MOUNT=$(bash <(9p read agent/tools/beads/list_mounts.sh) | grep "$(pwd)" | awk '{print $1}'); echo $MOUNT
|
||||
code: MOUNT=$(bash <(9p read agent/tools/list_mounts.sh) | grep "$(pwd)" | awk '{print $1}'); echo $MOUNT
|
||||
```
|
||||
|
||||
If no mount exists, create one:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/mount_beads.sh) "$(pwd)"
|
||||
code: bash <(9p read agent/tools/mount_beads.sh) "$(pwd)"
|
||||
```
|
||||
|
||||
## Tools
|
||||
|
|
@ -30,35 +30,35 @@ List mounts:
|
|||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/list_mounts.sh)
|
||||
code: bash <(9p read agent/tools/list_mounts.sh)
|
||||
```
|
||||
|
||||
List ready beads:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/list_ready_beads.sh) <mount>
|
||||
code: bash <(9p read agent/tools/list_ready_beads.sh) <mount>
|
||||
```
|
||||
|
||||
List all beads:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/list_beads.sh) <mount>
|
||||
code: bash <(9p read agent/tools/list_beads.sh) <mount>
|
||||
```
|
||||
|
||||
Read bead JSON:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/read_bead.sh) <mount> <id> json
|
||||
code: bash <(9p read agent/tools/read_bead.sh) <mount> <id> json
|
||||
```
|
||||
|
||||
Read bead comments:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/read_bead.sh) <mount> <id> comments
|
||||
code: bash <(9p read agent/tools/read_bead.sh) <mount> <id> comments
|
||||
```
|
||||
|
||||
**IMPORTANT:** When working on a bead, always check `comment_count` in the JSON output. If > 0, read comments for additional context, decisions, or blockers.
|
||||
|
|
@ -67,63 +67,63 @@ Claim bead:
|
|||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/claim_bead.sh) <mount> <id> [$AGENT_ID]
|
||||
code: bash <(9p read agent/tools/claim_bead.sh) <mount> <id> [$AGENT_ID]
|
||||
```
|
||||
|
||||
Complete bead:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/complete_bead.sh) <mount> <id>
|
||||
code: bash <(9p read agent/tools/complete_bead.sh) <mount> <id>
|
||||
```
|
||||
|
||||
Fail bead:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/fail_bead.sh) <mount> <id> "reason"
|
||||
code: bash <(9p read agent/tools/fail_bead.sh) <mount> <id> "reason"
|
||||
```
|
||||
|
||||
Create bead:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/create_bead.sh) <mount> "title" "desc" [parent]
|
||||
code: bash <(9p read agent/tools/create_bead.sh) <mount> "title" "desc" [parent]
|
||||
```
|
||||
|
||||
Update bead:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/update_bead.sh) <mount> <id> <field> <value>
|
||||
code: bash <(9p read agent/tools/update_bead.sh) <mount> <id> <field> <value>
|
||||
```
|
||||
|
||||
Add dependency:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/add_dependency.sh) <mount> <child> <parent>
|
||||
code: bash <(9p read agent/tools/add_dependency.sh) <mount> <child> <parent>
|
||||
```
|
||||
|
||||
Comment on bead:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/comment_bead.sh) <mount> <id> "text"
|
||||
code: bash <(9p read agent/tools/comment_bead.sh) <mount> <id> "text"
|
||||
```
|
||||
|
||||
Label bead:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/label_bead.sh) <mount> <id> <label>
|
||||
code: bash <(9p read agent/tools/label_bead.sh) <mount> <id> <label>
|
||||
```
|
||||
|
||||
Delete bead:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/beads/delete_bead.sh) <mount> <id>
|
||||
code: bash <(9p read agent/tools/delete_bead.sh) <mount> <id>
|
||||
```
|
||||
|
||||
**Note:** Delete does not cascade. To delete a parent and all children, delete children first, then parent.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Import GitHub issues into beads.
|
|||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/github/github_to_beads.sh) OWNER/REPO ISSUE_NUMBER
|
||||
code: bash <(9p read agent/tools/github_to_beads.sh) OWNER/REPO ISSUE_NUMBER
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ Import Jira ticket hierarchies into beads.
|
|||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/jira/jira_to_beads.sh) PROJ-12345
|
||||
code: bash <(9p read agent/tools/jira_to_beads.sh) PROJ-12345
|
||||
```
|
||||
|
||||
**What it does:**
|
||||
|
|
|
|||
|
|
@ -41,28 +41,28 @@ Spawn testing agent:
|
|||
```
|
||||
Tool: execute_code
|
||||
sandbox: default
|
||||
code: bash <(9p read agent/tools/agents/spawn_agent.sh) <your-id> "<system-prompt-above>"
|
||||
code: bash <(9p read agent/tools/spawn_agent.sh) <your-id> "<system-prompt-above>"
|
||||
```
|
||||
|
||||
Send test request:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/messaging/send_message.sh) <your-id> <testing-agent-id> PROMPT_REQUEST "Validate fix" "Bug: <desc>\nFix: <changes>\nFiles: <list>\nBranch: <name>"
|
||||
code: bash <(9p read agent/tools/send_message.sh) <your-id> <testing-agent-id> PROMPT_REQUEST "Validate fix" "Bug: <desc>\nFix: <changes>\nFiles: <list>\nBranch: <name>"
|
||||
```
|
||||
|
||||
Read response (user notifies when ready):
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/messaging/read_inbox.sh) <your-id>
|
||||
code: bash <(9p read agent/tools/read_inbox.sh) <your-id>
|
||||
```
|
||||
|
||||
Kill testing agent:
|
||||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/agents/kill_agent.sh) <testing-agent-id>
|
||||
code: bash <(9p read agent/tools/kill_agent.sh) <testing-agent-id>
|
||||
```
|
||||
|
||||
### Testing Agent Workflow
|
||||
|
|
@ -76,7 +76,7 @@ code: bash <(9p read agent/tools/agents/kill_agent.sh) <testing-agent-id>
|
|||
```
|
||||
Tool: execute_code
|
||||
sandbox: anvilmcp
|
||||
code: bash <(9p read agent/tools/messaging/send_message.sh) <your-id> <requester-id> PROMPT_RESPONSE "Validation complete" "Status: completed|failed\n<evidence>"
|
||||
code: bash <(9p read agent/tools/send_message.sh) <your-id> <requester-id> PROMPT_RESPONSE "Validation complete" "Status: completed|failed\n<evidence>"
|
||||
```
|
||||
|
||||
**FUSE testing**: Inform user daemon must start outside sandbox, wait for acknowledgement
|
||||
|
|
|
|||
Reference in New Issue