Skip to content

Commit 0c6e125

Browse files
committed
refactor(terminal-gateway): route send_input via terminal_write
- Replace tmux_session_name + tmux_pane_id fields with terminal_id: u64 in GatewayTerminalRuntime - send_input now calls terminal::terminal_write instead of tmux::send_tmux_raw_input, bridging via the terminal_id - session_runtime_liveness_for_binding checks state.terminals for presence instead of calling tmux_session_exists - All call sites updated to pass terminal_id (the real terminal.id from create_terminal_runtime, or a dummy value in test code) - send_input_marks_bound_session_running test asserts terminal_write_log contains the sent input
1 parent ac74aa2 commit 0c6e125

5 files changed

Lines changed: 50 additions & 57 deletions

File tree

apps/server/src/services/session_runtime.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,7 @@ pub(crate) fn session_runtime_start(
421421
params.workspace_id.clone(),
422422
params.session_id.clone(),
423423
session.provider.as_str().to_string(),
424-
tmux_runtime.session_name.clone(),
425-
tmux_runtime.pane_id.clone(),
424+
terminal.id,
426425
);
427426
state
428427
.terminal_runtimes
@@ -545,8 +544,7 @@ mod tests {
545544
"ws-1".to_string(),
546545
"session-1".to_string(),
547546
"claude".to_string(),
548-
String::new(),
549-
String::new(),
547+
0,
550548
));
551549
drop(registry);
552550

apps/server/src/services/terminal_gateway.rs

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ pub(crate) struct GatewayTerminalRuntime {
99
pub(crate) workspace_id: String,
1010
pub(crate) session_id: String,
1111
pub(crate) provider: String,
12-
pub(crate) tmux_session_name: String,
13-
pub(crate) tmux_pane_id: String,
12+
pub(crate) terminal_id: u64,
1413
}
1514

1615
pub(crate) type TerminalRuntime = GatewayTerminalRuntime;
@@ -21,16 +20,14 @@ impl GatewayTerminalRuntime {
2120
workspace_id: String,
2221
session_id: String,
2322
provider: String,
24-
tmux_session_name: String,
25-
tmux_pane_id: String,
23+
terminal_id: u64,
2624
) -> Self {
2725
Self {
2826
runtime_id,
2927
workspace_id,
3028
session_id,
3129
provider,
32-
tmux_session_name,
33-
tmux_pane_id,
30+
terminal_id,
3431
}
3532
}
3633
}
@@ -95,33 +92,23 @@ pub(crate) fn send_input(
9592
.cloned()
9693
.ok_or_else(|| "terminal_runtime_not_found".to_string())?;
9794

98-
#[cfg(test)]
99-
{
100-
let _ = input;
101-
let _ = sync_session_runtime_state(
102-
state,
103-
&runtime.workspace_id,
104-
&runtime.session_id,
105-
SessionStatus::Running,
106-
true,
107-
Some(SessionRuntimeLiveness::Attached),
108-
);
109-
return Ok(());
110-
}
111-
112-
#[cfg(not(test))]
113-
{
114-
crate::services::tmux::send_tmux_raw_input(&runtime.tmux_session_name, input)?;
115-
let _ = sync_session_runtime_state(
116-
state,
117-
&runtime.workspace_id,
118-
&runtime.session_id,
119-
SessionStatus::Running,
120-
true,
121-
Some(SessionRuntimeLiveness::Attached),
122-
);
123-
Ok(())
124-
}
95+
crate::services::terminal::terminal_write(
96+
runtime.workspace_id.clone(),
97+
runtime.terminal_id,
98+
input.to_string(),
99+
crate::TerminalWriteOrigin::User,
100+
state,
101+
)?;
102+
103+
let _ = sync_session_runtime_state(
104+
state,
105+
&runtime.workspace_id,
106+
&runtime.session_id,
107+
SessionStatus::Running,
108+
true,
109+
Some(SessionRuntimeLiveness::Attached),
110+
);
111+
Ok(())
125112
}
126113

127114
pub(crate) fn emit_terminal_channel_output(app: &AppHandle, runtime_id: &str, data: &str) {
@@ -135,7 +122,7 @@ mod tests {
135122
use crate::services::workspace::resolve_session_for_slot;
136123
use crate::{
137124
create_session, default_idle_policy, init_db, launch_workspace_record, AgentProvider,
138-
ExecTarget, SessionMode, WorkspaceSource, WorkspaceSourceKind,
125+
ExecTarget, SessionMode, TerminalWriteOrigin, WorkspaceSource, WorkspaceSourceKind,
139126
};
140127

141128
fn test_app() -> AppHandle {
@@ -167,8 +154,7 @@ mod tests {
167154
workspace_id.to_string(),
168155
session_id.to_string(),
169156
"claude".to_string(),
170-
format!("coder-studio-{workspace_id}-{session_id}"),
171-
"%1".to_string(),
157+
0,
172158
)
173159
}
174160

@@ -233,14 +219,14 @@ mod tests {
233219
app.state(),
234220
)
235221
.unwrap();
222+
let terminal_id = 42u64;
236223
app.state().terminal_runtimes.lock().unwrap().insert(
237224
TerminalRuntime::new(
238225
"runtime-1".to_string(),
239226
workspace_id.clone(),
240227
created.id.clone(),
241228
"claude".to_string(),
242-
"tmux-session-1".to_string(),
243-
"%1".to_string(),
229+
terminal_id,
244230
),
245231
);
246232

@@ -252,5 +238,14 @@ mod tests {
252238
updated.runtime_liveness,
253239
Some(SessionRuntimeLiveness::Attached)
254240
);
241+
242+
let log = app.state().terminal_write_log.lock().unwrap();
243+
assert!(
244+
log.iter().any(|(ws, tid, data, origin)| {
245+
ws == &workspace_id && *tid == terminal_id && data == "hello" && *origin == TerminalWriteOrigin::User
246+
}),
247+
"terminal_write_log should contain the sent input: {:?}",
248+
&*log
249+
);
255250
}
256251
}

apps/server/src/services/workspace.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -940,8 +940,7 @@ mod tests {
940940
workspace_id.clone(),
941941
created.id.clone(),
942942
"claude".to_string(),
943-
"missing-tmux-session".to_string(),
944-
"%1".to_string(),
943+
99,
945944
),
946945
);
947946
let mut rx = app.state().transport_events.subscribe();
@@ -996,8 +995,7 @@ mod tests {
996995
workspace_id.clone(),
997996
created.id.clone(),
998997
"claude".to_string(),
999-
"missing-tmux-session".to_string(),
1000-
"%1".to_string(),
998+
77,
1001999
),
10021000
);
10031001

apps/server/src/services/workspace_runtime.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,14 @@ pub(crate) fn session_runtime_liveness_for_binding(
351351
return Some(SessionRuntimeLiveness::ProviderExited);
352352
}
353353

354-
if crate::services::tmux::tmux_session_exists(&runtime.tmux_session_name) {
354+
let key = crate::ws::server::terminal_key(&runtime.workspace_id, runtime.terminal_id);
355+
if state
356+
.terminals
357+
.lock()
358+
.ok()
359+
.map(|terms| terms.contains_key(&key))
360+
.unwrap_or(false)
361+
{
355362
Some(SessionRuntimeLiveness::Attached)
356363
} else {
357364
Some(SessionRuntimeLiveness::TmuxMissing)
@@ -1427,8 +1434,7 @@ mod tests {
14271434
workspace_id.clone(),
14281435
other.id.to_string(),
14291436
"claude".to_string(),
1430-
"missing-tmux-session".to_string(),
1431-
"%1".to_string(),
1437+
99,
14321438
),
14331439
);
14341440

@@ -1471,8 +1477,7 @@ mod tests {
14711477
workspace_id.clone(),
14721478
session.id.to_string(),
14731479
"claude".to_string(),
1474-
"missing-tmux-session".to_string(),
1475-
"%1".to_string(),
1480+
99,
14761481
),
14771482
);
14781483

apps/server/src/ws/server.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -792,8 +792,7 @@ mod tests {
792792
workspace_id.clone(),
793793
"session-1".into(),
794794
"claude".into(),
795-
"tmux-session-1".into(),
796-
"%1".into(),
795+
1,
797796
);
798797
app.state()
799798
.terminal_runtimes
@@ -856,8 +855,7 @@ mod tests {
856855
"ws-1".to_string(),
857856
"session-1".to_string(),
858857
"claude".to_string(),
859-
"tmux-fake".to_string(),
860-
"%1".to_string(),
858+
42,
861859
),
862860
);
863861

@@ -919,8 +917,7 @@ mod tests {
919917
"ws-1".to_string(),
920918
"session-1".to_string(),
921919
"claude".to_string(),
922-
"tmux-fake".to_string(),
923-
"%1".to_string(),
920+
42,
924921
),
925922
);
926923

0 commit comments

Comments
 (0)