feat(kugetsu): add env pass-through for agent delegation

Add environment variable management for delegating to agents.

Features:
- Add ENV_DIR constant (\~/.kugetsu/env)
- Add mask_sensitive_vars() to hide sensitive values in logs
- Add load_agent_env() to load agent-specific env files
- Add cmd_env command for managing env files:
  - list: List all env files
  - show [agent]: Show env file contents (masked)
  - set <key> <value> [agent]: Set key=value
  - get <key> [agent]: Get value for key
  - rm <key> [agent]: Remove key
- Update cmd_delegate to load pm-agent.env or default.env before running

Example usage:
  kugetsu env set GITEA_TOKEN xxx pm-agent
  kugetsu delegate "post comment on #69"

Fixes #76
This commit is contained in:
shokollm
2026-04-02 00:30:28 +00:00
parent 33820b8f43
commit 756ac41aba

View File

@@ -8,6 +8,7 @@ REPOS_CONFIG="$KUGETSU_DIR/repos.json"
INDEX_FILE="$KUGETSU_DIR/index.json"
NOTIFICATIONS_FILE="$KUGETSU_DIR/notifications.json"
LOGS_DIR="$KUGETSU_DIR/logs"
ENV_DIR="${ENV_DIR:-$KUGETSU_DIR/env}"
MAX_CONCURRENT_AGENTS="${MAX_CONCURRENT_AGENTS:-3}"
# Load user config overrides (~/.kugetsu/config)
@@ -15,6 +16,31 @@ if [ -f "$KUGETSU_DIR/config" ]; then
source "$KUGETSU_DIR/config"
fi
mask_sensitive_vars() {
local line="$1"
for var in GITEA_TOKEN GITHUB_TOKEN GITLAB_TOKEN API_KEY PASSWORD TOKEN SECRET; do
if [[ "$line" =~ $var ]]; then
line=$(echo "$line" | sed -E "s/=.*/=***MASKED***/")
fi
done
echo "$line"
}
load_agent_env() {
local agent_type="${1:-base}"
local env_file="$ENV_DIR/${agent_type}.env"
if [ -f "$env_file" ]; then
set -a
source "$env_file"
set +a
elif [ -f "$ENV_DIR/default.env" ]; then
set -a
source "$ENV_DIR/default.env"
set +a
fi
}
count_active_dev_sessions() {
local count=0
if [ -d "$SESSIONS_DIR" ]; then
@@ -536,7 +562,16 @@ cmd_delegate() {
mkdir -p "$LOGS_DIR"
local log_file="$LOGS_DIR/delegate-$(date +%s).log"
nohup sh -c "opencode run '$message' --continue --session '$pm_session' >> '$log_file' 2>&1" > /dev/null 2>&1 &
mkdir -p "$ENV_DIR"
local env_sh=""
if [ -f "$ENV_DIR/pm-agent.env" ]; then
env_sh="source '$ENV_DIR/pm-agent.env'; "
elif [ -f "$ENV_DIR/default.env" ]; then
env_sh="source '$ENV_DIR/default.env'; "
fi
nohup sh -c "${env_sh}opencode run '$message' --continue --session '$pm_session' >> '$log_file' 2>&1" > /dev/null 2>&1 &
disown
echo "Delegated to PM agent (logged to $(basename "$log_file"))"
}
@@ -557,6 +592,106 @@ cmd_logs() {
done
}
cmd_env() {
local action="${1:-}"
local agent_type="${2:-}"
mkdir -p "$ENV_DIR"
case "$action" in
""|"list")
echo "Environment files in $ENV_DIR:"
if [ -d "$ENV_DIR" ]; then
for f in "$ENV_DIR"/*.env; do
if [ -f "$f" ]; then
echo " $(basename "$f")"
fi
done
fi
if [ ! -d "$ENV_DIR" ] || [ -z "$(ls -A "$ENV_DIR"/*.env 2>/dev/null)" ]; then
echo " (no env files found)"
fi
;;
"show")
local file="$ENV_DIR/${agent_type:-default}.env"
if [ -f "$file" ]; then
echo "=== $file ==="
while IFS= read -r line; do
echo "$(mask_sensitive_vars "$line")"
done < "$file"
else
echo "No env file for: ${agent_type:-default}"
fi
;;
"set")
local key="${2:-}"
local value="${3:-}"
local target="${4:-default}"
if [ -z "$key" ] || [ -z "$value" ]; then
echo "Usage: kugetsu env set <key> <value> [agent]" >&2
echo " agent: default, pm-agent, or issue ref" >&2
exit 1
fi
local file="$ENV_DIR/${target}.env"
if [ -f "$file" ]; then
if grep -q "^${key}=" "$file"; then
sed -i "s|^${key}=.*|${key}=\"${value}\"|" "$file"
else
echo "${key}=\"${value}\"" >> "$file"
fi
else
echo "${key}=\"${value}\"" > "$file"
fi
echo "Set ${key}=${value} in ${target}.env"
;;
"get")
local key="${2:-}"
local target="${3:-default}"
local file="$ENV_DIR/${target}.env"
if [ -z "$key" ]; then
echo "Usage: kugetsu env get <key> [agent]" >&2
exit 1
fi
if [ -f "$file" ]; then
local val=$(grep "^${key}=" "$file" | cut -d'=' -f2 | tr -d '"')
if [ -n "$val" ]; then
echo "$val"
else
echo "Key '$key' not found in ${target}.env" >&2
exit 1
fi
else
echo "No env file for: ${target}" >&2
exit 1
fi
;;
"rm"|"remove"|"delete")
local key="${2:-}"
local target="${3:-default}"
if [ -z "$key" ]; then
echo "Usage: kugetsu env rm <key> [agent]" >&2
exit 1
fi
local file="$ENV_DIR/${target}.env"
if [ -f "$file" ]; then
sed -i "/^${key}=/d" "$file"
echo "Removed $key from ${target}.env"
fi
;;
*)
echo "Usage: kugetsu env <list|show|set|get|rm> [args]" >&2
echo "" >&2
echo "Commands:" >&2
echo " list List all env files" >&2
echo " show [agent] Show env file contents (masked)" >&2
echo " set <k> <v> [a] Set key=value in agent env (default/pm-agent)" >&2
echo " get <key> [a] Get value for key" >&2
echo " rm <key> [a] Remove key from agent env" >&2
exit 1
;;
esac
}
cmd_doctor() {
local fix=false
@@ -1311,6 +1446,9 @@ main() {
server)
cmd_server "$@"
;;
env)
cmd_env "$@"
;;
doctor)
cmd_doctor "$@"
;;