#!/usr/bin/env bash # Install/refresh the host-side library capture agent. # # The agent is the only component with the Docker socket and the source # credentials. It runs as this user (no root), listens on one 0600 unix socket and # executes the fixed capture command with the declaration below. Containers get # the socket path only. set -euo pipefail ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) UNIT_DIR="$HOME/.config/systemd/user" SOCKET_DIR="$HOME/.local/share/knowledge-governance/agent" # 实例级维护接线(LIBRARY_TARGET_*)与源声明一起由这一个 0600 文件提供; # 它属于"这台主机上的哪个实例",不属于任何一次请求。 ENV_FILE="${AGENT_ENV_FILE:-$HOME/.local/share/knowledge-governance/agent.env}" SOURCE_APP="${AGENT_SOURCE_APP:-WKNFull-app}" SOURCE_PG="${AGENT_SOURCE_PG:-WKNFull-postgres}" SOURCE_ES="${AGENT_SOURCE_ES:-WKNFull-elasticsearch}" PROJECT="${AGENT_PROJECT:-weknora071full}" WRITERS="${AGENT_WRITERS:-app}" NON_WRITERS="${AGENT_NON_WRITERS:-frontend=UI only; no knowledge writes,mcp=read-only MCP server,dobotai-target=alpine placeholder; no knowledge writes,docreader=parse RPC service; app persists parse output,elasticsearch=search store; not an initiator,postgres=database store; not an initiator,redis=queue/cache store; not an initiator,neo4j=graph store; not an initiator,langfuse-web=LLM observability UI,langfuse-worker=LLM observability worker; own storage,langfuse-clickhouse=observability store,langfuse-minio=observability object store,langfuse-db-init=one-shot init; exited,searxng=read-only search proxy,searxng-init=one-shot init; exited}" mkdir -p "$UNIT_DIR" "$SOCKET_DIR" chmod 700 "$SOCKET_DIR" if [ ! -f "$ENV_FILE" ]; then # 宁可不装,也不要装出一个"没有闸门"的 agent:封存会在开窗口前被拒。 echo "AGENT_ENV_MISSING: $ENV_FILE" >&2 echo " write LIBRARY_TARGET_{INSTANCE,INGRESS_URL,INGRESS_SERVICE,INGRESS_DRAIN_FILE,REDIS_ADDR,REDIS_PASSWORD,REDIS_DB} there (0600)" >&2 exit 1 fi chmod 600 "$ENV_FILE" echo "=== build libraryctl + libraryagent ===" (cd "$ROOT" && go build -o libraryctl ./cmd/libraryctl && go build -o libraryagent ./cmd/libraryagent) echo "=== systemd user unit ===" cat > "$UNIT_DIR/knowledge-governance-library-agent.service" </dev/null systemctl --user restart knowledge-governance-library-agent.service # Keep the agent running when no login session is open (it owns no privilege # beyond this account, but a stopped agent means the page cannot capture). loginctl enable-linger "$(id -un)" >/dev/null 2>&1 || echo " WARN: enable-linger failed; agent stops with the last session" echo "=== read back ===" for _ in $(seq 1 30); do if [ -S "$SOCKET_DIR/agent.sock" ]; then break; fi sleep 0.2 done [ -S "$SOCKET_DIR/agent.sock" ] || { echo "AGENT_SOCKET_MISSING"; exit 1; } stat -c '%A %n' "$SOCKET_DIR" "$SOCKET_DIR/agent.sock" systemctl --user is-active knowledge-governance-library-agent.service