From 577dcfc3f08d5552e141ab12da8e2d2b47ef14a4 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Fri, 20 Mar 2026 17:18:23 +0100 Subject: [PATCH] Add ANVILLM_9MOUNT env var; update tools to use filesystem mounts --- main.go | 5 ++++- tools/check_inbox.sh | 15 +++++++-------- tools/control_session.sh | 3 ++- tools/create_session.sh | 3 ++- tools/discover_skill.sh | 15 +++++++-------- tools/kill_agent.sh | 3 ++- tools/list_roles.sh | 19 ++++++++++++++----- tools/list_sessions.sh | 5 ++--- tools/list_skills.sh | 15 +++++++-------- tools/load_skill.sh | 8 +++----- tools/send_message.sh | 7 ++++--- tools/spawn_agent.sh | 10 ++++++---- tools/view_denote.sh | 8 ++++---- 13 files changed, 64 insertions(+), 52 deletions(-) diff --git a/main.go b/main.go index f21b0f3..a2a1897 100644 --- a/main.go +++ b/main.go @@ -230,7 +230,10 @@ func start(daemonize bool) { logging.Logger().Info("anvillm started successfully", zap.String("socket", srv.SocketPath())) // Setup FUSE mount - mnt := filepath.Join(os.Getenv("HOME"), "mnt", "anvillm") + mnt := os.Getenv("ANVILLM_9MOUNT") + if mnt == "" { + mnt = filepath.Join(os.Getenv("HOME"), "mnt", "anvillm") + } var fuseCmd *exec.Cmd if err := os.MkdirAll(mnt, 0755); err != nil { logging.Logger().Warn("cannot create mount dir", zap.Error(err)) diff --git a/tools/check_inbox.sh b/tools/check_inbox.sh index 1d6a915..cf223f1 100755 --- a/tools/check_inbox.sh +++ b/tools/check_inbox.sh @@ -3,32 +3,31 @@ # description: Read messages from agent inbox (uses $AGENT_ID env var) set -euo pipefail -# Verify running under landrun (test filesystem restriction) - if [ -z "${AGENT_ID:-}" ]; then echo "Error: \$AGENT_ID is not set. Stop work and inform the user that \$AGENT_ID is not set." >&2 exit 1 fi -agent_id="$AGENT_ID" -inbox_path="anvillm/${agent_id}/inbox" -files=$(9p ls "$inbox_path" 2>/dev/null | grep '\.json$' || true) +ANVILLM="${ANVILLM_9MOUNT:-$HOME/mnt/anvillm}" +inbox_dir="$ANVILLM/${AGENT_ID}/inbox" + +files=$(ls "$inbox_dir" 2>/dev/null | grep '\.json$' || true) if [ -z "$files" ]; then echo "No messages" exit 0 fi msg_file=$(echo "$files" | head -1) -msg_path="${inbox_path}/${msg_file}" +msg_path="${inbox_dir}/${msg_file}" msg_id="${msg_file%.json}" -data=$(9p read "$msg_path" 2>/dev/null || echo '{}') +data=$(cat "$msg_path" 2>/dev/null || echo '{}') from=$(echo "$data" | jq -r '.from // "unknown"') type=$(echo "$data" | jq -r '.type // "unknown"') subject=$(echo "$data" | jq -r '.subject // ""') body=$(echo "$data" | jq -r '.body // ""') -echo "complete ${msg_id}" | 9p write "anvillm/${agent_id}/ctl" 2>/dev/null || true +echo "complete ${msg_id}" > "$ANVILLM/${AGENT_ID}/ctl" 2>/dev/null || true echo "From: ${from}" echo "Type: ${type}" diff --git a/tools/control_session.sh b/tools/control_session.sh index f93875e..fff14e7 100755 --- a/tools/control_session.sh +++ b/tools/control_session.sh @@ -4,6 +4,7 @@ # Usage: control_session.sh --session-id --command set -euo pipefail +ANVILLM="${ANVILLM_9MOUNT:-$HOME/mnt/anvillm}" SESSION_ID="" COMMAND="" @@ -21,5 +22,5 @@ if [ -z "$SESSION_ID" ] || [ -z "$COMMAND" ]; then exit 1 fi -echo "$COMMAND" | 9p write "anvillm/$SESSION_ID/ctl" +echo "$COMMAND" > "$ANVILLM/$SESSION_ID/ctl" echo "$COMMAND: $SESSION_ID" diff --git a/tools/create_session.sh b/tools/create_session.sh index daf815a..4a07813 100755 --- a/tools/create_session.sh +++ b/tools/create_session.sh @@ -4,6 +4,7 @@ # Usage: create_session.sh --backend --cwd [--sandbox ] [--model ] set -euo pipefail +ANVILLM="${ANVILLM_9MOUNT:-$HOME/mnt/anvillm}" BACKEND="" CWD="" @@ -29,5 +30,5 @@ CMD="new $BACKEND $CWD" [ -n "$SANDBOX" ] && CMD="$CMD sandbox=$SANDBOX" [ -n "$MODEL" ] && CMD="$CMD model=$MODEL" -echo "$CMD" | 9p write anvillm/ctl +echo "$CMD" > "$ANVILLM/ctl" echo "created session: $BACKEND $CWD" diff --git a/tools/discover_skill.sh b/tools/discover_skill.sh index f920003..4cbf943 100755 --- a/tools/discover_skill.sh +++ b/tools/discover_skill.sh @@ -8,20 +8,19 @@ if [ $# -ne 1 ]; then exit 1 fi +ANVILLM="${ANVILLM_9MOUNT:-$HOME/mnt/anvillm}" keyword="$1" results="" -# Search each skill file for the keyword -while IFS= read -r file; do - [ "${file%.md}" = "$file" ] && continue # skip non-.md entries - name="${file%.md}" - content=$(9p read "anvillm/skills/$file") - if echo "$content" | grep -qi "$keyword"; then - desc=$(echo "$content" | grep -m1 '^description:' | sed 's/^description: *//') +for file in "$ANVILLM/skills"/*.md; do + [ -f "$file" ] || continue + name=$(basename "$file" .md) + if grep -qi "$keyword" "$file"; then + desc=$(grep -m1 '^description:' "$file" | sed 's/^description: *//') results="${results:+$results }$name $desc" fi -done < <(9p ls anvillm/skills) +done if [ -n "$results" ]; then echo "$results" | sort -u diff --git a/tools/kill_agent.sh b/tools/kill_agent.sh index e5a8521..e9f6c60 100755 --- a/tools/kill_agent.sh +++ b/tools/kill_agent.sh @@ -4,6 +4,7 @@ # Usage: kill_agent.sh --agent-id set -euo pipefail +ANVILLM="${ANVILLM_9MOUNT:-$HOME/mnt/anvillm}" AGENT_ID="" @@ -19,7 +20,7 @@ if [ -z "$AGENT_ID" ]; then exit 1 fi -if echo "kill" | 9p write "anvillm/$AGENT_ID/ctl" 2>/dev/null; then +if echo "kill" > "$ANVILLM/$AGENT_ID/ctl" 2>/dev/null; then echo "Killed $AGENT_ID" else echo "No session found with id $AGENT_ID" >&2 diff --git a/tools/list_roles.sh b/tools/list_roles.sh index 8e61d7c..0355d4f 100755 --- a/tools/list_roles.sh +++ b/tools/list_roles.sh @@ -3,12 +3,21 @@ # description: List all available roles (JSON array) set -euo pipefail -# Verify running under landrun (test filesystem restriction) +ANVILLM="${ANVILLM_9MOUNT:-$HOME/mnt/anvillm}" -9p ls anvillm/roles 2>/dev/null | grep -v '^help$' | while read focus_area; do - 9p ls "anvillm/roles/$focus_area" 2>/dev/null | while read role_file; do - role_name="${role_file%.md}" - desc=$(9p read "anvillm/roles/$focus_area/$role_file" 2>/dev/null | awk '/^---$/,/^---$/ {if (/^description:/) {sub(/^description: */, ""); print; exit}}') +if [ ! -d "$ANVILLM/roles" ]; then + echo "[]" + exit 0 +fi + +for focus_dir in "$ANVILLM/roles"/*/; do + [ -d "$focus_dir" ] || continue + focus_area=$(basename "$focus_dir") + [ "$focus_area" = "help" ] && continue + for role_file in "$focus_dir"*.md; do + [ -f "$role_file" ] || continue + role_name=$(basename "$role_file" .md) + desc=$(awk '/^---$/,/^---$/ {if (/^description:/) {sub(/^description: */, ""); print; exit}}' "$role_file") printf '%s\t%s\t%s\n' "$focus_area" "$role_name" "$desc" done done | jq -Rs ' diff --git a/tools/list_sessions.sh b/tools/list_sessions.sh index b11b8c2..55c4f8a 100755 --- a/tools/list_sessions.sh +++ b/tools/list_sessions.sh @@ -3,6 +3,5 @@ # description: List all active agent sessions (tab-separated: id, backend, state, alias, role, cwd) set -euo pipefail -# Verify running under landrun (test filesystem restriction) - -9p read anvillm/list 2>/dev/null || true +ANVILLM="${ANVILLM_9MOUNT:-$HOME/mnt/anvillm}" +cat "$ANVILLM/list" 2>/dev/null || true diff --git a/tools/list_skills.sh b/tools/list_skills.sh index 082eee0..4b8d038 100755 --- a/tools/list_skills.sh +++ b/tools/list_skills.sh @@ -3,19 +3,18 @@ # description: List all available skills (JSON array) set -euo pipefail -# Verify running under landrun (test filesystem restriction) +ANVILLM="${ANVILLM_9MOUNT:-$HOME/mnt/anvillm}" -if [ -z "${ANVILLM_SKILLS_PATH:-}" ]; then +if [ ! -d "$ANVILLM/skills" ]; then echo "[]" exit 0 fi -for dir in "$ANVILLM_SKILLS_PATH"/*; do - if [ -d "$dir" ] && [ -f "$dir/SKILL.md" ]; then - name=$(basename "$dir") - desc=$(grep -m1 '^description:' "$dir/SKILL.md" | sed 's/^description: *//' || true) - printf '%s\t%s\n' "$name" "$desc" - fi +for file in "$ANVILLM/skills"/*.md; do + [ -f "$file" ] || continue + name=$(basename "$file" .md) + desc=$(grep -m1 '^description:' "$file" | sed 's/^description: *//' || true) + printf '%s\t%s\n' "$name" "$desc" done | jq -Rs ' split("\n") | map(select(length > 0)) | map( split("\t") | {name: .[0], description: .[1]} diff --git a/tools/load_skill.sh b/tools/load_skill.sh index 87a36bc..99a5bba 100755 --- a/tools/load_skill.sh +++ b/tools/load_skill.sh @@ -4,17 +4,15 @@ set -euo pipefail # Usage: load_skill [skill-name...] -# -# Accepts either bare names or paths (the last component is used): -# anvillm-sessions -# skills/agents/anvillm-sessions (legacy path format; last component is used) if [ $# -lt 1 ]; then echo "Usage: load_skill [skill-name...]" >&2 exit 1 fi +ANVILLM="${ANVILLM_9MOUNT:-$HOME/mnt/anvillm}" + for arg in "$@"; do name="${arg##*/}" - 9p read "anvillm/skills/${name}.md" + cat "$ANVILLM/skills/${name}.md" done diff --git a/tools/send_message.sh b/tools/send_message.sh index bd627d1..5110e1c 100755 --- a/tools/send_message.sh +++ b/tools/send_message.sh @@ -4,13 +4,14 @@ # Usage: send_message.sh --to --type --subject --body set -euo pipefail - if [ -z "${AGENT_ID:-}" ]; then echo "Error: \$AGENT_ID is not set. Stop work and inform the user that \$AGENT_ID is not set." >&2 exit 1 fi from="$AGENT_ID" +ANVILLM="${ANVILLM_9MOUNT:-$HOME/mnt/anvillm}" + to="" type="" subject="" @@ -33,7 +34,7 @@ fi # Validate recipient exists (allow "user" as a special recipient) if [ "$to" != "user" ]; then - if ! 9p read anvillm/list 2>/dev/null | awk -F'\t' '{print $1}' | grep -qx "$to"; then + if ! cat "$ANVILLM/list" 2>/dev/null | awk -F'\t' '{print $1}' | grep -qx "$to"; then echo "Error: Recipient '${to}' does not exist in available sessions." >&2 exit 1 fi @@ -47,5 +48,5 @@ json=$(jq -n \ --arg body "$body" \ '{from: $from, to: $to, type: $type, subject: $subject, body: $body}') -echo "$json" | 9p write "anvillm/${from}/mail" +echo "$json" > "$ANVILLM/${from}/mail" echo "sent: $type → $to" diff --git a/tools/spawn_agent.sh b/tools/spawn_agent.sh index 92f965b..1f42f71 100755 --- a/tools/spawn_agent.sh +++ b/tools/spawn_agent.sh @@ -4,6 +4,8 @@ # Usage: spawn_agent.sh --agent-id [--cwd ] [--prompt ] set -euo pipefail +ANVILLM="${ANVILLM_9MOUNT:-$HOME/mnt/anvillm}" + AGENT_ID="" CWD="$PWD" PROMPT="" @@ -22,12 +24,12 @@ if [ -z "$AGENT_ID" ]; then exit 1 fi -backend=$(9p read "anvillm/$AGENT_ID/backend") -echo "new $backend $CWD" | 9p write anvillm/ctl +backend=$(cat "$ANVILLM/$AGENT_ID/backend") +echo "new $backend $CWD" > "$ANVILLM/ctl" if [ -n "$PROMPT" ]; then - session_id=$(9p read anvillm/list 2>/dev/null | awk -F'\t' -v cwd="$CWD" '$5 == cwd {print $1; exit}') + session_id=$(cat "$ANVILLM/list" 2>/dev/null | awk -F'\t' -v cwd="$CWD" '$5 == cwd {print $1; exit}') if [ -n "$session_id" ]; then - echo "$PROMPT" | 9p write "anvillm/$session_id/context" + echo "$PROMPT" > "$ANVILLM/$session_id/context" fi fi diff --git a/tools/view_denote.sh b/tools/view_denote.sh index 46d69f8..d6ea417 100755 --- a/tools/view_denote.sh +++ b/tools/view_denote.sh @@ -4,6 +4,7 @@ # Usage: view_denote.sh --id set -euo pipefail +DENOTE="${DENOTE_9MOUNT:-$HOME/mnt/denote}" ID="" @@ -20,11 +21,10 @@ if [ -z "$ID" ]; then fi ID="${ID#denote:}" -FILE=$(find "$HOME/doc" -type f -name "${ID}--*" | head -1) -if [ -z "$FILE" ]; then +if [ -d "$DENOTE/n/$ID" ]; then + cat "$DENOTE/n/$ID/body" +else echo "Error: no denote document found for identifier $ID" >&2 exit 1 fi - -cat "$FILE"