@steerable/agent-shell-tauri 0.7.1 → 0.7.4

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steerable/agent-shell-tauri",
3
- "version": "0.7.1",
3
+ "version": "0.7.4",
4
4
  "description": "Reusable Tauri Rust host source for @steerable/agent-shell",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://steerableframework.com/",
package/src/lib.rs CHANGED
@@ -51,16 +51,17 @@ impl DesktopConfig {
51
51
  }
52
52
 
53
53
  fn install_menu(app: &tauri::App, data_dir_name: &str) -> tauri::Result<()> {
54
- let new_chat = MenuItemBuilder::with_id("new-chat", "新建对话")
54
+ let labels = zoom::zoom_menu_labels("zh");
55
+ let new_chat = MenuItemBuilder::with_id("new-chat", labels.new_chat)
55
56
  .accelerator("CmdOrCtrl+N")
56
57
  .build(app)?;
57
- let open_terminal = MenuItemBuilder::with_id("open-terminal", "打开终端")
58
+ let open_terminal = MenuItemBuilder::with_id("open-terminal", labels.open_terminal)
58
59
  .accelerator("CmdOrCtrl+T")
59
60
  .build(app)?;
60
- let quit = MenuItemBuilder::with_id("app-quit", "退出")
61
+ let quit = MenuItemBuilder::with_id("app-quit", labels.quit)
61
62
  .accelerator("CmdOrCtrl+Q")
62
63
  .build(app)?;
63
- let file = SubmenuBuilder::new(app, "文件")
64
+ let file = SubmenuBuilder::new(app, labels.file)
64
65
  .item(&new_chat)
65
66
  .separator()
66
67
  .close_window()
@@ -69,10 +70,10 @@ fn install_menu(app: &tauri::App, data_dir_name: &str) -> tauri::Result<()> {
69
70
  .build()?;
70
71
  // Predefined Paste delivers an empty clipboard into WKWebView. Own the
71
72
  // shortcut and read the pasteboard from the host process instead.
72
- let paste = MenuItemBuilder::with_id("edit-paste", "粘贴")
73
+ let paste = MenuItemBuilder::with_id("edit-paste", labels.paste)
73
74
  .accelerator("CmdOrCtrl+V")
74
75
  .build(app)?;
75
- let edit = SubmenuBuilder::new(app, "编辑")
76
+ let edit = SubmenuBuilder::new(app, labels.edit)
76
77
  .undo()
77
78
  .redo()
78
79
  .separator()
@@ -81,7 +82,6 @@ fn install_menu(app: &tauri::App, data_dir_name: &str) -> tauri::Result<()> {
81
82
  .item(&paste)
82
83
  .select_all()
83
84
  .build()?;
84
- let labels = zoom::zoom_menu_labels("zh");
85
85
  let zoom_in = MenuItemBuilder::with_id("view-zoom-in", labels.zoom_in)
86
86
  .accelerator("CmdOrCtrl+=")
87
87
  .build(app)?;
@@ -97,16 +97,7 @@ fn install_menu(app: &tauri::App, data_dir_name: &str) -> tauri::Result<()> {
97
97
  let zoom_reset = MenuItemBuilder::with_id("view-zoom-reset", labels.zoom_reset)
98
98
  .accelerator("CmdOrCtrl+0")
99
99
  .build(app)?;
100
- zoom::bind(
101
- app,
102
- data_dir_name,
103
- zoom_in.clone(),
104
- zoom_in_plus.clone(),
105
- zoom_out.clone(),
106
- zoom_reset.clone(),
107
- )
108
- .map_err(|error| tauri::Error::Io(std::io::Error::other(error)))?;
109
- let view = SubmenuBuilder::new(app, "视图")
100
+ let view = SubmenuBuilder::new(app, labels.view)
110
101
  .item(&zoom_in)
111
102
  .item(&zoom_in_plus)
112
103
  .item(&zoom_out)
@@ -116,6 +107,24 @@ fn install_menu(app: &tauri::App, data_dir_name: &str) -> tauri::Result<()> {
116
107
  .separator()
117
108
  .fullscreen()
118
109
  .build()?;
110
+ zoom::bind(
111
+ app,
112
+ data_dir_name,
113
+ zoom::ZoomMenuItems {
114
+ file: file.clone(),
115
+ new_chat,
116
+ quit,
117
+ edit: edit.clone(),
118
+ paste,
119
+ zoom_in,
120
+ zoom_in_plus,
121
+ zoom_out,
122
+ zoom_reset,
123
+ view: view.clone(),
124
+ open_terminal,
125
+ },
126
+ )
127
+ .map_err(|error| tauri::Error::Io(std::io::Error::other(error)))?;
119
128
  let menu = MenuBuilder::new(app)
120
129
  .items(&[&file, &edit, &view])
121
130
  .build()?;
@@ -586,9 +586,7 @@ async fn validate_local(path: &Path) -> Result<(), String> {
586
586
  const CREATE_NO_WINDOW: u32 = 0x0800_0000;
587
587
  command.creation_flags(CREATE_NO_WINDOW);
588
588
  }
589
- let output = command.output()
590
- .await
591
- .map_err(|error| error.to_string())?;
589
+ let output = command.output().await.map_err(|error| error.to_string())?;
592
590
  if !output.status.success() {
593
591
  return Err("Selected Python could not be started".into());
594
592
  }
package/src/zoom.rs CHANGED
@@ -7,7 +7,7 @@ use serde_json::{Map, Value};
7
7
  use std::fs;
8
8
  use std::path::{Path, PathBuf};
9
9
  use std::sync::Mutex;
10
- use tauri::menu::MenuItem;
10
+ use tauri::menu::{MenuItem, Submenu};
11
11
  use tauri::{AppHandle, Emitter, Manager, Wry};
12
12
 
13
13
  pub const MIN_ZOOM: f64 = 0.8;
@@ -20,35 +20,68 @@ struct ZoomChanged {
20
20
  scale: f64,
21
21
  }
22
22
 
23
+ pub struct ZoomMenuItems {
24
+ pub file: Submenu<Wry>,
25
+ pub new_chat: MenuItem<Wry>,
26
+ pub quit: MenuItem<Wry>,
27
+ pub edit: Submenu<Wry>,
28
+ pub paste: MenuItem<Wry>,
29
+ pub zoom_in: MenuItem<Wry>,
30
+ pub zoom_in_plus: MenuItem<Wry>,
31
+ pub zoom_out: MenuItem<Wry>,
32
+ pub zoom_reset: MenuItem<Wry>,
33
+ pub view: Submenu<Wry>,
34
+ pub open_terminal: MenuItem<Wry>,
35
+ }
36
+
23
37
  pub struct ZoomControls {
24
38
  path: PathBuf,
25
39
  scale: Mutex<f64>,
26
- zoom_in: MenuItem<Wry>,
27
- zoom_in_plus: MenuItem<Wry>,
28
- zoom_out: MenuItem<Wry>,
29
- zoom_reset: MenuItem<Wry>,
40
+ menu: ZoomMenuItems,
30
41
  }
31
42
 
32
43
  pub struct ZoomMenuLabels {
44
+ pub file: &'static str,
45
+ pub new_chat: &'static str,
46
+ pub quit: &'static str,
47
+ pub edit: &'static str,
48
+ pub paste: &'static str,
49
+ pub view: &'static str,
33
50
  pub zoom_in: &'static str,
34
51
  pub zoom_out: &'static str,
35
52
  pub zoom_reset: &'static str,
53
+ pub open_terminal: &'static str,
36
54
  }
37
55
 
38
- /// View-menu labels for the page locale. Both zoom-in rows share one label.
56
+ /// App-menu labels for the page locale. Both zoom-in rows share one label.
57
+ /// Undo, cut, and the other predefined items stay with the operating system.
39
58
  pub fn zoom_menu_labels(locale: &str) -> ZoomMenuLabels {
40
59
  let normalized = locale.trim().to_lowercase().replace('_', "-");
41
60
  if normalized == "zh" || normalized.starts_with("zh-") {
42
61
  ZoomMenuLabels {
62
+ file: "文件",
63
+ new_chat: "新建对话",
64
+ quit: "退出",
65
+ edit: "编辑",
66
+ paste: "粘贴",
67
+ view: "视图",
43
68
  zoom_in: "放大",
44
69
  zoom_out: "缩小",
45
70
  zoom_reset: "实际大小",
71
+ open_terminal: "打开终端",
46
72
  }
47
73
  } else {
48
74
  ZoomMenuLabels {
75
+ file: "File",
76
+ new_chat: "New chat",
77
+ quit: "Quit",
78
+ edit: "Edit",
79
+ paste: "Paste",
80
+ view: "View",
49
81
  zoom_in: "Zoom in",
50
82
  zoom_out: "Zoom out",
51
83
  zoom_reset: "Actual size",
84
+ open_terminal: "Open terminal",
52
85
  }
53
86
  }
54
87
  }
@@ -199,22 +232,12 @@ pub fn user_data_dir(app: &AppHandle, data_dir_name: &str) -> Result<PathBuf, St
199
232
  Ok(dir)
200
233
  }
201
234
 
202
- pub fn bind(
203
- app: &tauri::App,
204
- data_dir_name: &str,
205
- zoom_in: MenuItem<Wry>,
206
- zoom_in_plus: MenuItem<Wry>,
207
- zoom_out: MenuItem<Wry>,
208
- zoom_reset: MenuItem<Wry>,
209
- ) -> Result<(), String> {
235
+ pub fn bind(app: &tauri::App, data_dir_name: &str, menu: ZoomMenuItems) -> Result<(), String> {
210
236
  let path = user_data_dir(app.handle(), data_dir_name)?.join("window-state.json");
211
237
  app.manage(ZoomControls {
212
238
  path,
213
239
  scale: Mutex::new(DEFAULT_ZOOM),
214
- zoom_in,
215
- zoom_in_plus,
216
- zoom_out,
217
- zoom_reset,
240
+ menu,
218
241
  });
219
242
  Ok(())
220
243
  }
@@ -224,10 +247,17 @@ pub fn apply_locale(app: &AppHandle, locale: &str) {
224
247
  return;
225
248
  };
226
249
  let labels = zoom_menu_labels(locale);
227
- let _ = controls.zoom_in.set_text(labels.zoom_in);
228
- let _ = controls.zoom_in_plus.set_text(labels.zoom_in);
229
- let _ = controls.zoom_out.set_text(labels.zoom_out);
230
- let _ = controls.zoom_reset.set_text(labels.zoom_reset);
250
+ let _ = controls.menu.file.set_text(labels.file);
251
+ let _ = controls.menu.new_chat.set_text(labels.new_chat);
252
+ let _ = controls.menu.quit.set_text(labels.quit);
253
+ let _ = controls.menu.edit.set_text(labels.edit);
254
+ let _ = controls.menu.paste.set_text(labels.paste);
255
+ let _ = controls.menu.view.set_text(labels.view);
256
+ let _ = controls.menu.zoom_in.set_text(labels.zoom_in);
257
+ let _ = controls.menu.zoom_in_plus.set_text(labels.zoom_in);
258
+ let _ = controls.menu.zoom_out.set_text(labels.zoom_out);
259
+ let _ = controls.menu.zoom_reset.set_text(labels.zoom_reset);
260
+ let _ = controls.menu.open_terminal.set_text(labels.open_terminal);
231
261
  }
232
262
 
233
263
  pub fn apply_saved(app: &AppHandle) {
@@ -288,9 +318,12 @@ fn commit(
288
318
  .scale
289
319
  .lock()
290
320
  .unwrap_or_else(|poison| poison.into_inner()) = scale;
291
- let _ = controls.zoom_in.set_enabled(zoom_in_enabled(scale));
292
- let _ = controls.zoom_in_plus.set_enabled(zoom_in_enabled(scale));
293
- let _ = controls.zoom_out.set_enabled(zoom_out_enabled(scale));
321
+ let _ = controls.menu.zoom_in.set_enabled(zoom_in_enabled(scale));
322
+ let _ = controls
323
+ .menu
324
+ .zoom_in_plus
325
+ .set_enabled(zoom_in_enabled(scale));
326
+ let _ = controls.menu.zoom_out.set_enabled(zoom_out_enabled(scale));
294
327
  if persist {
295
328
  if let Err(error) = write_zoom(&controls.path, scale) {
296
329
  eprintln!("[zoom] failed to write window-state.json: {error}");
@@ -367,13 +400,27 @@ mod tests {
367
400
  #[test]
368
401
  fn menu_labels_follow_the_page_locale() {
369
402
  let chinese = zoom_menu_labels("zh-CN");
403
+ assert_eq!(chinese.file, "文件");
404
+ assert_eq!(chinese.new_chat, "新建对话");
405
+ assert_eq!(chinese.quit, "退出");
406
+ assert_eq!(chinese.edit, "编辑");
407
+ assert_eq!(chinese.paste, "粘贴");
408
+ assert_eq!(chinese.view, "视图");
370
409
  assert_eq!(chinese.zoom_in, "放大");
371
410
  assert_eq!(chinese.zoom_out, "缩小");
372
411
  assert_eq!(chinese.zoom_reset, "实际大小");
412
+ assert_eq!(chinese.open_terminal, "打开终端");
373
413
  let english = zoom_menu_labels("en");
414
+ assert_eq!(english.file, "File");
415
+ assert_eq!(english.new_chat, "New chat");
416
+ assert_eq!(english.quit, "Quit");
417
+ assert_eq!(english.edit, "Edit");
418
+ assert_eq!(english.paste, "Paste");
419
+ assert_eq!(english.view, "View");
374
420
  assert_eq!(english.zoom_in, "Zoom in");
375
421
  assert_eq!(english.zoom_out, "Zoom out");
376
422
  assert_eq!(english.zoom_reset, "Actual size");
423
+ assert_eq!(english.open_terminal, "Open terminal");
377
424
  assert_eq!(zoom_menu_labels("").zoom_in, "Zoom in");
378
425
  }
379
426