Skip to content

feat: run remote Agent Roles in a Local Project's linked GitHub repo and keep their sidebar nesting - #2027

Merged
lodyai[bot] merged 4 commits into
mainfrom
feat/role-mention-local-github-project
Oct 28, 2026
Merged

lodyai[bot] merged 4 commits into
mainfrom
feat/role-mention-local-github-project

Conversation

@lodyai

@lodyai lodyai Bot commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Related issue

Problem / pressure

When an Agent Role bound to another Machine is mentioned from a Local Project session, the remote Machine cannot reach the project's filesystem, so MCP creates the Role session as a plain chat with no code. If that Local Project has a GitHub remote that the workspace already enables, the remote Machine could clone it and work like a GitHub-project session.

Separately, in the Workspace sidebar the resulting session lands in another group (Chats or a GitHub repository) than its opener, so the opened-by tree renders it top-level and the fan-out hierarchy is lost.

Summary

  • MCP Role placement (apps/cli/src/mcp/lody-mcp-server.ts): if a remote Role has no explicit workContext and the requester's Local Project has a linked GitHub repository that resolveRoleCloneableRepo finds enabled in the workspace, the Role session starts in that repository on the default branch. The default branch is used because the local branch may be unpushed and would fail the clone. An unlisted repository keeps the plain-chat placement instead of failing. Same-machine Roles still default to a child Session, and an explicit workContext still wins. Applied to single, batch and legacy create paths; the tool description is updated.
  • Sidebar placement (packages/components): placeOpenedSessionsWithOpeners and placeWorkspaceSessionsWithOpeners move an opened Session into the Workspace group of its topmost rendered ancestor, so the tree there indents it. Every row still appears exactly once; Pinned and Updated keep their natural membership. An opener in a hidden project, in Pinned or in the archive leaves the row where it was, and a cycle also stays put. Keyboard-navigation group lookup and the local-project hover card (the row's own machine, not the project's) follow the moved row.
  • Mobile chat list (mobile/mobile-chat-list.tsx): project buckets apply the same placement, and a bucket's project heading comes only from its own rows. Date buckets put a whole opened-by tree under the day of its freshest member, the same time that already ranks the opener.
  • Docs: packages/components/src/components/mobile/AGENTS.md, specs/agent-role-mentions.md (draft), apps/cli/src/mcp/AGENTS.md, the cross-machine Role note (EN/ZH), packages/components/src/components/AGENTS.md, .agents/docs/components-sidebar-session-tree.md (records the rejected alternatives: a cross-machine parentSessionId child, and duplicate rows).

Visual explanation

flowchart TD
  A[Local Project session on Machine A<br/>mentions Role bound to Machine B] --> B{explicit workContext?}
  B -- yes --> W[use it]
  B -- no --> C{Local Project's GitHub repo<br/>enabled in workspace?}
  C -- yes --> G[GitHub workContext: repo, default branch<br/>cloned on Machine B]
  C -- no --> P[plain chat on Machine B]
  G --> S[openedBySessionId = requester]
  P --> S
  S --> T[Workspace sidebar / mobile project buckets:<br/>row moves into opener's group]
  T --> U[opened-by tree indents it under the opener]
Loading

Before / after

Before After
Remote Role from a Local Project → plain chat, shown top-level in Chats Linked + enabled repo → GitHub-repo session; either way nested under the opener in the Local Project group

Test plan

  • apps/cli: vitest run src/mcp/lody-mcp-server.test.ts passes (50). The new case covers four outcomes: an enabled linked repo gives a GitHub workContext on the default branch, an unlisted repo stays plain chat, an explicit workContext is unchanged, and a same-machine Role is still a child.
  • packages/components: the sidebar, session-list and opened-by test files pass (26 files, 251 tests). New cases cover a remote plain chat nested in the opener's Local Project group, a Local Project Session joining a GitHub group as a task row and indenting there, an unrendered opener that leaves the row in place, and a cycle that stays put.
  • Mobile: the mobile test files pass (23 files, 148 tests). New cases cover a remote chat and a GitHub child joining the opener's project bucket, the heading staying the opener's project, and a stale opener with a fresh child filed together under today's date bucket. The date assertions are time-zone independent.
  • Root pnpm typecheck passes. Type-aware oxlint on the changed files reports 0 errors. lint:effect, lint:i18n and all check:* boundary scripts, including check:public-boundary, pass. pnpm run docs check passes.
  • Not run: the full-repo type-aware lint (tsgolint was killed by SIGTERM on a 7 GB host) and the full test:ci.
  • Not verified in the running desktop app; a real cross-machine Workspace-mode check is still needed.

🤖 Generated with Claude Code

Leeeon233 and others added 2 commits October 28, 2026 13:55
…itory

A Role dispatched from a Local Project to another Machine started as a plain
chat because that Machine cannot reach the project's filesystem. When the
Local Project's observed GitHub remote is enabled in the workspace, the Role
now starts in that repository (default branch), as from a GitHub project.
An unlisted repository keeps the plain-chat placement.

Model: claude-opus-5-5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r groups

An opened Session whose opener renders in another Workspace group (for
example a cross-machine Role chat opened from a Local Project) now moves into
the opener's group so the opened-by tree can indent it. Pinned and Updated
lists keep natural membership; an opener outside the rendered groups leaves
the row where it was.

Model: claude-opus-5-5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mobile project buckets now place an opened Session in its topmost unpinned
ancestor's bucket, matching the desktop Workspace groups; a bucket's project
heading comes only from its own rows. Date buckets file a whole opened-by
tree under the day of its freshest member, the time that already ranks the
opener.

Model: claude-opus-5-5

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@lodyai
lodyai Bot marked this pull request as ready for review October 28, 2026 23:38
…al-github-project

# Conflicts:
#	packages/components/src/components/mobile/mobile-chat-list.tsx
@lodyai
lodyai Bot merged commit a6e889b into main Oct 28, 2026
15 checks passed
@lodyai
lodyai Bot deleted the feat/role-mention-local-github-project branch October 28, 2026 23:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant