Skip the startup update check when started for an agent (#3097)

* Skip the startup update check when started for an agent

An app started with --control or EFFECTCRAFT_CONTROL_PORT still checked
for updates at start, and the modal "newer version available" prompt
blocked agent runs until a person dismissed it. Agent launches already
skip crash recovery and the Home screen; now they skip the startup update
check too. Help > Check for Updates is unaffected (it goes through
updates_ui::check / check_requested, independent of the startup flag).

Documents what a control-port launch skips in docs/control-protocol.md and
the main.rs module doc, with a unit test for the startup decision.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Control protocol docs: a window-start failure still shows a blocking message box

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Valentin KleinandClaude Opus 5.5 authored and GitHub committed 2026-11-06 17:18:52 +01:00
1 parent 779df34e13
commit 0f94a1f983
2 files changed
+30 -2

No files matched your search

+23 -2
View File
@@ -8,7 +8,9 @@
//! `--demo` opens the demo project instead (also Help ▸ Open Demo Project).
//!
//! `--control <port>` (or `EFFECTCRAFT_CONTROL_PORT`) starts a localhost JSON-lines control server;
//! see `effectcraft_ui_egui::control` for the methods.
//! see `effectcraft_ui_egui::control` for the methods. An app started for an agent opens without
//! taking keyboard focus and skips crash recovery, the Home screen (unless `--home`) and the
//! startup update check.
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
#![cfg_attr(all(target_os = "windows", not(debug_assertions)), windows_subsystem = "windows")]
@@ -112,6 +114,13 @@ fn parse_args(args: impl IntoIterator<Item = String>, env_port: Result<String, s
Ok(Some(out))
}
/// Whether the app looks for a newer release when it starts. Not when started for an agent
/// (`--control`): the "update available" prompt is modal and would block the run until a person
/// dismisses it. Help ▸ Check for Updates still works.
fn startup_update_check(control_port: Option<u16>) -> bool {
control_port.is_none()
}
/// A control-channel port from 1 to 65535 (0 would listen on a port nobody is told); `name` is
/// the flag or variable it came from.
fn control_port(name: &str, value: Option<&str>) -> Result<u16, String> {
@@ -310,7 +319,7 @@ fn main() -> eframe::Result {
// reported in a toast and forgotten).
let _ = session.execute("window.restoreScriptPanels", json!({}));
let mut app = EffectcraftApp::new(session);
app.set_startup_update_check(true);
app.set_startup_update_check(startup_update_check(control_port));
app.set_gpu_failure_bridge(gpu_failures);
app.ui.start_screen = show_home;
if let Some(n) = notice {
@@ -666,6 +675,18 @@ mod tests {
assert_eq!(parse_env(&[], Ok("9000".into())).unwrap().map(|a| a.control_port), Some(Some(9000)));
}
/// An app started for an agent (`--control` or `EFFECTCRAFT_CONTROL_PORT`) doesn't check for
/// updates at start, so no modal update prompt blocks the run; a normal launch still does.
#[test]
fn agent_runs_skip_the_startup_update_check() {
let port = |args: &[&str], env| parse_env(args, env).unwrap().unwrap_or_default().control_port;
assert!(super::startup_update_check(port(&[], Err(VarError::NotPresent))));
assert!(super::startup_update_check(port(&[], Ok(String::new()))));
assert!(!super::startup_update_check(port(&["--control", "9877"], Err(VarError::NotPresent))));
assert!(!super::startup_update_check(port(&["--control=9877"], Err(VarError::NotPresent))));
assert!(!super::startup_update_check(port(&[], Ok("9877".into()))));
}
/// A missing, non-numeric or zero `--control` value stops the launch instead of starting
/// without a control server, and the argument after `--control` isn't reinterpreted (#997).
#[test]
+7
View File
@@ -9,6 +9,13 @@ effectcraft --control 9877 # or EFFECTCRAFT_CONTROL_PORT=9877
The port must be a number from 1 to 65535, and `--control` overrides the variable. A bad port or an
unknown option prints an error and the app exits with status 1 before it opens a window.
An app started with a control port is meant to be driven by an agent, so a normal launch does not
wait for a person: the window opens without taking keyboard focus, and the app skips crash recovery,
the Home screen (unless `--home` is given) and the startup update check. Help ▸ Check for Updates
still works. One exception: when the window cannot start at all, the app writes the error to
standard error and the session log and then shows it in a message box, and it exits only after
someone closes that box.
- **Transport:** TCP on `127.0.0.1` only, one JSON object per line in each direction. Connections are
persistent; requests on one connection are answered in order.
- **Request:** `{"id": 1, "method": "engine.execute", "params": {...}}` (`id` is echoed back, `params`