diff --git a/AGENTS.md b/AGENTS.md index c5aebbff..8e1bbd6e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -69,6 +69,9 @@ Follow that checklist's safety rules: the manual verification performed. - For runtime, streaming, recovery, replay, compression, or sidebar metadata changes, name the state layer being mutated and prove the relevant invariant. +- For Docker build changes in `docker_init.bash`, mirror directory exclusions + in both the `rsync` and `cp -a` paths — `/opt/hermes` may contain subdirectories + with restricted permissions (e.g. `.playwright/`). ## Local state and secrets diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f22f9d7..d0142176 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,8 @@ ### Fixed +- **Docker build no longer fails when `/opt/hermes` contains a `.playwright/` directory.** The agent-source staging step now excludes `.playwright` in both the `rsync` and `cp -a` fallback paths, fixing `rsync error code 23` during the build. Thanks @enihcam. (#5316, fixes #5315) + - **Reorder the chat-footer controls by dragging.** The composer footer controls (Attach, Saved prompts, Mic, Profile, Workspace, Model, Reasoning, Context, and the situational controls) can now be reordered by dragging their chips in Settings, in addition to toggling visibility. The order persists per profile and is validated/deduplicated server-side. Thanks @Paladin173. (#5075) - **Orphaned zero-message native/CLI sidebar sessions are pruned from the sidebar.** When a CLI or API-server session that was clicked in WebUI (creating a WebUI-owned sidecar) is later deleted outside WebUI, the stale zero-message row no longer lingers in the sidebar forever — it's pruned once the backing agent session is confirmed gone. A session with any real transcript (`message_count > 0`), attention signal, or active/pending stream is always preserved (never pruned), so no transcript is lost. Thanks @enihcam. (#4988, fixes #4985) diff --git a/docker_init.bash b/docker_init.bash index b402ec5a..11af18f9 100644 --- a/docker_init.bash +++ b/docker_init.bash @@ -452,6 +452,7 @@ else rsync -a \ --exclude='*.egg-info' --exclude='build' --exclude='dist' \ --exclude='__pycache__' --exclude='.git' \ + --exclude='.playwright' \ "$_agent_src"/ "$_stage_src"/ \ || error_exit "Failed to stage hermes-agent source to writable build dir" else @@ -460,6 +461,7 @@ else cp -a "$_agent_src"/. "$_stage_src"/ \ || error_exit "Failed to copy hermes-agent source to writable build dir" rm -rf "$_stage_src"/*.egg-info "$_stage_src"/build "$_stage_src"/dist 2>/dev/null || true + rm -rf "$_stage_src"/.playwright 2>/dev/null || true find "$_stage_src" -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true fi chmod -R u+w "$_stage_src" \ diff --git a/tests/test_docker_docs_and_readonly.py b/tests/test_docker_docs_and_readonly.py index 821118f0..d5428346 100644 --- a/tests/test_docker_docs_and_readonly.py +++ b/tests/test_docker_docs_and_readonly.py @@ -253,6 +253,16 @@ def test_docker_init_excludes_egg_info_during_staging(): "rsync staging must --exclude='__pycache__' to keep the copy minimal." ) + assert "--exclude='.playwright'" in stage_block, ( + "rsync staging must --exclude='.playwright' so unreadable Playwright " + "browser dependency files (e.g. deb.deps, rpm.deps) don't cause " + "rsync error code 23 and kill container startup." + ) + assert ".playwright" in stage_block, ( + "Both rsync (--exclude) and cp-fallback (rm -rf) must handle " + ".playwright so the build doesn't choke on unreadable browser files." + ) + def test_docker_init_makes_staged_dir_writable_after_ro_mount_copy(): """Regression test for the docker-init "could not create hermes_agent.egg-info: