Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f04494ba8
|
||
|
|
8062a8ac77
|
||
|
|
4a982ae089
|
||
|
|
d9e2c4a01d
|
No files matched your search
@@ -62,5 +62,8 @@ jobs:
|
|||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
run: |
|
run: |
|
||||||
git tag -l --format='%(contents)' "$TAG" | sed '/-----BEGIN SSH SIGNATURE-----/,$d' > notes.md
|
git tag -l --format='%(contents)' "$TAG" | sed '/-----BEGIN SSH SIGNATURE-----/,$d' > notes.md
|
||||||
|
# A tag moved to a fixed commit and pushed again replaces its release:
|
||||||
|
# the old one, and the files built from the old commit, go first.
|
||||||
|
gh release delete "$TAG" --repo "$GITHUB_REPOSITORY" --yes 2>/dev/null || true
|
||||||
gh release create "$TAG" --repo "$GITHUB_REPOSITORY" --verify-tag \
|
gh release create "$TAG" --repo "$GITHUB_REPOSITORY" --verify-tag \
|
||||||
--title "LLeMbas Desktop $VERSION" --notes-file notes.md dist/*
|
--title "LLeMbas Desktop $VERSION" --notes-file notes.md dist/*
|
||||||
@@ -6,6 +6,34 @@ All notable changes to LLeMbas Desktop. The format follows
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.7.1] — 2026-10-24
|
||||||
|
|
||||||
|
The microphone works, and LLeMbas CLI 1.5.1 inside.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- **Dictation said the microphone was blocked, with no way to allow it.** The server's page asks
|
||||||
|
for the microphone, and a webview grants it only if the app answers: WebKitGTK refuses whatever
|
||||||
|
it is not answered on, and shows no prompt of its own. Desktop now allows the microphone -- the
|
||||||
|
microphone only, and only for the server's page in the content view; a camera or a screen still
|
||||||
|
gets the platform's refusal.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Carries LLeMbas CLI 1.5.1: an image counts by its size, so a screenshot no longer makes the
|
||||||
|
agent compact.
|
||||||
|
|
||||||
|
## [0.7.0] — 2026-10-20
|
||||||
|
|
||||||
|
Carries LLeMbas CLI 1.5.0: harness spec 2.0.0 — background work as jobs the person can see,
|
||||||
|
enter and stop, and subagents that run in the background and talk back.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Carries LLeMbas CLI 1.5.0. The agent on this computer runs subagents in the background, keeps
|
||||||
|
every background command and subagent as a job of its session, and reports them to a LLeMbas
|
||||||
|
server 1.6.0, which shows them in the chat with Stop and a message box.
|
||||||
|
|
||||||
## [0.6.0] — 2026-10-20
|
## [0.6.0] — 2026-10-20
|
||||||
|
|
||||||
Carries LLeMbas CLI 1.4.0: harness spec 1.2.0, so the agent's memory, notes and skills are the
|
Carries LLeMbas CLI 1.4.0: harness spec 1.2.0, so the agent's memory, notes and skills are the
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
1.4.0
|
1.5.1
|
||||||
Generated
+1
-1
@@ -2064,7 +2064,7 @@ checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "llembas-desktop"
|
name = "llembas-desktop"
|
||||||
version = "0.6.0"
|
version = "0.7.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gtk",
|
"gtk",
|
||||||
"libc",
|
"libc",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "llembas-desktop"
|
name = "llembas-desktop"
|
||||||
version = "0.6.0"
|
version = "0.7.1"
|
||||||
description = "LLeMbas Desktop: your LLeMbas server in a window, with the agent on this computer"
|
description = "LLeMbas Desktop: your LLeMbas server in a window, with the agent on this computer"
|
||||||
authors = ["Jaroslav Beneš"]
|
authors = ["Jaroslav Beneš"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@@ -17,7 +17,7 @@ crate-type = ["staticlib", "cdylib", "rlib"]
|
|||||||
tauri-build = { version = "2", features = [] }
|
tauri-build = { version = "2", features = [] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tauri = { version = "2", features = ["tray-icon", "unstable"] }
|
tauri = { version = "2.12", features = ["tray-icon", "unstable"] }
|
||||||
tauri-plugin-dialog = "2"
|
tauri-plugin-dialog = "2"
|
||||||
tauri-plugin-opener = "2"
|
tauri-plugin-opener = "2"
|
||||||
tauri-plugin-single-instance = "2"
|
tauri-plugin-single-instance = "2"
|
||||||
|
|||||||
+21
-2
@@ -30,7 +30,7 @@ use std::sync::Mutex;
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tauri::menu::{Menu, MenuItem, PredefinedMenuItem};
|
use tauri::menu::{Menu, MenuItem, PredefinedMenuItem};
|
||||||
use tauri::tray::TrayIconBuilder;
|
use tauri::tray::TrayIconBuilder;
|
||||||
use tauri::webview::WebviewBuilder;
|
use tauri::webview::{PermissionKind, PermissionResponse, WebviewBuilder};
|
||||||
use tauri::window::{Color, WindowBuilder};
|
use tauri::window::{Color, WindowBuilder};
|
||||||
use tauri::{
|
use tauri::{
|
||||||
AppHandle, Emitter, LogicalPosition, LogicalSize, Manager, RunEvent, Url, Webview, WebviewUrl,
|
AppHandle, Emitter, LogicalPosition, LogicalSize, Manager, RunEvent, Url, Webview, WebviewUrl,
|
||||||
@@ -425,12 +425,14 @@ fn build_main(handle: &AppHandle, target: Option<Url>) -> tauri::Result<()> {
|
|||||||
pin_titlebar(&bar);
|
pin_titlebar(&bar);
|
||||||
}
|
}
|
||||||
let nav = handle.clone();
|
let nav = handle.clone();
|
||||||
|
let perm = handle.clone();
|
||||||
window.add_child(
|
window.add_child(
|
||||||
WebviewBuilder::new(CONTENT, url)
|
WebviewBuilder::new(CONTENT, url)
|
||||||
.user_agent(&user_agent())
|
.user_agent(&user_agent())
|
||||||
.background_color(theme.background())
|
.background_color(theme.background())
|
||||||
.initialization_script(THEME_SCRIPT)
|
.initialization_script(THEME_SCRIPT)
|
||||||
.on_navigation(move |url| allowed(&nav, url)),
|
.on_navigation(move |url| allowed(&nav, url))
|
||||||
|
.on_permission_request(move |view, kind| permission(&perm, &view, kind)),
|
||||||
LogicalPosition::new(FRAME, FRAME + TITLE_H),
|
LogicalPosition::new(FRAME, FRAME + TITLE_H),
|
||||||
LogicalSize::new(
|
LogicalSize::new(
|
||||||
size.width - 2.0 * FRAME,
|
size.width - 2.0 * FRAME,
|
||||||
@@ -441,6 +443,23 @@ fn build_main(handle: &AppHandle, target: Option<Url>) -> tauri::Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The server's dictation asks for the microphone, and a webview answers a permission request
|
||||||
|
/// only if its app does: WebKitGTK refuses anything it is not answered on, and has no prompt of
|
||||||
|
/// its own -- so the microphone simply said "Permission may be blocked" with no way to allow it.
|
||||||
|
/// Granted for the microphone, in the content view, once a server is chosen, and for nothing
|
||||||
|
/// else (a camera or a screen gets the platform's default, which on Linux is no). The content view
|
||||||
|
/// never shows another origin: `allowed` sends every other site to the system browser.
|
||||||
|
fn permission(handle: &AppHandle, view: &Webview, kind: PermissionKind) -> PermissionResponse {
|
||||||
|
if kind != PermissionKind::Microphone || view.label() != CONTENT {
|
||||||
|
return PermissionResponse::Default;
|
||||||
|
}
|
||||||
|
if handle.state::<App>().settings().server.is_some() {
|
||||||
|
PermissionResponse::Allow
|
||||||
|
} else {
|
||||||
|
PermissionResponse::Deny
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// On Linux, Tauri packs every webview of a window into the window's GTK box, each with an equal
|
/// On Linux, Tauri packs every webview of a window into the window's GTK box, each with an equal
|
||||||
/// share of the height, and positions and sizes set on a webview are not applied there. So the
|
/// share of the height, and positions and sizes set on a webview are not applied there. So the
|
||||||
/// title bar is told directly: a fixed height, no share of what is left (the content takes it).
|
/// title bar is told directly: a fixed height, no share of what is left (the content takes it).
|
||||||
|
|||||||
Reference in new issue
Block a user