diff --git a/docs/API-Reference/project/SidebarView.md b/docs/API-Reference/project/SidebarView.md
index 4b0184fec8..78d98ae61c 100644
--- a/docs/API-Reference/project/SidebarView.md
+++ b/docs/API-Reference/project/SidebarView.md
@@ -43,3 +43,23 @@ Returns the visibility state of the sidebar.
**Kind**: global function
**Returns**: boolean - true if element is visible, false if it is not visible
+
+
+## resize(width)
+Programmatically resize the sidebar to the given width. Persists
+the new size so it is restored on reload, resyncs the drag handle,
+and fires `panelResizeEnd`.
+
+**Kind**: global function
+
+| Param | Type | Description |
+| --- | --- | --- |
+| width | number | Desired sidebar width in pixels |
+
+
+
+## getWidth() ⇒ number
+Get the current sidebar width in pixels. Returns the CSS width
+even if the sidebar is hidden (so the value can be restored later).
+
+**Kind**: global function
diff --git a/docs/API-Reference/view/SidebarTabs.md b/docs/API-Reference/view/SidebarTabs.md
index fbbd4bdd60..430d35d52a 100644
--- a/docs/API-Reference/view/SidebarTabs.md
+++ b/docs/API-Reference/view/SidebarTabs.md
@@ -22,6 +22,8 @@ cached jQuery/DOM references held by extensions remain valid.
* [view/SidebarTabs](#module_view/SidebarTabs)
* [.SIDEBAR_TAB_FILES](#module_view/SidebarTabs..SIDEBAR_TAB_FILES) : string
+ * [.AI_TAB_GOOD_WIDTH](#module_view/SidebarTabs..AI_TAB_GOOD_WIDTH) : number
+ * [.PREF_AI_WIDTH_SET_INITIAL](#module_view/SidebarTabs..PREF_AI_WIDTH_SET_INITIAL)
* [.EVENT_TAB_ADDED](#module_view/SidebarTabs..EVENT_TAB_ADDED) : string
* [.EVENT_TAB_REMOVED](#module_view/SidebarTabs..EVENT_TAB_REMOVED) : string
* [.EVENT_TAB_CHANGED](#module_view/SidebarTabs..EVENT_TAB_CHANGED) : string
@@ -38,6 +40,19 @@ cached jQuery/DOM references held by extensions remain valid.
### view/SidebarTabs.SIDEBAR\_TAB\_FILES : string
The built-in Files tab id.
+**Kind**: inner constant of [view/SidebarTabs](#module_view/SidebarTabs)
+
+
+### view/SidebarTabs.AI\_TAB\_GOOD\_WIDTH : number
+Preferred sidebar width (px) when a non-files tab (e.g. AI) is
+first activated. Applied once if the current width is narrower.
+
+**Kind**: inner constant of [view/SidebarTabs](#module_view/SidebarTabs)
+
+
+### view/SidebarTabs.PREF\_AI\_WIDTH\_SET\_INITIAL
+Preference key used to track whether the initial width bump has been applied.
+
**Kind**: inner constant of [view/SidebarTabs](#module_view/SidebarTabs)
diff --git a/package.json b/package.json
index e93657da42..fa15bba19d 100644
--- a/package.json
+++ b/package.json
@@ -75,12 +75,12 @@
"_patchVersionBump": "gulp patchVersionBump",
"_minorVersionBump": "gulp minorVersionBump",
"_majorVersionBump": "gulp majorVersionBump",
- "serve": "node serve-proxy.js . -p 8000 -c-1",
- "serveLocalAccount": "node serve-proxy.js . -p 8000 -c-1 --localAccount",
- "serveStagingAccount": "node serve-proxy.js . -p 8000 -c-1 --stagingAccount",
+ "serve": "npm install --prefix src-node && node serve-proxy.js . -p 8000 -c-1",
+ "serveLocalAccount": "npm install --prefix src-node && node serve-proxy.js . -p 8000 -c-1 --localAccount",
+ "serveStagingAccount": "npm install --prefix src-node && node serve-proxy.js . -p 8000 -c-1 --stagingAccount",
"_serveWithWebCacheHelp": "echo !!!Make sure to npm run release:dev/stageing/prod before testing the cache!!!",
"serveWithWebCache": "npm run _releaseWebCache && npm run _serveWithWebCacheHelp && http-server ./dist -p 8000 -c-1",
- "serveExternal": "node serve-proxy.js . -p 8000 -a 0.0.0.0 --log-ip -c-1",
+ "serveExternal": "npm install --prefix src-node && node serve-proxy.js . -p 8000 -a 0.0.0.0 --log-ip -c-1",
"createJSDocs": "node build/api-docs-generator.js && git add docs",
"_translateStrings": "gulp translateStrings",
"_minify": "r.js -o require.min.config.js && echo this is untested see https://stackoverflow.com/questions/14337970/minifying-requirejs-javascript-codebase-to-a-single-file"
diff --git a/serve-proxy.js b/serve-proxy.js
index 33484fbd13..cbef43b270 100644
--- a/serve-proxy.js
+++ b/serve-proxy.js
@@ -270,6 +270,31 @@ const server = http.createServer((req, res) => {
return;
}
+ // Handle getPhoenixPath API for Tauri dev mode
+ if (parsedUrl.pathname === '/api/getPhoenixPath') {
+ const response = {
+ phoenixPath: config.root
+ };
+
+ if (!config.silent) {
+ console.log(`[API] ${req.method} ${parsedUrl.pathname} -> ${JSON.stringify(response)}`);
+ }
+
+ const headers = {
+ 'Content-Type': 'application/json'
+ };
+
+ if (config.cors) {
+ headers['Access-Control-Allow-Origin'] = '*';
+ headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE, OPTIONS';
+ headers['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept, Authorization, Cache-Control';
+ }
+
+ res.writeHead(200, headers);
+ res.end(JSON.stringify(response));
+ return;
+ }
+
// Handle proxy config request
if (parsedUrl.pathname === '/proxy/config') {
const configResponse = {
diff --git a/src/node-loader.js b/src/node-loader.js
index 67bcf80c1a..c612729f20 100644
--- a/src/node-loader.js
+++ b/src/node-loader.js
@@ -635,18 +635,34 @@ function nodeLoader() {
nodeErrorLogCount = 0;
}, NODE_ERROR_LOGS_RESET_INTERVAL);
- async function _tauriNodeSetup() {
- let nodeSrcPath = await window.__TAURI__.path.resolveResource("src-node/index.js");
+ async function _resolveSrcNodePath() {
+ // Check if running from localhost dev server
+ if (window.location.href.startsWith('http://localhost:')) {
+ // Fetch phoenix path from dev server API to use local src-node
+ const response = await fetch('/api/getPhoenixPath');
+ const pathInfo = await response.json();
+ const srcNodePath = `${pathInfo.phoenixPath}/src-node/index.js`;
+ console.log('PhNode: Using dev server src-node path:', srcNodePath);
+ return srcNodePath;
+ }
+
+ // Production Tauri path resolution
+ let srcNodePath = await window.__TAURI__.path.resolveResource("src-node/index.js");
// Strip Windows UNC prefix (\\?\) that Tauri adds on Windows
// Node 24 doesn't handle UNC paths correctly in module resolution
- if (Phoenix.platform === "win" && nodeSrcPath.startsWith('\\\\?\\')) {
- nodeSrcPath = nodeSrcPath.slice(4);
+ if (Phoenix.platform === "win" && srcNodePath.startsWith('\\\\?\\')) {
+ srcNodePath = srcNodePath.slice(4);
}
- if(Phoenix.platform === "linux") {
+ if (Phoenix.platform === "linux") {
// in linux installed distributions, src-node is present in the same dir as the executable.
const cliArgs = await window.__TAURI__.invoke('_get_commandline_args');
- nodeSrcPath = `${window.path.dirname(cliArgs[0])}/src-node/index.js`;
+ srcNodePath = `${window.path.dirname(cliArgs[0])}/src-node/index.js`;
}
+ return srcNodePath;
+ }
+
+ async function _tauriNodeSetup() {
+ const nodeSrcPath = await _resolveSrcNodePath();
// node is designed such that it is not required at boot time to lower startup time.
// Keep this so to increase boot speed.
const inspectPort = Phoenix.isTestWindow ? getRandomNumber(5000, 50000) : 9229;