Skip to content

feat(desktop): load external web dir via CODEG_STATIC_DIR so that user can custom froentend - #829

Open
leehom0123 wants to merge 2 commits into
spacering-net:mainfrom
leehom0123:feat/codeg-static-dir
Open

leehom0123 wants to merge 2 commits into
spacering-net:mainfrom
leehom0123:feat/codeg-static-dir

Conversation

@leehom0123

Copy link
Copy Markdown
Contributor

Summary

  • Setting CODEG_STATIC_DIR to a directory containing index.html makes the desktop Tauri window load from the built-in HTTP server (which serves that dir) instead of the embedded frontend assets
  • The web server is force-started when the env var is set, even if auto_start is off in the persisted config
  • Lets pnpm build + restart pick up UI changes without recompiling Rust

Test plan

  • Set CODEG_STATIC_DIR=D:\repos\agent-app\codeg\out and launch codeg.exe — the desktop window should load from the external dir (check the log line [WEB] Desktop window loading from external dir: ...)
  • Modify a frontend file, pnpm build, restart codeg.exe — the change appears without rebuilding Rust
  • Unset CODEG_STATIC_DIR — the app falls back to embedded assets as before
  • cargo check --no-default-features --bin codeg-server still compiles cleanly (no dead-code warning)

https://github.com/xintaofei/codeg/issues/

Setting CODEG_STATIC_DIR to a directory containing index.html makes the
desktop window load from the built-in HTTP server (which serves that dir)
instead of the embedded frontend assets. This lets `pnpm build` + restart
pick up UI changes without recompiling Rust.

The web server is force-started when the env var is set, even if auto_start
is off in the persisted config.
@leehom0123 leehom0123 changed the title feat(desktop): load external web dir via CODEG_STATIC_DIR feat(desktop): load external web dir via CODEG_STATIC_DIR so that user can customer froentend Sep 24, 2026
@leehom0123 leehom0123 changed the title feat(desktop): load external web dir via CODEG_STATIC_DIR so that user can customer froentend feat(desktop): load external web dir via CODEG_STATIC_DIR so that user can custom froentend Sep 24, 2026

@dawNotPoi dawNotPoi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I traced the external-window startup path against CodeG's Tauri capabilities and web-server state. Two issues appear to block the advertised desktop behavior; details are inline. I could not run a native desktop window from this environment, so the review is based on the current source and Tauri's documented origin rules.

Comment thread src-tauri/src/lib.rs Outdated
tracing::info!(
"[WEB] Desktop window loading from external dir: {external}"
);
tauri::WebviewUrl::External(external.parse().unwrap())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes main from the bundled app origin to http://127.0.0.1, but neither capabilities/default.json nor desktop.json grants that external origin via remote.urls. Tauri v2 grants API access to remote pages only when explicitly configured (https://v2.tauri.app/security/capabilities/); CodeG's main window still relies on Tauri commands/plugins for desktop behavior. At this URL those IPC calls are denied, so loading the HTML is insufficient to make the desktop app work. Please keep the custom assets under the app origin, or add a narrowly scoped remote capability and verify the main window's IPC calls on a packaged desktop build.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e0a0ef2. Both capability files now grant the external origin via remote.urls: ["http://127.0.0.1:*"], so core/plugin APIs stay available when main loads the served page. Two notes: (1) Tauri 2.9's remote config supports only urls — no per-window scoping — and the port follows the web-service config, so it cannot be pinned narrower than 127.0.0.1:*; the capability therefore also applies to any other page served from a local port that opens in a codeg window. (2) I verified at source level plus unit tests; a packaged-desktop smoke run of the external-dir path is still on my list.

Comment thread src-tauri/src/lib.rs Outdated
let url = if web::external_static_dir().is_some() {
let port = app
.state::<web::WebServerState>()
.running_port();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The force-start at lines 1123-1141 only logs an error. If binding the configured port fails (or loading the web-service config fails), WebServerState.port remains at its initial 0, yet this branch still builds http://127.0.0.1:0/... because CODEG_STATIC_DIR is valid. The desktop window then opens an unreachable page instead of the bundled UI. Please select the external URL only from a successful server start with a valid returned port; on failure, fall back to the app URL or show an actionable startup error. A port-collision regression case would cover this path.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e0a0ef2. The window URL is now built by resolve_main_window_url: the external http://127.0.0.1:{port} origin is used only when running_port > 0, i.e. after a successful bind; on a failed bind (or an unparseable URL) the window falls back to WebviewUrl::App with an error log saying why, and the CODEG_STATIC_DIR force-start failure now also raises the same system notification as the auto-start path. Added unit tests covering the port-collision case (port 0 → bundled app URL) plus the live-port, normalization, and no-external-dir paths. cargo check, cargo clippy --all-targets and the new tests pass; the packaged port-collision scenario itself has not been run in a built app yet.

@leehom0123
leehom0123 requested a review from dawNotPoi October 13, 2026 05:01

@dawNotPoi dawNotPoi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed the current head, ad27199. It is unchanged from my September 25 review, and both existing findings remain unresolved:

  1. The main window loads an external http://127.0.0.1 origin, but neither capability file grants that origin through remote.urls, and tauri.conf.json adds no such capability. Core/plugin APIs protected by those capabilities remain unavailable to this page. Please preserve the app origin or configure narrowly scoped remote access and verify desktop functionality in a packaged build. See #829 (comment) and https://v2.tauri.app/security/capabilities/#remote-api-access.
  2. WebServerState.port starts at 0. A failed listener bind returns before a successful start records the port; startup only logs the failure, while main-window URL selection still depends solely on a valid CODEG_STATIC_DIR. A port collision can therefore open http://127.0.0.1:0/... instead of a usable UI. Please use the external URL only after successful startup, with a fallback or actionable error on failure, and cover the port-collision case. See #829 (comment).

Please address these findings before requesting another review. This is a source-level verification; I have not run the packaged desktop app.

…e capability

A failed port bind left WebServerState.running_port at 0, so the main
window could open http://127.0.0.1:0 while CODEG_STATIC_DIR was set.
The URL choice now lives in resolve_main_window_url: the external
origin is used only with a bound port, otherwise the window falls back
to the bundled assets with an error log; a force-start failure also
raises a system notification. Both capability files grant
http://127.0.0.1:* via remote.urls so Tauri IPC works on the
externally-served page. Covers review findings on spacering-net#829.
@leehom0123

Copy link
Copy Markdown
Contributor Author

Both review findings are addressed in e0a0ef2 (see inline replies). cargo check, clippy --all-targets and 4 new unit tests (desktop mode) pass. Ready for re-review; the packaged-desktop smoke run of the CODEG_STATIC_DIR path is still pending on my side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants