Skip to content

[bug] Sessions and dashboard ignore a relocated Cursor CLI or Muse data dir #1138

Closed

Description

@SaulMoro

Follow-up to #725 and #939, which made Claude Code and Codex relocatable through the recorded toolRoots. #1135 extends that to their session stores. Other tools can also move their data, and TeamAI still reads their default paths.

What moves and what TeamAI reads

Tool What moves its data What TeamAI reads Effect
Cursor CLI CURSOR_DATA_DIR: transcripts under <dir>/projects (seen in cursor-agent 2026.09.28) ~/.cursor/projects (getCursorProjectsDir in src/session-flow/fs.ts) session migrate does not find the transcripts, and copies land where Cursor does not look
Muse Code XDG_DATA_HOME: sessions under $XDG_DATA_HOME/muse (seen in muse 1.4.6) ~/.local/share/muse/sessions (src/dashboard-collector.ts) The dashboard loses token counts for Muse sessions
Cursor IDE on Linux Probably XDG_CONFIG_HOME, as VS Code does. Not checked on Cursor ~/.config/Cursor (src/session-flow/cursor-store.ts) Probably the same as Cursor CLI. src/session-flow/ide-history.ts already honors XDG_CONFIG_HOME; cursor-store does not
claude-internal, tclaude, codex-internal, tcodex, CodeBuddy, WorkBuddy Unknown Fixed ~/.<tool> paths Not checked: none is installed where I looked. If a Claude Code or Codex fork reads CLAUDE_CONFIG_DIR or CODEX_HOME, its sessions are not found either

Why this is not a one-line change

A tool joins RELOCATABLE_TOOLS (src/types.ts) only after every TeamAI write for that tool follows the recorded root, so a partial move does not split its files in two places. Cursor uses two variables (CURSOR_CONFIG_DIR for configuration and CURSOR_DATA_DIR for project data), so adding it needs an audit of both, not a path change. Muse touches the dashboard collector, not session-flow.

Proposal

  1. Cursor CLI: record CURSOR_DATA_DIR at teamai init the way toolRoots records CLAUDE_CONFIG_DIR, audit every Cursor read and write, then add it to RELOCATABLE_TOOLS.
  2. Muse: read the sessions under $XDG_DATA_HOME/muse when it is set, recorded the same way so hooks without the variable agree.
  3. Cursor IDE on Linux: confirm whether it honors XDG_CONFIG_HOME; if it does, resolve cursor-store the way ide-history does.
  4. The forks: check which variable each one reads before changing anything.

Related: #725, #939, #1010, #1135.

