diff --git a/.agents/skills/lib.sh b/.agents/skills/lib.sh index 8bfb719..f2356fa 100644 --- a/.agents/skills/lib.sh +++ b/.agents/skills/lib.sh @@ -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.1" +MAM_VERSION="4.1.2" export MAM_VERSION AGENT_SESSIONS_YAML="${AGENT_SESSIONS_YAML:-$WORKSPACE_ROOT/.mam/agent-sessions.yaml}" @@ -412,7 +412,7 @@ try: if tws: panes = [p for p in panes if p.get('workspace_id') == tws] # ISSUE-2: exact match first, then agent-sessions.yaml lookup fallback - for key in ('label', 'name', 'agent'): + for key in ('label', 'name'): for p in panes: v = p.get(key) if v and (v == tn or v == tsa): @@ -433,7 +433,13 @@ try: break except Exception as e: sys.stderr.write(f'warning: yaml load failed: {e}\n') - if agent_kind: + # BUG-1: only trust the generic agent_kind fallback when the caller's + # own target string IS the bare kind (e.g. target == 'agy'). Using a + # *derived* kind (looked up via the yaml entry matched by tn/tsa) to + # then broadly match any pane of this kind is unsound whenever another, + # unrelated same-kind session is alive in the workspace - it misattributes + # that unrelated pane as this target even though their names differ. + if agent_kind and (tn == agent_kind or tsa == agent_kind): matching = [p.get('pane_id') for p in panes if p.get('agent') == agent_kind and p.get('pane_id')] if len(matching) == 1: print(matching[0]) @@ -702,6 +708,32 @@ except Exception: ws_id="" target_pane="" if [ -n "$existing_ws" ]; then + # BUG-4: prefer an already-idle (agent-less) pane in the existing + # workspace over splitting a new one — avoids unbounded pane + # proliferation and 2x2 grid-layout churn when a prior agent's pane + # was left behind idle. + idle_pane=$(_real_herdr pane list 2>/dev/null | TARGET_WS="$existing_ws" python3 -c " +import sys, json, os +target_ws = os.environ.get('TARGET_WS', '') +try: + d = json.loads(sys.stdin.read()) + panes = d.get('result', {}).get('panes', []) + for p in panes: + if p.get('workspace_id') == target_ws and not p.get('agent') and p.get('pane_id'): + print(p.get('pane_id')) + break +except Exception: + pass +" 2>/dev/null || echo "") + + if [ -n "$idle_pane" ]; then + target_pane="$idle_pane" + if [ -n "$final_cmd" ]; then + idle_env="${env_flags//--env /}" + idle_env="${idle_env:+$idle_env }HERDR_WORKSPACE_ID=$existing_ws" + final_cmd="env $idle_env $final_cmd" + fi + else # W2a: Determine split direction policy via pane layout sample_pane=$(_real_herdr pane list 2>/dev/null | TARGET_WS="$existing_ws" python3 -c " import sys, json, os @@ -751,6 +783,7 @@ except Exception: pass " 2>/dev/null || echo "") fi + fi fi if [ -z "$existing_ws" ] || [ -z "$target_pane" ]; then