feat(agent): hierarchical executor with path resolve, runtime probe, quiet UI
Make Zed Agent closer to Cursor: deterministic DevOps path index, live Traefik port probe before blind edits, stop-after-edit, and quieter Russian progress.
This commit is contained in:
+8
-2
@@ -1,3 +1,9 @@
|
||||
FROM thejohnd0e/vless-to-http:latest
|
||||
FROM alpine:3.20
|
||||
|
||||
# vless.conf mounted via Swarm secret at /app/vless.conf
|
||||
WORKDIR /app
|
||||
RUN apk add --no-cache curl unzip ca-certificates wget procps && curl -L -o /tmp/xray.zip https://github.com/XTLS/Xray-core/releases/latest/download/Xray-linux-64.zip && unzip /tmp/xray.zip -d /tmp/xray && install -m755 /tmp/xray/xray /usr/local/bin/Xray && mkdir -p /usr/local/share/xray && mv /tmp/xray/geoip.dat /tmp/xray/geosite.dat /usr/local/share/xray/ && rm -rf /tmp/xray /tmp/xray.zip
|
||||
|
||||
COPY entrypoint.sh /app/entrypoint.sh
|
||||
RUN chmod +x /app/entrypoint.sh
|
||||
EXPOSE 8080
|
||||
CMD ["/app/entrypoint.sh"]
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Stub when VPN_ENABLED=false (vless replicas=0). Replace with Dockerfile when enabling VPN.
|
||||
FROM alpine:3.20
|
||||
RUN apk add --no-cache wget
|
||||
EXPOSE 8080
|
||||
CMD ["sleep", "infinity"]
|
||||
@@ -0,0 +1,184 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
CFG=/app/config.json
|
||||
|
||||
# ---- read vless.conf (compose mount or swarm secret rotate) ----
|
||||
CONF=""
|
||||
for p in /app/vless.conf /run/secrets/vless_conf; do
|
||||
if [ -s "$p" ]; then CONF="$p"; break; fi
|
||||
done
|
||||
if [ -z "$CONF" ]; then
|
||||
echo "vless.conf not found or empty" >&2
|
||||
exit 23
|
||||
fi
|
||||
VLESS_URL="$(tr -d '\r\n' < "$CONF")"
|
||||
VLESS_URL="${VLESS_URL%%#*}"
|
||||
|
||||
# ---- extract fields from URL ----
|
||||
USER_ID="$(printf '%s' "$VLESS_URL" | sed -n 's#^vless://\([^@/]*\).*#\1#p')"
|
||||
SERVER="$( printf '%s' "$VLESS_URL" | sed -n 's#.*@\([^:/?]*\).*#\1#p')"
|
||||
PORT_RAW="$(printf '%s' "$VLESS_URL" | sed -n 's#.*:\([0-9][0-9]*\).*#\1#p')"
|
||||
PORT="$(printf '%s' "$PORT_RAW" | tr -cd '0-9')"
|
||||
|
||||
PUBKEY="$( printf '%s' "$VLESS_URL" | sed -n 's#.*[?&]pbk=\([^&]*\).*#\1#p')"
|
||||
SNI="$( printf '%s' "$VLESS_URL" | sed -n 's#.*[?&]sni=\([^&]*\).*#\1#p')"
|
||||
FP="$( printf '%s' "$VLESS_URL" | sed -n 's#.*[?&]fp=\([^&]*\).*#\1#p')"
|
||||
SID="$( printf '%s' "$VLESS_URL" | sed -n 's#.*[?&]sid=\([^&]*\).*#\1#p')"
|
||||
SPX="$( printf '%s' "$VLESS_URL" | sed -n 's#.*[?&]spx=\([^&]*\).*#\1#p' | sed 's/%2F/\//g')"
|
||||
FLOW="$( printf '%s' "$VLESS_URL" | sed -n 's#.*[?&]flow=\([^&]*\).*#\1#p')"
|
||||
TYPE="$( printf '%s' "$VLESS_URL" | sed -n 's#.*[?&]type=\([^&]*\).*#\1#p')"
|
||||
PATH_RAW="$(printf '%s' "$VLESS_URL" | sed -n 's#.*[?&]path=\([^&]*\).*#\1#p')"
|
||||
HOST_RAW="$(printf '%s' "$VLESS_URL" | sed -n 's#.*[?&]host=\([^&]*\).*#\1#p')"
|
||||
MODE="$( printf '%s' "$VLESS_URL" | sed -n 's#.*[?&]mode=\([^&]*\).*#\1#p')"
|
||||
|
||||
[ -z "${FP:-}" ] && FP="firefox"
|
||||
[ -z "${SPX:-}" ] && SPX="/"
|
||||
[ -z "${TYPE:-}" ] && TYPE="tcp"
|
||||
XHTTP_PATH="$(printf '%s' "${PATH_RAW:-}" | sed 's/%2[Ff]/\//g')"
|
||||
HOST="$(printf '%s' "${HOST_RAW:-}" | sed 's/%2[Cc]/,/g')"
|
||||
|
||||
# ---- minimal validation ----
|
||||
[ -n "${USER_ID:-}" ] || { echo "ERR: empty USER_ID"; exit 23; }
|
||||
[ -n "${SERVER:-}" ] || { echo "ERR: empty SERVER"; exit 23; }
|
||||
[ -n "${PORT:-}" ] || { echo "ERR: empty PORT"; exit 23; }
|
||||
[ -n "${PUBKEY:-}" ] || { echo "ERR: empty PUBKEY"; exit 23; }
|
||||
[ -n "${SNI:-}" ] || { echo "ERR: empty SNI"; exit 23; }
|
||||
[ -n "${SID:-}" ] || { echo "ERR: empty SID"; exit 23; }
|
||||
|
||||
case "$TYPE" in
|
||||
tcp|xhttp) ;;
|
||||
*)
|
||||
echo "ERR: unsupported transport type '$TYPE' (supported: tcp, xhttp)" >&2
|
||||
exit 23
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$TYPE" = "xhttp" ] && [ -z "${XHTTP_PATH:-}" ]; then
|
||||
echo "ERR: empty PATH for xhttp transport" >&2
|
||||
exit 23
|
||||
fi
|
||||
|
||||
# ---- build user block safely (with/without flow) ----
|
||||
if [ -n "${FLOW:-}" ]; then
|
||||
USER_BLOCK=$(cat <<JSON
|
||||
{
|
||||
"id": "${USER_ID}",
|
||||
"encryption": "none",
|
||||
"level": 0,
|
||||
"flow": "${FLOW}"
|
||||
}
|
||||
JSON
|
||||
)
|
||||
else
|
||||
USER_BLOCK=$(cat <<JSON
|
||||
{
|
||||
"id": "${USER_ID}",
|
||||
"encryption": "none",
|
||||
"level": 0
|
||||
}
|
||||
JSON
|
||||
)
|
||||
fi
|
||||
|
||||
if [ "$TYPE" = "xhttp" ]; then
|
||||
XHTTP_HOST_LINE=""
|
||||
XHTTP_MODE_LINE=""
|
||||
if [ -n "${HOST:-}" ]; then
|
||||
XHTTP_HOST_LINE=$(cat <<JSON
|
||||
,
|
||||
"host": "${HOST}"
|
||||
JSON
|
||||
)
|
||||
fi
|
||||
if [ -n "${MODE:-}" ]; then
|
||||
XHTTP_MODE_LINE=$(cat <<JSON
|
||||
,
|
||||
"mode": "${MODE}"
|
||||
JSON
|
||||
)
|
||||
fi
|
||||
STREAM_SETTINGS_BLOCK=$(cat <<JSON
|
||||
"streamSettings": {
|
||||
"network": "xhttp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": false,
|
||||
"publicKey": "${PUBKEY}",
|
||||
"shortId": "${SID}",
|
||||
"spiderX": "${SPX}",
|
||||
"fingerprint": "${FP}",
|
||||
"serverName": "${SNI}"
|
||||
},
|
||||
"xhttpSettings": {
|
||||
"path": "${XHTTP_PATH}"${XHTTP_HOST_LINE}${XHTTP_MODE_LINE}
|
||||
}
|
||||
},
|
||||
JSON
|
||||
)
|
||||
else
|
||||
STREAM_SETTINGS_BLOCK=$(cat <<JSON
|
||||
"streamSettings": {
|
||||
"network": "tcp",
|
||||
"security": "reality",
|
||||
"realitySettings": {
|
||||
"show": false,
|
||||
"publicKey": "${PUBKEY}",
|
||||
"shortId": "${SID}",
|
||||
"spiderX": "${SPX}",
|
||||
"fingerprint": "${FP}",
|
||||
"serverName": "${SNI}"
|
||||
}
|
||||
},
|
||||
JSON
|
||||
)
|
||||
fi
|
||||
|
||||
# ---- generate config.json ----
|
||||
cat > "$CFG" <<EOF
|
||||
{
|
||||
"log": { "loglevel": "debug" },
|
||||
"inbounds": [
|
||||
{
|
||||
"port": 8080,
|
||||
"protocol": "http",
|
||||
"listen": "0.0.0.0",
|
||||
"settings": { "allowTransparent": true, "timeout": 300 },
|
||||
"sniffing": { "enabled": true, "destOverride": ["http","tls"] }
|
||||
},
|
||||
{
|
||||
"port": 1080,
|
||||
"protocol": "socks",
|
||||
"listen": "0.0.0.0",
|
||||
"settings": { "auth": "noauth", "udp": true }
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"protocol": "vless",
|
||||
"settings": {
|
||||
"vnext": [
|
||||
{
|
||||
"address": "${SERVER}",
|
||||
"port": ${PORT},
|
||||
"users": [
|
||||
${USER_BLOCK}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
${STREAM_SETTINGS_BLOCK}
|
||||
"tag": "proxy"
|
||||
},
|
||||
{ "protocol": "freedom", "settings": {}, "tag": "direct" }
|
||||
]
|
||||
}
|
||||
EOF
|
||||
|
||||
# ---- print generated config for debugging ----
|
||||
echo "===== GENERATED CONFIG ====="
|
||||
cat "$CFG"
|
||||
echo "============================"
|
||||
|
||||
# ---- start Xray ----
|
||||
exec /usr/local/bin/Xray run -config "$CFG"
|
||||
Reference in New Issue
Block a user