Skip to content

OpenCode session discovery fails on macOS because lsof cwd lookup uses OR semantics without -a #120

@Alexander-He

Description

@Alexander-He

Summary

OpenCode sessions may not be discovered on macOS even when:

  • an opencode process is actively running
  • ~/.local/share/opencode/opencode.db exists
  • sqlite3 is available
  • the session row exists in the OpenCode SQLite database

The root cause appears to be the macOS cwd lookup in src/collector/opencode.rs.

Environment

  • abtop: 0.4.3
  • OS: macOS
  • OpenCode: 1.14.48

What I observed

On my machine:

  • opencode is running
  • sqlite3 is installed
  • ~/.local/share/opencode/opencode.db exists and contains the current session
  • abtop --once still shows:
abtop — 0 sessions, 0 mcp servers

The current OpenCode session row in the DB has:

  • directory = /Users/alexanderhe

The running opencode process is also in:

  • /Users/alexanderhe

So discovery should succeed, but it does not.

Suspected root cause

In src/collector/opencode.rs, the macOS cwd lookup uses:

lsof -p <pid> -d cwd -Fn

On macOS, lsof selection terms are OR-ed unless -a is provided.

That means this command does not mean “cwd for this pid”.
It effectively means something closer to:

  • entries matching pid=<pid> OR
  • entries matching fd=cwd

As a result, the output can include cwd entries from many unrelated processes.

The current code then takes the first n... line:

stdout
    .lines()
    .find(|l| l.starts_with('n') && l.len() > 1)
    .map(|l| l[1..].to_string())

If that first n... line belongs to another process, abtop gets the wrong cwd, fails to match it against the OpenCode DB session directory, and the session is dropped.

Why fallback did not help

The fallback matcher also checks whether the command line contains the session directory:

if cmd.contains(session_dir)

But when OpenCode is launched simply as:

opencode

the command line does not include the cwd, so this fallback also fails.

Proposed fix

Use -a when invoking lsof for cwd discovery on macOS:

lsof -a -p <pid> -d cwd -Fn

That makes the filters apply with AND semantics and should return only the cwd entry for the target process.

Suggested patch

In get_process_cwd() for non-Linux targets, change:

.args(["-p", &pid.to_string(), "-d", "cwd", "-Fn"])

to:

.args(["-a", "-p", &pid.to_string(), "-d", "cwd", "-Fn"])

Notes

This seems distinct from the already-fixed OpenCode matching issues around:

  • one PID being reused for multiple DB rows
  • weak substring matching for short/empty directories

Those fixes are helpful, but they do not address this macOS-specific cwd lookup bug.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions