Skip to content

Commit 2a8623f

Browse files
committed
chore: bump version to 0.15.1
- Claim defaults to stream mode instead of template - Refactor route.rs: extract send_command/find_target_pane, add [route] logging
1 parent 11fe70b commit 2a8623f

File tree

5 files changed

+53
-70
lines changed

5 files changed

+53
-70
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "agent-doc"
3-
version = "0.15.0"
3+
version = "0.15.1"
44
edition = "2024"
55
description = "Interactive document sessions with AI agents"
66
license = "MIT"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "maturin"
44

55
[project]
66
name = "agent-doc"
7-
version = "0.15.0"
7+
version = "0.15.1"
88
description = "Interactive document sessions with AI agents"
99
readme = "README.md"
1010
license = "MIT"

src/claim.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,17 @@ pub fn run(file: &Path, position: Option<&str>, pane: Option<&str>, window: Opti
8787
}
8888
}
8989

90-
// Default to template mode if agent_doc_mode is not set
90+
// Default to stream mode if agent_doc_mode is not set
9191
{
9292
let content = std::fs::read_to_string(file)
9393
.with_context(|| format!("failed to read {}", file.display()))?;
9494
let (fm, _) = frontmatter::parse(&content)?;
9595
if fm.mode.is_none() {
96-
let updated = frontmatter::set_mode(&content, "template")?;
96+
let updated = frontmatter::set_mode(&content, "stream")?;
9797
if updated != content {
9898
std::fs::write(file, &updated)
9999
.with_context(|| format!("failed to write agent_doc_mode to {}", file.display()))?;
100-
eprintln!("set agent_doc_mode=template in {}", file.display());
100+
eprintln!("set agent_doc_mode=stream in {}", file.display());
101101
}
102102
}
103103
}

src/route.rs

Lines changed: 47 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -35,85 +35,68 @@ pub fn run_with_tmux(file: &Path, tmux: &Tmux, pane: Option<&str>) -> Result<()>
3535
if updated_content != content {
3636
std::fs::write(file, &updated_content)
3737
.with_context(|| format!("failed to write {}", file.display()))?;
38-
eprintln!("Generated session UUID: {}", session_id);
38+
eprintln!("[route] Generated session UUID: {}", session_id);
3939
}
4040

41-
// Compute the file path to send (relative to cwd)
4241
let file_path = file.to_string_lossy();
43-
44-
// Look up pane for this session
4542
let registered = sessions::lookup(&session_id)?;
4643

44+
// Step 1: Check if registered pane is alive
4745
if let Some(ref registered_pane) = registered {
4846
if tmux.pane_alive(registered_pane) {
49-
// Pane is alive — send the command
50-
let command = format!("/agent-doc {}", file_path);
51-
tmux.send_keys(registered_pane, &command)?;
52-
if let Err(e) = tmux.select_pane(registered_pane) {
53-
eprintln!("warning: failed to focus pane {}: {}", registered_pane, e);
54-
}
55-
eprintln!("Sent /agent-doc {} → pane {}", file_path, registered_pane);
56-
return Ok(());
57-
}
58-
// Pane is dead — try lazy claim
59-
let target_pane = pane
60-
.map(|p| p.to_string())
61-
.or_else(|| tmux.active_pane(TMUX_SESSION_NAME));
62-
if let Some(new_pane) = target_pane
63-
&& tmux.pane_alive(&new_pane)
64-
{
65-
eprintln!(
66-
"Pane {} is dead, lazy-claiming to pane {}",
67-
registered_pane, new_pane
68-
);
69-
sessions::register(&session_id, &new_pane, &file_path)?;
70-
let command = format!("/agent-doc {}", file_path);
71-
tmux.send_keys(&new_pane, &command)?;
72-
if let Err(e) = tmux.select_pane(&new_pane) {
73-
eprintln!("warning: failed to focus pane {}: {}", new_pane, e);
74-
}
75-
eprintln!("Sent /agent-doc {} → pane {}", file_path, new_pane);
76-
sync_after_claim(tmux, &new_pane);
77-
return Ok(());
47+
eprintln!("[route] Pane {} is alive", registered_pane);
48+
return send_command(tmux, registered_pane, &file_path);
7849
}
79-
eprintln!("Pane {} is dead, auto-starting...", registered_pane);
50+
eprintln!("[route] Pane {} is dead", registered_pane);
8051
} else {
81-
// No registered pane — try lazy claim
82-
let target_pane = pane
83-
.map(|p| p.to_string())
84-
.or_else(|| tmux.active_pane(TMUX_SESSION_NAME));
85-
if let Some(new_pane) = target_pane
86-
&& tmux.pane_alive(&new_pane)
87-
{
88-
eprintln!(
89-
"No pane registered for session {}, lazy-claiming to pane {}",
90-
&session_id[..std::cmp::min(8, session_id.len())],
91-
new_pane
92-
);
93-
sessions::register(&session_id, &new_pane, &file_path)?;
94-
let command = format!("/agent-doc {}", file_path);
95-
tmux.send_keys(&new_pane, &command)?;
96-
if let Err(e) = tmux.select_pane(&new_pane) {
97-
eprintln!("warning: failed to focus pane {}: {}", new_pane, e);
98-
}
99-
eprintln!("Sent /agent-doc {} → pane {}", file_path, new_pane);
100-
sync_after_claim(tmux, &new_pane);
101-
return Ok(());
102-
}
10352
eprintln!(
104-
"No pane registered for session {}, auto-starting...",
53+
"[route] No pane registered for session {}",
10554
&session_id[..std::cmp::min(8, session_id.len())]
10655
);
10756
}
10857

