fix(skills): the sandbox document venv is built privately and published atomically

The no-Hermes fallback treated an executable bin/python as a finished
environment, but CPython creates it before ensurepip runs. A second
document task started in that window skipped creation, ran a pip that
did not exist yet, and its helper failed (8 concurrent fresh callers in
nousresearch/hermes-sandbox:desktop: 5/8 succeeded).

Each caller now builds into its own mktemp dir next to the target,
installs and verifies the imports there, then publishes it with
a symlink (os.symlink: atomic, fails if another caller already published); losers
delete their copy. A published env that no longer imports is replaced
with os.replace and removed. Same block in docx, xlsx, powerpoint, pdf,
excel-author, pptx-author and both OCR side environments.

Same 8-caller probe after the fix: 8/8 under dash and bash; 4
concurrent repairs of a broken env: 4/4, one env left.
This commit is contained in:
Teknium committed 2026-10-28 19:26:17 -07:00
1 parent d202ddfda2
commit dc82bec3bd
13 files changed
+208 -40

No files matched your search

+15 -3
View File
@@ -38,9 +38,21 @@ python -c "import openpyxl" 2>/dev/null && PY=python || if command -v hermes >/d
PY="$(hermes pm environment documents --extra documents --extra documents-pdf)"
else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-docs-venv"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null ||
"$PY" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-docs-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
export PY
```
+15 -3
View File
@@ -39,9 +39,21 @@ python -c "import pptx" 2>/dev/null && PY=python || if command -v hermes >/dev/n
PY="$(hermes pm environment documents --extra documents --extra documents-pdf)"
else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-docs-venv"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null ||
"$PY" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-docs-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
export PY
```
+15 -3
View File
@@ -51,9 +51,21 @@ fields, and package health checks. It does not render documents itself
PY="$(hermes pm environment documents --extra documents --extra documents-pdf)"
else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-docs-venv"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null ||
"$PY" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-docs-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
export PY
"$PY" scripts/docx_create.py --help
+15 -3
View File
@@ -46,9 +46,21 @@ Create PDFs from structured specs, build and fill AcroForm forms (with layout li
PY="$(hermes pm environment documents --extra documents --extra documents-pdf)"
else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-docs-venv"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null ||
"$PY" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-docs-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
export PY
"$PY" scripts/pdf_create.py --help
@@ -62,8 +62,20 @@ if command -v hermes >/dev/null 2>&1; then
PY="$(hermes pm environment pdf-pymupdf --requirement 'pymupdf>=1.26,<3' --requirement 'pymupdf4llm>=0.2,<3')"
else
PY="$HOME/.cache/hermes-pdf-pymupdf-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-pdf-pymupdf-venv"
"$PY" -c "import pymupdf, pymupdf4llm" 2>/dev/null || "$PY" -m pip install -q --disable-pip-version-check 'pymupdf>=1.26,<3' 'pymupdf4llm>=0.2,<3'
"$PY" -c "import pymupdf, pymupdf4llm" 2>/dev/null || (
# concurrency-safe build: see the documents block in SKILL.md
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-pdf-pymupdf-venv.XXXXXX)" || exit 1
old="$(readlink hermes-pdf-pymupdf-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check 'pymupdf>=1.26,<3' 'pymupdf4llm>=0.2,<3' &&
"$stage/bin/python" -c "import pymupdf, pymupdf4llm" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-pdf-pymupdf-venv
elif [ "$(readlink hermes-pdf-pymupdf-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-pdf-pymupdf-venv &&
case "$old" in hermes-pdf-pymupdf-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-pdf-pymupdf-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
```
@@ -100,8 +112,20 @@ if command -v hermes >/dev/null 2>&1; then
PY="$(hermes pm environment pdf-marker --requirement 'marker-pdf>=1.8,<3')"
else
PY="$HOME/.cache/hermes-pdf-marker-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-pdf-marker-venv"
"$PY" -c "import marker" 2>/dev/null || "$PY" -m pip install -q --disable-pip-version-check 'marker-pdf>=1.8,<3'
"$PY" -c "import marker" 2>/dev/null || (
# concurrency-safe build: see the documents block in SKILL.md
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-pdf-marker-venv.XXXXXX)" || exit 1
old="$(readlink hermes-pdf-marker-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check 'marker-pdf>=1.8,<3' &&
"$stage/bin/python" -c "import marker" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-pdf-marker-venv
elif [ "$(readlink hermes-pdf-marker-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-pdf-marker-venv &&
case "$old" in hermes-pdf-marker-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-pdf-marker-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
```
+15 -3
View File
@@ -48,9 +48,21 @@ and slide rendering — all offline, no PowerPoint installation required.
PY="$(hermes pm environment documents --extra documents --extra documents-pdf)"
else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-docs-venv"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null ||
"$PY" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-docs-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
export PY
"$PY" scripts/pptx_create.py --help
+15 -3
View File
@@ -54,9 +54,21 @@ scripts are argparse CLIs that print JSON and use explicit UTF-8 I/O.
PY="$(hermes pm environment documents --extra documents --extra documents-pdf)"
else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-docs-venv"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null ||
"$PY" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-docs-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
export PY
"$PY" scripts/xlsx_create.py --help
@@ -68,9 +68,21 @@ fields, and package health checks. It does not render documents itself
PY="$(hermes pm environment documents --extra documents --extra documents-pdf)"
else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-docs-venv"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null ||
"$PY" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-docs-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
export PY
"$PY" scripts/docx_create.py --help
@@ -63,9 +63,21 @@ Create PDFs from structured specs, build and fill AcroForm forms (with layout li
PY="$(hermes pm environment documents --extra documents --extra documents-pdf)"
else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-docs-venv"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null ||
"$PY" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-docs-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
export PY
"$PY" scripts/pdf_create.py --help
@@ -65,9 +65,21 @@ and slide rendering — all offline, no PowerPoint installation required.
PY="$(hermes pm environment documents --extra documents --extra documents-pdf)"
else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-docs-venv"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null ||
"$PY" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-docs-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
export PY
"$PY" scripts/pptx_create.py --help
@@ -71,9 +71,21 @@ scripts are argparse CLIs that print JSON and use explicit UTF-8 I/O.
PY="$(hermes pm environment documents --extra documents --extra documents-pdf)"
else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-docs-venv"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null ||
"$PY" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-docs-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
export PY
"$PY" scripts/xlsx_create.py --help
@@ -56,9 +56,21 @@ python -c "import openpyxl" 2>/dev/null && PY=python || if command -v hermes >/d
PY="$(hermes pm environment documents --extra documents --extra documents-pdf)"
else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-docs-venv"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null ||
"$PY" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-docs-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
export PY
```
@@ -57,9 +57,21 @@ python -c "import pptx" 2>/dev/null && PY=python || if command -v hermes >/dev/n
PY="$(hermes pm environment documents --extra documents --extra documents-pdf)"
else
PY="$HOME/.cache/hermes-docs-venv/bin/python"
[ -x "$PY" ] || python3 -m venv "$HOME/.cache/hermes-docs-venv"
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null ||
"$PY" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0
"$PY" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" 2>/dev/null || (
# Safe to run from several agents at once: each caller builds a private venv,
# a symlink publishes the first finished one atomically, the others delete theirs.
mkdir -p "$HOME/.cache" && cd "$HOME/.cache" && stage="$(mktemp -d hermes-docs-venv.XXXXXX)" || exit 1
old="$(readlink hermes-docs-venv)" # an earlier build that no longer imports, if any
python3 -m venv "$stage" &&
"$stage/bin/python" -m pip install -q --disable-pip-version-check python-docx==1.2.0 openpyxl==3.1.5 python-pptx==1.0.2 reportlab==5.1.0 pypdf==6.21.2 pdfplumber==0.11.10 pypdfium2==5.14.0 &&
"$stage/bin/python" -c "import docx, openpyxl, pptx, reportlab, pypdf, pdfplumber, pypdfium2" &&
if [ -z "$old" ]; then python3 -c 'import os, sys; os.symlink(*sys.argv[1:])' "$stage" hermes-docs-venv
elif [ "$(readlink hermes-docs-venv)" = "$old" ]; then
ln -s "$stage" "$stage.lnk" && python3 -c 'import os, sys; os.replace(*sys.argv[1:])' "$stage.lnk" hermes-docs-venv &&
case "$old" in hermes-docs-venv.??????) rm -rf "$old" ;; esac
fi 2>/dev/null
[ "$(readlink hermes-docs-venv)" = "$stage" ] || rm -rf "$stage" "$stage.lnk"
)
fi
export PY
```