[FEATURE] Projects (beta): attach a running local Claude Code session to a Project as a pseudothread
Written by Claude Opus 5.5 via Claude Code for the Claude Code maintainers; I prompted it, it did the work, I read it.
Feature category: Projects (cowork) / CLI
Priority: Medium
Follow-up to: #99156, and to https://github.com/anthropics/claude-code/issues/100714 (send messages into a Project by name or ID).
Problem statement
#99156 asks for Project threads that run as local sessions, created by the Project. This request is the reverse direction, which #99156 explicitly leaves out of scope: a local Claude Code session that I already started in my terminal, in my own checkout with my own tools, joins a Project as a thread.
Today a local session and a Project are completely separate:
- The Project can't see that the local session exists, what it's working on, or what it has produced.
- The local session can't read the project chat, project memory, or other threads.
- Anything that moves between them goes through a side channel, such as a shared folder plus a manual "go pick this up", or a raw
--cloud <session_id>message with no sender (see the companion request). - Remote Control lets the Project drive a session on my device, but the Project starts that session. I can't adopt one I'm already working in.
Proposed solution
Joining
/project join <project> # in a running local session
claude --project <project> ... # at startup
/project leave
<project>is the Project ID or a unique name, the same addressing as in the companion request.- Joining creates a pseudothread in the Project. It shows in the project chat as a thread card with a distinct marker (for example "local · laptop · homesetup-automation") and live status (working / idle / needs input / offline).
- The session stays a normal local session. I keep typing in my terminal, and permissions, tools, and hooks stay local. The Project gets a mirror and a mailbox, not control.
What flows in each direction
| Direction | What |
|---|---|
| local → Project | The thread title. Status and checklist updates (the same update_status semantics as cloud threads). Messages the local Claude chooses to post with reply. Declared outputs (files, PR links). Optionally a summary of each turn. Raw tool calls and the full transcript are not sent by default. |
| Project → local | Messages posted in the pseudothread by people or the coordinator. They arrive as a turn with sender identity (author, trust), the same envelope cloud threads get. Read-only access to the project chat, other threads, and project memory, through the same tools cloud threads have (fetch_thread, fetch_project_timeline, memory read). |
- Messages from the Project are queued while the local session is busy, delivered between turns, and never auto-approve local permission prompts.
- When the local session ends or the machine goes offline, the pseudothread shows "offline" and keeps its history. The next
/project join … --resume <thread>re-attaches the same thread.
Coordinator behaviour
- The coordinator treats a pseudothread like any other thread: it can route follow-ups to it, read it, and summarise it. It can't start or restart one. Only the local user can, by joining.
- If a message arrives for an offline pseudothread, the coordinator either queues it or tells the user that the local session is offline.
Alternative solutions considered
- #99156 (Project-created local threads): good for new work. It doesn't help with a session I'm already halfway through.
- Remote Control sessions started from a thread: the Project starts and owns them, and they report back only through cross-session messages that users can't see.
- Shared folder plus manual pickup: our current workaround. It works, but it's invisible to the Project, has no status, and needs a person to relay every message.
Use case example
- I'm debugging a deploy locally in
homesetup-automationand realise it touches a plan discussed in my homelab Project. - I run
/project join homelab. A thread card "local · homesetup · fix olares apps" appears in the project chat. - In the Project on my phone, I post in that thread: "also check the backup job". The local session picks it up after its current turn, labelled as from me via the Project.
- The local Claude posts a reply with the fix and the commit link. Its status shows "done". A cloud thread later reads that pseudothread for context.
Additional context
- Builds on: #99156 (the opposite direction), #77932 (cross-session messaging), and https://github.com/anthropics/claude-code/issues/100714 (addressing a Project by name or ID) with sender identity. Both requests need the same pieces: stable Project addressing and a sender envelope.
- Verified 2026-10-08: a cloud thread can read a local Remote Control session's transcript and
send_messageinto it. The local side can't answer the same way, and none of this is visible in the Project UI.