Fix MCP bead tools: add mount parameter and handle multi-line inputs

- All bead tools now require explicit mount parameter as first arg
- Multi-line values (descriptions, comments, reasons) properly quoted with printf
- Fixes issue where tools wrote to read-only agent/beads/list instead of mount-specific ctl
This commit is contained in:
Levi Neely 2026-02-28 23:07:21 +01:00
parent 495136c70c
commit 27188f1f55
16 changed files with 118 additions and 70 deletions

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads
# description: Add a dependency (child depends on parent)
# Usage: add_dependency.sh <child-id> <parent-id>
# Usage: add_dependency.sh <mount> <child-id> <parent-id>
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,9 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 2 ]; then
echo "usage: add_dependency.sh <child-id> <parent-id>" >&2
if [ $# -lt 3 ]; then
echo "usage: add_dependency.sh <mount> <child-id> <parent-id>" >&2
exit 1
fi
echo "dep $*" | 9p write agent/beads/list
echo "dep $2 $3" | 9p write agent/beads/$1/ctl

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads, tasks
# description: Claim a bead for work
# Usage: claim_bead.sh <bead-id> [assignee]
# Usage: claim_bead.sh <mount> <bead-id> [assignee]
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,17 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 1 ]; then
echo "usage: claim_bead.sh <bead-id> [assignee]" >&2
if [ $# -lt 2 ]; then
echo "usage: claim_bead.sh <mount> <bead-id> [assignee]" >&2
exit 1
fi
echo "claim $*" | 9p write agent/beads/list
MOUNT="$1"
BEAD_ID="$2"
ASSIGNEE="${3:-}"
if [ -n "$ASSIGNEE" ]; then
echo "claim $BEAD_ID $ASSIGNEE" | 9p write agent/beads/$MOUNT/ctl
else
echo "claim $BEAD_ID" | 9p write agent/beads/$MOUNT/ctl
fi

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads, tasks
# description: Add a comment to a bead
# Usage: comment_bead.sh <bead-id> <text>
# Usage: comment_bead.sh <mount> <bead-id> <text>
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,14 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 2 ]; then
echo "usage: comment_bead.sh <bead-id> <text>" >&2
if [ $# -lt 3 ]; then
echo "usage: comment_bead.sh <mount> <bead-id> <text>" >&2
exit 1
fi
echo "comment $*" | 9p write agent/beads/list
MOUNT="$1"
BEAD_ID="$2"
shift 2
TEXT="$*"
printf "comment %s '%s'\n" "$BEAD_ID" "$TEXT" | 9p write agent/beads/$MOUNT/ctl

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads, tasks
# description: Complete a bead
# Usage: complete_bead.sh <bead-id>
# Usage: complete_bead.sh <mount> <bead-id>
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,9 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 1 ]; then
echo "usage: complete_bead.sh <bead-id>" >&2
if [ $# -lt 2 ]; then
echo "usage: complete_bead.sh <mount> <bead-id>" >&2
exit 1
fi
echo "complete $1" | 9p write agent/beads/list
echo "complete $2" | 9p write agent/beads/$1/ctl

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads, tasks
# description: Create a new bead
# Usage: create_bead.sh <title> [description] [parent-id] [--no-lint] [capability=low|standard|high]
# Usage: create_bead.sh <mount> <title> [description] [parent-id] [--no-lint] [capability=low|standard|high]
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,16 +9,16 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 1 ]; then
echo "usage: create_bead.sh <title> [description] [parent-id] [--no-lint] [capability=low|standard|high]" >&2
if [ $# -lt 2 ]; then
echo "usage: create_bead.sh <mount> <title> [description] [parent-id] [--no-lint] [capability=low|standard|high]" >&2
exit 1
fi
# Find the first mounted project
MOUNT=$(9p ls agent/beads | grep -v '^ctl$' | grep -v '^mtab$' | grep -v '^ready$' | head -1)
if [ -z "$MOUNT" ]; then
echo "Error: No beads projects mounted" >&2
exit 1
fi
MOUNT="$1"
TITLE="$2"
DESC="${3:-}"
PARENT="${4:-}"
NOLINT="${5:-}"
CAP="${6:-}"
echo "new \"$1\" \"${2:-}\" ${3:-} ${4:-} ${5:-}" | 9p write agent/beads/$MOUNT/ctl
printf "new '%s' '%s' %s %s %s\n" "$TITLE" "$DESC" "$PARENT" "$NOLINT" "$CAP" | 9p write agent/beads/$MOUNT/ctl

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads, tasks
# description: Delete a bead
# Usage: delete_bead.sh <bead-id>
# Usage: delete_bead.sh <mount> <bead-id>
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,9 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 1 ]; then
echo "usage: delete_bead.sh <bead-id>" >&2
if [ $# -lt 2 ]; then
echo "usage: delete_bead.sh <mount> <bead-id>" >&2
exit 1
fi
echo "delete $1" | 9p write agent/beads/list
echo "delete $2" | 9p write agent/beads/$1/ctl

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads, tasks
# description: Fail a bead with reason
# Usage: fail_bead.sh <bead-id> <reason>
# Usage: fail_bead.sh <mount> <bead-id> <reason>
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,14 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 2 ]; then
echo "usage: fail_bead.sh <bead-id> <reason>" >&2
if [ $# -lt 3 ]; then
echo "usage: fail_bead.sh <mount> <bead-id> <reason>" >&2
exit 1
fi
echo "fail $*" | 9p write agent/beads/list
MOUNT="$1"
BEAD_ID="$2"
shift 2
REASON="$*"
printf "fail %s '%s'\n" "$BEAD_ID" "$REASON" | 9p write agent/beads/$MOUNT/ctl

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads, tasks
# description: Add a label to a bead
# Usage: label_bead.sh <bead-id> <label>
# Usage: label_bead.sh <mount> <bead-id> <label>
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,9 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 2 ]; then
echo "usage: label_bead.sh <bead-id> <label>" >&2
if [ $# -lt 3 ]; then
echo "usage: label_bead.sh <mount> <bead-id> <label>" >&2
exit 1
fi
echo "label $*" | 9p write agent/beads/list
echo "label $2 $3" | 9p write agent/beads/$1/ctl

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads
# description: Mark a bead as pending approval
# Usage: mark_pending_approval.sh <bead-id> [assignee]
# Usage: mark_pending_approval.sh <mount> <bead-id> [assignee]
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,17 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 1 ]; then
echo "usage: mark_pending_approval.sh <bead-id> [assignee]" >&2
if [ $# -lt 2 ]; then
echo "usage: mark_pending_approval.sh <mount> <bead-id> [assignee]" >&2
exit 1
fi
echo "pending-approval $*" | 9p write agent/beads/list
MOUNT="$1"
BEAD_ID="$2"
ASSIGNEE="${3:-}"
if [ -n "$ASSIGNEE" ]; then
echo "pending-approval $BEAD_ID $ASSIGNEE" | 9p write agent/beads/$MOUNT/ctl
else
echo "pending-approval $BEAD_ID" | 9p write agent/beads/$MOUNT/ctl
fi

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads
# description: Mark a bead as pending review
# Usage: mark_pending_review.sh <bead-id> [assignee]
# Usage: mark_pending_review.sh <mount> <bead-id> [assignee]
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,17 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 1 ]; then
echo "usage: mark_pending_review.sh <bead-id> [assignee]" >&2
if [ $# -lt 2 ]; then
echo "usage: mark_pending_review.sh <mount> <bead-id> [assignee]" >&2
exit 1
fi
echo "pending-review $*" | 9p write agent/beads/list
MOUNT="$1"
BEAD_ID="$2"
ASSIGNEE="${3:-}"
if [ -n "$ASSIGNEE" ]; then
echo "pending-review $BEAD_ID $ASSIGNEE" | 9p write agent/beads/$MOUNT/ctl
else
echo "pending-review $BEAD_ID" | 9p write agent/beads/$MOUNT/ctl
fi

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads
# description: Remove a dependency
# Usage: remove_dependency.sh <child-id> <parent-id>
# Usage: remove_dependency.sh <mount> <child-id> <parent-id>
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,9 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 2 ]; then
echo "usage: remove_dependency.sh <child-id> <parent-id>" >&2
if [ $# -lt 3 ]; then
echo "usage: remove_dependency.sh <mount> <child-id> <parent-id>" >&2
exit 1
fi
echo "undep $*" | 9p write agent/beads/list
echo "undep $2 $3" | 9p write agent/beads/$1/ctl

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads
# description: Resume work on a bead after approval/review
# Usage: resume_work.sh <bead-id> [assignee]
# Usage: resume_work.sh <mount> <bead-id> [assignee]
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,17 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 1 ]; then
echo "usage: resume_work.sh <bead-id> [assignee]" >&2
if [ $# -lt 2 ]; then
echo "usage: resume_work.sh <mount> <bead-id> [assignee]" >&2
exit 1
fi
echo "resume $*" | 9p write agent/beads/list
MOUNT="$1"
BEAD_ID="$2"
ASSIGNEE="${3:-}"
if [ -n "$ASSIGNEE" ]; then
echo "resume $BEAD_ID $ASSIGNEE" | 9p write agent/beads/$MOUNT/ctl
else
echo "resume $BEAD_ID" | 9p write agent/beads/$MOUNT/ctl
fi

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads
# description: Set capability level on a bead (low|standard|high)
# Usage: set_capability.sh <bead-id> <level>
# Usage: set_capability.sh <mount> <bead-id> <level>
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,9 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 2 ]; then
echo "usage: set_capability.sh <bead-id> <level>" >&2
if [ $# -lt 3 ]; then
echo "usage: set_capability.sh <mount> <bead-id> <level>" >&2
exit 1
fi
echo "set-capability $*" | 9p write agent/beads/list
echo "set-capability $2 $3" | 9p write agent/beads/$1/ctl

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads, tasks
# description: Unclaim a bead (reset to open)
# Usage: unclaim_bead.sh <bead-id>
# Usage: unclaim_bead.sh <mount> <bead-id>
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,9 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 1 ]; then
echo "usage: unclaim_bead.sh <bead-id>" >&2
if [ $# -lt 2 ]; then
echo "usage: unclaim_bead.sh <mount> <bead-id>" >&2
exit 1
fi
echo "unclaim $1" | 9p write agent/beads/list
echo "unclaim $2" | 9p write agent/beads/$1/ctl

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads, tasks
# description: Remove a label from a bead
# Usage: unlabel_bead.sh <bead-id> <label>
# Usage: unlabel_bead.sh <mount> <bead-id> <label>
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,9 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 2 ]; then
echo "usage: unlabel_bead.sh <bead-id> <label>" >&2
if [ $# -lt 3 ]; then
echo "usage: unlabel_bead.sh <mount> <bead-id> <label>" >&2
exit 1
fi
echo "unlabel $*" | 9p write agent/beads/list
echo "unlabel $2 $3" | 9p write agent/beads/$1/ctl

View File

@ -1,7 +1,7 @@
#!/bin/bash
# capabilities: beads, tasks
# description: Update a bead field
# Usage: update_bead.sh <bead-id> <field> <value>
# Usage: update_bead.sh <mount> <bead-id> <field> <value>
set -euo pipefail
if cat /etc/shadow >/dev/null 2>&1; then
@ -9,9 +9,15 @@ if cat /etc/shadow >/dev/null 2>&1; then
exit 1
fi
if [ $# -lt 3 ]; then
echo "usage: update_bead.sh <bead-id> <field> <value>" >&2
if [ $# -lt 4 ]; then
echo "usage: update_bead.sh <mount> <bead-id> <field> <value>" >&2
exit 1
fi
echo "update $*" | 9p write agent/beads/list
MOUNT="$1"
BEAD_ID="$2"
FIELD="$3"
shift 3
VALUE="$*"
printf "update %s %s '%s'\n" "$BEAD_ID" "$FIELD" "$VALUE" | 9p write agent/beads/$MOUNT/ctl