Skip to content

Chat: Grok chat on macOS #1387

Closed
Closed

Description

@345ml

Problem

On macOS, every Grok pane shows "Conversation unavailable" and falls back to Terminal, even when nothing about the session is ambiguous. The Grok reader binds a pane by the process's held events.jsonl and its GROK_HOME, and today it reads both from /proc only (#1207: "macOS and Windows still show the terminal view, because that evidence is read from /proc"). Claude Code and Codex panes already get chat on macOS. #776 first proposed Linux, macOS and Windows paths; the reader that shipped (#777) binds on Linux only.

Proposal

Read the same evidence on macOS and keep the binding rule exactly as on Linux. Chat shows only when the Grok process holds one events.jsonl session and that session is the ID Herdr reports. Anything else stays on Terminal.

  • Held files: lsof -nPbw -a -p <pid> -Ffn, the call agy-store.ts makes for Antigravity's lock, plus descriptor fields (-Ffn rather than -Fn). Numeric descriptors are the holds. The first txt entry is the executable; macOS lists mapped files as later txt entries.
  • GROK_HOME: ps -E -ww -p <pid> -o command=, as codex.ts and claude-store.ts already read CODEX_HOME and CLAUDE_CONFIG_DIR.
  • Fail closed: a failed or timed-out command, an over-long or incomplete listing, or a name that cannot be read back keeps the pane on Terminal. It never produces a shorter list.
  • Windows: unchanged.

I have this working on a branch, with unit tests and a macOS-only test that runs the real lsof and ps against a stand-in process. I also checked it by hand against live Grok 1.0.52 and 1.0.60 on Apple silicon. I'll open the PR if this is welcome. It touches server/grok-store.ts, the same place as #1352, so it would follow whichever binding rule lands there.

Where

Chat and prompt cards

Where it exists today

herdr web ui itself: Grok chat on Linux (#777, #1207), Claude Code and Codex chat on macOS, which read process environment with ps -E; Antigravity, which reads held files with lsof.

Workarounds and alternatives

Today: use Terminal for Grok panes on macOS.

Alternative: have Grok, or a status-line helper, report the current session file, as #776 sketched. That needs configuration on the user's side; reading the process needs none.

Activity

  1. devswha commented on Oct 24, 2026

    @devswha
    Owner

    Thanks, this is welcome; please open the PR. It brings Grok chat on macOS closer to the existing Linux support. lsof and ps -E are reads already used by agy-store.ts, codex.ts and claude-store.ts.

    #1352 has merged since this issue was opened, so please build on server/grok-store.ts as it is on main. Change the evidence-reading platform path, not the binding rule:

    • Herdr’s exact reported session id (herdr:grok) chooses the conversation; held-file evidence must never select another session.
    • Require exactly one verified Grok foreground process.
    • Resolve the Grok home from that process’s environment (GROK_HOME, otherwise its HOME/.grok); do not substitute the bridge’s home.
    • Find the exact id across session groups; duplicates are ambiguous, and symlinked sessions must not be followed.
    • Per fix(chat): keep Grok chat when older session files stay open #1352, older sessions can stay open. Herdr’s session must be held and have a strictly newer write time than every other held events.jsonl; ties fail closed.
    • Deleted/renamed held files or a descriptor that does not refer to the named file must keep Chat on Terminal. grokHeldSessions checks this with device/inode identity on Linux.

    Please run lsof and ps as awaited children with bounded timeouts, not spawnSync: resolution runs periodically for watched panes. Keep Windows on Terminal and update docs/grok-chat.md to describe macOS support. The Native macOS session identity job in .github/workflows/ci.yml runs a fixed test list, so add the macOS-only test there if it should run in CI.

  2. devswha commented on Oct 24, 2026

    @devswha
    Owner

    Thanks, this is welcome: please open the PR. It brings Grok chat on macOS level with Linux. lsof and ps -E are the same reads agy-store.ts, codex.ts and claude-store.ts already make.

    #1352 has merged since you wrote this, so please build on server/grok-store.ts as it is on main. Change only where the evidence comes from, not the binding rule:

    • herdr's reported id (herdr:grok) chooses the session. A held file never chooses a different one.
    • The pane has exactly one Grok foreground process, and its executable is checked to be Grok.
    • The home comes from that process's environment (GROK_HOME, else its HOME/.grok). The bridge never falls back to its own home.
    • The lookup is by exact id across the cwd groups. A duplicate id fails closed, and a symlinked session is never followed.
    • Since fix(chat): keep Grok chat when older session files stay open #1352, older sessions may stay open. herdr's session must be held and have the strictly newest write time among the held events.jsonl files, and a tie fails closed. So "the process holds one events.jsonl session" in the proposal becomes "the process holds herdr's session, and it is the newest held".
    • A held events.jsonl that is deleted, renamed (events.jsonl.old) or not the same file as its path keeps the pane on Terminal. On Linux, grokHeldSessions checks this by comparing device and inode.

    A few more points for the PR:

    • Run lsof and ps as awaited children with a timeout, as agy-store.ts does, never with spawnSync. The resolver runs every few seconds for each watched pane.
    • Keep Windows on Terminal, and update the platform line in docs/grok-chat.md.
    • CI's Native macOS session identity job runs a fixed list of test files (.github/workflows/ci.yml). To run your macOS-only test on every PR, add it to that list, and mention it in the description because that change touches a workflow.
  3. 345ml commented on Oct 24, 2026

    @345ml
    ContributorAuthor

    @devswha
    Thanks!
    I made this PR. #1858

  4. added a commit that references this issue on Oct 25, 2026
    b510ce3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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