@moejay/wrightty 0.0.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/cli.d.ts +3 -0
  2. package/dist/cli.js +144 -0
  3. package/dist/client.d.ts +14 -0
  4. package/dist/client.js +83 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.js +8 -0
  7. package/dist/terminal.d.ts +48 -0
  8. package/dist/terminal.js +210 -0
  9. package/dist/types.d.ts +90 -0
  10. package/dist/types.js +3 -0
  11. package/package.json +38 -15
  12. package/.github/workflows/ci.yml +0 -90
  13. package/.github/workflows/release.yml +0 -177
  14. package/Cargo.lock +0 -2662
  15. package/Cargo.toml +0 -38
  16. package/PROTOCOL.md +0 -1351
  17. package/README.md +0 -386
  18. package/agents/ceo/AGENTS.md +0 -24
  19. package/agents/ceo/HEARTBEAT.md +0 -72
  20. package/agents/ceo/SOUL.md +0 -33
  21. package/agents/ceo/TOOLS.md +0 -3
  22. package/agents/founding-engineer/AGENTS.md +0 -44
  23. package/crates/wrightty/Cargo.toml +0 -43
  24. package/crates/wrightty/src/client_cmds.rs +0 -366
  25. package/crates/wrightty/src/discover.rs +0 -78
  26. package/crates/wrightty/src/main.rs +0 -100
  27. package/crates/wrightty/src/server.rs +0 -100
  28. package/crates/wrightty/src/term.rs +0 -338
  29. package/crates/wrightty-bridge-ghostty/Cargo.toml +0 -27
  30. package/crates/wrightty-bridge-ghostty/src/ghostty.rs +0 -422
  31. package/crates/wrightty-bridge-ghostty/src/lib.rs +0 -2
  32. package/crates/wrightty-bridge-ghostty/src/main.rs +0 -146
  33. package/crates/wrightty-bridge-ghostty/src/rpc.rs +0 -307
  34. package/crates/wrightty-bridge-kitty/Cargo.toml +0 -26
  35. package/crates/wrightty-bridge-kitty/src/kitty.rs +0 -269
  36. package/crates/wrightty-bridge-kitty/src/lib.rs +0 -2
  37. package/crates/wrightty-bridge-kitty/src/main.rs +0 -124
  38. package/crates/wrightty-bridge-kitty/src/rpc.rs +0 -304
  39. package/crates/wrightty-bridge-tmux/Cargo.toml +0 -26
  40. package/crates/wrightty-bridge-tmux/src/lib.rs +0 -2
  41. package/crates/wrightty-bridge-tmux/src/main.rs +0 -119
  42. package/crates/wrightty-bridge-tmux/src/rpc.rs +0 -291
  43. package/crates/wrightty-bridge-tmux/src/tmux.rs +0 -215
  44. package/crates/wrightty-bridge-wezterm/Cargo.toml +0 -26
  45. package/crates/wrightty-bridge-wezterm/src/lib.rs +0 -2
  46. package/crates/wrightty-bridge-wezterm/src/main.rs +0 -119
  47. package/crates/wrightty-bridge-wezterm/src/rpc.rs +0 -339
  48. package/crates/wrightty-bridge-wezterm/src/wezterm.rs +0 -190
  49. package/crates/wrightty-bridge-zellij/Cargo.toml +0 -27
  50. package/crates/wrightty-bridge-zellij/src/lib.rs +0 -2
  51. package/crates/wrightty-bridge-zellij/src/main.rs +0 -125
  52. package/crates/wrightty-bridge-zellij/src/rpc.rs +0 -328
  53. package/crates/wrightty-bridge-zellij/src/zellij.rs +0 -199
  54. package/crates/wrightty-client/Cargo.toml +0 -16
  55. package/crates/wrightty-client/src/client.rs +0 -254
  56. package/crates/wrightty-client/src/lib.rs +0 -2
  57. package/crates/wrightty-core/Cargo.toml +0 -21
  58. package/crates/wrightty-core/src/input.rs +0 -212
  59. package/crates/wrightty-core/src/lib.rs +0 -4
  60. package/crates/wrightty-core/src/screen.rs +0 -325
  61. package/crates/wrightty-core/src/session.rs +0 -249
  62. package/crates/wrightty-core/src/session_manager.rs +0 -77
  63. package/crates/wrightty-protocol/Cargo.toml +0 -13
  64. package/crates/wrightty-protocol/src/error.rs +0 -8
  65. package/crates/wrightty-protocol/src/events.rs +0 -138
  66. package/crates/wrightty-protocol/src/lib.rs +0 -4
  67. package/crates/wrightty-protocol/src/methods.rs +0 -321
  68. package/crates/wrightty-protocol/src/types.rs +0 -201
  69. package/crates/wrightty-server/Cargo.toml +0 -23
  70. package/crates/wrightty-server/src/lib.rs +0 -2
  71. package/crates/wrightty-server/src/main.rs +0 -65
  72. package/crates/wrightty-server/src/rpc.rs +0 -455
  73. package/crates/wrightty-server/src/state.rs +0 -39
  74. package/examples/basic_command.py +0 -53
  75. package/examples/interactive_tui.py +0 -86
  76. package/examples/record_session.py +0 -96
  77. package/install.sh +0 -81
  78. package/sdks/node/package-lock.json +0 -85
  79. package/sdks/node/package.json +0 -44
  80. package/sdks/node/src/client.ts +0 -94
  81. package/sdks/node/src/index.ts +0 -19
  82. package/sdks/node/src/terminal.ts +0 -258
  83. package/sdks/node/src/types.ts +0 -105
  84. package/sdks/node/tsconfig.json +0 -17
  85. package/sdks/python/README.md +0 -96
  86. package/sdks/python/pyproject.toml +0 -42
  87. package/sdks/python/wrightty/__init__.py +0 -6
  88. package/sdks/python/wrightty/cli.py +0 -210
  89. package/sdks/python/wrightty/client.py +0 -136
  90. package/sdks/python/wrightty/mcp_server.py +0 -434
  91. package/sdks/python/wrightty/terminal.py +0 -333
  92. package/skills/wrightty/SKILL.md +0 -261
  93. package/src/lib.rs +0 -1
  94. package/tests/integration_test.rs +0 -618