Activity

  1. Smilewithoutfalling commented on Oct 15, 2026

    @Smilewithoutfalling
    Contributor

    I'd like to take the two Cursor entries.

    Scope I'd claim — items 1 and 3.

    • Item 1 (Cursor CLI). getCursorProjectsDir() in src/session-flow/fs.ts:75 resolves ~/.cursor/projects with no argument. I'd give it a toolRoots? parameter the same way getClaudeCodeProjectsDir / getCodexSessionsDir received one in feat(session): safe session reads and copies for workflows, drivers, scorers, and benchmarks (#593 follow-up) #1135, add the spec to RELOCATABLE_TOOLS, and forward toolRoots from the cursor factory in adapters/index.ts. Then audit every Cursor read/write before it joins the allowlist, per the note in types.ts.
    • Item 3 (Cursor IDE on Linux). cursor-store.ts resolves ~/.config/Cursor from a bare homedir(). ide-history.ts already reads XDG_CONFIG_HOME ?? path.join(home, '.config') for the same class of path, so I'd follow that existing pattern instead of adding a second one.

    Checked on main 987a7466 (after #1135 landed):

    • RELOCATABLE_TOOLS (src/types.ts:2347) still has exactly two entries: claude-code → CLAUDE_CONFIG_DIR, codex → CODEX_HOME.
    • ADAPTER_REGISTRY (src/session-flow/adapters/index.ts:28) registers 11 platforms. AdapterFactory is typed (toolRoots?: LocalConfig['toolRoots']) => AgentAdapter, but only claude-code and codex forward the argument — the other nine (including cursor) are zero-arg factories.
    • fs.ts has nine get*Dir() helpers; only two take toolRoots?. getCursorProjectsDir() (:75) takes none.
    • No open PR touches session-flow/fs.ts, session-flow/adapters/cursor.ts, or session-flow/cursor-store.ts.

    Item 2 is already taken by #1142. For item 4 I can't check the forks from outside — I have no way to see which variable any of them reads.

    One thing I need confirmed before writing code. The "Why this is not a one-line change" section says: "Cursor uses two variables (CURSOR_CONFIG_DIR for configuration and CURSOR_DATA_DIR for project data)." But the table above lists only CURSOR_DATA_DIR, and searching main for literal env-var names turns up only CLAUDE_CONFIG_DIR and CODEX_HOME — CURSOR_CONFIG_DIR appears nowhere else in the tree. Is CURSOR_CONFIG_DIR a variable cursor-agent actually reads (i.e. item 1 has to audit two variables, not one), and does it also apply to Cursor IDE on Linux — or should item 3 still key off XDG_CONFIG_HOME?

  2. SaulMoro commented on Oct 15, 2026

    @SaulMoro
    CollaboratorAuthor

    Thanks. Items 1 and 3 are yours.

    CURSOR_CONFIG_DIR is real, and it changes the scope of item 1. I read it in the cursor-agent 2026.09.28 bundle (cursor-config/dist/paths.js). The CLI resolves two directories:

    Directory Resolution What lives there
    config CURSOR_CONFIG_DIR, else $XDG_CONFIG_HOME/cursor, else ~/.cursor cli-config.json, permissions.json, chats/, acp-sessions/, acp-config.json
    data CURSOR_DATA_DIR (also set by --data-dir), else ~/.cursor projects/ (the transcripts)

    The user mcp.json, rules/ and commands/ stay hard-coded to ~/.cursor in that version, whatever these variables say.

    For TeamAI this means:

    • Session-flow only reads transcripts, so getCursorProjectsDir follows the data root (CURSOR_DATA_DIR).
    • TeamAI also writes ~/.cursor/cli-config.json (src/coauthor-reconcile.ts:164, the co-author setting). The CLI reads that file from the config root. So with only XDG_CONFIG_HOME set, the CLI already reads $XDG_CONFIG_HOME/cursor/cli-config.json and TeamAI's write misses it. RELOCATABLE_TOOLS requires every write for a tool to follow its root. So Cursor needs both roots recorded at init (data and config, the config one with the XDG_CONFIG_HOME fallback), and the co-author target has to follow the config root. That is the two-variable audit the issue meant. The table missed the XDG_CONFIG_HOME fallback, sorry about that.
    • mcp.json, rules and commands keep their ~/.cursor paths.

    Item 3: no, CURSOR_CONFIG_DIR does not apply to the IDE. Neither CURSOR_ variable appears in the IDE's own code (Cursor 3.16.29, out/). It shows up only in its bundled agent extensions. The IDE resolves its user data through the VS Code path logic (userDataPath.js): VSCODE_PORTABLE, then VSCODE_APPDATA, then --user-data-dir, and on Linux $XDG_CONFIG_HOME or ~/.config, joined with Cursor. So keying cursor-store off XDG_CONFIG_HOME, the way ide-history.ts does, is right. I read that from the macOS build, which ships the same Linux branch. I have not run it on Linux.

    These are internals of a closed-source bundle. If a newer cursor-agent resolves differently, please note the version you checked in the PR.

  3. kittimzhe commented on Oct 16, 2026

    @kittimzhe
    Contributor

    Taking item 2 (Muse).

    Mechanism first, because it changes the fix's shape: readMuseSessionTokens has exactly one caller — the stop-hook branch of parseHookEvent (dashboard-collector.ts:1346) — so the reader runs inside muse's own hook process, inheriting muse's environment. Tokens are stamped onto the event at that moment, and the dashboard only replays the stamped events; nothing re-reads the muse tree from the server. That means a live $XDG_DATA_HOME read is sufficient — no toolRoots recording needed, the same resolution the OpenCode adapter already uses (session-flow/adapters/opencode.ts:305): root = ${XDG_DATA_HOME:-~/.local/share}/muse/sessions. Recording would only matter if a reader without the variable had to find the tree, and there is no such reader today (that's also why Muse never needed the RELOCATABLE_TOOLS write audit — TeamAI only ever reads it).

    Red test first, then the one-line resolution change in findMuseSessionLog.

  4. Smilewithoutfalling commented on Oct 16, 2026

    @Smilewithoutfalling
    Contributor

    Delivered as #1165 — items 1 and 3 of this issue.

    Scope. Item 1 registers the two roots Cursor CLI actually moves — cursor-data for CURSOR_DATA_DIR, cursor-config for CURSOR_CONFIG_DIR — and makes the transcript store and the cli-config.json write follow them, which is the widened scope you described. Item 3 makes session-flow/cursor-store.ts resolve the IDE user-data dir the way VS Code does ($XDG_CONFIG_HOME, else ~/.config, joined with Cursor) instead of hard-coding ~/.config/Cursor.

    Versions read, as you asked: cursor-agent 2026.09.28 bundle (cursor-config/dist/paths.js) and Cursor IDE 3.16.29. Both are stated in the PR description.

    State. 16 files, +594/-39, based on c57da5af. On d4990e12: Lint & Test green on ubuntu and macOS at Node 20/22/24, E2E (fork-safe, no credentials) green, and Codex PR Review reports no new findings.

    Item 2 (Muse) is @kittimzhe's — that diff and this one do not overlap.

  5. STiFLeR7 commented on Oct 19, 2026

    @STiFLeR7
    Collaborator

    All three items here are merged:

    Closing as fully resolved. (Triage access only — closing based on the linked merged PRs, no code changes from me.)

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

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions