mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 20:47:03 +01:00
Indexes the arch-wiki-docs dump that is already on disk and exposes it
to the knowledge-rag MCP server, so Arch questions can be asked by
symptom ("why doesn't my systemd user unit see DISPLAY under i3")
rather than by page title, with no network round-trip at query time.
The one Arch-specific MCP server in the wild fetches pages over the
network and bundles pacman operations that duplicate the local yay-mcp.
This does neither: it only searches, against a local corpus.
install.sh installs its own dependencies, wires the MCP config and
registers a pacman hook so the index follows package updates. The
generated index is machine-specific and regenerable, so it is
gitignored rather than committed.
_reindex_entry runs under the knowledge-rag interpreter, where
mcp_server is importable and this repo's packages are not. Resolving
that import with importlib.import_module states the deferral outright
instead of a function-level import statement that reads as an oversight,
and the backend failure path now re-raises as SystemExit, so the
exit-code translation is explicit rather than a swallowed exception.
Both replace lint suppressions; the package carries none.
pylint runs in its own venv, so beautifulsoup4 and markdownify are
declared there too — being in meta/requirements.txt does not make them
resolvable to the hook.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YQLwdquDCNmWtvgi3Lk72J
131 lines
3.4 KiB
Bash
Executable File
131 lines
3.4 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# ============================================================================
|
|
# Install the offline Arch Wiki RAG corpus and its refresh hook.
|
|
#
|
|
# Installs dependencies, builds the corpus, and registers a pacman hook that
|
|
# refreshes it whenever `arch-wiki-docs` is upgraded.
|
|
# ============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_NAME="$(basename "$0")"
|
|
PKG_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
REPO_ROOT="$(cd "${PKG_DIR}/../.." && pwd)"
|
|
readonly SCRIPT_NAME PKG_DIR REPO_ROOT
|
|
readonly STORE_DIR="${HOME}/.local/share/knowledge-rag-archwiki"
|
|
readonly REFRESH_BIN="/usr/local/bin/archwiki-rag-refresh"
|
|
readonly HOOK_PATH="/etc/pacman.d/hooks/95-archwiki-rag.hook"
|
|
readonly MCP_CONFIG="${HOME}/.claude/mcp-optional/archwiki.json"
|
|
|
|
usage() {
|
|
echo "Usage: $SCRIPT_NAME [--no-hook]"
|
|
echo "Options:"
|
|
echo " --no-hook Install dependencies and build the corpus, but skip the"
|
|
echo " pacman hook (which needs sudo)."
|
|
echo " -h, --help Show this help"
|
|
exit 0
|
|
}
|
|
|
|
INSTALL_HOOK=1
|
|
|
|
install_dependencies() {
|
|
echo "==> Installing dependencies"
|
|
# arch-wiki-docs is the corpus itself; the two Python packages do the
|
|
# HTML -> Markdown conversion.
|
|
sudo pacman -S --needed --noconfirm \
|
|
arch-wiki-docs \
|
|
python-beautifulsoup4 \
|
|
python-markdownify
|
|
}
|
|
|
|
write_mcp_config() {
|
|
echo "==> Writing MCP config: $MCP_CONFIG"
|
|
mkdir -p "$(dirname "$MCP_CONFIG")"
|
|
cat >"$MCP_CONFIG" <<EOF
|
|
{
|
|
"mcpServers": {
|
|
"archwiki": {
|
|
"type": "stdio",
|
|
"command": "${HOME}/.local/bin/knowledge-rag",
|
|
"args": [],
|
|
"env": {
|
|
"KNOWLEDGE_RAG_DIR": "${STORE_DIR}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
EOF
|
|
}
|
|
|
|
build_corpus() {
|
|
echo "==> Building corpus (this takes ~1 min for conversion)"
|
|
PYTHONPATH="$REPO_ROOT" python3 -m python_pkg.archwiki_rag sync --reindex
|
|
}
|
|
|
|
install_hook() {
|
|
echo "==> Installing pacman hook"
|
|
|
|
# The hook runs as root; this wrapper drops back to the invoking user and
|
|
# detaches the CPU-bound reindex so the pacman transaction is not blocked
|
|
# while the corpus re-embeds.
|
|
sudo tee "$REFRESH_BIN" >/dev/null <<EOF
|
|
#!/bin/bash
|
|
# Refresh the offline Arch Wiki RAG corpus. Installed by $SCRIPT_NAME.
|
|
set -euo pipefail
|
|
exec systemd-run --machine="${USER}@" --user --quiet --collect \\
|
|
--unit=archwiki-rag-refresh \\
|
|
--setenv=PYTHONPATH="$REPO_ROOT" \\
|
|
/usr/bin/python3 -m python_pkg.archwiki_rag sync --reindex
|
|
EOF
|
|
sudo chmod 755 "$REFRESH_BIN"
|
|
|
|
# Only Install/Upgrade/Remove are valid Operation values; an invalid hook
|
|
# aborts EVERY pacman transaction, so this file must stay minimal.
|
|
sudo mkdir -p "$(dirname "$HOOK_PATH")"
|
|
sudo tee "$HOOK_PATH" >/dev/null <<EOF
|
|
[Trigger]
|
|
Operation = Install
|
|
Operation = Upgrade
|
|
Type = Package
|
|
Target = arch-wiki-docs
|
|
|
|
[Action]
|
|
Description = Refreshing offline Arch Wiki RAG corpus...
|
|
When = PostTransaction
|
|
Exec = $REFRESH_BIN
|
|
EOF
|
|
}
|
|
|
|
main() {
|
|
install_dependencies
|
|
write_mcp_config
|
|
build_corpus
|
|
|
|
if [[ "$INSTALL_HOOK" -eq 1 ]]; then
|
|
install_hook
|
|
else
|
|
echo "==> Skipping pacman hook (--no-hook)"
|
|
fi
|
|
|
|
echo "==> Done. Start a session with: claude-archwiki"
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case $1 in
|
|
--no-hook)
|
|
INSTALL_HOOK=0
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
main "$@"
|