1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// SPDX-FileCopyrightText: 2026 Andrei G <bug-ops>
// SPDX-License-Identifier: MIT OR Apache-2.0
//! [`WorktreeAccess`] — command handler access to the live session's git worktree manager
//! and the session working directory.
use std::future::Future;
use std::pin::Pin;
use crate::CommandError;
/// Access to `/worktree` and `/cd`.
///
/// Implemented by `zeph-core::Agent<C>`. Part of the [`crate::AgentAccess`] supertrait.
pub trait WorktreeAccess {
// ----- /worktree -----
/// Return a formatted list of active and stale git worktrees tracked by the live
/// session's worktree manager, or `None` when the worktree subsystem is disabled.
///
/// Used by `/worktree` and `/worktree list`.
///
/// # Errors
///
/// Returns `Err` when the underlying git reconciliation fails.
fn list_worktrees<'a>(
&'a mut self,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, CommandError>> + Send + 'a>> {
Box::pin(async { Ok(None) })
}
/// Remove stale worktrees tracked by the live session's worktree manager.
///
/// `force` mirrors `zeph worktree clean --force`: also removes worktrees whose
/// directory git does not report as prunable. Returns `None` when the worktree
/// subsystem is disabled.
///
/// Used by `/worktree clean`.
///
/// # Errors
///
/// Returns `Err` when the underlying git reconciliation or registry pruning fails.
fn clean_worktrees<'a>(
&'a mut self,
force: bool,
) -> Pin<Box<dyn Future<Output = Result<Option<String>, CommandError>> + Send + 'a>> {
let _ = force;
Box::pin(async { Ok(None) })
}
// ----- /cd -----
/// Change the session's primary working directory, or report the current one when
/// `path` is empty (#6032, FR-009).
///
/// Reuses `zeph_tools::resolve_and_set_cwd` — the same path-resolution logic the
/// LLM-invoked `set_working_directory` tool uses — then runs the agent's
/// `check_cwd_changed` post-change pipeline (repo-map invalidation, `cwd_changed` hooks,
/// and — unless the session is in `--safe-mode` — CLAUDE.md/AGENTS.md instruction
/// re-discovery). `/cd` is an additive user-facing entry point into that existing
/// mechanism, not a parallel implementation.
///
/// Returns a confirmation string with the new (or current) absolute working directory.
///
/// # Errors
///
/// Returns `Err` when `path` does not resolve to an existing, readable directory.
fn change_working_directory<'a>(
&'a mut self,
path: &'a str,
) -> Pin<Box<dyn Future<Output = Result<String, CommandError>> + Send + 'a>> {
let _ = path;
Box::pin(async move { Err(CommandError::new("/cd is not supported in this context")) })
}
}