The browser reached the daemon through maestro-web, a second binary that served the SPA and reverse-proxied /api/* — two TCP connections and a WebSocket frame re-encode on every keystroke and every byte of PTY output. On one machine that hop buys nothing. The daemon now embeds the bundle and serves it off its own listener, behind a default-on `web` feature. `--no-default-features` builds without pnpm or node; MAESTRO_WEB_DIST still takes a prebuilt bundle. The router's fallback answers an unmatched /api/* with 404 rather than the SPA shell, so a client expecting JSON gets a status it can read instead of HTML. Removes maestro-web and the [web] config section. An existing [web] block is ignored, not rejected. The installer deletes a leftover maestro-web.service on upgrade. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
32 lines
1.2 KiB
Rust
32 lines
1.2 KiB
Rust
//! The daemon binary must embed the real SPA bundle, never the placeholder.
|
|
//! `build.rs` guarantees `web/dist` is populated before `include_dir!` runs.
|
|
|
|
#![cfg(feature = "web")]
|
|
|
|
use axum::body::to_bytes;
|
|
use maestro_daemon::static_bundle::serve_index;
|
|
|
|
#[tokio::test]
|
|
async fn embedded_index_is_real_spa_not_placeholder() {
|
|
let resp = serve_index();
|
|
let body = to_bytes(resp.into_body(), usize::MAX).await.unwrap();
|
|
let html = String::from_utf8(body.to_vec()).unwrap();
|
|
|
|
assert!(
|
|
html.contains(r#"id="app""#),
|
|
"served index is missing the SPA mount point; got:\n{html}"
|
|
);
|
|
assert!(
|
|
!html.contains("maestro is running"),
|
|
"served index is the placeholder, not the built bundle"
|
|
);
|
|
// Stronger signal than `id="app"` (which appears in both source and built
|
|
// HTML): the vite build rewrites the entry to a hashed `/assets/index-<hash>`
|
|
// bundle, whereas the un-built source references `/src/main.ts`. This catches
|
|
// both an empty/placeholder embed and the staleness case.
|
|
assert!(
|
|
html.contains("/assets/index-"),
|
|
"served index does not reference a vite-built hashed asset; got:\n{html}"
|
|
);
|
|
}
|