# workspace_uuid.py — workspace UUID discovery logic # Extracted from lib.sh find_workspace_uuid PYEOF block import os, sys, json, glob, sqlite3 from lib_py.verify_session import verify_session_uuid, workspace_key, mam_orchestrator_uuids, mam_row_own_uuid OWN_KEY = { 'claude': 'claude_session_id_own', 'agy': 'agy_conversation_id_own', 'hermes': 'hermes_conversation_id_own', 'cline': 'cline_conversation_id_own' } def iso_root_of(s): iso = s.get('isolation') return iso.get('root') if isinstance(iso, dict) else None def find_workspace_uuid_main(): ws = os.environ['WS_ABS'] agent = os.environ['AGENT'] home = os.environ['HOME_DIR'] claude_project_dir = os.environ.get('CLAUDE_PROJECT_DIR', f"{home}/.claude/projects") target = os.environ.get('TARGET_SESSION', '') try: d = json.loads(os.environ.get('MAM_STATE_JSON', '{}')) except Exception: d = {} running_ids = set() for s_item in d.get('herdr_sessions', []): if s_item.get('status') == 'running': if target and s_item.get('name') == target: continue for k in ['claude_session_id_own', 'agy_conversation_id_own', 'hermes_conversation_id_own', 'cline_conversation_id_own']: val = s_item.get(k) if val: running_ids.add(val) orchestrator_ids = set(mam_orchestrator_uuids()) if target: for s_item in d.get('herdr_sessions', []): if s_item.get('name') == target: own = mam_row_own_uuid(s_item) if own: orchestrator_ids.discard(own) def emit(u): if u in running_ids or u in orchestrator_ids: return print(u) sys.exit(0) # Fetch all sessions matching this workspace sessions = [] for s in d.get('herdr_sessions', []): s_cwd = (s.get('pane') or {}).get('cwd', '') if isinstance(s, dict) else '' if s_cwd and (s_cwd == ws or os.path.realpath(s_cwd) == os.path.realpath(ws)): sessions.append(s) if target: for s in sessions: if s.get('name') != target: continue iso = iso_root_of(s) cand = s.get(OWN_KEY.get(agent, ''), None) if cand and verify_session_uuid(ws, agent, cand, s, mode="revalidate"): emit(cand) if iso: key = workspace_key(ws) if agent == 'claude': for j in sorted(glob.glob(f"{iso}/projects/{key}/*.jsonl"), key=os.path.getmtime, reverse=True): cand = os.path.basename(j)[:-6] if cand and verify_session_uuid(ws, agent, cand, s): emit(cand) elif agent == 'agy': for j in sorted(glob.glob(f"{iso}/.gemini/antigravity-cli/conversations/*.db"), key=os.path.getmtime, reverse=True): cand = os.path.basename(j)[:-3] if cand and verify_session_uuid(ws, agent, cand, s): emit(cand) elif agent == 'hermes': hdb = f"{iso}/.hermes/state.db" if os.path.exists(hdb): try: conn = sqlite3.connect(hdb) r = conn.execute("SELECT id FROM sessions WHERE cwd=? ORDER BY started_at DESC LIMIT 1", (ws,)).fetchone() conn.close() if r: cand = r[0] if verify_session_uuid(ws, agent, cand, s): emit(cand) except Exception: pass elif agent == 'cline': for folder in sorted(glob.glob(f"{iso}/sessions/*"), key=os.path.getmtime, reverse=True): fn = os.path.basename(folder) if os.path.exists(f"{folder}/{fn}.json"): if verify_session_uuid(ws, agent, fn, s): emit(fn) print('') sys.exit(0) for s in sessions: name = s.get('name', '') if agent == 'claude' and name.endswith('-creator-claude'): cand = s.get('claude_session_id_own') if cand and verify_session_uuid(ws, agent, cand, s, mode="revalidate"): emit(cand) if agent == 'agy' and name.endswith('-creator-agy'): cand = s.get('agy_conversation_id_own') if cand and verify_session_uuid(ws, agent, cand, s, mode="revalidate"): emit(cand) if agent == 'hermes' and name.endswith('-creator-hermes'): cand = s.get('hermes_conversation_id_own') if cand and verify_session_uuid(ws, agent, cand, s, mode="revalidate"): emit(cand) if agent == 'cline' and name.endswith('-creator-cline'): cand = s.get('cline_conversation_id_own') if cand and verify_session_uuid(ws, agent, cand, s, mode="revalidate"): emit(cand) if agent == 'claude': key = workspace_key(ws) proj = f"{claude_project_dir}/{key}" if os.path.isdir(proj): for j in sorted(glob.glob(f"{proj}/*.jsonl"), key=os.path.getmtime, reverse=True): cand = os.path.basename(j)[:-6] if cand and verify_session_uuid(ws, agent, cand): emit(cand) elif agent == 'agy': lc = f"{home}/.gemini/antigravity-cli/cache/last_conversations.json" if os.path.exists(lc): cand = None try: cand = json.load(open(lc)).get(ws) except Exception: cand = None if cand and verify_session_uuid(ws, agent, cand): emit(cand) elif agent == 'hermes': hdb = f"{home}/.hermes/state.db" if os.path.exists(hdb): cand = None try: conn = sqlite3.connect(hdb) r = conn.execute("SELECT id FROM sessions WHERE cwd=? ORDER BY started_at DESC LIMIT 1", (ws,)).fetchone() conn.close() if r: cand = r[0] except Exception: cand = None if cand and verify_session_uuid(ws, agent, cand): emit(cand) elif agent == 'cline': sessions_dir = f"{home}/.cline/data/sessions" if os.path.isdir(sessions_dir): candidates = [] for session_folder in glob.glob(f"{sessions_dir}/*"): if os.path.isdir(session_folder): folder_name = os.path.basename(session_folder) json_file = f"{session_folder}/{folder_name}.json" if os.path.exists(json_file): candidates.append(json_file) candidates.sort(key=os.path.getmtime, reverse=True) for j in candidates: cand = os.path.basename(j)[:-5] if cand and verify_session_uuid(ws, agent, cand): emit(cand) ai = d.get('agent_identities') if isinstance(d, dict) else None if not isinstance(ai, dict) or not ai: ai = {} try: yaml_path = os.environ['YAML_PATH'] db_path = os.path.splitext(yaml_path)[0] + '.db' if os.path.exists(db_path): conn = sqlite3.connect(db_path, timeout=60.0) conn.execute('PRAGMA busy_timeout = 60000') try: row = conn.execute('SELECT data FROM state WHERE id=1').fetchone() if row: ai = json.loads(row[0]).get('agent_identities') or {} except sqlite3.OperationalError: pass conn.close() elif os.path.exists(yaml_path): import yaml with open(yaml_path) as f: _ydoc = yaml.safe_load(f) or {} ai = _ydoc.get('agent_identities') or {} except Exception as e: print(f"WARN: tier-3 identity lookup failed: {e}", file=sys.stderr) if not isinstance(ai, dict): ai = {} ai_agent = ai.get(agent) or {} if ai_agent.get('project_cwd') == ws: if agent == 'claude': cand = ai_agent.get('session_id') if cand and verify_session_uuid(ws, agent, cand, mode="revalidate"): emit(cand) elif agent == 'agy': cand = ai_agent.get('conversation_id') if cand and verify_session_uuid(ws, agent, cand, mode="revalidate"): emit(cand) elif agent == 'hermes': cand = ai_agent.get('session_id') or ai_agent.get('conversation_id') if cand and verify_session_uuid(ws, agent, cand, mode="revalidate"): emit(cand) elif agent == 'cline': cand = ai_agent.get('session_id') or ai_agent.get('conversation_id') if cand and verify_session_uuid(ws, agent, cand, mode="revalidate"): emit(cand) print('') if __name__ == '__main__': find_workspace_uuid_main()