@@ -1,338 +0,0 @@
1
- use std::process;
2
-
3
- use clap::Args;
4
-
5
- use crate::server::{self, PORT_RANGE_START, PORT_RANGE_END};
6
-
7
- #[derive(Args)]
8
- pub struct TermArgs {
9
- #[command(flatten)]
10
- mode: TermMode,
11
-
12
- /// Host to bind on
13
- #[arg(long, default_value = "127.0.0.1")]
14
- host: String,
15
-
16
- /// Port to listen on (default: auto-select)
17
- #[arg(long)]
18
- port: Option<u16>,
19
-
20
- /// Max sessions for headless mode
21
- #[arg(long, default_value_t = 64)]
22
- max_sessions: usize,
23
-
24
- /// Watchdog interval in seconds for bridges (0 to disable)
25
- #[arg(long, default_value_t = 5)]
26
- watchdog_interval: u64,
27
- }
28
-
29
- #[derive(Args)]
30
- #[group(required = true, multiple = false)]
31
- struct TermMode {
32
- /// Start the headless terminal server (virtual PTY, no GUI)
33
- #[cfg(feature = "headless")]
34
- #[arg(long)]
35
- headless: bool,
36
-
37
- /// Launch the Alacritty fork with built-in wrightty support
38
- #[arg(long)]
39
- alacritty: bool,
40
-
41
- /// Bridge to a running WezTerm instance
42
- #[cfg(feature = "bridge-wezterm")]
43
- #[arg(long)]
44
- bridge_wezterm: bool,
45
-
46
- /// Bridge to a running tmux server
47
- #[cfg(feature = "bridge-tmux")]
48
- #[arg(long)]
49
- bridge_tmux: bool,
50
-
51
- /// Bridge to a running Kitty instance
52
- #[cfg(feature = "bridge-kitty")]
53
- #[arg(long)]
54
- bridge_kitty: bool,
55
-
56
- /// Bridge to a running Zellij session
57
- #[cfg(feature = "bridge-zellij")]
58
- #[arg(long)]
59
- bridge_zellij: bool,
60
-
61
- /// Bridge to a running Ghostty instance
62
- #[cfg(feature = "bridge-ghostty")]
63
- #[arg(long)]
64
- bridge_ghostty: bool,
65
- }
66
-
67
- pub async fn run(args: TermArgs) -> anyhow::Result<()> {
68
- #[cfg(feature = "headless")]
69
- if args.mode.headless {
70
- return run_headless(args).await;
71
- }
72
-
73
- if args.mode.alacritty {
74
- return run_alacritty(args).await;
75
- }
76
-
77
- #[cfg(feature = "bridge-wezterm")]
78
- if args.mode.bridge_wezterm {
79
- return run_bridge_wezterm(args).await;
80
- }
81
-
82
- #[cfg(feature = "bridge-tmux")]
83
- if args.mode.bridge_tmux {
84
- return run_bridge_tmux(args).await;
85
- }
86
-
87
- #[cfg(feature = "bridge-kitty")]
88
- if args.mode.bridge_kitty {
89
- return run_bridge_kitty(args).await;
90
- }
91
-
92
- #[cfg(feature = "bridge-zellij")]
93
- if args.mode.bridge_zellij {
94
- return run_bridge_zellij(args).await;
95
- }
96
-
97
- #[cfg(feature = "bridge-ghostty")]
98
- if args.mode.bridge_ghostty {
99
- return run_bridge_ghostty(args).await;
100
- }
101
-
102
- anyhow::bail!("No terminal mode selected. Use --headless, --bridge-tmux, etc.")
103
- }
104
-
105
- fn resolve_port(args: &TermArgs) -> anyhow::Result<u16> {
106
- match args.port {
107
- Some(p) => Ok(p),
108
- None => server::find_available_port(&args.host, PORT_RANGE_START, PORT_RANGE_END)
109
- .ok_or_else(|| {
110
- anyhow::anyhow!("No available port in range {PORT_RANGE_START}-{PORT_RANGE_END}")
111
- }),
112
- }
113
- }
114
-
115
- // --- Headless mode ---
116
-
117
- #[cfg(feature = "headless")]
118
- async fn run_headless(args: TermArgs) -> anyhow::Result<()> {
119
- let port = resolve_port(&args)?;
120
- let state = wrightty_server::state::AppState::new(args.max_sessions);
121
- let module = wrightty_server::rpc::build_rpc_module(state)?;
122
- server::start_server(&args.host, port, "wrightty (headless)", module).await
123
- }
124
-
125
- // --- Alacritty mode ---
126
-
127
- async fn run_alacritty(args: TermArgs) -> anyhow::Result<()> {
128
- let port = args.port.unwrap_or(PORT_RANGE_START);
129
-
130
- // Find the alacritty binary — check for wrightty-patched version
131
- let alacritty = which_alacritty()?;
132
-
133
- tracing::info!("Launching {alacritty} --wrightty {port}");
134
- println!("Launching {alacritty} --wrightty {port}");
135
-
136
- let status = tokio::process::Command::new(&alacritty)
137
- .arg("--wrightty")
138
- .arg(port.to_string())
139
- .status()
140
- .await?;
141
-
142
- if !status.success() {
143
- anyhow::bail!("Alacritty exited with status {status}");
144
- }
145
-
146
- Ok(())
147
- }
148
-
149
- fn which_alacritty() -> anyhow::Result<String> {
150
- // Check PATH for alacritty
151
- let output = std::process::Command::new("which")
152
- .arg("alacritty")
153
- .output();
154
-
155
- match output {
156
- Ok(o) if o.status.success() => {
157
- let path = String::from_utf8_lossy(&o.stdout).trim().to_string();
158
- // Verify it supports --wrightty
159
- let check = std::process::Command::new(&path)
160
- .arg("--help")
161
- .output();
162
- if let Ok(help) = check {
163
- let help_text = String::from_utf8_lossy(&help.stdout);
164
- if help_text.contains("wrightty") {
165
- return Ok(path);
166
- }
167
- }
168
- anyhow::bail!(
169
- "Found alacritty at {path} but it doesn't support --wrightty.\n\
170
- Install the wrightty-patched fork:\n \
171
- git clone -b wrightty-support https://github.com/moejay/alacritty.git\n \
172
- cd alacritty && cargo install --path alacritty --features wrightty"
173
- );
174
- }
175
- _ => anyhow::bail!(
176
- "alacritty not found in PATH.\n\
177
- Install the wrightty-patched fork:\n \
178
- git clone -b wrightty-support https://github.com/moejay/alacritty.git\n \
179
- cd alacritty && cargo install --path alacritty --features wrightty"
180
- ),
181
- }
182
- }
183
-
184
- // --- Bridge modes ---
185
-
186
- #[cfg(feature = "bridge-wezterm")]
187
- async fn run_bridge_wezterm(args: TermArgs) -> anyhow::Result<()> {
188
- tracing::info!("Checking WezTerm connectivity...");
189
- match wrightty_bridge_wezterm::wezterm::health_check().await {
190
- Ok(()) => tracing::info!("WezTerm is reachable"),
191
- Err(e) => {
192
- eprintln!("error: Cannot connect to WezTerm: {e}");
193
- eprintln!();
194
- eprintln!("Make sure WezTerm is running. If using flatpak, set:");
195
- eprintln!(
196
- " WEZTERM_CMD=\"flatpak run --command=wezterm org.wezfurlong.wezterm\""
197
- );
198
- process::exit(1);
199
- }
200
- }
201
-
202
- let port = resolve_port(&args)?;
203
- let module = wrightty_bridge_wezterm::rpc::build_rpc_module()?;
204
- server::start_server_with_watchdog(
205
- &args.host,
206
- port,
207
- "wrightty (wezterm bridge)",
208
- module,
209
- args.watchdog_interval,
210
- || async { wrightty_bridge_wezterm::wezterm::health_check().await.map_err(|e| e.into()) },
211
- )
212
- .await
213
- }
214
-
215
- #[cfg(feature = "bridge-tmux")]
216
- async fn run_bridge_tmux(args: TermArgs) -> anyhow::Result<()> {
217
- tracing::info!("Checking tmux connectivity...");
218
- match wrightty_bridge_tmux::tmux::health_check().await {
219
- Ok(()) => tracing::info!("tmux is reachable"),
220
- Err(e) => {
221
- eprintln!("error: Cannot connect to tmux: {e}");
222
- eprintln!();
223
- eprintln!("Make sure a tmux server is running. Start one with:");
224
- eprintln!(" tmux new-session -d -s main");
225
- process::exit(1);
226
- }
227
- }
228
-
229
- let port = resolve_port(&args)?;
230
- let module = wrightty_bridge_tmux::rpc::build_rpc_module()?;
231
- server::start_server_with_watchdog(
232
- &args.host,
233
- port,
234
- "wrightty (tmux bridge)",
235
- module,
236
- args.watchdog_interval,
237
- || async { wrightty_bridge_tmux::tmux::health_check().await.map_err(|e| e.into()) },
238
- )
239
- .await
240
- }
241
-
242
- #[cfg(feature = "bridge-kitty")]
243
- async fn run_bridge_kitty(args: TermArgs) -> anyhow::Result<()> {
244
- tracing::info!("Checking kitty connectivity...");
245
- match wrightty_bridge_kitty::kitty::health_check().await {
246
- Ok(()) => tracing::info!("kitty is reachable"),
247
- Err(e) => {
248
- eprintln!("error: Cannot connect to kitty: {e}");
249
- eprintln!();
250
- eprintln!("Make sure kitty is running with remote control enabled.");
251
- eprintln!("Add to kitty.conf:");
252
- eprintln!(" allow_remote_control yes");
253
- eprintln!("Or launch kitty with:");
254
- eprintln!(" kitty --listen-on unix:/tmp/kitty.sock");
255
- process::exit(1);
256
- }
257
- }
258
-
259
- let port = resolve_port(&args)?;
260
- let module = wrightty_bridge_kitty::rpc::build_rpc_module()?;
261
- server::start_server_with_watchdog(
262
- &args.host,
263
- port,
264
- "wrightty (kitty bridge)",
265
- module,
266
- args.watchdog_interval,
267
- || async { wrightty_bridge_kitty::kitty::health_check().await.map_err(|e| e.into()) },
268
- )
269
- .await
270
- }
271
-
272
- #[cfg(feature = "bridge-zellij")]
273
- async fn run_bridge_zellij(args: TermArgs) -> anyhow::Result<()> {
274
- tracing::info!("Checking zellij connectivity...");
275
- match wrightty_bridge_zellij::zellij::health_check().await {
276
- Ok(()) => tracing::info!("zellij is reachable"),
277
- Err(e) => {
278
- eprintln!("error: Cannot connect to zellij: {e}");
279
- eprintln!();
280
- eprintln!("This bridge must run from within a zellij session.");
281
- eprintln!("Start zellij first:");
282
- eprintln!(" zellij");
283
- process::exit(1);
284
- }
285
- }
286
-
287
- let port = resolve_port(&args)?;
288
- let module = wrightty_bridge_zellij::rpc::build_rpc_module()?;
289
- server::start_server_with_watchdog(
290
- &args.host,
291
- port,
292
- "wrightty (zellij bridge)",
293
- module,
294
- args.watchdog_interval,
295
- || async { wrightty_bridge_zellij::zellij::health_check().await.map_err(|e| e.into()) },
296
- )
297
- .await
298
- }
299
-
300
- #[cfg(feature = "bridge-ghostty")]
301
- async fn run_bridge_ghostty(args: TermArgs) -> anyhow::Result<()> {
302
- tracing::info!("Checking Ghostty connectivity...");
303
- match wrightty_bridge_ghostty::ghostty::health_check().await {
304
- Ok(()) => tracing::info!("Ghostty IPC socket is reachable"),
305
- Err(e) => {
306
- eprintln!("error: Cannot connect to Ghostty: {e}");
307
- eprintln!();
308
- eprintln!("Make sure Ghostty is running. The bridge connects to:");
309
- eprintln!(" $XDG_RUNTIME_DIR/ghostty/sock (Linux)");
310
- eprintln!(" $TMPDIR/ghostty-<uid>.sock (macOS)");
311
- eprintln!("Override with: GHOSTTY_SOCKET=/path/to/sock");
312
- process::exit(1);
313
- }
314
- }
315
-
316
- let backend = wrightty_bridge_ghostty::ghostty::InputBackend::detect();
317
- if backend == wrightty_bridge_ghostty::ghostty::InputBackend::None {
318
- tracing::warn!(
319
- "No input backend detected. \
320
- Install xdotool (Linux/X11) or enable Accessibility (macOS) for \
321
- Input.sendText / Input.sendKeys support."
322
- );
323
- } else {
324
- tracing::info!("Input backend: {:?}", backend);
325
- }
326
-
327
- let port = resolve_port(&args)?;
328
- let module = wrightty_bridge_ghostty::rpc::build_rpc_module()?;
329
- server::start_server_with_watchdog(
330
- &args.host,
331
- port,
332
- "wrightty (ghostty bridge)",
333
- module,
334
- args.watchdog_interval,
335
- || async { wrightty_bridge_ghostty::ghostty::health_check().await.map_err(|e| e.into()) },
336
- )
337
- .await
338
- }
@@ -1,27 +0,0 @@
1
- [package]
2
- name = "wrightty-bridge-ghostty"
3
- version.workspace = true
4
- edition.workspace = true
5
- license.workspace = true
6
- authors.workspace = true
7
- repository.workspace = true
8
- homepage.workspace = true
9
- description = "Bridge that translates wrightty protocol calls into Ghostty IPC commands"
10
-
11
- [[bin]]
12
- name = "wrightty-bridge-ghostty"
13
- path = "src/main.rs"
14
-
15
- [dependencies]
16
- wrightty-protocol = { version = "0.1.0", path = "../wrightty-protocol" }
17
-
18
- jsonrpsee = { version = "0.24", features = ["server"] }
19
- tokio = { version = "1", features = ["full"] }
20
- clap = { version = "4", features = ["derive"] }
21
- tracing = "0.1"
22
- tracing-subscriber = { version = "0.3", features = ["env-filter"] }
23
- anyhow = "1"
24
- serde = { version = "1", features = ["derive"] }
25
- serde_json = "1"
26
- thiserror = "1"
27
- libc = "0.2"