pub struct ClaudeHistoryAdapter {
user_home: Option<PathBuf>,
shared_dir: Option<PathBuf>,
agentmux_home: Option<PathBuf>,
}Expand description
Where Claude homes live. The homes under them — one per account, and
channels — are listed again on every discovery (ClaudeHistoryAdapter::base_dirs),
because they are created while srv runs: an account added or switched
after srv started used to stay invisible until the next restart.
Fields§
§user_home: Option<PathBuf>The user’s home: ~/.claude and ~/.config/claude-*.
<shared>: providers/claude and identities/*.
agentmux_home: Option<PathBuf>AgentMux’s home: channels/*/identities/* and dev/…/identities/*.
Implementations§
Source§impl ClaudeHistoryAdapter
impl ClaudeHistoryAdapter
Sourcefn push_deduped_dir(
dirs: &mut Vec<PathBuf>,
seen: &mut HashSet<PathBuf>,
path: PathBuf,
)
fn push_deduped_dir( dirs: &mut Vec<PathBuf>, seen: &mut HashSet<PathBuf>, path: PathBuf, )
Push path onto dirs iff it’s a real directory AND its
canonical (symlink/junction-resolved) form hasn’t already been
pushed — the dedup key, not path itself, since two different
base_dirs entries can be different paths to the same physical
directory (a per-channel isolated projects/ junction and the
global location it points at). Falls back to the literal path
when canonicalization fails (e.g. a dangling/broken link) rather
than silently dropping it.
pub fn new() -> Self
pub(crate) fn with_roots( user_home: Option<PathBuf>, shared_dir: Option<PathBuf>, agentmux_home: Option<PathBuf>, ) -> Self
Sourcefn base_dirs(&self, problems: &mut Vec<String>) -> Vec<PathBuf>
fn base_dirs(&self, problems: &mut Vec<String>) -> Vec<PathBuf>
Every Claude projects/ directory under the roots, as the filesystem
stands now. Deduplicated by canonical (symlink/junction-resolved) path:
after Step 3 above, a per-channel isolated projects/ dir may be a
junction pointing at the exact same physical location as one of the
global <shared>/... entries, and scanning both would surface every
session twice.
Sourcefn scan_isolated_identities_under(
root: &Path,
base_dirs: &mut Vec<PathBuf>,
seen: &mut HashSet<PathBuf>,
max_depth: u8,
problems: &mut Vec<String>,
)
fn scan_isolated_identities_under( root: &Path, base_dirs: &mut Vec<PathBuf>, seen: &mut HashSet<PathBuf>, max_depth: u8, problems: &mut Vec<String>, )
Find every identities/ directory up to max_depth levels under
root, and for each, every <account_id>/claude/projects that
exists. Bounded, not an unbounded recursive walk — channel/dev
directory layouts are shallow by construction
(channels/<slug>/identities/, dev/<branch>/identities/ or
dev/<branch>/<clone_id>/identities/), so depth 2 covers every
known layout without risking an expensive filesystem walk if
something unexpected is nested underneath.
Sourcefn count_subagents(session_dir: &Path) -> u32
fn count_subagents(session_dir: &Path) -> u32
Count subagent JSONL files in a session’s subagents/ directory.
Sourcefn decode_project_path(encoded: &str) -> String
fn decode_project_path(encoded: &str) -> String
Decode a project directory name back to a path. e.g., “C–Users-user–claw-agentx-workspace” → “C:/Users/user/.claw/agentx-workspace” This is lossy — real hyphens are indistinguishable from path separators.
Sourcefn identity_id_from_path(path: &Path) -> String
fn identity_id_from_path(path: &Path) -> String
Parse the account id a session’s absolute file path was
discovered under, if any: .../identities/<account_id>/claude/...
(both the always-global <shared>/identities/... location and the
per-channel isolated <home>/channels/*/identities/... /
<home>/dev/*/(*/)?identities/... locations share this same
identities/<account_id>/claude/ shape — see new()’s scan roots).
Empty string for any other base_dir (personal ~/.claude, the
default <shared>/providers/claude/projects, legacy
~/.config/claude-*) — those have no account to attribute to.
Trait Implementations§
Source§impl HistoryAdapter for ClaudeHistoryAdapter
impl HistoryAdapter for ClaudeHistoryAdapter
Source§fn provider(&self) -> &str
fn provider(&self) -> &str
Source§fn discover_files(&self) -> Result<Vec<DiscoveredFile>, HistoryError>
fn discover_files(&self) -> Result<Vec<DiscoveredFile>, HistoryError>
Source§fn discover(&self) -> Result<Discovery, HistoryError>
fn discover(&self) -> Result<Discovery, HistoryError>
Self::discover_files, plus what the walk couldn’t read. An adapter
whose discovery can’t fail part-way keeps this default.Source§fn extract_meta(
&self,
file_path: &str,
) -> Result<Option<SessionMeta>, HistoryError>
fn extract_meta( &self, file_path: &str, ) -> Result<Option<SessionMeta>, HistoryError>
Source§fn parse_file(
&self,
file_path: &str,
) -> Result<Option<HistorySession>, HistoryError>
fn parse_file( &self, file_path: &str, ) -> Result<Option<HistorySession>, HistoryError>
Auto Trait Implementations§
impl Freeze for ClaudeHistoryAdapter
impl RefUnwindSafe for ClaudeHistoryAdapter
impl Send for ClaudeHistoryAdapter
impl Sync for ClaudeHistoryAdapter
impl Unpin for ClaudeHistoryAdapter
impl UnsafeUnpin for ClaudeHistoryAdapter
impl UnwindSafe for ClaudeHistoryAdapter
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more