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:
Levi Neely 2026-03-06 13:43:57 +01:00
parent 57cd96fc6c
commit 9643a9a034
14 changed files with 134 additions and 262 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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")

View File

@ -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 {

View File

@ -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")
}

View File

@ -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": [

View File

@ -2,6 +2,7 @@
"mcpServers": {
"anvilmcp": {
"command": "anvilmcp",
"autoApproveTools": ["execute_code"],
"args": [],
"env": {}
}

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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:**

View File

@ -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:**

View File

@ -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