@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 +1 -1
- package/src/lib.rs +26 -17
- package/src/python_runner.rs +1 -3
- package/src/zoom.rs +72 -25
package/package.json
CHANGED
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
|
|
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
|
-
|
|
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()?;
|
package/src/python_runner.rs
CHANGED
|
@@ -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
|
-
|
|
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
|
-
///
|
|
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
|
-
|
|
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.
|
|
228
|
-
let _ = controls.
|
|
229
|
-
let _ = controls.
|
|
230
|
-
let _ = controls.
|
|
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
|
|
293
|
-
|
|
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
|
|