chore(release): bump framework and 8 skills to v4.1.1 (PATCH — agent creation & runtime reliability fixes)

This commit is contained in:
2026-08-30 06:08:15 +09:00
parent 6de15350c0
commit eb8057b031
14 changed files with 243 additions and 30 deletions
+66 -1
View File
@@ -29,7 +29,7 @@ export WORKSPACE_ROOT
# Framework semantic version. Single runtime source of truth; kept in lockstep
# with VERSIONS.md and the 8 SKILL.md frontmatters by tests/test_version_consistency.py.
# NOTE: unlike other MAM_* variables this one is intentionally NOT env-overridable.
MAM_VERSION="4.1.0"
MAM_VERSION="4.1.1"
export MAM_VERSION
AGENT_SESSIONS_YAML="${AGENT_SESSIONS_YAML:-$WORKSPACE_ROOT/.mam/agent-sessions.yaml}"
@@ -154,6 +154,15 @@ _init_herdr_isolation() {
# Herdr-to-Herdr translation shim wrapper
set -euo pipefail
# This shim can run as a standalone subprocess (e.g. spawned directly by
# herdr) without inheriting the parent shell's PYTHONPATH export from
# lib.sh, which breaks the `python3 -m lib_py...` / `from lib_py...` calls
# below. Re-derive it from the shim's own on-disk location instead of
# assuming inheritance.
_SHIM_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
_SKILL_DIR="$(cd "$_SHIM_DIR/../../.agents/skills" 2>/dev/null && pwd || true)"
[ -n "$_SKILL_DIR" ] && export PYTHONPATH="$_SKILL_DIR:${PYTHONPATH:-}"
# Dynamic real herdr path resolution to prevent infinite recursion
_resolve_real_herdr() {
local dir save_ifs="$IFS" real_path=""
@@ -339,7 +348,39 @@ sys.exit(1)
# and return 1. Callers MUST wrap with `|| true` (shim runs under set -e).
_resolve_herdr_pane_id() {
local target="$1"
# Fast path: caller already passed a real pane_id (e.g. "w1E:p1") — skip
# agent-get/pane-list resolution entirely.
if [[ "$target" =~ ^w[A-Za-z0-9]+:p[A-Za-z0-9]+$ ]]; then
printf '%s\n' "$target"
return 0
fi
local target_ws="${2:-$(_herdr_ws_scope)}"
# A caller may pass a workspace *label* (e.g. $MAM_WS_LABEL) rather than
# the raw workspace_id — panes only carry workspace_id, so translate a
# label to its id via `herdr workspace list` before filtering. Falls
# back to the original value on any failure/no-match (permissive; keeps
# prior behavior when $target_ws is already a raw id).
if [ -n "$target_ws" ]; then
local resolved_ws
resolved_ws=$(_real_herdr workspace list 2>/dev/null | TARGET_WS="$target_ws" python3 -c "
import sys, json, os
tws = os.environ.get('TARGET_WS', '')
try:
wss = json.load(sys.stdin).get('result', {}).get('workspaces', [])
ids = {w.get('workspace_id') for w in wss}
if tws in ids:
print(tws)
sys.exit(0)
hit = next((w.get('workspace_id') for w in wss if w.get('label') == tws), '')
if hit:
print(hit)
sys.exit(0)
except Exception:
pass
sys.exit(1)
" 2>/dev/null || echo "$target_ws")
[ -n "$resolved_ws" ] && target_ws="$resolved_ws"
fi
local sat pid=""
sat=$(_sanitize_herdr_agent_name "$target")
@@ -780,6 +821,30 @@ except Exception:
fi
done
if [ "$success" -ne 1 ]; then
# A "timed out waiting for agent startup" result is ambiguous — herdr
# returns the identical text whether the process died or the TUI
# render was just slow (see the comment above the retry loop). Rather
# than trust that text either way, re-query herdr directly: if the
# agent is actually registered and alive, treat this as success; if
# not, fall back to sending the launch command straight into the
# pane before giving up.
if echo "$res" | grep -qiE "timed out waiting for agent startup"; then
if [ -n "$(_herdr_agent_get_scoped "$agent_name" 2>/dev/null || true)" ]; then
success=1
else
if [ -n "$final_cmd" ]; then
_real_herdr pane send-text "$target_pane" "$final_cmd" >/dev/null 2>&1 || true
_real_herdr pane send-keys "$target_pane" Enter >/dev/null 2>&1 || true
fi
sleep 1
if [ -n "$(_herdr_agent_get_scoped "$agent_name" 2>/dev/null || true)" ]; then
success=1
fi
fi
fi
fi
if [ "$success" -ne 1 ]; then
echo "$res" >&2
exit 1