109-
// Auto-start cascade (can be disabled for testing)
58+
// Step 2: Try lazy claim to an active pane
59+
if let Some(new_pane) = find_target_pane(tmux, pane) {
60+
let reason = if registered.is_some() {
61+
"dead pane"
62+
} else {
63+
"no registration"
64+
};
65+
eprintln!("[route] Lazy-claiming to pane {} ({})", new_pane, reason);
66+
sessions::register(&session_id, &new_pane, &file_path)?;
67+
send_command(tmux, &new_pane, &file_path)?;
68+
sync_after_claim(tmux, &new_pane);
69+
return Ok(());
70+
}
71+
72+
// Step 3: Auto-start a new Claude session
73+
eprintln!("[route] No active pane found, auto-starting...");
11074
if std::env::var("AGENT_DOC_NO_AUTOSTART").is_ok() {
11175
anyhow::bail!("auto-start skipped (AGENT_DOC_NO_AUTOSTART set)");
11276
}
11377
auto_start(tmux, file, &session_id, &file_path)?;
11478
Ok(())
11579
}
11680

81+
/// Send `/agent-doc <file>` to a pane and focus it.
82+
fn send_command(tmux: &Tmux, pane: &str, file_path: &str) -> Result<()> {
83+
let command = format!("/agent-doc {}", file_path);
84+
tmux.send_keys(pane, &command)?;
85+
if let Err(e) = tmux.select_pane(pane) {
86+
eprintln!("[route] warning: failed to focus pane {}: {}", pane, e);
87+
}
88+
eprintln!("[route] Sent /agent-doc {} → pane {}", file_path, pane);
89+
Ok(())
90+
}
91+
92+
/// Find an active target pane for lazy claiming.
93+
fn find_target_pane(tmux: &Tmux, explicit_pane: Option<&str>) -> Option<String> {
94+
let target = explicit_pane
95+
.map(|p| p.to_string())
96+
.or_else(|| tmux.active_pane(TMUX_SESSION_NAME));
97+
target.filter(|p| tmux.pane_alive(p))
98+
}
99+
117100
/// Auto-start a new Claude session in tmux.
118101
///
119102
/// Cascade:
@@ -138,7 +121,7 @@ fn auto_start(tmux: &Tmux, file: &Path, session_id: &str, file_path: &str) -> Re
138121
&& active != new_pane
139122
&& let Err(e) = tmux.join_pane(&new_pane, &active, "-dh")
140123
{
141-
eprintln!("warning: join_pane failed ({} → {}): {}", new_pane, active, e);
124+
eprintln!("[route] warning: join_pane failed ({} → {}): {}", new_pane, active, e);
142125
}
143126

144127
// Register immediately so subsequent route calls find this pane
@@ -149,13 +132,13 @@ fn auto_start(tmux: &Tmux, file: &Path, session_id: &str, file_path: &str) -> Re
149132
tmux.send_keys(&new_pane, &start_cmd)?;
150133

151134
eprintln!(
152-
"Started Claude for {} in pane {} (session {})",
135+
"[route] Started Claude for {} in pane {} (session {})",
153136
file_path,
154137
new_pane,
155138
&session_id[..std::cmp::min(8, session_id.len())]
156139
);
157140
eprintln!(
158-
"Wait for Claude to start, then run `agent-doc route {}` again to send the command.",
141+
"[route] Wait for Claude to start, then run `agent-doc route {}` again to send the command.",
159142
file_path
160143
);
161144

@@ -191,14 +174,14 @@ fn sync_after_claim(tmux: &Tmux, pane_id: &str) {
191174
.collect();
192175

193176
if window_files.len() < 2 {
194-
return; // Single file — no layout sync needed
177+
return; // 0 or 1 files — no layout sync needed
195178
}
196179

197180
// Call sync with all files as a single column
198181
let col_args = vec![window_files.join(",")];
199182
if let Err(e) = sync::run(&col_args, Some(&window_id), None) {
200-
eprintln!("warning: post-claim sync failed: {}", e);
183+
eprintln!("[route] warning: post-claim sync failed: {}", e);
201184
} else {
202-
eprintln!("Auto-synced {} files in window {}", window_files.len(), window_id);
185+
eprintln!("[route] Auto-synced {} files in window {}", window_files.len(), window_id);
203186
}
204187
}

0 commit comments

Comments
 (0)