Documentation
¶
Overview ¶
Package session provides multi-workspace session management for Claude CLI instances.
Index ¶
- type HistoryInfo
- type Info
- type Manager
- func (m *Manager) ActivateSession(workspaceID, sessionID string) error
- func (m *Manager) CancelSessionFileWatcher(workspaceID string)
- func (m *Manager) CountActiveSessionsForWorkspace(workspaceID string) int
- func (m *Manager) DeleteHistorySession(workspaceID, sessionID string) error
- func (m *Manager) EmitPermissionResolved(sessionID, clientID, input string)
- func (m *Manager) FailSessionIDResolution(workspaceID, temporaryID, reason, message string)
- func (m *Manager) GetActiveSession(workspaceID string) string
- func (m *Manager) GetGitDiff(workspaceID string, staged bool) (string, error)
- func (m *Manager) GetGitDiffWithMeta(workspaceID string, path string) (diff string, isStaged bool, isNew bool, err error)
- func (m *Manager) GetGitEnhancedStatus(workspaceID string) (*git.EnhancedStatus, error)
- func (m *Manager) GetGitStatus(workspaceID string) (interface{}, error)
- func (m *Manager) GetLatestSessionID(workspaceID string) (string, error)
- func (m *Manager) GetSession(sessionID string) (*Session, error)
- func (m *Manager) GetSessionForWorkspace(workspaceID string) *Session
- func (m *Manager) GetSessionMessages(workspaceID, sessionID string, limit, offset int, order string) (*SessionMessagesResult, error)
- func (m *Manager) GetSessionsForWorkspace(workspaceID string) []*Session
- func (m *Manager) GetWatchedSession() *WatchInfo
- func (m *Manager) GetWorkspace(workspaceID string) (*workspace.Workspace, error)
- func (m *Manager) GitBranches(workspaceID string) (*git.BranchesResult, error)
- func (m *Manager) GitCheckout(workspaceID string, branch string, create bool) (*git.CheckoutResult, error)
- func (m *Manager) GitCommit(workspaceID string, message string, push bool) (*git.CommitResult, error)
- func (m *Manager) GitDeleteBranch(workspaceID string, branch string, force bool) (*git.DeleteBranchResult, error)
- func (m *Manager) GitDiscard(workspaceID string, paths []string) error
- func (m *Manager) GitFetch(workspaceID string, remote string, prune bool) (*git.FetchResult, error)
- func (m *Manager) GitGetStatus(workspaceID string) (*git.Status, error)
- func (m *Manager) GitInit(workspaceID string, initialBranch string, initialCommit bool, ...) (*git.InitResult, error)
- func (m *Manager) GitLog(workspaceID string, limit int, skip int, branch string, path string, ...) (*git.LogResult, error)
- func (m *Manager) GitMerge(workspaceID string, branch string, noFastForward bool, message string) (*git.MergeResult, error)
- func (m *Manager) GitMergeAbort(workspaceID string) (*git.MergeResult, error)
- func (m *Manager) GitPull(workspaceID string, rebase bool) (*git.PullResult, error)
- func (m *Manager) GitPush(workspaceID string, force bool, setUpstream bool, remote, branch string) (*git.PushResult, error)
- func (m *Manager) GitRemoteAdd(workspaceID string, name string, url string, fetch bool) (*git.RemoteAddResult, error)
- func (m *Manager) GitRemoteList(workspaceID string) (*git.RemoteListResult, error)
- func (m *Manager) GitRemoteRemove(workspaceID string, name string) (*git.RemoteRemoveResult, error)
- func (m *Manager) GitSetUpstream(workspaceID string, branch string, upstream string) (*git.SetUpstreamResult, error)
- func (m *Manager) GitStage(workspaceID string, paths []string) error
- func (m *Manager) GitStash(workspaceID string, message string, includeUntracked bool) (*git.StashResult, error)
- func (m *Manager) GitStashApply(workspaceID string, index int) (*git.StashResult, error)
- func (m *Manager) GitStashDrop(workspaceID string, index int) (*git.StashResult, error)
- func (m *Manager) GitStashList(workspaceID string) (*git.StashListResult, error)
- func (m *Manager) GitStashPop(workspaceID string, index int) (*git.StashResult, error)
- func (m *Manager) GitUnstage(workspaceID string, paths []string) error
- func (m *Manager) HasActiveSessionFileWatcher(workspaceID string) bool
- func (m *Manager) ListHistory(workspaceID string, limit int) ([]HistoryInfo, error)
- func (m *Manager) ListSessions(workspaceID string) []*Info
- func (m *Manager) ListWorkspaces() []*workspace.Workspace
- func (m *Manager) OnClientDisconnect(clientID string, subscribedWorkspaces []string)
- func (m *Manager) PublishEvent(event *events.BaseEvent)
- func (m *Manager) RegisterWorkspace(ws *workspace.Workspace)
- func (m *Manager) RespondToPermission(sessionID string, allow bool) error
- func (m *Manager) RespondToQuestion(sessionID string, response string) error
- func (m *Manager) SendInput(sessionID string, input string) error
- func (m *Manager) SendKey(sessionID string, key string) error
- func (m *Manager) SendPrompt(sessionID string, prompt string, mode string, permissionMode string, ...) error
- func (m *Manager) SessionFileExists(workspaceID string, sessionID string) (bool, error)
- func (m *Manager) SetGitTrackerManager(gtm *workspace.GitTrackerManager)
- func (m *Manager) SetLiveSessionSupport(workspacePath string)
- func (m *Manager) Start() error
- func (m *Manager) StartGitWatcher(workspaceID string) error
- func (m *Manager) StartSession(workspaceID string) (*Session, error)
- func (m *Manager) Stop() error
- func (m *Manager) StopGitWatcher(workspaceID string)
- func (m *Manager) StopSession(sessionID string) error
- func (m *Manager) UnregisterWorkspace(workspaceID string) error
- func (m *Manager) UnwatchWorkspaceSession(clientID string, sessionID string) *WatchInfo
- func (m *Manager) WatchForNewSessionFile(ctx context.Context, workspaceID, temporaryID, repoPath string)
- func (m *Manager) WatchWorkspaceSession(clientID, workspaceID, sessionID string) (*WatchInfo, error)
- type RuntimeState
- type Session
- func (s *Session) ClaudeManager() *claude.Manager
- func (s *Session) FileWatcher() *watcher.Watcher
- func (s *Session) GetID() string
- func (s *Session) GetLastActive() time.Time
- func (s *Session) GetStatus() Status
- func (s *Session) GitTracker() *git.Tracker
- func (s *Session) SetClaudeManager(m *claude.Manager)
- func (s *Session) SetError(err error)
- func (s *Session) SetFileWatcher(w *watcher.Watcher)
- func (s *Session) SetGitTracker(t *git.Tracker)
- func (s *Session) SetSessionID(newID string)
- func (s *Session) SetStatus(status Status)
- func (s *Session) ToInfo() *Info
- func (s *Session) ToRuntimeState() *RuntimeState
- func (s *Session) UpdateLastActive()
- type SessionMessage
- type SessionMessagesResult
- type Status
- type WatchInfo
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type HistoryInfo ¶
type HistoryInfo struct {
SessionID string `json:"session_id"`
Summary string `json:"summary"`
MessageCount int `json:"message_count"`
LastUpdated time.Time `json:"last_updated"`
Branch string `json:"branch,omitempty"`
}
HistoryInfo represents historical session information from the session cache.
type Info ¶
type Info struct {
ID string `json:"id"`
WorkspaceID string `json:"workspace_id"`
Status Status `json:"status"`
StartedAt time.Time `json:"started_at"`
LastActive time.Time `json:"last_active"`
Error string `json:"error,omitempty"`
// Viewers is the list of client IDs currently viewing this session.
// Populated by workspace/list when session focus info is available.
Viewers []string `json:"viewers,omitempty"`
}
Info is a serializable representation of a session.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager orchestrates multiple Claude sessions across workspaces.
func NewManager ¶
NewManager creates a new session manager.
func (*Manager) ActivateSession ¶
ActivateSession sets the active session for a workspace. This allows iOS clients to switch which session they are viewing/interacting with. Multiple clients can have different active sessions for the same workspace.
func (*Manager) CancelSessionFileWatcher ¶
CancelSessionFileWatcher cancels an active session file watcher for a workspace. Called when a session is stopped or workspace is removed. Does NOT emit any event - use FailSessionIDResolution if you need to emit an event.
func (*Manager) CountActiveSessionsForWorkspace ¶
CountActiveSessionsForWorkspace returns the count of active sessions for a workspace.
func (*Manager) DeleteHistorySession ¶
DeleteHistorySession deletes a historical Claude session file. This removes the .jsonl file from ~/.claude/projects/<encoded-path>/
func (*Manager) EmitPermissionResolved ¶
EmitPermissionResolved broadcasts a pty_permission_resolved event to all devices. This is called when one device responds to a permission prompt, so other devices can dismiss their permission popup.
func (*Manager) FailSessionIDResolution ¶
FailSessionIDResolution cancels the session file watcher and emits a session_id_failed event. Called when Claude exits without creating a session (e.g., user declined trust folder). Parameters:
- workspaceID: The workspace ID
- temporaryID: The temporary session ID that was waiting for resolution
- reason: "trust_declined", "claude_exited", or "error"
- message: Optional human-readable message
func (*Manager) GetActiveSession ¶
GetActiveSession returns the active session ID for a workspace. Returns empty string if no session is explicitly activated.
func (*Manager) GetGitDiff ¶
GetGitDiff returns git diff for a workspace. If staged is true, returns staged changes; otherwise returns unstaged changes.
func (*Manager) GetGitDiffWithMeta ¶
func (m *Manager) GetGitDiffWithMeta(workspaceID string, path string) (diff string, isStaged bool, isNew bool, err error)
GetGitDiffWithMeta returns git diff with metadata (isStaged, isNew). This matches the git/diff response format.
func (*Manager) GetGitEnhancedStatus ¶
func (m *Manager) GetGitEnhancedStatus(workspaceID string) (*git.EnhancedStatus, error)
GetGitEnhancedStatus returns enhanced git status for a workspace.
func (*Manager) GetGitStatus ¶
GetGitStatus returns git status for a workspace.
func (*Manager) GetLatestSessionID ¶
GetLatestSessionID returns the most recently modified session ID from .claude/projects. This is the source of truth for Claude Code sessions. Only returns main sessions (UUID-formatted files with user interaction), not agent sub-sessions.
func (*Manager) GetSession ¶
GetSession returns a session by ID.
func (*Manager) GetSessionForWorkspace ¶
GetSessionForWorkspace returns the first active session for a workspace (if any). Used for operations that need any session (e.g., git operations).
func (*Manager) GetSessionMessages ¶
func (m *Manager) GetSessionMessages(workspaceID, sessionID string, limit, offset int, order string) (*SessionMessagesResult, error)
GetSessionMessages returns messages from a historical Claude session. This reads from the Claude session files at ~/.claude/projects/<encoded-path>
func (*Manager) GetSessionsForWorkspace ¶
GetSessionsForWorkspace returns all sessions for a workspace.
func (*Manager) GetWatchedSession ¶
GetWatchedSession returns information about the currently watched session.
func (*Manager) GetWorkspace ¶
GetWorkspace returns a workspace by ID.
func (*Manager) GitBranches ¶
func (m *Manager) GitBranches(workspaceID string) (*git.BranchesResult, error)
GitBranches lists branches for a workspace.
func (*Manager) GitCheckout ¶
func (m *Manager) GitCheckout(workspaceID string, branch string, create bool) (*git.CheckoutResult, error)
GitCheckout checks out a branch for a workspace.
func (*Manager) GitCommit ¶
func (m *Manager) GitCommit(workspaceID string, message string, push bool) (*git.CommitResult, error)
GitCommit commits staged changes for a workspace.
func (*Manager) GitDeleteBranch ¶
func (m *Manager) GitDeleteBranch(workspaceID string, branch string, force bool) (*git.DeleteBranchResult, error)
GitDeleteBranch deletes a branch for a workspace.
func (*Manager) GitDiscard ¶
GitDiscard discards changes for a workspace.
func (*Manager) GitGetStatus ¶
GitGetStatus returns the comprehensive git status for a workspace.
func (*Manager) GitInit ¶
func (m *Manager) GitInit(workspaceID string, initialBranch string, initialCommit bool, commitMessage string) (*git.InitResult, error)
GitInit initializes a git repository for a workspace. This method works on non-git directories to initialize them.
func (*Manager) GitLog ¶
func (m *Manager) GitLog(workspaceID string, limit int, skip int, branch string, path string, graph bool) (*git.LogResult, error)
GitLog returns the commit log for a workspace.
func (*Manager) GitMerge ¶
func (m *Manager) GitMerge(workspaceID string, branch string, noFastForward bool, message string) (*git.MergeResult, error)
GitMerge merges a branch for a workspace.
func (*Manager) GitMergeAbort ¶
func (m *Manager) GitMergeAbort(workspaceID string) (*git.MergeResult, error)
GitMergeAbort aborts a merge for a workspace.
func (*Manager) GitPush ¶
func (m *Manager) GitPush(workspaceID string, force bool, setUpstream bool, remote, branch string) (*git.PushResult, error)
GitPush pushes commits to remote for a workspace.
func (*Manager) GitRemoteAdd ¶
func (m *Manager) GitRemoteAdd(workspaceID string, name string, url string, fetch bool) (*git.RemoteAddResult, error)
GitRemoteAdd adds a remote to a workspace.
func (*Manager) GitRemoteList ¶
func (m *Manager) GitRemoteList(workspaceID string) (*git.RemoteListResult, error)
GitRemoteList lists remotes for a workspace.
func (*Manager) GitRemoteRemove ¶
GitRemoteRemove removes a remote from a workspace.
func (*Manager) GitSetUpstream ¶
func (m *Manager) GitSetUpstream(workspaceID string, branch string, upstream string) (*git.SetUpstreamResult, error)
GitSetUpstream sets the upstream for a branch.
func (*Manager) GitStash ¶
func (m *Manager) GitStash(workspaceID string, message string, includeUntracked bool) (*git.StashResult, error)
GitStash creates a stash for a workspace.
func (*Manager) GitStashApply ¶
GitStashApply applies a stash for a workspace.
func (*Manager) GitStashDrop ¶
GitStashDrop drops a stash for a workspace.
func (*Manager) GitStashList ¶
func (m *Manager) GitStashList(workspaceID string) (*git.StashListResult, error)
GitStashList lists stashes for a workspace.
func (*Manager) GitStashPop ¶
GitStashPop pops a stash for a workspace.
func (*Manager) GitUnstage ¶
GitUnstage unstages files for a workspace.
func (*Manager) HasActiveSessionFileWatcher ¶
HasActiveSessionFileWatcher returns true if there's an active watcher for the workspace.
func (*Manager) ListHistory ¶
func (m *Manager) ListHistory(workspaceID string, limit int) ([]HistoryInfo, error)
ListHistory returns historical Claude sessions for a workspace. This reads from the Claude session cache at ~/.claude/projects/<encoded-path>
func (*Manager) ListSessions ¶
ListSessions returns all sessions, optionally filtered by workspace.
func (*Manager) ListWorkspaces ¶
ListWorkspaces returns all registered workspaces.
func (*Manager) OnClientDisconnect ¶
OnClientDisconnect handles cleanup when a client disconnects. This is called by the unified server when a WebSocket connection is closed. It decrements git watcher counts and session streamer counts for the disconnected client.
func (*Manager) PublishEvent ¶
PublishEvent publishes an event to the hub. Used by RPC handlers to emit events.
func (*Manager) RegisterWorkspace ¶
RegisterWorkspace registers a workspace with the manager.
func (*Manager) RespondToPermission ¶
RespondToPermission responds to a permission request in a session.
func (*Manager) RespondToQuestion ¶
RespondToQuestion responds to an interactive question in a session.
func (*Manager) SendInput ¶
SendInput sends input to a session's Claude PTY (for interactive responses). Supports both managed sessions (started by cdev) and LIVE sessions (user's terminal). This is used to respond to permission prompts when running in interactive mode.
func (*Manager) SendKey ¶
SendKey sends a special key (like arrow keys, enter, escape) to a session. For LIVE sessions, uses platform-specific key code injection instead of text keystroke.
func (*Manager) SendPrompt ¶
func (m *Manager) SendPrompt(sessionID string, prompt string, mode string, permissionMode string, yoloMode bool) error
SendPrompt sends a prompt to a session's Claude instance. Supports both managed sessions (started by cdev) and LIVE sessions (user's terminal). permissionMode controls how Claude handles permissions: - "default": Standard permission prompts (may hang if stdin is closed) - "acceptEdits": Auto-accept file edits - "bypassPermissions": Skip all permission checks - "plan": Plan mode only - "interactive": Use PTY mode for true interactive permission handling yoloMode is runtime-agnostic bypass intent (mapped to runtime-specific flags when supported).
func (*Manager) SessionFileExists ¶
SessionFileExists checks if a session file exists in .claude/projects for the workspace. This validates against the source of truth for Claude Code sessions.
func (*Manager) SetGitTrackerManager ¶
func (m *Manager) SetGitTrackerManager(gtm *workspace.GitTrackerManager)
SetGitTrackerManager sets the shared git tracker manager.
func (*Manager) SetLiveSessionSupport ¶
SetLiveSessionSupport enables LIVE session support. This allows sending messages to Claude instances running in the user's terminal. The detector is created dynamically per workspace, but the injector is shared.
func (*Manager) StartGitWatcher ¶
StartGitWatcher starts watching git state changes for a workspace. This is called when a client subscribes to a workspace (workspace/subscribe). The watcher emits git_status_changed events when staging/commits/branch changes occur. Uses reference counting - multiple clients can subscribe, watcher starts on first subscriber. Returns nil if git is disabled.
func (*Manager) StartSession ¶
StartSession starts a new Claude session for a workspace. It automatically uses the most recent historical session ID from ~/.claude/projects/ so that session/send with mode "continue" will properly resume the conversation.
func (*Manager) StopGitWatcher ¶
StopGitWatcher decrements the subscriber count for a workspace's git watcher. The watcher is only stopped when the last subscriber unsubscribes. This is called when a client unsubscribes from a workspace (workspace/unsubscribe).
func (*Manager) StopSession ¶
StopSession stops a running session. For managed sessions (started via cdev), this stops the Claude process. For LIVE sessions (watched but not started by cdev), this unwatches and clears active status.
func (*Manager) UnregisterWorkspace ¶
UnregisterWorkspace removes a workspace from the manager.
func (*Manager) UnwatchWorkspaceSession ¶
UnwatchWorkspaceSession stops watching a session for one client. The streamer continues running until all clients have stopped watching. If sessionID is empty, one watched session is removed deterministically for backward compatibility.
func (*Manager) WatchForNewSessionFile ¶
func (m *Manager) WatchForNewSessionFile(ctx context.Context, workspaceID, temporaryID, repoPath string)
WatchForNewSessionFile watches the .claude/projects directory for new session files. When a new .jsonl file is created (after trust folder is accepted), it emits a session_id_resolved event with the real session ID from Claude.
Thread-safety: Only one watcher per workspace is allowed. If a watcher already exists for this workspace, this call is a no-op. The watcher is automatically cleaned up on completion, timeout, or cancellation.
func (*Manager) WatchWorkspaceSession ¶
func (m *Manager) WatchWorkspaceSession(clientID, workspaceID, sessionID string) (*WatchInfo, error)
WatchWorkspaceSession starts watching a session file for live message updates. This is used by iOS to receive real-time claude_message events when new messages are added to the session file.
Multiple clients can watch the same session. The streamer uses client tracking to keep watching until the last client stops watching. The clientID parameter identifies the client making this request.
type RuntimeState ¶
type RuntimeState struct {
// Session info
ID string `json:"id"`
WorkspaceID string `json:"workspace_id"`
Status Status `json:"status"`
StartedAt time.Time `json:"started_at"`
LastActive time.Time `json:"last_active"`
Error string `json:"error,omitempty"`
// Claude state
ClaudeState string `json:"claude_state"` // idle, running, error, waiting
ClaudeSessionID string `json:"claude_session_id"` // For conversation continuity
IsRunning bool `json:"is_running"` // Is Claude process running
WaitingForInput bool `json:"waiting_for_input"` // Is Claude waiting for user input
PendingToolUseID string `json:"pending_tool_use_id,omitempty"`
PendingToolName string `json:"pending_tool_name,omitempty"`
}
RuntimeState contains the current runtime state of a session for reconnection sync.
type Session ¶
type Session struct {
ID string `json:"id"`
WorkspaceID string `json:"workspace_id"`
Status Status `json:"status"`
StartedAt time.Time `json:"started_at"`
LastActive time.Time `json:"last_active"`
Error string `json:"error,omitempty"`
// contains filtered or unexported fields
}
Session represents an active Claude CLI instance for a workspace.
func NewSession ¶
NewSession creates a new session for a workspace.
func (*Session) ClaudeManager ¶
ClaudeManager returns the Claude manager for this session.
func (*Session) FileWatcher ¶
FileWatcher returns the file watcher for this session.
func (*Session) GetLastActive ¶
GetLastActive returns the last active timestamp.
func (*Session) GitTracker ¶
GitTracker returns the git tracker for this session.
func (*Session) SetClaudeManager ¶
SetClaudeManager sets the Claude manager for this session.
func (*Session) SetFileWatcher ¶
SetFileWatcher sets the file watcher for this session.
func (*Session) SetGitTracker ¶
SetGitTracker sets the git tracker for this session.
func (*Session) SetSessionID ¶
SetSessionID updates the session ID (thread-safe). This is used when the real session ID is detected from Claude. Also updates the ClaudeManager's session ID if present.
func (*Session) ToRuntimeState ¶
func (s *Session) ToRuntimeState() *RuntimeState
ToRuntimeState returns the current runtime state for reconnection sync.
func (*Session) UpdateLastActive ¶
func (s *Session) UpdateLastActive()
UpdateLastActive updates the last active timestamp.
type SessionMessage ¶
type SessionMessage struct {
ID int64 `json:"id"`
SessionID string `json:"session_id"`
Type string `json:"type"`
UUID string `json:"uuid,omitempty"`
Timestamp string `json:"timestamp,omitempty"`
GitBranch string `json:"git_branch,omitempty"`
Message json.RawMessage `json:"message"`
// IsContextCompaction is true when this is an auto-generated message
// created by Claude Code when the context window was maxed out.
IsContextCompaction bool `json:"is_context_compaction,omitempty"`
// IsMeta is true for system-generated metadata messages (e.g., command caveats).
IsMeta bool `json:"is_meta,omitempty"`
}
SessionMessage represents a message from a Claude session. This struct matches the format in methods.SessionMessage for consistency.
type SessionMessagesResult ¶
type SessionMessagesResult struct {
SessionID string `json:"session_id"`
Messages []SessionMessage `json:"messages"`
Total int `json:"total"`
Limit int `json:"limit"`
Offset int `json:"offset"`
HasMore bool `json:"has_more"`
QueryTimeMs float64 `json:"query_time_ms"`
}
SessionMessagesResult represents the result of GetSessionMessages.