This commit is contained in:
@@ -14,6 +14,7 @@ SANDBOX_CONF="$HOME/.config/coredesktop/sandbox/base.json"
|
||||
CLAUDE_SETTINGS="$HOME/.claude/settings.json"
|
||||
OPENCODE_CONF="$HOME/.config/opencode/opencode.json"
|
||||
source "$COREDESKTOP/configure.d/lib/mdns.sh"
|
||||
source "$COREDESKTOP/configure.d/lib/json.sh"
|
||||
|
||||
# Ports LLM servers listen on by default, and who uses each. All of them answer
|
||||
# OpenAI's API at /v1, which is how every agent here talks to them.
|
||||
@@ -62,23 +63,6 @@ find_servers() {
|
||||
rm -rf "$dir"
|
||||
}
|
||||
|
||||
# Edit a JSON file in place with jq, creating it from $2 if it's missing.
|
||||
# Leaves the file alone if it isn't valid JSON or jq fails.
|
||||
edit_json() {
|
||||
local file="$1" empty="$2" tmp
|
||||
shift 2
|
||||
mkdir -p "$(dirname "$file")" || return 1
|
||||
[ -f "$file" ] || echo "$empty" > "$file"
|
||||
tmp="$(mktemp "$file.XXXXXX")" || return 1
|
||||
if jq "$@" "$file" > "$tmp"; then
|
||||
mv -f "$tmp" "$file"
|
||||
else
|
||||
echo "Couldn't change $file; is it valid JSON?"
|
||||
rm -f "$tmp"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Let every sandboxed agent (opencode, Hermes, Cline) reach host:port, and
|
||||
# only that port
|
||||
sandbox_allow() {
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
#!/bin/bash
|
||||
|
||||
# configure reads TITLE and DESCRIPTION
|
||||
# shellcheck disable=SC2034
|
||||
TITLE="Agent sandbox"
|
||||
# shellcheck disable=SC2034
|
||||
DESCRIPTION="Choose what agents may read, e.g. WinBoat's settings"
|
||||
|
||||
# The sandbox config every sandboxed agent reads (see sandbox/agent)
|
||||
SANDBOX_CONF="$HOME/.config/coredesktop/sandbox/base.json"
|
||||
source "$COREDESKTOP/configure.d/lib/json.sh"
|
||||
|
||||
# Folders the sandbox hides from agents (sandbox/config/base.json) that you
|
||||
# may let them read: "path|what it is". Your SSH keys, password stores,
|
||||
# browsers and the like aren't here; they're always hidden. A path in
|
||||
# allowRead can be read even inside one in denyRead, so letting agents read
|
||||
# one is adding it to allowRead in your own config.
|
||||
# The paths are written as in sandbox/config/base.json, with ~ for srt to expand
|
||||
# shellcheck disable=SC2088
|
||||
OPTIONAL_HIDDEN=(
|
||||
"~/.winboat|WinBoat's settings, which include your Windows password"
|
||||
)
|
||||
|
||||
# Offered only when one of the folders is on this machine
|
||||
is_installed() {
|
||||
local entry path
|
||||
for entry in "${OPTIONAL_HIDDEN[@]}"; do
|
||||
path="${entry%%|*}"
|
||||
[ -e "${path/#\~/$HOME}" ] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Hiding them is the default, so there's nothing you need to do
|
||||
is_configured() {
|
||||
true
|
||||
}
|
||||
|
||||
# True if agents may read $1 (it's in your config's allowRead)
|
||||
readable() {
|
||||
jq -e --arg path "$1" '.filesystem.allowRead // [] | index($path)' "$SANDBOX_CONF" &> /dev/null
|
||||
}
|
||||
|
||||
let_read() {
|
||||
edit_json "$SANDBOX_CONF" '{}' --arg path "$1" \
|
||||
'.filesystem.allowRead = ((.filesystem.allowRead // []) - [$path] + [$path])'
|
||||
}
|
||||
|
||||
hide() {
|
||||
[ -f "$SANDBOX_CONF" ] || return 0
|
||||
edit_json "$SANDBOX_CONF" '{}' --arg path "$1" \
|
||||
'if .filesystem.allowRead then .filesystem.allowRead -= [$path] else . end'
|
||||
}
|
||||
|
||||
run_configure() {
|
||||
local choice i path what state
|
||||
echo "Agents in the sandbox can't read these unless you let them. Changes apply the next"
|
||||
echo "time you start an agent (restart Hermes' gateway with: systemctl --user restart hermes-gateway)."
|
||||
echo "Claude Code's own sandbox doesn't use this list."
|
||||
|
||||
while true; do
|
||||
echo
|
||||
for i in "${!OPTIONAL_HIDDEN[@]}"; do
|
||||
IFS='|' read -r path what <<< "${OPTIONAL_HIDDEN[$i]}"
|
||||
if readable "$path"; then state="\e[33magents can read it\e[0m"; else state="\e[32mhidden\e[0m"; fi
|
||||
printf " %d) %-12s $state %s\n" $((i + 1)) "$path" "$what"
|
||||
done
|
||||
echo " q) Done"
|
||||
echo
|
||||
read -rp "Choose one to switch: " choice || return 0
|
||||
if ! [[ "$choice" =~ ^[0-9]+$ ]] || (( choice < 1 || choice > ${#OPTIONAL_HIDDEN[@]} )); then
|
||||
return 0
|
||||
fi
|
||||
IFS='|' read -r path what <<< "${OPTIONAL_HIDDEN[$((choice - 1))]}"
|
||||
if readable "$path"; then
|
||||
hide "$path" || return 1
|
||||
echo "$path is hidden from agents again."
|
||||
elif confirm "Let agents read $path ($what)?"; then
|
||||
let_read "$path" || return 1
|
||||
echo "Agents can read $path."
|
||||
fi
|
||||
done
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Purpose : Edit JSON settings files for configure.d items. Source this file.
|
||||
|
||||
# Edit a JSON file in place with jq, creating it from $2 if it's missing.
|
||||
# Leaves the file alone if it isn't valid JSON or jq fails.
|
||||
edit_json() {
|
||||
local file="$1" empty="$2" tmp
|
||||
shift 2
|
||||
mkdir -p "$(dirname "$file")" || return 1
|
||||
[ -f "$file" ] || echo "$empty" > "$file"
|
||||
tmp="$(mktemp "$file.XXXXXX")" || return 1
|
||||
if jq "$@" "$file" > "$tmp"; then
|
||||
mv -f "$tmp" "$file"
|
||||
else
|
||||
echo "Couldn't change $file; is it valid JSON?"
|
||||
rm -f "$tmp"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user