@edenapp/sdk 0.5.1 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-frame/frame-injector.js +6 -6
- package/dist/app-frame/frame-injector.js.map +3 -3
- package/dist/apps/prebuilt/com.eden.context-menu/dist/assets/{index-DUrqfNSi.js → index-B-ks_-b3.js} +1 -1
- package/dist/apps/prebuilt/com.eden.context-menu/dist/index.html +1 -1
- package/dist/apps/prebuilt/com.eden.eveshell/dist/assets/{index-CEfffVHu.js → index-CokBDS24.js} +1 -1
- package/dist/apps/prebuilt/com.eden.eveshell/dist/index.html +1 -1
- package/dist/apps/prebuilt/com.eden.eveshell/manifest.json +9 -1
- package/dist/apps/prebuilt/com.eden.example.hello/backend/node_modules/@edenapp/types/AppManifest.d.ts +9 -3
- package/dist/apps/prebuilt/com.eden.example.hello/backend/node_modules/@edenapp/types/CHANGELOG.md +6 -0
- package/dist/apps/prebuilt/com.eden.example.hello/backend/node_modules/@edenapp/types/commands.generated.d.ts +61 -15
- package/dist/apps/prebuilt/com.eden.example.hello/backend/node_modules/@edenapp/types/global.d.ts +8 -3
- package/dist/apps/prebuilt/com.eden.example.hello/backend/node_modules/@edenapp/types/package.json +1 -1
- package/dist/apps/prebuilt/com.eden.example.hello/frontend/node_modules/@edenapp/types/AppManifest.d.ts +9 -3
- package/dist/apps/prebuilt/com.eden.example.hello/frontend/node_modules/@edenapp/types/CHANGELOG.md +6 -0
- package/dist/apps/prebuilt/com.eden.example.hello/frontend/node_modules/@edenapp/types/commands.generated.d.ts +61 -15
- package/dist/apps/prebuilt/com.eden.example.hello/frontend/node_modules/@edenapp/types/global.d.ts +8 -3
- package/dist/apps/prebuilt/com.eden.example.hello/frontend/node_modules/@edenapp/types/package.json +1 -1
- package/dist/apps/prebuilt/com.eden.login/dist/assets/{index-DyI95N2f.js → index-KswMPsHx.js} +1 -1
- package/dist/apps/prebuilt/com.eden.login/dist/index.html +1 -1
- package/dist/apps/prebuilt/com.eden.toaster/dist/assets/{index-C4cVyh7j.js → index-b5EUNXyn.js} +2 -2
- package/dist/apps/prebuilt/com.eden.toaster/dist/index.html +1 -1
- package/dist/generated/runtime.d.ts.map +1 -1
- package/dist/generated/runtime.js +6 -1
- package/dist/generated/runtime.js.map +1 -1
- package/dist/process-manager/ProcessHandler.d.ts +12 -0
- package/dist/process-manager/ProcessHandler.d.ts.map +1 -1
- package/dist/process-manager/ProcessHandler.js +24 -3
- package/dist/process-manager/ProcessHandler.js.map +1 -1
- package/dist/view-manager/ViewCreator.d.ts.map +1 -1
- package/dist/view-manager/ViewCreator.js +2 -1
- package/dist/view-manager/ViewCreator.js.map +1 -1
- package/dist/view-manager/ViewHandler.d.ts +67 -20
- package/dist/view-manager/ViewHandler.d.ts.map +1 -1
- package/dist/view-manager/ViewHandler.js +204 -122
- package/dist/view-manager/ViewHandler.js.map +1 -1
- package/package.json +4 -4
- package/dist/main.d.ts +0 -2
- package/dist/main.d.ts.map +0 -1
- package/dist/main.js +0 -15
- package/dist/main.js.map +0 -1
- package/dist/view-manager/DevToolsManager.d.ts +0 -29
- package/dist/view-manager/DevToolsManager.d.ts.map +0 -1
- package/dist/view-manager/DevToolsManager.js +0 -88
- package/dist/view-manager/DevToolsManager.js.map +0 -1
- package/dist/view-manager/LayoutCalculator.d.ts +0 -49
- package/dist/view-manager/LayoutCalculator.d.ts.map +0 -1
- package/dist/view-manager/LayoutCalculator.js +0 -94
- package/dist/view-manager/LayoutCalculator.js.map +0 -1
- package/dist/view-manager/TilingManager.d.ts +0 -61
- package/dist/view-manager/TilingManager.d.ts.map +0 -1
- package/dist/view-manager/TilingManager.js +0 -142
- package/dist/view-manager/TilingManager.js.map +0 -1
- package/dist/view-manager/ViewLifecycle.d.ts +0 -66
- package/dist/view-manager/ViewLifecycle.d.ts.map +0 -1
- package/dist/view-manager/ViewLifecycle.js +0 -142
- package/dist/view-manager/ViewLifecycle.js.map +0 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
"use strict";(()=>{var
|
|
2
|
-
`).slice(1);for(let
|
|
3
|
-
${
|
|
1
|
+
"use strict";(()=>{var A={trace:10,debug:20,info:30,warn:40,error:50,fatal:60};function k(e){if(!e)return null;let n=e.trim().toLowerCase();return n in A?n:null}function B(e,n){return A[e]>=A[n]}var M={},F=Q(),z={debug:console.debug.bind(console),warn:console.warn.bind(console),error:console.error.bind(console),info:console.log.bind(console)};function O(e){return{trace:(...n)=>E({level:"trace",args:n,context:e}),debug:(...n)=>E({level:"debug",args:n,context:e}),info:(...n)=>E({level:"info",args:n,context:e}),warn:(...n)=>E({level:"warn",args:n,context:e}),error:(...n)=>E({level:"error",args:n,context:e}),fatal:(...n)=>E({level:"fatal",args:n,context:e})}}var o=O();function E(e){let{level:n}=e;if(!B(n,F.minLevel))return;let t=e.timestamp??Date.now(),i=q(e.context),u=e.callsite??(F.includeCallsite&&!e.skipCallsite?j():void 0),p=F.format==="pretty"?K({level:n,timestamp:t,context:i,callsite:u}):"",r=J(n);p?r(p,...e.args):r(...e.args)}function q(e){return{...U(),...e}}function U(){let e=x("EDEN_APP_ID"),n=globalThis.__EDEN_APP_ID__;return{processType:R(),appId:M.appId??e??n,viewId:M.viewId,webContentsId:M.webContentsId,source:M.source}}function R(){let e=globalThis.process;if(e){let n=e.type;if(n==="browser")return"main";if(n==="utility")return"backend";if(n)return n}return typeof globalThis.window<"u"?"renderer":"node"}function Q(){let e=k(x("EDEN_LOG_LEVEL")),n=x("EDEN_LOG_FORMAT"),t=x("EDEN_LOG_PATH"),i=x("NODE_ENV")==="test",u=R()==="renderer";return{minLevel:e??"debug",format:n??(i||u?"raw":"pretty"),includeTimestamp:S("EDEN_LOG_TIMESTAMP",!i),includeCallsite:S("EDEN_LOG_CALLSITE",!i&&!u),pathMode:t??"short"}}function J(e){let n=x("NODE_ENV")==="test";switch(e){case"trace":case"debug":return n?console.debug.bind(console):z.debug;case"warn":return n?console.warn.bind(console):z.warn;case"error":case"fatal":return n?console.error.bind(console):z.error;case"info":default:return n?console.log.bind(console):z.info}}function K(e){let n=[];if(F.includeTimestamp&&n.push(new Date(e.timestamp).toISOString()),n.push(e.level.toUpperCase()),e.context?.processType&&n.push(e.context.processType),e.context?.appId&&n.push(`app=${e.context.appId}`),e.context?.viewId!==void 0&&n.push(`view=${e.context.viewId}`),e.context?.webContentsId!==void 0&&n.push(`wc=${e.context.webContentsId}`),e.context?.source&&n.push(e.context.source),e.callsite){let t=Z(e.callsite.file,F.pathMode);n.push(`${t}:${e.callsite.line}`)}return`[${n.join("] [")}]`}function j(){let e=new Error;Error.captureStackTrace?.(e,j);let n=e.stack;if(!n)return;let t=n.split(`
|
|
2
|
+
`).slice(1);for(let i of t){let u=i.trim();if(!u||u.includes("/logging/")||u.includes("\\logging\\"))continue;let p=u.match(/\(([^)]+):(\d+):(\d+)\)$/)??u.match(/at\s+([^\s]+):(\d+):(\d+)$/);if(!p)continue;let r=p[1],s=Number(p[2]),a=Number(p[3]);if(!(!r||Number.isNaN(s)))return{file:r,line:s,column:Number.isNaN(a)?void 0:a}}}function Z(e,n){if(n==="full")return e;if(n==="file")return e.replace(/^[^:]*[\\/]/,"")||e;let t=e;t.startsWith("file://")&&(t=t.slice(7));try{let s=globalThis.process;if(s?.cwd){let a=s.cwd();if(t.startsWith(a))return t.slice(a.length+1)}}catch{}let i=t.replace(/\\/g,"/"),u=i.lastIndexOf("/dist/");if(u>=0)return i.slice(u+1);let p=i.lastIndexOf("/sdk/");if(p>=0)return i.slice(p+1);let r=i.split("/").filter(Boolean);return r.length>=2?r.slice(-2).join("/"):i}function x(e){let n=globalThis.process;if(n?.env?.[e])return n.env[e];let t=globalThis[e];if(typeof t=="string")return t}function S(e,n){let t=x(e);if(t===void 0)return n;let i=t.trim().toLowerCase();return["1","true","yes","on"].includes(i)?!0:["0","false","no","off"].includes(i)?!1:n}async function _(){await window.edenAPI.shellCommand("process/exit",{})}async function P(){await window.edenAPI.shellCommand("view/set-visibility",{visible:!1})}async function D(){await window.edenAPI.shellCommand("view/toggle-mode",{}),o.info("View mode toggled")}function X(){let e=document.getElementById("eden-close-btn");e&&e.addEventListener("click",()=>{_().catch(o.error)})}function W(){let e=document.getElementById("eden-minimize-btn");e&&e.addEventListener("click",()=>{P().catch(o.error)})}function Y(){let e=document.getElementById("eden-toggle-mode-btn");e&&e.addEventListener("click",()=>{D().catch(o.error)})}function V(e){let n=document.createElement("div");n.id="eden-app-frame-overlay";let t=e.mode==="both",i=e.showTitle!==!1,u=t?'<button class="eden-app-frame-button toggle-mode" id="eden-toggle-mode-btn" title="Toggle Window Mode">\u229E</button>':"",p=i?'<div id="eden-app-frame-title">App</div>':"";return n.innerHTML=`
|
|
3
|
+
${p}
|
|
4
4
|
<div id="eden-app-frame-controls">
|
|
5
|
-
${
|
|
5
|
+
${u}
|
|
6
6
|
<button class="eden-app-frame-button minimize" id="eden-minimize-btn" title="Minimize">\u2212</button>
|
|
7
7
|
<button class="eden-app-frame-button close" id="eden-close-btn" title="Close">\xD7</button>
|
|
8
8
|
</div>
|
|
9
|
-
`,
|
|
9
|
+
`,n}function H(e,n){let t=()=>{o.info("injectOverlay called, body exists:",!!document.body),document.body?(document.body.insertBefore(e,document.body.firstChild),document.body.classList.add("eden-framed"),o.info("Overlay injected into body"),n&&n()):(o.info("Body not ready, retrying..."),setTimeout(t,10))};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",t):t()}function $(e){let n=window.matchMedia("(prefers-color-scheme: dark)"),t=i=>{i.matches?e.classList.add("dark"):e.classList.remove("dark")};t(n),n.addEventListener("change",t)}function y(e){let n=document.getElementById("eden-app-frame-title");n&&(n.textContent=e)}function I(e,n="en"){if(typeof e=="string"){let t=e.split("."),i=t[t.length-1]||e;return i.charAt(0).toUpperCase()+i.slice(1)}return e[n]||e.en||Object.values(e)[0]||"App"}function C(e){if("screenX"in e&&e.screenX!==void 0&&e.screenY!==void 0)return{x:e.screenX,y:e.screenY};if("touches"in e&&e.touches&&e.touches[0]){let n=e.touches[0];if(n.screenX!==void 0&&n.screenY!==void 0)return{x:n.screenX,y:n.screenY};let t=window.edenFrame?._internal.bounds;return t?{x:t.x+n.clientX,y:t.y+n.clientY}:{x:n.clientX+(window.screenX||0),y:n.clientY+(window.screenY||0)}}return{x:0,y:0}}function N(e,n,t){let i=!1,u=0,p=0,r=null,s=!1,a=null,g=null,d=t?.dragRegionSelector,c=()=>{g&&(window.edenAPI.shellCommand("view/update-bounds",{bounds:g}).catch(o.error),g=null),i&&(a=requestAnimationFrame(c))},m=l=>{let h=l.target instanceof Element?l.target:null;if(!h)return;if(d){if(!h.closest(d)||h.closest("[data-eden-no-drag]"))return}else if(h.closest(".eden-app-frame-button"))return;let b=window.edenFrame?._internal.bounds;if(b&&b.x!==void 0)n.current={...b},o.info(n.current);else if(!n.current){o.warn("Cannot start drag - currentBounds not initialized!");return}i=!0,s=l.type.startsWith("touch");let v=C(l);u=v.x,p=v.y,r={...n.current},l.preventDefault(),l.stopPropagation(),l.stopImmediatePropagation(),s&&(a=requestAnimationFrame(c)),s||window.edenAPI.shellCommand("view/start-drag",{startX:v.x,startY:v.y}).catch(o.error),s||window.addEventListener("mouseup",f)},w=l=>{if(l.preventDefault(),l.stopPropagation(),!i||!r)return;let h=C(l),b=h.x-u,v=h.y-p,L={x:r.x+b,y:r.y+v,width:r.width,height:r.height};n.current=L,g=L},f=l=>{l.type.startsWith("touch")&&l.touches&&l.touches.length>0||i&&(i=!1,r=null,window.removeEventListener("mouseup",f),a&&(cancelAnimationFrame(a),a=null,g&&(window.edenAPI.shellCommand("view/update-bounds",{bounds:g}).catch(o.error),window.edenFrame._internal.bounds={...g},g=null)),s&&n.current&&(window.edenFrame._internal.bounds={...n.current},o.info("Updated edenFrame._internal.bounds after touch drag:",window.edenFrame?._internal.bounds)),s||window.edenAPI.shellCommand("view/end-drag",{}).catch(o.error),window.edenAPI.shellCommand("view/focus",{}).catch(o.error))};return e.addEventListener("mousedown",m),e.addEventListener("touchstart",m,{passive:!1}),document.addEventListener("touchmove",w,{passive:!1,capture:!0}),document.addEventListener("touchend",f,{passive:!1}),document.addEventListener("touchcancel",f,{passive:!1}),o.info("Drag event listeners registered"),()=>{e.removeEventListener("mousedown",m),e.removeEventListener("touchstart",m),document.removeEventListener("touchmove",w,{capture:!0}),document.removeEventListener("touchend",f),document.removeEventListener("touchcancel",f),window.removeEventListener("mouseup",f),a&&cancelAnimationFrame(a),o.info("Drag event listeners removed")}}function G(e,n){let t=document.createElement("div");t.id="eden-resize-handle",t.style.cssText=`
|
|
10
10
|
position: fixed;
|
|
11
11
|
bottom: 0;
|
|
12
12
|
right: 0;
|
|
@@ -16,5 +16,5 @@
|
|
|
16
16
|
z-index: 2147483647;
|
|
17
17
|
-webkit-app-region: no-drag;
|
|
18
18
|
touch-action: none;
|
|
19
|
-
`,document.body.appendChild(t);let
|
|
19
|
+
`,document.body.appendChild(t);let i=!1,u=0,p=0,r=null,s=!1,a=null,g=null,d=()=>{g&&(window.edenAPI.shellCommand("view/update-bounds",{bounds:g}).catch(o.error),g=null),i&&(a=requestAnimationFrame(d))},c=f=>{if(!n.current){let h=window.edenFrame?._internal.bounds;if(h&&h.x!==void 0)n.current={...h},o.info("Initialized currentBounds from edenFrame._internal.bounds:",n.current);else{o.warn("Cannot start resize - currentBounds not initialized!");return}}i=!0,s=f.type.startsWith("touch");let l=C(f);u=l.x,p=l.y,r={...n.current},f.preventDefault(),f.stopPropagation(),s&&(a=requestAnimationFrame(d)),s||window.edenAPI.shellCommand("view/start-resize",{startX:l.x,startY:l.y}).catch(o.error),s||window.addEventListener("mouseup",w)},m=f=>{if(o.info("moveResize called, isResizing:",i,"event type:",f.type),f.preventDefault(),f.stopPropagation(),!i||!r){o.info("moveResize returning early - isResizing:",i,"resizeStartBounds:",r);return}let l=C(f),h=l.x-u,b=l.y-p;o.info("moveResize coords:",l,"delta:",{deltaX:h,deltaY:b});let v=r.width+h,L=r.height+b;e.minSize?(v=Math.max(v,e.minSize.width||200),L=Math.max(L,e.minSize.height||200)):(v=Math.max(v,200),L=Math.max(L,200)),e.maxSize&&(v=Math.min(v,e.maxSize.width||2e3),L=Math.min(L,e.maxSize.height||2e3));let T={x:r.x,y:r.y,width:Math.round(v),height:Math.round(L)};o.info("moveResize newBounds:",T),n.current=T,g=T},w=f=>{i&&(i=!1,r=null,window.removeEventListener("mouseup",w),a&&(cancelAnimationFrame(a),a=null,g&&(window.edenAPI.shellCommand("view/update-bounds",{bounds:g}).catch(o.error),window.edenFrame._internal.bounds={...g},g=null)),s&&n.current&&(window.edenFrame._internal.bounds={...n.current},o.info("Updated edenFrame._internal.bounds after touch resize:",window.edenFrame?._internal.bounds)),s||window.edenAPI.shellCommand("view/end-resize",{}).catch(o.error),window.edenAPI.shellCommand("view/focus",{}).catch(o.error))};return t.addEventListener("mousedown",c),t.addEventListener("touchstart",c,{passive:!1}),document.addEventListener("touchmove",m,{passive:!1,capture:!0}),document.addEventListener("touchend",w,{passive:!1}),document.addEventListener("touchcancel",w,{passive:!1}),o.info("Resize event listeners registered"),()=>{t.parentNode&&t.parentNode.removeChild(t),t.removeEventListener("mousedown",c),t.removeEventListener("touchstart",c),document.removeEventListener("touchmove",m,{capture:!0}),document.removeEventListener("touchend",w),document.removeEventListener("touchcancel",w),window.removeEventListener("mouseup",w),a&&cancelAnimationFrame(a),o.info("Resize event listeners removed")}}(()=>{if(o.info("Injection script started"),window.edenFrame||(window.edenFrame={setTitle:d=>{},resetTitle:()=>{},close:async()=>{},minimize:async()=>{},toggleMode:async()=>{},_internal:{appId:"",appName:"",injected:!1,config:{},currentMode:"tiled",bounds:{x:0,y:0,width:0,height:0}}}),window.edenFrame.setTitle||(window.edenFrame.setTitle=()=>{}),window.edenFrame.resetTitle||(window.edenFrame.resetTitle=()=>{}),window.edenFrame.close||(window.edenFrame.close=async()=>{}),window.edenFrame.minimize||(window.edenFrame.minimize=async()=>{}),window.edenFrame.toggleMode||(window.edenFrame.toggleMode=async()=>{}),window.edenFrame._internal.injected){o.info("Already injected, skipping");return}window.edenFrame._internal.injected=!0;let e="App",n={current:null},t=null,i=null,r=(window.edenFrame._internal.config.injections?.appFrame==="window-only"?"window-only":"full")==="full",s=r?V(window.edenFrame._internal.config):null,a=()=>{if(window.edenFrame){let d=window.edenFrame._internal.appName;e=I(d,"en"),r&&(window.edenAPI.shellCommand("i18n/get-locale",{}).then(c=>{let w=c?.locale||"en";e=I(d,w),y(e)}).catch(()=>{e=I(d,"en"),y(e)}),y(e),window.edenAPI.subscribe("i18n/locale-changed",c=>{let m=c.locale,w=I(d,m);y(w),e=w}))}r&&(X(),W(),Y()),g(),window.edenAPI.subscribe("view/mode-changed",d=>{let{mode:c,bounds:m}=d;o.info("View mode changed to:",c,"with bounds:",m),window.edenFrame._internal.currentMode=c,m&&m.x!==void 0&&(window.edenFrame._internal.bounds=m,n.current={...m}),g()}),o.info("Subscribed to view/mode-changed")},g=()=>{let d=window.edenFrame._internal.currentMode,c=window.edenFrame._internal.config,m=window.edenFrame._internal.bounds;if(o.info("Window mode:",m),t&&(t(),t=null),i&&(i(),i=null),d!=="floating")return;if(m&&m.x!==void 0)n.current={...m},o.info("Initialized bounds from backend:",n.current);else if(c.defaultSize){let b=c.defaultPosition?.x||0,v=c.defaultPosition?.y||0;n.current={x:0+b,y:0+v,width:c.defaultSize.width||800,height:c.defaultSize.height||600},o.info("Initialized bounds from config:",n.current)}let w=c.movable!==!1,f=c.resizable!==!1;o.info("Movable:",w,"Resizable:",f),w&&(s?t=N(s,n):t=N(document,n,{dragRegionSelector:"[data-eden-drag-region]"})),f&&(i=G(c,n))};window.edenAPI.subscribe("view/bounds-updated",d=>{n.current={...d},window.edenFrame._internal.bounds={...d}}),o.info("Subscribed to view/bounds-updated"),document.addEventListener("touchstart",d=>{o.info("Global touchstart on:",d.target)},{passive:!1,capture:!0}),document.addEventListener("touchcancel",d=>{o.info("Global touchcancel on:",d.target),o.info("Stack trace:",new Error().stack)},{capture:!0}),s?H(s,()=>{$(s),a()}):document.readyState==="loading"?document.addEventListener("DOMContentLoaded",a):a(),window.edenFrame.setTitle=d=>{y(d)},window.edenFrame.resetTitle=()=>{y(e)},window.edenFrame.close=()=>_(),window.edenFrame.minimize=()=>P(),window.edenFrame.toggleMode=()=>D()})();})();
|
|
20
20
|
//# sourceMappingURL=frame-injector.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/logging/levels.ts", "../../src/logging/logger.ts", "../../src/app-frame/button-handlers.ts", "../../src/app-frame/ui-builder.ts", "../../src/app-frame/utils.ts", "../../src/app-frame/window-dragging.ts", "../../src/app-frame/window-resizing.ts", "../../src/app-frame/frame-injector.ts"],
|
|
4
|
-
"sourcesContent": ["export type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n\nexport const LOG_LEVEL_ORDER: Record<LogLevel, number> = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n fatal: 60,\n};\n\nexport function parseLogLevel(value?: string | null): LogLevel | null {\n if (!value) return null;\n const normalized = value.trim().toLowerCase();\n if (normalized in LOG_LEVEL_ORDER) {\n return normalized as LogLevel;\n }\n return null;\n}\n\nexport function isLogLevelEnabled(\n level: LogLevel,\n minLevel: LogLevel,\n): boolean {\n return LOG_LEVEL_ORDER[level] >= LOG_LEVEL_ORDER[minLevel];\n}\n", "import type { LogLevel } from \"./levels\";\nimport { isLogLevelEnabled, parseLogLevel } from \"./levels\";\n\nexport type LogFormat = \"pretty\" | \"raw\";\nexport type LogPathMode = \"short\" | \"full\" | \"file\";\n\nexport interface LogContext {\n appId?: string;\n viewId?: number;\n webContentsId?: number;\n processType?: string;\n source?: string;\n}\n\nexport interface CallsiteInfo {\n file: string;\n line: number;\n column?: number;\n}\n\nexport interface LoggerConfig {\n minLevel: LogLevel;\n format: LogFormat;\n includeTimestamp: boolean;\n includeCallsite: boolean;\n pathMode: LogPathMode;\n}\n\nexport interface Logger {\n trace: (...args: unknown[]) => void;\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n fatal: (...args: unknown[]) => void;\n}\n\ninterface LogRecord {\n level: LogLevel;\n args: unknown[];\n context?: LogContext;\n callsite?: CallsiteInfo;\n timestamp?: number;\n skipCallsite?: boolean;\n}\n\nlet globalContext: LogContext = {};\n\nlet config: LoggerConfig = resolveDefaultConfig();\nconst baseConsole = {\n debug: console.debug.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n info: console.log.bind(console),\n};\n\nexport function configureLogger(next: Partial<LoggerConfig>): void {\n config = { ...config, ...next };\n}\n\nexport function getLoggerConfig(): LoggerConfig {\n return config;\n}\n\nexport function setLogContext(next: Partial<LogContext>): void {\n globalContext = { ...globalContext, ...next };\n}\n\nexport function createLogger(context?: LogContext): Logger {\n return {\n trace: (...args) => emit({ level: \"trace\", args, context }),\n debug: (...args) => emit({ level: \"debug\", args, context }),\n info: (...args) => emit({ level: \"info\", args, context }),\n warn: (...args) => emit({ level: \"warn\", args, context }),\n error: (...args) => emit({ level: \"error\", args, context }),\n fatal: (...args) => emit({ level: \"fatal\", args, context }),\n };\n}\n\nexport const log: Logger = createLogger();\n\nexport function logExternal(record: {\n level: LogLevel;\n message: string;\n context?: LogContext;\n callsite?: CallsiteInfo;\n}): void {\n emit({\n level: record.level,\n args: [record.message],\n context: record.context,\n callsite: record.callsite,\n skipCallsite: true,\n });\n}\n\nexport function logFromConsole(record: {\n level: LogLevel;\n args: unknown[];\n context?: LogContext;\n callsite?: CallsiteInfo;\n}): void {\n emit({\n level: record.level,\n args: record.args,\n context: record.context,\n callsite: record.callsite,\n skipCallsite: true,\n });\n}\n\nfunction emit(record: LogRecord): void {\n const { level } = record;\n if (!isLogLevelEnabled(level, config.minLevel)) return;\n\n const timestamp = record.timestamp ?? Date.now();\n const context = mergeContext(record.context);\n const callsite =\n record.callsite ??\n (config.includeCallsite && !record.skipCallsite\n ? captureCallsite()\n : undefined);\n\n const prefix =\n config.format === \"pretty\"\n ? formatPrefix({ level, timestamp, context, callsite })\n : \"\";\n\n const target = consoleForLevel(level);\n if (prefix) {\n target(prefix, ...record.args);\n } else {\n target(...record.args);\n }\n}\n\nfunction mergeContext(context?: LogContext): LogContext {\n const base = getBaseContext();\n return { ...base, ...context };\n}\n\nfunction getBaseContext(): LogContext {\n const envAppId = getEnvValue(\"EDEN_APP_ID\");\n const globalAppId = (globalThis as any).__EDEN_APP_ID__ as string | undefined;\n return {\n processType: detectProcessType(),\n appId: globalContext.appId ?? envAppId ?? globalAppId,\n viewId: globalContext.viewId,\n webContentsId: globalContext.webContentsId,\n source: globalContext.source,\n };\n}\n\nfunction detectProcessType(): string {\n const processObj = (globalThis as any).process as\n | { type?: string; env?: Record<string, string>; cwd?: () => string }\n | undefined;\n if (processObj) {\n const type = processObj.type;\n if (type === \"browser\") return \"main\";\n if (type === \"utility\") return \"backend\";\n if (type) return type;\n }\n if (typeof (globalThis as any).window !== \"undefined\") return \"renderer\";\n return \"node\";\n}\n\nfunction resolveDefaultConfig(): LoggerConfig {\n const envLevel = parseLogLevel(getEnvValue(\"EDEN_LOG_LEVEL\"));\n const envFormat = getEnvValue(\"EDEN_LOG_FORMAT\") as LogFormat | undefined;\n const envPathMode = getEnvValue(\"EDEN_LOG_PATH\") as LogPathMode | undefined;\n const isTest = getEnvValue(\"NODE_ENV\") === \"test\";\n const isRenderer = detectProcessType() === \"renderer\";\n\n return {\n minLevel: envLevel ?? \"debug\",\n format: envFormat ?? (isTest || isRenderer ? \"raw\" : \"pretty\"),\n includeTimestamp: getEnvBool(\"EDEN_LOG_TIMESTAMP\", !isTest),\n includeCallsite: getEnvBool(\"EDEN_LOG_CALLSITE\", !isTest && !isRenderer),\n pathMode: envPathMode ?? \"short\",\n };\n}\n\nfunction consoleForLevel(level: LogLevel): (...args: unknown[]) => void {\n const useLiveConsole = getEnvValue(\"NODE_ENV\") === \"test\";\n switch (level) {\n case \"trace\":\n case \"debug\":\n return useLiveConsole ? console.debug.bind(console) : baseConsole.debug;\n case \"warn\":\n return useLiveConsole ? console.warn.bind(console) : baseConsole.warn;\n case \"error\":\n case \"fatal\":\n return useLiveConsole ? console.error.bind(console) : baseConsole.error;\n case \"info\":\n default:\n return useLiveConsole ? console.log.bind(console) : baseConsole.info;\n }\n}\n\nfunction formatPrefix(record: {\n level: LogLevel;\n timestamp: number;\n context?: LogContext;\n callsite?: CallsiteInfo;\n}): string {\n const parts: string[] = [];\n\n if (config.includeTimestamp) {\n parts.push(new Date(record.timestamp).toISOString());\n }\n\n parts.push(record.level.toUpperCase());\n\n if (record.context?.processType) {\n parts.push(record.context.processType);\n }\n if (record.context?.appId) {\n parts.push(`app=${record.context.appId}`);\n }\n if (record.context?.viewId !== undefined) {\n parts.push(`view=${record.context.viewId}`);\n }\n if (record.context?.webContentsId !== undefined) {\n parts.push(`wc=${record.context.webContentsId}`);\n }\n if (record.context?.source) {\n parts.push(record.context.source);\n }\n if (record.callsite) {\n const file = shortenPath(record.callsite.file, config.pathMode);\n parts.push(`${file}:${record.callsite.line}`);\n }\n\n return `[${parts.join(\"] [\")}]`;\n}\n\nfunction captureCallsite(): CallsiteInfo | undefined {\n const err = new Error();\n (Error as any).captureStackTrace?.(err, captureCallsite);\n const stack = err.stack;\n if (!stack) return undefined;\n\n const lines = stack.split(\"\\n\").slice(1);\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.includes(\"/logging/\") || trimmed.includes(\"\\\\logging\\\\\")) {\n continue;\n }\n\n const match =\n trimmed.match(/\\(([^)]+):(\\d+):(\\d+)\\)$/) ??\n trimmed.match(/at\\s+([^\\s]+):(\\d+):(\\d+)$/);\n\n if (!match) continue;\n\n const file = match[1];\n const lineNumber = Number(match[2]);\n const columnNumber = Number(match[3]);\n\n if (!file || Number.isNaN(lineNumber)) continue;\n\n return {\n file,\n line: lineNumber,\n column: Number.isNaN(columnNumber) ? undefined : columnNumber,\n };\n }\n\n return undefined;\n}\n\nfunction shortenPath(path: string, mode: LogPathMode): string {\n if (mode === \"full\") return path;\n if (mode === \"file\") {\n const cleaned = path.replace(/^[^:]*[\\\\/]/, \"\");\n return cleaned || path;\n }\n\n let normalized = path;\n if (normalized.startsWith(\"file://\")) {\n normalized = normalized.slice(\"file://\".length);\n }\n\n try {\n const processObj = (globalThis as any).process as\n | { cwd?: () => string }\n | undefined;\n if (processObj?.cwd) {\n const cwd = processObj.cwd();\n if (normalized.startsWith(cwd)) {\n return normalized.slice(cwd.length + 1);\n }\n }\n } catch {\n // Ignore errors resolving cwd\n }\n\n const normalizedPath = normalized.replace(/\\\\/g, \"/\");\n const distIndex = normalizedPath.lastIndexOf(\"/dist/\");\n if (distIndex >= 0) {\n return normalizedPath.slice(distIndex + 1);\n }\n\n const sdkIndex = normalizedPath.lastIndexOf(\"/sdk/\");\n if (sdkIndex >= 0) {\n return normalizedPath.slice(sdkIndex + 1);\n }\n\n const segments = normalizedPath.split(\"/\").filter(Boolean);\n if (segments.length >= 2) {\n return segments.slice(-2).join(\"/\");\n }\n\n return normalizedPath;\n}\n\nfunction getEnvValue(key: string): string | undefined {\n const processObj = (globalThis as any).process as\n | { env?: Record<string, string> }\n | undefined;\n if (processObj?.env?.[key]) {\n return processObj.env[key];\n }\n const globalValue = (globalThis as any)[key];\n if (typeof globalValue === \"string\") {\n return globalValue;\n }\n return undefined;\n}\n\nfunction getEnvBool(key: string, fallback: boolean): boolean {\n const value = getEnvValue(key);\n if (value === undefined) return fallback;\n const normalized = value.trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) return true;\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) return false;\n return fallback;\n}\n", "import { log } from \"../logging\";\n/**\n * App Frame Button Handlers\n *\n * Event handlers for frame control buttons (close, minimize, toggle mode)\n */\n\n/**\n * Setup close button handler\n */\nexport function setupCloseButton(): void {\n const closeBtn = document.getElementById(\"eden-close-btn\");\n if (!closeBtn) return;\n\n closeBtn.addEventListener(\"click\", () => {\n // Wait for edenFrame to be available\n const stopApp = () => {\n const appId = window.edenFrame?._internal.appId;\n log.info(\"Stopping app:\", appId);\n\n if (appId) {\n window.edenAPI.shellCommand(\"process/stop\", { appId }).catch(log.error);\n } else {\n // Retry if API or appId not yet available\n setTimeout(stopApp, 100);\n }\n };\n stopApp();\n });\n}\n\n/**\n * Setup minimize button handler\n */\nexport function setupMinimizeButton(): void {\n const minBtn = document.getElementById(\"eden-minimize-btn\");\n if (!minBtn) return;\n\n minBtn.addEventListener(\"click\", () => {\n const minimize = () => {\n const appId = window.edenFrame?._internal.appId;\n\n if (appId) {\n window.edenAPI\n .shellCommand(\"view/set-view-visibility\", {\n appId,\n visible: false,\n })\n .catch(log.error);\n } else {\n setTimeout(minimize, 100);\n }\n };\n minimize();\n });\n}\n\n/**\n * Setup toggle mode button handler (for apps that support both tiled and floating)\n */\nexport function setupToggleModeButton(): void {\n const toggleBtn = document.getElementById(\"eden-toggle-mode-btn\");\n if (!toggleBtn) return;\n\n toggleBtn.addEventListener(\"click\", () => {\n const toggleMode = () => {\n const appId = window.edenFrame?._internal.appId;\n\n if (appId) {\n window.edenAPI\n .shellCommand(\"view/toggle-view-mode\", {\n appId,\n })\n .then(() => {\n log.info(\"View mode toggled\");\n })\n .catch(log.error);\n } else {\n setTimeout(toggleMode, 100);\n }\n };\n toggleMode();\n });\n}\n", "import { log } from \"../logging\";\n/**\n * App Frame UI Builder\n *\n * Functions for creating and managing the app frame overlay UI\n */\n\n/**\n * Create the app frame overlay element\n * @param windowConfig - Window configuration from manifest\n * @returns The overlay element\n */\nexport function createOverlay(\n windowConfig: NonNullable<Window[\"edenFrame\"]>[\"_internal\"][\"config\"],\n): HTMLElement {\n const overlay = document.createElement(\"div\");\n overlay.id = \"eden-app-frame-overlay\";\n\n const supportsToggle = windowConfig.mode === \"both\";\n const showTitle = windowConfig.showTitle !== false; // Default to true if not specified\n\n // Create toggle button HTML if supported\n const toggleButtonHtml = supportsToggle\n ? `<button class=\"eden-app-frame-button toggle-mode\" id=\"eden-toggle-mode-btn\" title=\"Toggle Window Mode\">\u229E</button>`\n : \"\";\n\n // Create title HTML if showTitle is true\n const titleHtml = showTitle ? `<div id=\"eden-app-frame-title\">App</div>` : \"\";\n\n overlay.innerHTML = `\n ${titleHtml}\n <div id=\"eden-app-frame-controls\">\n ${toggleButtonHtml}\n <button class=\"eden-app-frame-button minimize\" id=\"eden-minimize-btn\" title=\"Minimize\">\u2212</button>\n <button class=\"eden-app-frame-button close\" id=\"eden-close-btn\" title=\"Close\">\u00D7</button>\n </div>\n `;\n\n return overlay;\n}\n\n/**\n * Inject the overlay into the DOM when ready\n * @param overlay - The overlay element to inject\n * @param callback - Called after injection\n */\nexport function injectOverlay(\n overlay: HTMLElement,\n callback?: () => void,\n): void {\n const inject = () => {\n log.info(\"injectOverlay called, body exists:\", !!document.body);\n if (document.body) {\n document.body.insertBefore(overlay, document.body.firstChild);\n document.body.classList.add(\"eden-framed\");\n log.info(\"Overlay injected into body\");\n\n if (callback) {\n callback();\n }\n } else {\n log.info(\"Body not ready, retrying...\");\n setTimeout(inject, 10);\n }\n };\n\n // Inject when DOM is ready\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", inject);\n } else {\n inject();\n }\n}\n\n/**\n * Setup dark mode detection and updates\n * @param overlay - The overlay element\n */\nexport function setupDarkMode(overlay: HTMLElement): void {\n const prefersDark = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n const updateTheme = (e: MediaQueryListEvent | MediaQueryList) => {\n if (e.matches) {\n overlay.classList.add(\"dark\");\n } else {\n overlay.classList.remove(\"dark\");\n }\n };\n\n updateTheme(prefersDark);\n prefersDark.addEventListener(\"change\", updateTheme);\n}\n\n/**\n * Set the title bar text\n * @param title - The title to display\n */\nexport function setTitle(title: string): void {\n const titleEl = document.getElementById(\"eden-app-frame-title\");\n if (titleEl) {\n titleEl.textContent = title;\n }\n}\n\n/**\n * Extract a readable name from app ID\n * @param name - The app name (string or localized object)\n * @param locale - The locale to use (default 'en')\n * @returns Readable name\n */\nexport function getAppName(\n name: string | Record<string, string>,\n locale: string = \"en\",\n): string {\n if (typeof name === \"string\") {\n const parts = name.split(\".\");\n const readable = parts[parts.length - 1] || name;\n return readable.charAt(0).toUpperCase() + readable.slice(1);\n }\n\n return name[locale] || name[\"en\"] || Object.values(name)[0] || \"App\";\n}\n", "/**\n * App Frame Utilities\n *\n * Shared utility functions for the app frame\n */\n\n/**\n * Get screen coordinates from mouse or touch event\n * @param e - The event\n * @returns Screen coordinates\n */\nexport function getScreenCoords(e: MouseEvent | TouchEvent): {\n x: number;\n y: number;\n} {\n // For mouse events, use screenX/screenY directly\n if (\"screenX\" in e && e.screenX !== undefined && e.screenY !== undefined) {\n return { x: e.screenX, y: e.screenY };\n }\n\n // For touch events, calculate screen coordinates from client coordinates\n if (\"touches\" in e && e.touches && e.touches[0]) {\n const touch = e.touches[0];\n // Try touch.screenX/screenY first (if available)\n if (touch.screenX !== undefined && touch.screenY !== undefined) {\n return { x: touch.screenX, y: touch.screenY };\n }\n // Fallback: calculate from clientX/clientY + view bounds position\n // Use currentBounds which has the actual view position\n const currentBounds = window.edenFrame?._internal.bounds;\n if (currentBounds) {\n return {\n x: currentBounds.x + touch.clientX,\n y: currentBounds.y + touch.clientY,\n };\n }\n // Last resort: use window.screenX/screenY\n return {\n x: touch.clientX + (window.screenX || 0),\n y: touch.clientY + (window.screenY || 0),\n };\n }\n\n return { x: 0, y: 0 };\n}\n", "import { log } from \"../logging\";\n/**\n * Window Dragging\n *\n * Handles dragging for floating windows\n */\n\nimport { getScreenCoords } from \"./utils\";\n\n/**\n * Setup window dragging for floating windows\n * @param overlay - The title bar overlay element\n * @param currentBoundsRef - Reference object containing current bounds\n */\nexport function setupWindowDragging(\n overlay: HTMLElement,\n currentBoundsRef: {\n current: { x: number; y: number; width: number; height: number } | null;\n },\n): () => void {\n let isDragging = false;\n let startX = 0;\n let startY = 0;\n let dragStartBounds: {\n x: number;\n y: number;\n width: number;\n height: number;\n } | null = null;\n let isTouch = false;\n let rafId: number | null = null;\n let pendingBounds: {\n x: number;\n y: number;\n width: number;\n height: number;\n } | null = null;\n\n // Animation frame update function - throttles IPC to 60fps\n const updatePosition = () => {\n const appId = window.edenFrame?._internal.appId;\n if (pendingBounds && appId) {\n window.edenAPI\n .shellCommand(\"view/update-view-bounds\", {\n appId,\n bounds: pendingBounds,\n })\n .catch(log.error);\n\n pendingBounds = null;\n }\n\n if (isDragging) {\n rafId = requestAnimationFrame(updatePosition);\n }\n };\n\n const startDrag = (e: MouseEvent | TouchEvent) => {\n // Only drag on the title bar itself, not on buttons\n if ((e.target as HTMLElement).closest(\".eden-app-frame-button\")) {\n return;\n }\n\n // ALWAYS refresh currentBounds at start to handle case where mouse drag updated position\n const initialBounds = window.edenFrame?._internal.bounds;\n if (initialBounds && initialBounds.x !== undefined) {\n currentBoundsRef.current = { ...initialBounds };\n log.info(currentBoundsRef.current);\n } else if (!currentBoundsRef.current) {\n log.warn(\"Cannot start drag - currentBounds not initialized!\");\n return;\n }\n\n isDragging = true;\n isTouch = e.type.startsWith(\"touch\");\n\n // Get screen coordinates\n const coords = getScreenCoords(e);\n startX = coords.x;\n startY = coords.y;\n dragStartBounds = { ...currentBoundsRef.current };\n\n // IMPORTANT: Prevent default FIRST to stop touch from being canceled\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n\n // Start animation frame loop for smooth updates\n if (isTouch) {\n rafId = requestAnimationFrame(updatePosition);\n }\n\n const appId = window.edenFrame?._internal.appId;\n\n // NOTE: We do NOT call focus-app here anymore.\n // On macOS (and Linux touch), calling focus-app during drag start causes view reordering\n // which cancels the drag/touch event. Instead, we bring the window to front after drag ends.\n\n // For mouse events, use global tracking in main process\n // For touch events, we'll handle updates in touchmove\n if (!isTouch && appId) {\n window.edenAPI\n .shellCommand(\"view/start-drag\", {\n appId,\n startX: coords.x,\n startY: coords.y,\n })\n .catch(log.error);\n }\n\n // Add mouseup listener when drag starts (removed when drag ends)\n if (!isTouch) {\n window.addEventListener(\"mouseup\", endDrag);\n }\n };\n\n const moveDrag = (e: MouseEvent | TouchEvent) => {\n // Prevent default immediately\n e.preventDefault();\n e.stopPropagation();\n\n if (!isDragging || !dragStartBounds) {\n return;\n }\n\n // Get current coordinates\n const coords = getScreenCoords(e);\n const deltaX = coords.x - startX;\n const deltaY = coords.y - startY;\n\n const newBounds = {\n x: dragStartBounds.x + deltaX,\n y: dragStartBounds.y + deltaY,\n width: dragStartBounds.width,\n height: dragStartBounds.height,\n };\n\n // Update tracked bounds immediately for next move calculation\n currentBoundsRef.current = newBounds;\n\n // Store pending update for next animation frame\n pendingBounds = newBounds;\n };\n\n const endDrag = (e: MouseEvent | TouchEvent) => {\n // For touch events, only end if there are no remaining touches\n if (\n e.type.startsWith(\"touch\") &&\n (e as TouchEvent).touches &&\n (e as TouchEvent).touches.length > 0\n ) {\n return;\n }\n\n if (!isDragging) {\n return;\n }\n\n isDragging = false;\n dragStartBounds = null;\n\n // Remove mouseup listener since drag is done\n window.removeEventListener(\"mouseup\", endDrag);\n\n const appId = window.edenFrame?._internal.appId;\n\n // Cancel animation frame and send final position\n if (rafId) {\n cancelAnimationFrame(rafId);\n rafId = null;\n\n // Send final pending bounds immediately\n if (pendingBounds && appId) {\n window.edenAPI\n .shellCommand(\"view/update-view-bounds\", {\n appId,\n bounds: pendingBounds,\n })\n .catch(log.error);\n\n // Update edenFrame._internal.bounds so next interaction starts from correct position\n window.edenFrame!._internal.bounds = { ...pendingBounds };\n pendingBounds = null;\n }\n }\n\n // For touch drag, ensure edenFrame._internal.bounds is updated with final position\n if (isTouch && currentBoundsRef.current) {\n window.edenFrame!._internal.bounds = { ...currentBoundsRef.current };\n log.info(\n \"Updated edenFrame._internal.bounds after touch drag:\",\n window.edenFrame?._internal.bounds,\n );\n }\n\n // Stop global drag tracking in main process (for mouse events)\n if (!isTouch && appId) {\n window.edenAPI.shellCommand(\"view/end-drag\", { appId }).catch(log.error);\n }\n\n if (appId) {\n window.edenAPI.shellCommand(\"view/focus-app\", { appId }).catch(log.error);\n }\n };\n\n // Mouse events\n overlay.addEventListener(\"mousedown\", startDrag);\n\n // Touch events - don't use capture for start, do use for move\n overlay.addEventListener(\"touchstart\", startDrag, { passive: false });\n\n // Move events for touch (mouse uses main process tracking)\n // Use capture for move to ensure we get it\n document.addEventListener(\"touchmove\", moveDrag as EventListener, {\n passive: false,\n capture: true,\n });\n\n // Touch end/cancel events (mouseup is added dynamically when drag starts)\n document.addEventListener(\"touchend\", endDrag, { passive: false });\n document.addEventListener(\"touchcancel\", endDrag, { passive: false });\n\n log.info(\"Drag event listeners registered\");\n\n return () => {\n overlay.removeEventListener(\"mousedown\", startDrag);\n overlay.removeEventListener(\"touchstart\", startDrag);\n document.removeEventListener(\"touchmove\", moveDrag as EventListener, {\n capture: true,\n });\n document.removeEventListener(\"touchend\", endDrag);\n document.removeEventListener(\"touchcancel\", endDrag);\n window.removeEventListener(\"mouseup\", endDrag);\n\n if (rafId) {\n cancelAnimationFrame(rafId);\n }\n log.info(\"Drag event listeners removed\");\n };\n}\n", "import { log } from \"../logging\";\n/**\n * Window Resizing\n *\n * Handles resizing for floating windows\n */\n\nimport { getScreenCoords } from \"./utils.js\";\n\ninterface Bounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\ninterface BoundsRef {\n current: Bounds | null;\n}\n\n/**\n * Setup window resizing for floating windows\n */\n/**\n * Setup window resizing for floating windows\n */\nexport function setupWindowResizing(\n windowConfig: NonNullable<Window[\"edenFrame\"]>[\"_internal\"][\"config\"],\n currentBoundsRef: BoundsRef,\n): () => void {\n // Create resize handle in bottom-right corner\n const resizeHandle = document.createElement(\"div\");\n resizeHandle.id = \"eden-resize-handle\";\n resizeHandle.style.cssText = `\n position: fixed;\n bottom: 0;\n right: 0;\n width: 20px;\n height: 20px;\n cursor: nwse-resize;\n z-index: 2147483647;\n -webkit-app-region: no-drag;\n touch-action: none;\n `;\n\n document.body.appendChild(resizeHandle);\n\n let isResizing = false;\n let startX = 0;\n let startY = 0;\n let resizeStartBounds: Bounds | null = null;\n let isTouch = false;\n let rafId: number | null = null;\n let pendingBounds: Bounds | null = null;\n\n // Animation frame update function - throttles IPC to 60fps\n const updateResizePosition = () => {\n const appId = window.edenFrame?._internal.appId;\n if (pendingBounds && appId) {\n window.edenAPI\n .shellCommand(\"view/update-view-bounds\", {\n appId,\n bounds: pendingBounds,\n })\n .catch(log.error);\n\n pendingBounds = null;\n }\n\n if (isResizing) {\n rafId = requestAnimationFrame(updateResizePosition);\n }\n };\n\n const startResize = (e: MouseEvent | TouchEvent): void => {\n // Initialize current bounds if not set\n if (!currentBoundsRef.current) {\n const initialBounds = window.edenFrame?._internal.bounds;\n if (initialBounds && initialBounds.x !== undefined) {\n currentBoundsRef.current = { ...initialBounds };\n log.info(\n \"Initialized currentBounds from edenFrame._internal.bounds:\",\n currentBoundsRef.current,\n );\n } else {\n log.warn(\"Cannot start resize - currentBounds not initialized!\");\n return;\n }\n }\n\n isResizing = true;\n isTouch = e.type.startsWith(\"touch\");\n\n // Get screen coordinates\n const coords = getScreenCoords(e);\n startX = coords.x;\n startY = coords.y;\n resizeStartBounds = { ...currentBoundsRef.current };\n\n e.preventDefault();\n e.stopPropagation();\n\n // Start animation frame loop for smooth updates\n if (isTouch) {\n rafId = requestAnimationFrame(updateResizePosition);\n }\n\n const appId = window.edenFrame?._internal.appId;\n\n // NOTE: We do NOT call focus-app here anymore.\n // On macOS (and Linux touch), calling focus-app during resize start causes view reordering\n // which cancels the resize/touch event. Instead, we bring the window to front after resize ends.\n\n // For mouse events, use global tracking in main process\n // For touch events, we'll handle updates in touchmove\n if (!isTouch && appId) {\n window.edenAPI\n .shellCommand(\"view/start-resize\", {\n appId,\n startX: coords.x,\n startY: coords.y,\n })\n .catch(log.error);\n }\n\n // Add mouseup listener when resize starts (removed when resize ends)\n if (!isTouch) {\n window.addEventListener(\"mouseup\", endResize);\n }\n };\n\n const moveResize = (e: MouseEvent | TouchEvent): void => {\n log.info(\n \"moveResize called, isResizing:\",\n isResizing,\n \"event type:\",\n e.type,\n );\n\n e.preventDefault();\n e.stopPropagation();\n\n if (!isResizing || !resizeStartBounds) {\n log.info(\n \"moveResize returning early - isResizing:\",\n isResizing,\n \"resizeStartBounds:\",\n resizeStartBounds,\n );\n return;\n }\n\n // Get current coordinates\n const coords = getScreenCoords(e);\n const deltaX = coords.x - startX;\n const deltaY = coords.y - startY;\n\n log.info(\"moveResize coords:\", coords, \"delta:\", {\n deltaX,\n deltaY,\n });\n\n let newWidth = resizeStartBounds.width + deltaX;\n let newHeight = resizeStartBounds.height + deltaY;\n\n // Apply min/max constraints\n if (windowConfig.minSize) {\n newWidth = Math.max(newWidth, windowConfig.minSize.width || 200);\n newHeight = Math.max(newHeight, windowConfig.minSize.height || 200);\n } else {\n newWidth = Math.max(newWidth, 200);\n newHeight = Math.max(newHeight, 200);\n }\n\n if (windowConfig.maxSize) {\n newWidth = Math.min(newWidth, windowConfig.maxSize.width || 2000);\n newHeight = Math.min(newHeight, windowConfig.maxSize.height || 2000);\n }\n\n const newBounds = {\n x: resizeStartBounds.x,\n y: resizeStartBounds.y,\n width: Math.round(newWidth),\n height: Math.round(newHeight),\n };\n\n log.info(\"moveResize newBounds:\", newBounds);\n\n // Update tracked bounds immediately for next move calculation\n currentBoundsRef.current = newBounds;\n\n // Store pending update for next animation frame\n pendingBounds = newBounds;\n };\n\n const endResize = (e?: MouseEvent | TouchEvent): void => {\n if (!isResizing) {\n return;\n }\n\n isResizing = false;\n resizeStartBounds = null;\n\n // Remove mouseup listener since resize is done\n window.removeEventListener(\"mouseup\", endResize);\n\n const appId = window.edenFrame?._internal.appId;\n\n // Cancel animation frame and send final position\n if (rafId) {\n cancelAnimationFrame(rafId);\n rafId = null;\n\n // Send final pending bounds immediately\n if (pendingBounds && appId) {\n window.edenAPI\n .shellCommand(\"view/update-view-bounds\", {\n appId,\n bounds: pendingBounds,\n })\n .catch(log.error);\n\n // Update edenFrame._internal.bounds so next interaction starts from correct position\n window.edenFrame!._internal.bounds = { ...pendingBounds };\n pendingBounds = null;\n }\n }\n\n // For touch resize, ensure edenFrame._internal.bounds is updated with final position\n if (isTouch && currentBoundsRef.current) {\n window.edenFrame!._internal.bounds = { ...currentBoundsRef.current };\n log.info(\n \"Updated edenFrame._internal.bounds after touch resize:\",\n window.edenFrame?._internal.bounds,\n );\n }\n\n // Stop global resize tracking in main process (for mouse events)\n if (!isTouch && appId) {\n window.edenAPI\n .shellCommand(\"view/end-resize\", { appId })\n .catch(log.error);\n }\n\n if (appId) {\n window.edenAPI.shellCommand(\"view/focus-app\", { appId }).catch(log.error);\n }\n };\n\n // Mouse events\n resizeHandle.addEventListener(\"mousedown\", startResize);\n\n // Touch events\n resizeHandle.addEventListener(\"touchstart\", startResize, { passive: false });\n\n // Move events for touch (mouse uses main process tracking)\n // Use document and capture to ensure we get all touch moves\n document.addEventListener(\"touchmove\", moveResize, {\n passive: false,\n capture: true,\n });\n\n // Touch end/cancel events (mouseup is added dynamically when resize starts)\n document.addEventListener(\"touchend\", endResize, { passive: false });\n document.addEventListener(\"touchcancel\", endResize, { passive: false });\n\n log.info(\"Resize event listeners registered\");\n\n return () => {\n if (resizeHandle.parentNode) {\n resizeHandle.parentNode.removeChild(resizeHandle);\n }\n\n resizeHandle.removeEventListener(\"mousedown\", startResize);\n resizeHandle.removeEventListener(\"touchstart\", startResize);\n\n document.removeEventListener(\"touchmove\", moveResize, {\n capture: true,\n });\n document.removeEventListener(\"touchend\", endResize);\n document.removeEventListener(\"touchcancel\", endResize);\n window.removeEventListener(\"mouseup\", endResize);\n\n if (rafId) {\n cancelAnimationFrame(rafId);\n }\n log.info(\"Resize event listeners removed\");\n };\n}\n", "import { log } from \"../logging\";\n\n/**\n * Eden App Frame Injector\n *\n * Main orchestrator for the app frame system.\n * This script is injected into every app to add a title bar with controls.\n */\n\nimport {\n setupCloseButton,\n setupMinimizeButton,\n setupToggleModeButton,\n} from \"./button-handlers.js\";\nimport {\n createOverlay,\n getAppName,\n injectOverlay,\n setTitle,\n setupDarkMode,\n} from \"./ui-builder.js\";\nimport { setupWindowDragging } from \"./window-dragging.js\";\nimport { setupWindowResizing } from \"./window-resizing.js\";\n\n(() => {\n log.info(\"Injection script started\");\n\n // Initialize edenFrame object if not exists\n if (!window.edenFrame) {\n window.edenFrame = {\n setTitle: (title: string) => {\n /* will be set later */\n },\n resetTitle: () => {\n /* will be set later */\n },\n _internal: {\n appId: \"\",\n appName: \"\" as string | Record<string, string>,\n injected: false,\n config: {},\n currentMode: \"tiled\",\n bounds: { x: 0, y: 0, width: 0, height: 0 },\n },\n };\n }\n\n // Check if already injected\n if (window.edenFrame._internal.injected) {\n log.info(\"Already injected, skipping\");\n return;\n }\n window.edenFrame._internal.injected = true;\n\n let appId: string | null = null;\n let appName: string = \"App\";\n\n // Track current window bounds for floating windows\n // Using an object reference so we can update it and have the change reflected in all modules\n const currentBoundsRef: {\n current: { x: number; y: number; width: number; height: number } | null;\n } = { current: null };\n\n let cleanupDrag: (() => void) | null = null;\n let cleanupResize: (() => void) | null = null;\n\n // Create the overlay\n const overlay = createOverlay(window.edenFrame._internal.config);\n\n // Setup handlers after overlay is injected\n const setupHandlers = (): void => {\n // Get appId from injected config\n if (window.edenFrame && window.edenFrame._internal.appId) {\n appId = window.edenFrame._internal.appId;\n const rawName = window.edenFrame._internal.appName;\n\n // Async fetch locale\n window.edenAPI\n .shellCommand(\"i18n/get-locale\", {})\n .then((response: { locale: string }) => {\n const locale = response?.locale;\n const currentLocale = locale || \"en\";\n appName = getAppName(rawName, currentLocale);\n setTitle(appName);\n\n // Update resetTitle to use this locale\n if (window.edenFrame) {\n window.edenFrame.setTitle = (title: string) => setTitle(title);\n (window.edenFrame as any).resetTitle = () => setTitle(appName);\n }\n })\n .catch(() => {\n appName = getAppName(rawName, \"en\");\n setTitle(appName);\n if (window.edenFrame) {\n window.edenFrame.setTitle = (title: string) => setTitle(title);\n (window.edenFrame as any).resetTitle = () => setTitle(appName);\n }\n });\n\n // Set initial title (english fallback) to avoid empty title while fetching\n setTitle(getAppName(rawName, \"en\"));\n\n // Subscribe to locale changes for live updates\n window.edenAPI.subscribe(\n \"i18n/locale-changed\",\n (data: { locale: string }) => {\n const newLocale = data.locale;\n const currentName = getAppName(rawName, newLocale);\n\n // Update title\n setTitle(currentName);\n\n // Update resetTitle to use the new locale\n if (window.edenFrame) {\n (window.edenFrame as any).resetTitle = () => setTitle(currentName);\n }\n },\n );\n }\n\n // Setup button handlers\n setupCloseButton();\n setupMinimizeButton();\n setupToggleModeButton();\n\n // Setup floating window controls\n setupFloatingWindowControls();\n\n window.edenAPI.subscribe(\n \"view/mode-changed\",\n (data: { mode: \"tiled\" | \"floating\"; bounds: any }) => {\n const { mode, bounds } = data;\n log.info(\"View mode changed to:\", mode, \"with bounds:\", bounds);\n\n // Update window mode and bounds\n window.edenFrame!._internal.currentMode = mode;\n if (bounds && bounds.x !== undefined) {\n window.edenFrame!._internal.bounds = bounds;\n currentBoundsRef.current = { ...bounds };\n }\n\n // Re-setup controls for new mode\n setupFloatingWindowControls();\n },\n );\n log.info(\"Subscribed to view/mode-changed\");\n };\n\n const setupFloatingWindowControls = (): void => {\n const windowMode = window.edenFrame!._internal.currentMode;\n const windowConfig = window.edenFrame!._internal.config;\n const initialBounds = window.edenFrame!._internal.bounds;\n\n log.info(\"Window mode:\", initialBounds);\n\n // Clean up previous controls if they exist (crucial for mode switching)\n if (cleanupDrag) {\n cleanupDrag();\n cleanupDrag = null;\n }\n if (cleanupResize) {\n cleanupResize();\n cleanupResize = null;\n }\n\n // Only enable dragging/resizing for floating windows\n if (windowMode !== \"floating\") {\n // If we are not floating, we just returned after cleanup, so handles are gone.\n return;\n }\n\n // Initialize current bounds from the actual bounds set by ViewManager\n if (initialBounds && initialBounds.x !== undefined) {\n currentBoundsRef.current = { ...initialBounds };\n log.info(\"Initialized bounds from backend:\", currentBoundsRef.current);\n } else if (windowConfig.defaultSize) {\n // Fallback to config if no initial bounds provided\n const workspaceX = 0;\n const workspaceY = 0;\n\n const x = windowConfig.defaultPosition?.x || 0;\n const y = windowConfig.defaultPosition?.y || 0;\n\n currentBoundsRef.current = {\n x: workspaceX + x,\n y: workspaceY + y,\n width: windowConfig.defaultSize.width || 800,\n height: windowConfig.defaultSize.height || 600,\n };\n\n log.info(\"Initialized bounds from config:\", currentBoundsRef.current);\n }\n\n // Check if dragging is allowed\n const isMovable = windowConfig.movable !== false; // default true\n const isResizable = windowConfig.resizable !== false; // default true\n\n log.info(\"Movable:\", isMovable, \"Resizable:\", isResizable);\n\n // Setup window dragging\n if (isMovable) {\n cleanupDrag = setupWindowDragging(overlay, currentBoundsRef);\n }\n\n // Setup window resizing\n if (isResizable) {\n cleanupResize = setupWindowResizing(windowConfig, currentBoundsRef);\n }\n };\n\n // Listen for bounds updates from main process (during mouse drag/resize)\n // This keeps currentBounds in sync even when main process is controlling movement\n window.edenAPI.subscribe(\"view/bounds-updated\", (newBounds) => {\n currentBoundsRef.current = { ...newBounds };\n window.edenFrame!._internal.bounds = { ...newBounds };\n });\n log.info(\"Subscribed to view/bounds-updated\");\n\n // Add global touch handler to diagnose issues\n document.addEventListener(\n \"touchstart\",\n (e) => {\n log.info(\"Global touchstart on:\", e.target);\n },\n { passive: false, capture: true },\n );\n\n document.addEventListener(\n \"touchcancel\",\n (e) => {\n log.info(\"Global touchcancel on:\", e.target);\n log.info(\"Stack trace:\", new Error().stack);\n },\n { capture: true },\n );\n\n // Inject overlay and setup handlers\n injectOverlay(overlay, () => {\n setupDarkMode(overlay);\n setupHandlers();\n });\n\n // Expose API for apps to update the title\n window.edenFrame.setTitle = (title: string) => {\n setTitle(title);\n };\n\n // Expose resetTitle immediately (using English/default name initially)\n // This will be updated to use the correct locale once fetched\n window.edenFrame.resetTitle = () => {\n // If locale hasn't loaded yet, getAppName will use 'en' fallback\n if (window.edenFrame) {\n const currentName = getAppName(\n window.edenFrame._internal.appName || window.edenFrame._internal.appId,\n \"en\",\n );\n setTitle(currentName);\n }\n };\n})();\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["LOG_LEVEL_ORDER", "parseLogLevel", "value", "normalized", "isLogLevelEnabled", "level", "minLevel", "globalContext", "config", "resolveDefaultConfig", "baseConsole", "createLogger", "context", "args", "emit", "log", "emit", "record", "level", "isLogLevelEnabled", "config", "timestamp", "context", "mergeContext", "callsite", "captureCallsite", "prefix", "formatPrefix", "target", "consoleForLevel", "getBaseContext", "envAppId", "getEnvValue", "globalAppId", "detectProcessType", "globalContext", "processObj", "type", "resolveDefaultConfig", "envLevel", "parseLogLevel", "envFormat", "envPathMode", "isTest", "isRenderer", "getEnvBool", "useLiveConsole", "baseConsole", "parts", "file", "shortenPath", "err", "stack", "lines", "line", "trimmed", "match", "lineNumber", "columnNumber", "path", "mode", "normalized", "cwd", "normalizedPath", "distIndex", "sdkIndex", "segments", "key", "globalValue", "fallback", "value", "
|
|
4
|
+
"sourcesContent": ["export type LogLevel = \"trace\" | \"debug\" | \"info\" | \"warn\" | \"error\" | \"fatal\";\n\nexport const LOG_LEVEL_ORDER: Record<LogLevel, number> = {\n trace: 10,\n debug: 20,\n info: 30,\n warn: 40,\n error: 50,\n fatal: 60,\n};\n\nexport function parseLogLevel(value?: string | null): LogLevel | null {\n if (!value) return null;\n const normalized = value.trim().toLowerCase();\n if (normalized in LOG_LEVEL_ORDER) {\n return normalized as LogLevel;\n }\n return null;\n}\n\nexport function isLogLevelEnabled(\n level: LogLevel,\n minLevel: LogLevel,\n): boolean {\n return LOG_LEVEL_ORDER[level] >= LOG_LEVEL_ORDER[minLevel];\n}\n", "import type { LogLevel } from \"./levels\";\nimport { isLogLevelEnabled, parseLogLevel } from \"./levels\";\n\nexport type LogFormat = \"pretty\" | \"raw\";\nexport type LogPathMode = \"short\" | \"full\" | \"file\";\n\nexport interface LogContext {\n appId?: string;\n viewId?: number;\n webContentsId?: number;\n processType?: string;\n source?: string;\n}\n\nexport interface CallsiteInfo {\n file: string;\n line: number;\n column?: number;\n}\n\nexport interface LoggerConfig {\n minLevel: LogLevel;\n format: LogFormat;\n includeTimestamp: boolean;\n includeCallsite: boolean;\n pathMode: LogPathMode;\n}\n\nexport interface Logger {\n trace: (...args: unknown[]) => void;\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n fatal: (...args: unknown[]) => void;\n}\n\ninterface LogRecord {\n level: LogLevel;\n args: unknown[];\n context?: LogContext;\n callsite?: CallsiteInfo;\n timestamp?: number;\n skipCallsite?: boolean;\n}\n\nlet globalContext: LogContext = {};\n\nlet config: LoggerConfig = resolveDefaultConfig();\nconst baseConsole = {\n debug: console.debug.bind(console),\n warn: console.warn.bind(console),\n error: console.error.bind(console),\n info: console.log.bind(console),\n};\n\nexport function configureLogger(next: Partial<LoggerConfig>): void {\n config = { ...config, ...next };\n}\n\nexport function getLoggerConfig(): LoggerConfig {\n return config;\n}\n\nexport function setLogContext(next: Partial<LogContext>): void {\n globalContext = { ...globalContext, ...next };\n}\n\nexport function createLogger(context?: LogContext): Logger {\n return {\n trace: (...args) => emit({ level: \"trace\", args, context }),\n debug: (...args) => emit({ level: \"debug\", args, context }),\n info: (...args) => emit({ level: \"info\", args, context }),\n warn: (...args) => emit({ level: \"warn\", args, context }),\n error: (...args) => emit({ level: \"error\", args, context }),\n fatal: (...args) => emit({ level: \"fatal\", args, context }),\n };\n}\n\nexport const log: Logger = createLogger();\n\nexport function logExternal(record: {\n level: LogLevel;\n message: string;\n context?: LogContext;\n callsite?: CallsiteInfo;\n}): void {\n emit({\n level: record.level,\n args: [record.message],\n context: record.context,\n callsite: record.callsite,\n skipCallsite: true,\n });\n}\n\nexport function logFromConsole(record: {\n level: LogLevel;\n args: unknown[];\n context?: LogContext;\n callsite?: CallsiteInfo;\n}): void {\n emit({\n level: record.level,\n args: record.args,\n context: record.context,\n callsite: record.callsite,\n skipCallsite: true,\n });\n}\n\nfunction emit(record: LogRecord): void {\n const { level } = record;\n if (!isLogLevelEnabled(level, config.minLevel)) return;\n\n const timestamp = record.timestamp ?? Date.now();\n const context = mergeContext(record.context);\n const callsite =\n record.callsite ??\n (config.includeCallsite && !record.skipCallsite\n ? captureCallsite()\n : undefined);\n\n const prefix =\n config.format === \"pretty\"\n ? formatPrefix({ level, timestamp, context, callsite })\n : \"\";\n\n const target = consoleForLevel(level);\n if (prefix) {\n target(prefix, ...record.args);\n } else {\n target(...record.args);\n }\n}\n\nfunction mergeContext(context?: LogContext): LogContext {\n const base = getBaseContext();\n return { ...base, ...context };\n}\n\nfunction getBaseContext(): LogContext {\n const envAppId = getEnvValue(\"EDEN_APP_ID\");\n const globalAppId = (globalThis as any).__EDEN_APP_ID__ as string | undefined;\n return {\n processType: detectProcessType(),\n appId: globalContext.appId ?? envAppId ?? globalAppId,\n viewId: globalContext.viewId,\n webContentsId: globalContext.webContentsId,\n source: globalContext.source,\n };\n}\n\nfunction detectProcessType(): string {\n const processObj = (globalThis as any).process as\n | { type?: string; env?: Record<string, string>; cwd?: () => string }\n | undefined;\n if (processObj) {\n const type = processObj.type;\n if (type === \"browser\") return \"main\";\n if (type === \"utility\") return \"backend\";\n if (type) return type;\n }\n if (typeof (globalThis as any).window !== \"undefined\") return \"renderer\";\n return \"node\";\n}\n\nfunction resolveDefaultConfig(): LoggerConfig {\n const envLevel = parseLogLevel(getEnvValue(\"EDEN_LOG_LEVEL\"));\n const envFormat = getEnvValue(\"EDEN_LOG_FORMAT\") as LogFormat | undefined;\n const envPathMode = getEnvValue(\"EDEN_LOG_PATH\") as LogPathMode | undefined;\n const isTest = getEnvValue(\"NODE_ENV\") === \"test\";\n const isRenderer = detectProcessType() === \"renderer\";\n\n return {\n minLevel: envLevel ?? \"debug\",\n format: envFormat ?? (isTest || isRenderer ? \"raw\" : \"pretty\"),\n includeTimestamp: getEnvBool(\"EDEN_LOG_TIMESTAMP\", !isTest),\n includeCallsite: getEnvBool(\"EDEN_LOG_CALLSITE\", !isTest && !isRenderer),\n pathMode: envPathMode ?? \"short\",\n };\n}\n\nfunction consoleForLevel(level: LogLevel): (...args: unknown[]) => void {\n const useLiveConsole = getEnvValue(\"NODE_ENV\") === \"test\";\n switch (level) {\n case \"trace\":\n case \"debug\":\n return useLiveConsole ? console.debug.bind(console) : baseConsole.debug;\n case \"warn\":\n return useLiveConsole ? console.warn.bind(console) : baseConsole.warn;\n case \"error\":\n case \"fatal\":\n return useLiveConsole ? console.error.bind(console) : baseConsole.error;\n case \"info\":\n default:\n return useLiveConsole ? console.log.bind(console) : baseConsole.info;\n }\n}\n\nfunction formatPrefix(record: {\n level: LogLevel;\n timestamp: number;\n context?: LogContext;\n callsite?: CallsiteInfo;\n}): string {\n const parts: string[] = [];\n\n if (config.includeTimestamp) {\n parts.push(new Date(record.timestamp).toISOString());\n }\n\n parts.push(record.level.toUpperCase());\n\n if (record.context?.processType) {\n parts.push(record.context.processType);\n }\n if (record.context?.appId) {\n parts.push(`app=${record.context.appId}`);\n }\n if (record.context?.viewId !== undefined) {\n parts.push(`view=${record.context.viewId}`);\n }\n if (record.context?.webContentsId !== undefined) {\n parts.push(`wc=${record.context.webContentsId}`);\n }\n if (record.context?.source) {\n parts.push(record.context.source);\n }\n if (record.callsite) {\n const file = shortenPath(record.callsite.file, config.pathMode);\n parts.push(`${file}:${record.callsite.line}`);\n }\n\n return `[${parts.join(\"] [\")}]`;\n}\n\nfunction captureCallsite(): CallsiteInfo | undefined {\n const err = new Error();\n (Error as any).captureStackTrace?.(err, captureCallsite);\n const stack = err.stack;\n if (!stack) return undefined;\n\n const lines = stack.split(\"\\n\").slice(1);\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n if (trimmed.includes(\"/logging/\") || trimmed.includes(\"\\\\logging\\\\\")) {\n continue;\n }\n\n const match =\n trimmed.match(/\\(([^)]+):(\\d+):(\\d+)\\)$/) ??\n trimmed.match(/at\\s+([^\\s]+):(\\d+):(\\d+)$/);\n\n if (!match) continue;\n\n const file = match[1];\n const lineNumber = Number(match[2]);\n const columnNumber = Number(match[3]);\n\n if (!file || Number.isNaN(lineNumber)) continue;\n\n return {\n file,\n line: lineNumber,\n column: Number.isNaN(columnNumber) ? undefined : columnNumber,\n };\n }\n\n return undefined;\n}\n\nfunction shortenPath(path: string, mode: LogPathMode): string {\n if (mode === \"full\") return path;\n if (mode === \"file\") {\n const cleaned = path.replace(/^[^:]*[\\\\/]/, \"\");\n return cleaned || path;\n }\n\n let normalized = path;\n if (normalized.startsWith(\"file://\")) {\n normalized = normalized.slice(\"file://\".length);\n }\n\n try {\n const processObj = (globalThis as any).process as\n | { cwd?: () => string }\n | undefined;\n if (processObj?.cwd) {\n const cwd = processObj.cwd();\n if (normalized.startsWith(cwd)) {\n return normalized.slice(cwd.length + 1);\n }\n }\n } catch {\n // Ignore errors resolving cwd\n }\n\n const normalizedPath = normalized.replace(/\\\\/g, \"/\");\n const distIndex = normalizedPath.lastIndexOf(\"/dist/\");\n if (distIndex >= 0) {\n return normalizedPath.slice(distIndex + 1);\n }\n\n const sdkIndex = normalizedPath.lastIndexOf(\"/sdk/\");\n if (sdkIndex >= 0) {\n return normalizedPath.slice(sdkIndex + 1);\n }\n\n const segments = normalizedPath.split(\"/\").filter(Boolean);\n if (segments.length >= 2) {\n return segments.slice(-2).join(\"/\");\n }\n\n return normalizedPath;\n}\n\nfunction getEnvValue(key: string): string | undefined {\n const processObj = (globalThis as any).process as\n | { env?: Record<string, string> }\n | undefined;\n if (processObj?.env?.[key]) {\n return processObj.env[key];\n }\n const globalValue = (globalThis as any)[key];\n if (typeof globalValue === \"string\") {\n return globalValue;\n }\n return undefined;\n}\n\nfunction getEnvBool(key: string, fallback: boolean): boolean {\n const value = getEnvValue(key);\n if (value === undefined) return fallback;\n const normalized = value.trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) return true;\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) return false;\n return fallback;\n}\n", "import { log } from \"../logging\";\n/**\n * App Frame Button Handlers\n *\n * Shared actions + event handlers for frame control buttons.\n */\n\nexport async function closeAppFrameView(): Promise<void> {\n await window.edenAPI.shellCommand(\"process/exit\", {});\n}\n\nexport async function minimizeAppFrameView(): Promise<void> {\n await window.edenAPI.shellCommand(\"view/set-visibility\", {\n visible: false,\n });\n}\n\nexport async function toggleAppFrameViewMode(): Promise<void> {\n await window.edenAPI.shellCommand(\"view/toggle-mode\", {});\n log.info(\"View mode toggled\");\n}\n\n/**\n * Setup close button handler\n */\nexport function setupCloseButton(): void {\n const closeBtn = document.getElementById(\"eden-close-btn\");\n if (!closeBtn) return;\n\n closeBtn.addEventListener(\"click\", () => {\n closeAppFrameView().catch(log.error);\n });\n}\n\n/**\n * Setup minimize button handler\n */\nexport function setupMinimizeButton(): void {\n const minBtn = document.getElementById(\"eden-minimize-btn\");\n if (!minBtn) return;\n\n minBtn.addEventListener(\"click\", () => {\n minimizeAppFrameView().catch(log.error);\n });\n}\n\n/**\n * Setup toggle mode button handler (for apps that support both tiled and floating)\n */\nexport function setupToggleModeButton(): void {\n const toggleBtn = document.getElementById(\"eden-toggle-mode-btn\");\n if (!toggleBtn) return;\n\n toggleBtn.addEventListener(\"click\", () => {\n toggleAppFrameViewMode().catch(log.error);\n });\n}\n", "import { log } from \"../logging\";\n/**\n * App Frame UI Builder\n *\n * Functions for creating and managing the app frame overlay UI\n */\n\n/**\n * Create the app frame overlay element\n * @param windowConfig - Window configuration from manifest\n * @returns The overlay element\n */\nexport function createOverlay(\n windowConfig: NonNullable<Window[\"edenFrame\"]>[\"_internal\"][\"config\"],\n): HTMLElement {\n const overlay = document.createElement(\"div\");\n overlay.id = \"eden-app-frame-overlay\";\n\n const supportsToggle = windowConfig.mode === \"both\";\n const showTitle = windowConfig.showTitle !== false; // Default to true if not specified\n\n // Create toggle button HTML if supported\n const toggleButtonHtml = supportsToggle\n ? `<button class=\"eden-app-frame-button toggle-mode\" id=\"eden-toggle-mode-btn\" title=\"Toggle Window Mode\">\u229E</button>`\n : \"\";\n\n // Create title HTML if showTitle is true\n const titleHtml = showTitle ? `<div id=\"eden-app-frame-title\">App</div>` : \"\";\n\n overlay.innerHTML = `\n ${titleHtml}\n <div id=\"eden-app-frame-controls\">\n ${toggleButtonHtml}\n <button class=\"eden-app-frame-button minimize\" id=\"eden-minimize-btn\" title=\"Minimize\">\u2212</button>\n <button class=\"eden-app-frame-button close\" id=\"eden-close-btn\" title=\"Close\">\u00D7</button>\n </div>\n `;\n\n return overlay;\n}\n\n/**\n * Inject the overlay into the DOM when ready\n * @param overlay - The overlay element to inject\n * @param callback - Called after injection\n */\nexport function injectOverlay(\n overlay: HTMLElement,\n callback?: () => void,\n): void {\n const inject = () => {\n log.info(\"injectOverlay called, body exists:\", !!document.body);\n if (document.body) {\n document.body.insertBefore(overlay, document.body.firstChild);\n document.body.classList.add(\"eden-framed\");\n log.info(\"Overlay injected into body\");\n\n if (callback) {\n callback();\n }\n } else {\n log.info(\"Body not ready, retrying...\");\n setTimeout(inject, 10);\n }\n };\n\n // Inject when DOM is ready\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", inject);\n } else {\n inject();\n }\n}\n\n/**\n * Setup dark mode detection and updates\n * @param overlay - The overlay element\n */\nexport function setupDarkMode(overlay: HTMLElement): void {\n const prefersDark = window.matchMedia(\"(prefers-color-scheme: dark)\");\n\n const updateTheme = (e: MediaQueryListEvent | MediaQueryList) => {\n if (e.matches) {\n overlay.classList.add(\"dark\");\n } else {\n overlay.classList.remove(\"dark\");\n }\n };\n\n updateTheme(prefersDark);\n prefersDark.addEventListener(\"change\", updateTheme);\n}\n\n/**\n * Set the title bar text\n * @param title - The title to display\n */\nexport function setTitle(title: string): void {\n const titleEl = document.getElementById(\"eden-app-frame-title\");\n if (titleEl) {\n titleEl.textContent = title;\n }\n}\n\n/**\n * Extract a readable name from app ID\n * @param name - The app name (string or localized object)\n * @param locale - The locale to use (default 'en')\n * @returns Readable name\n */\nexport function getAppName(\n name: string | Record<string, string>,\n locale: string = \"en\",\n): string {\n if (typeof name === \"string\") {\n const parts = name.split(\".\");\n const readable = parts[parts.length - 1] || name;\n return readable.charAt(0).toUpperCase() + readable.slice(1);\n }\n\n return name[locale] || name[\"en\"] || Object.values(name)[0] || \"App\";\n}\n", "/**\n * App Frame Utilities\n *\n * Shared utility functions for the app frame\n */\n\n/**\n * Get screen coordinates from mouse or touch event\n * @param e - The event\n * @returns Screen coordinates\n */\nexport function getScreenCoords(e: MouseEvent | TouchEvent): {\n x: number;\n y: number;\n} {\n // For mouse events, use screenX/screenY directly\n if (\"screenX\" in e && e.screenX !== undefined && e.screenY !== undefined) {\n return { x: e.screenX, y: e.screenY };\n }\n\n // For touch events, calculate screen coordinates from client coordinates\n if (\"touches\" in e && e.touches && e.touches[0]) {\n const touch = e.touches[0];\n // Try touch.screenX/screenY first (if available)\n if (touch.screenX !== undefined && touch.screenY !== undefined) {\n return { x: touch.screenX, y: touch.screenY };\n }\n // Fallback: calculate from clientX/clientY + view bounds position\n // Use currentBounds which has the actual view position\n const currentBounds = window.edenFrame?._internal.bounds;\n if (currentBounds) {\n return {\n x: currentBounds.x + touch.clientX,\n y: currentBounds.y + touch.clientY,\n };\n }\n // Last resort: use window.screenX/screenY\n return {\n x: touch.clientX + (window.screenX || 0),\n y: touch.clientY + (window.screenY || 0),\n };\n }\n\n return { x: 0, y: 0 };\n}\n", "import { log } from \"../logging\";\n/**\n * Window Dragging\n *\n * Handles dragging for floating windows\n */\n\nimport { getScreenCoords } from \"./utils\";\n\n/**\n * Setup window dragging for floating windows\n * @param dragSource - Event source (system overlay or document for custom drag regions)\n * @param currentBoundsRef - Reference object containing current bounds\n */\nexport function setupWindowDragging(\n dragSource: HTMLElement | Document,\n currentBoundsRef: {\n current: { x: number; y: number; width: number; height: number } | null;\n },\n options?: {\n dragRegionSelector?: string;\n },\n): () => void {\n let isDragging = false;\n let startX = 0;\n let startY = 0;\n let dragStartBounds: {\n x: number;\n y: number;\n width: number;\n height: number;\n } | null = null;\n let isTouch = false;\n let rafId: number | null = null;\n let pendingBounds: {\n x: number;\n y: number;\n width: number;\n height: number;\n } | null = null;\n\n const dragRegionSelector = options?.dragRegionSelector;\n\n // Animation frame update function - throttles IPC to 60fps\n const updatePosition = () => {\n if (pendingBounds) {\n window.edenAPI\n .shellCommand(\"view/update-bounds\", {\n bounds: pendingBounds,\n })\n .catch(log.error);\n\n pendingBounds = null;\n }\n\n if (isDragging) {\n rafId = requestAnimationFrame(updatePosition);\n }\n };\n\n const startDrag = (e: MouseEvent | TouchEvent) => {\n const target = e.target instanceof Element ? e.target : null;\n if (!target) {\n return;\n }\n\n // In custom mode, only start drag from explicit drag regions.\n if (dragRegionSelector) {\n if (!target.closest(dragRegionSelector)) {\n return;\n }\n // Allow opt-out for interactive controls inside a drag region.\n if (target.closest(\"[data-eden-no-drag]\")) {\n return;\n }\n } else if (target.closest(\".eden-app-frame-button\")) {\n // In system top bar mode, don't drag on frame buttons.\n return;\n }\n\n // ALWAYS refresh currentBounds at start to handle case where mouse drag updated position\n const initialBounds = window.edenFrame?._internal.bounds;\n if (initialBounds && initialBounds.x !== undefined) {\n currentBoundsRef.current = { ...initialBounds };\n log.info(currentBoundsRef.current);\n } else if (!currentBoundsRef.current) {\n log.warn(\"Cannot start drag - currentBounds not initialized!\");\n return;\n }\n\n isDragging = true;\n isTouch = e.type.startsWith(\"touch\");\n\n // Get screen coordinates\n const coords = getScreenCoords(e);\n startX = coords.x;\n startY = coords.y;\n dragStartBounds = { ...currentBoundsRef.current };\n\n // IMPORTANT: Prevent default FIRST to stop touch from being canceled\n e.preventDefault();\n e.stopPropagation();\n e.stopImmediatePropagation();\n\n // Start animation frame loop for smooth updates\n if (isTouch) {\n rafId = requestAnimationFrame(updatePosition);\n }\n\n // NOTE: We do NOT call focus here anymore.\n // On macOS (and Linux touch), calling focus during drag start causes view reordering\n // which cancels the drag/touch event. Instead, we bring the window to front after drag ends.\n\n // For mouse events, use global tracking in main process\n // For touch events, we'll handle updates in touchmove\n if (!isTouch) {\n window.edenAPI\n .shellCommand(\"view/start-drag\", {\n startX: coords.x,\n startY: coords.y,\n })\n .catch(log.error);\n }\n\n // Add mouseup listener when drag starts (removed when drag ends)\n if (!isTouch) {\n window.addEventListener(\"mouseup\", endDrag);\n }\n };\n\n const moveDrag = (e: MouseEvent | TouchEvent) => {\n // Prevent default immediately\n e.preventDefault();\n e.stopPropagation();\n\n if (!isDragging || !dragStartBounds) {\n return;\n }\n\n // Get current coordinates\n const coords = getScreenCoords(e);\n const deltaX = coords.x - startX;\n const deltaY = coords.y - startY;\n\n const newBounds = {\n x: dragStartBounds.x + deltaX,\n y: dragStartBounds.y + deltaY,\n width: dragStartBounds.width,\n height: dragStartBounds.height,\n };\n\n // Update tracked bounds immediately for next move calculation\n currentBoundsRef.current = newBounds;\n\n // Store pending update for next animation frame\n pendingBounds = newBounds;\n };\n\n const endDrag = (e: MouseEvent | TouchEvent) => {\n // For touch events, only end if there are no remaining touches\n if (\n e.type.startsWith(\"touch\") &&\n (e as TouchEvent).touches &&\n (e as TouchEvent).touches.length > 0\n ) {\n return;\n }\n\n if (!isDragging) {\n return;\n }\n\n isDragging = false;\n dragStartBounds = null;\n\n // Remove mouseup listener since drag is done\n window.removeEventListener(\"mouseup\", endDrag);\n\n // Cancel animation frame and send final position\n if (rafId) {\n cancelAnimationFrame(rafId);\n rafId = null;\n\n // Send final pending bounds immediately\n if (pendingBounds) {\n window.edenAPI\n .shellCommand(\"view/update-bounds\", {\n bounds: pendingBounds,\n })\n .catch(log.error);\n\n // Update edenFrame._internal.bounds so next interaction starts from correct position\n window.edenFrame!._internal.bounds = { ...pendingBounds };\n pendingBounds = null;\n }\n }\n\n // For touch drag, ensure edenFrame._internal.bounds is updated with final position\n if (isTouch && currentBoundsRef.current) {\n window.edenFrame!._internal.bounds = { ...currentBoundsRef.current };\n log.info(\n \"Updated edenFrame._internal.bounds after touch drag:\",\n window.edenFrame?._internal.bounds,\n );\n }\n\n // Stop global drag tracking in main process (for mouse events)\n if (!isTouch) {\n window.edenAPI.shellCommand(\"view/end-drag\", {}).catch(log.error);\n }\n\n window.edenAPI.shellCommand(\"view/focus\", {}).catch(log.error);\n };\n\n // Mouse events\n dragSource.addEventListener(\"mousedown\", startDrag as EventListener);\n\n // Touch events - don't use capture for start, do use for move\n dragSource.addEventListener(\"touchstart\", startDrag as EventListener, {\n passive: false,\n });\n\n // Move events for touch (mouse uses main process tracking)\n // Use capture for move to ensure we get it\n document.addEventListener(\"touchmove\", moveDrag as EventListener, {\n passive: false,\n capture: true,\n });\n\n // Touch end/cancel events (mouseup is added dynamically when drag starts)\n document.addEventListener(\"touchend\", endDrag, { passive: false });\n document.addEventListener(\"touchcancel\", endDrag, { passive: false });\n\n log.info(\"Drag event listeners registered\");\n\n return () => {\n dragSource.removeEventListener(\"mousedown\", startDrag as EventListener);\n dragSource.removeEventListener(\"touchstart\", startDrag as EventListener);\n document.removeEventListener(\"touchmove\", moveDrag as EventListener, {\n capture: true,\n });\n document.removeEventListener(\"touchend\", endDrag);\n document.removeEventListener(\"touchcancel\", endDrag);\n window.removeEventListener(\"mouseup\", endDrag);\n\n if (rafId) {\n cancelAnimationFrame(rafId);\n }\n log.info(\"Drag event listeners removed\");\n };\n}\n", "import { log } from \"../logging\";\n/**\n * Window Resizing\n *\n * Handles resizing for floating windows\n */\n\nimport { getScreenCoords } from \"./utils.js\";\n\ninterface Bounds {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\ninterface BoundsRef {\n current: Bounds | null;\n}\n\n/**\n * Setup window resizing for floating windows\n */\n/**\n * Setup window resizing for floating windows\n */\nexport function setupWindowResizing(\n windowConfig: NonNullable<Window[\"edenFrame\"]>[\"_internal\"][\"config\"],\n currentBoundsRef: BoundsRef,\n): () => void {\n // Create resize handle in bottom-right corner\n const resizeHandle = document.createElement(\"div\");\n resizeHandle.id = \"eden-resize-handle\";\n resizeHandle.style.cssText = `\n position: fixed;\n bottom: 0;\n right: 0;\n width: 20px;\n height: 20px;\n cursor: nwse-resize;\n z-index: 2147483647;\n -webkit-app-region: no-drag;\n touch-action: none;\n `;\n\n document.body.appendChild(resizeHandle);\n\n let isResizing = false;\n let startX = 0;\n let startY = 0;\n let resizeStartBounds: Bounds | null = null;\n let isTouch = false;\n let rafId: number | null = null;\n let pendingBounds: Bounds | null = null;\n\n // Animation frame update function - throttles IPC to 60fps\n const updateResizePosition = () => {\n if (pendingBounds) {\n window.edenAPI\n .shellCommand(\"view/update-bounds\", {\n bounds: pendingBounds,\n })\n .catch(log.error);\n\n pendingBounds = null;\n }\n\n if (isResizing) {\n rafId = requestAnimationFrame(updateResizePosition);\n }\n };\n\n const startResize = (e: MouseEvent | TouchEvent): void => {\n // Initialize current bounds if not set\n if (!currentBoundsRef.current) {\n const initialBounds = window.edenFrame?._internal.bounds;\n if (initialBounds && initialBounds.x !== undefined) {\n currentBoundsRef.current = { ...initialBounds };\n log.info(\n \"Initialized currentBounds from edenFrame._internal.bounds:\",\n currentBoundsRef.current,\n );\n } else {\n log.warn(\"Cannot start resize - currentBounds not initialized!\");\n return;\n }\n }\n\n isResizing = true;\n isTouch = e.type.startsWith(\"touch\");\n\n // Get screen coordinates\n const coords = getScreenCoords(e);\n startX = coords.x;\n startY = coords.y;\n resizeStartBounds = { ...currentBoundsRef.current };\n\n e.preventDefault();\n e.stopPropagation();\n\n // Start animation frame loop for smooth updates\n if (isTouch) {\n rafId = requestAnimationFrame(updateResizePosition);\n }\n\n // NOTE: We do NOT call focus here anymore.\n // On macOS (and Linux touch), calling focus during resize start causes view reordering\n // which cancels the resize/touch event. Instead, we bring the window to front after resize ends.\n\n // For mouse events, use global tracking in main process\n // For touch events, we'll handle updates in touchmove\n if (!isTouch) {\n window.edenAPI\n .shellCommand(\"view/start-resize\", {\n startX: coords.x,\n startY: coords.y,\n })\n .catch(log.error);\n }\n\n // Add mouseup listener when resize starts (removed when resize ends)\n if (!isTouch) {\n window.addEventListener(\"mouseup\", endResize);\n }\n };\n\n const moveResize = (e: MouseEvent | TouchEvent): void => {\n log.info(\n \"moveResize called, isResizing:\",\n isResizing,\n \"event type:\",\n e.type,\n );\n\n e.preventDefault();\n e.stopPropagation();\n\n if (!isResizing || !resizeStartBounds) {\n log.info(\n \"moveResize returning early - isResizing:\",\n isResizing,\n \"resizeStartBounds:\",\n resizeStartBounds,\n );\n return;\n }\n\n // Get current coordinates\n const coords = getScreenCoords(e);\n const deltaX = coords.x - startX;\n const deltaY = coords.y - startY;\n\n log.info(\"moveResize coords:\", coords, \"delta:\", {\n deltaX,\n deltaY,\n });\n\n let newWidth = resizeStartBounds.width + deltaX;\n let newHeight = resizeStartBounds.height + deltaY;\n\n // Apply min/max constraints\n if (windowConfig.minSize) {\n newWidth = Math.max(newWidth, windowConfig.minSize.width || 200);\n newHeight = Math.max(newHeight, windowConfig.minSize.height || 200);\n } else {\n newWidth = Math.max(newWidth, 200);\n newHeight = Math.max(newHeight, 200);\n }\n\n if (windowConfig.maxSize) {\n newWidth = Math.min(newWidth, windowConfig.maxSize.width || 2000);\n newHeight = Math.min(newHeight, windowConfig.maxSize.height || 2000);\n }\n\n const newBounds = {\n x: resizeStartBounds.x,\n y: resizeStartBounds.y,\n width: Math.round(newWidth),\n height: Math.round(newHeight),\n };\n\n log.info(\"moveResize newBounds:\", newBounds);\n\n // Update tracked bounds immediately for next move calculation\n currentBoundsRef.current = newBounds;\n\n // Store pending update for next animation frame\n pendingBounds = newBounds;\n };\n\n const endResize = (e?: MouseEvent | TouchEvent): void => {\n if (!isResizing) {\n return;\n }\n\n isResizing = false;\n resizeStartBounds = null;\n\n // Remove mouseup listener since resize is done\n window.removeEventListener(\"mouseup\", endResize);\n\n // Cancel animation frame and send final position\n if (rafId) {\n cancelAnimationFrame(rafId);\n rafId = null;\n\n // Send final pending bounds immediately\n if (pendingBounds) {\n window.edenAPI\n .shellCommand(\"view/update-bounds\", {\n bounds: pendingBounds,\n })\n .catch(log.error);\n\n // Update edenFrame._internal.bounds so next interaction starts from correct position\n window.edenFrame!._internal.bounds = { ...pendingBounds };\n pendingBounds = null;\n }\n }\n\n // For touch resize, ensure edenFrame._internal.bounds is updated with final position\n if (isTouch && currentBoundsRef.current) {\n window.edenFrame!._internal.bounds = { ...currentBoundsRef.current };\n log.info(\n \"Updated edenFrame._internal.bounds after touch resize:\",\n window.edenFrame?._internal.bounds,\n );\n }\n\n // Stop global resize tracking in main process (for mouse events)\n if (!isTouch) {\n window.edenAPI.shellCommand(\"view/end-resize\", {}).catch(log.error);\n }\n\n window.edenAPI.shellCommand(\"view/focus\", {}).catch(log.error);\n };\n\n // Mouse events\n resizeHandle.addEventListener(\"mousedown\", startResize);\n\n // Touch events\n resizeHandle.addEventListener(\"touchstart\", startResize, { passive: false });\n\n // Move events for touch (mouse uses main process tracking)\n // Use document and capture to ensure we get all touch moves\n document.addEventListener(\"touchmove\", moveResize, {\n passive: false,\n capture: true,\n });\n\n // Touch end/cancel events (mouseup is added dynamically when resize starts)\n document.addEventListener(\"touchend\", endResize, { passive: false });\n document.addEventListener(\"touchcancel\", endResize, { passive: false });\n\n log.info(\"Resize event listeners registered\");\n\n return () => {\n if (resizeHandle.parentNode) {\n resizeHandle.parentNode.removeChild(resizeHandle);\n }\n\n resizeHandle.removeEventListener(\"mousedown\", startResize);\n resizeHandle.removeEventListener(\"touchstart\", startResize);\n\n document.removeEventListener(\"touchmove\", moveResize, {\n capture: true,\n });\n document.removeEventListener(\"touchend\", endResize);\n document.removeEventListener(\"touchcancel\", endResize);\n window.removeEventListener(\"mouseup\", endResize);\n\n if (rafId) {\n cancelAnimationFrame(rafId);\n }\n log.info(\"Resize event listeners removed\");\n };\n}\n", "import { log } from \"../logging\";\n\n/**\n * Eden App Frame Injector\n *\n * Main orchestrator for the app frame system.\n * This script is injected into app views to apply frame runtime behavior.\n */\n\nimport {\n closeAppFrameView,\n minimizeAppFrameView,\n setupCloseButton,\n setupMinimizeButton,\n setupToggleModeButton,\n toggleAppFrameViewMode,\n} from \"./button-handlers.js\";\nimport {\n createOverlay,\n getAppName,\n injectOverlay,\n setTitle,\n setupDarkMode,\n} from \"./ui-builder.js\";\nimport { setupWindowDragging } from \"./window-dragging.js\";\nimport { setupWindowResizing } from \"./window-resizing.js\";\n\n(() => {\n log.info(\"Injection script started\");\n\n // Initialize edenFrame object if not exists\n if (!window.edenFrame) {\n window.edenFrame = {\n setTitle: (title: string) => {\n /* will be set later */\n },\n resetTitle: () => {\n /* will be set later */\n },\n close: async () => {\n /* will be set later */\n },\n minimize: async () => {\n /* will be set later */\n },\n toggleMode: async () => {\n /* will be set later */\n },\n _internal: {\n appId: \"\",\n appName: \"\" as string | Record<string, string>,\n injected: false,\n config: {},\n currentMode: \"tiled\",\n bounds: { x: 0, y: 0, width: 0, height: 0 },\n },\n };\n }\n if (!window.edenFrame.setTitle) {\n window.edenFrame.setTitle = () => {\n /* no-op until initialized */\n };\n }\n if (!window.edenFrame.resetTitle) {\n window.edenFrame.resetTitle = () => {\n /* no-op until initialized */\n };\n }\n if (!window.edenFrame.close) {\n window.edenFrame.close = async () => {\n /* no-op until initialized */\n };\n }\n if (!window.edenFrame.minimize) {\n window.edenFrame.minimize = async () => {\n /* no-op until initialized */\n };\n }\n if (!window.edenFrame.toggleMode) {\n window.edenFrame.toggleMode = async () => {\n /* no-op until initialized */\n };\n }\n\n // Check if already injected\n if (window.edenFrame._internal.injected) {\n log.info(\"Already injected, skipping\");\n return;\n }\n window.edenFrame._internal.injected = true;\n\n let appName: string = \"App\";\n\n // Track current window bounds for floating windows\n // Using an object reference so we can update it and have the change reflected in all modules\n const currentBoundsRef: {\n current: { x: number; y: number; width: number; height: number } | null;\n } = { current: null };\n\n let cleanupDrag: (() => void) | null = null;\n let cleanupResize: (() => void) | null = null;\n\n const configuredAppFrameMode =\n window.edenFrame._internal.config.injections?.appFrame;\n const appFrameMode =\n configuredAppFrameMode === \"window-only\" ? \"window-only\" : \"full\";\n const includeSystemTopBar = appFrameMode === \"full\";\n\n // Only create the Eden title bar in full mode.\n const overlay = includeSystemTopBar\n ? createOverlay(window.edenFrame._internal.config)\n : null;\n\n // Setup handlers after overlay is injected\n const setupHandlers = (): void => {\n // Get appId from injected config\n if (window.edenFrame) {\n const rawName = window.edenFrame._internal.appName;\n appName = getAppName(rawName, \"en\");\n\n if (includeSystemTopBar) {\n // Async fetch locale for title text\n window.edenAPI\n .shellCommand(\"i18n/get-locale\", {})\n .then((response: { locale: string }) => {\n const locale = response?.locale;\n const currentLocale = locale || \"en\";\n appName = getAppName(rawName, currentLocale);\n setTitle(appName);\n })\n .catch(() => {\n appName = getAppName(rawName, \"en\");\n setTitle(appName);\n });\n\n // Set initial title (english fallback) to avoid empty title while fetching\n setTitle(appName);\n\n // Subscribe to locale changes for live updates\n window.edenAPI.subscribe(\n \"i18n/locale-changed\",\n (data: { locale: string }) => {\n const newLocale = data.locale;\n const currentName = getAppName(rawName, newLocale);\n setTitle(currentName);\n appName = currentName;\n },\n );\n }\n }\n\n if (includeSystemTopBar) {\n // Setup system top bar button handlers\n setupCloseButton();\n setupMinimizeButton();\n setupToggleModeButton();\n }\n\n // Setup floating window controls\n setupFloatingWindowControls();\n\n window.edenAPI.subscribe(\n \"view/mode-changed\",\n (data: { mode: \"tiled\" | \"floating\"; bounds: any }) => {\n const { mode, bounds } = data;\n log.info(\"View mode changed to:\", mode, \"with bounds:\", bounds);\n\n // Update window mode and bounds\n window.edenFrame!._internal.currentMode = mode;\n if (bounds && bounds.x !== undefined) {\n window.edenFrame!._internal.bounds = bounds;\n currentBoundsRef.current = { ...bounds };\n }\n\n // Re-setup controls for new mode\n setupFloatingWindowControls();\n },\n );\n log.info(\"Subscribed to view/mode-changed\");\n };\n\n const setupFloatingWindowControls = (): void => {\n const windowMode = window.edenFrame!._internal.currentMode;\n const windowConfig = window.edenFrame!._internal.config;\n const initialBounds = window.edenFrame!._internal.bounds;\n\n log.info(\"Window mode:\", initialBounds);\n\n // Clean up previous controls if they exist (crucial for mode switching)\n if (cleanupDrag) {\n cleanupDrag();\n cleanupDrag = null;\n }\n if (cleanupResize) {\n cleanupResize();\n cleanupResize = null;\n }\n\n // Only enable dragging/resizing for floating windows\n if (windowMode !== \"floating\") {\n // If we are not floating, we just returned after cleanup, so handles are gone.\n return;\n }\n\n // Initialize current bounds from the actual bounds set by ViewManager\n if (initialBounds && initialBounds.x !== undefined) {\n currentBoundsRef.current = { ...initialBounds };\n log.info(\"Initialized bounds from backend:\", currentBoundsRef.current);\n } else if (windowConfig.defaultSize) {\n // Fallback to config if no initial bounds provided\n const workspaceX = 0;\n const workspaceY = 0;\n\n const x = windowConfig.defaultPosition?.x || 0;\n const y = windowConfig.defaultPosition?.y || 0;\n\n currentBoundsRef.current = {\n x: workspaceX + x,\n y: workspaceY + y,\n width: windowConfig.defaultSize.width || 800,\n height: windowConfig.defaultSize.height || 600,\n };\n\n log.info(\"Initialized bounds from config:\", currentBoundsRef.current);\n }\n\n // Check if dragging is allowed\n const isMovable = windowConfig.movable !== false; // default true\n const isResizable = windowConfig.resizable !== false; // default true\n\n log.info(\"Movable:\", isMovable, \"Resizable:\", isResizable);\n\n // Setup window dragging\n if (isMovable) {\n if (overlay) {\n cleanupDrag = setupWindowDragging(overlay, currentBoundsRef);\n } else {\n cleanupDrag = setupWindowDragging(document, currentBoundsRef, {\n dragRegionSelector: \"[data-eden-drag-region]\",\n });\n }\n }\n\n // Setup window resizing\n if (isResizable) {\n cleanupResize = setupWindowResizing(windowConfig, currentBoundsRef);\n }\n };\n\n // Listen for bounds updates from main process (during mouse drag/resize)\n // This keeps currentBounds in sync even when main process is controlling movement\n window.edenAPI.subscribe(\"view/bounds-updated\", (newBounds) => {\n currentBoundsRef.current = { ...newBounds };\n window.edenFrame!._internal.bounds = { ...newBounds };\n });\n log.info(\"Subscribed to view/bounds-updated\");\n\n // Add global touch handler to diagnose issues\n document.addEventListener(\n \"touchstart\",\n (e) => {\n log.info(\"Global touchstart on:\", e.target);\n },\n { passive: false, capture: true },\n );\n\n document.addEventListener(\n \"touchcancel\",\n (e) => {\n log.info(\"Global touchcancel on:\", e.target);\n log.info(\"Stack trace:\", new Error().stack);\n },\n { capture: true },\n );\n\n // Inject overlay and setup handlers\n if (overlay) {\n injectOverlay(overlay, () => {\n setupDarkMode(overlay);\n setupHandlers();\n });\n } else if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", setupHandlers);\n } else {\n setupHandlers();\n }\n\n // Expose API for apps to update the title\n window.edenFrame.setTitle = (title: string) => {\n setTitle(title);\n };\n\n // Expose resetTitle immediately (using English/default name initially)\n window.edenFrame.resetTitle = () => {\n setTitle(appName);\n };\n\n // Expose app frame actions for custom title bars.\n window.edenFrame.close = () => closeAppFrameView();\n window.edenFrame.minimize = () => minimizeAppFrameView();\n window.edenFrame.toggleMode = () => toggleAppFrameViewMode();\n})();\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["LOG_LEVEL_ORDER", "parseLogLevel", "value", "normalized", "isLogLevelEnabled", "level", "minLevel", "globalContext", "config", "resolveDefaultConfig", "baseConsole", "createLogger", "context", "args", "emit", "log", "emit", "record", "level", "isLogLevelEnabled", "config", "timestamp", "context", "mergeContext", "callsite", "captureCallsite", "prefix", "formatPrefix", "target", "consoleForLevel", "getBaseContext", "envAppId", "getEnvValue", "globalAppId", "detectProcessType", "globalContext", "processObj", "type", "resolveDefaultConfig", "envLevel", "parseLogLevel", "envFormat", "envPathMode", "isTest", "isRenderer", "getEnvBool", "useLiveConsole", "baseConsole", "parts", "file", "shortenPath", "err", "stack", "lines", "line", "trimmed", "match", "lineNumber", "columnNumber", "path", "mode", "normalized", "cwd", "normalizedPath", "distIndex", "sdkIndex", "segments", "key", "globalValue", "fallback", "value", "closeAppFrameView", "minimizeAppFrameView", "toggleAppFrameViewMode", "log", "setupCloseButton", "closeBtn", "setupMinimizeButton", "minBtn", "setupToggleModeButton", "toggleBtn", "createOverlay", "windowConfig", "overlay", "supportsToggle", "showTitle", "toggleButtonHtml", "titleHtml", "injectOverlay", "callback", "inject", "log", "setupDarkMode", "prefersDark", "updateTheme", "e", "setTitle", "title", "titleEl", "getAppName", "name", "locale", "parts", "readable", "getScreenCoords", "touch", "currentBounds", "setupWindowDragging", "dragSource", "currentBoundsRef", "options", "isDragging", "startX", "startY", "dragStartBounds", "isTouch", "rafId", "pendingBounds", "dragRegionSelector", "updatePosition", "log", "startDrag", "e", "target", "initialBounds", "coords", "getScreenCoords", "endDrag", "moveDrag", "deltaX", "deltaY", "newBounds", "setupWindowResizing", "windowConfig", "currentBoundsRef", "resizeHandle", "isResizing", "startX", "startY", "resizeStartBounds", "isTouch", "rafId", "pendingBounds", "updateResizePosition", "log", "startResize", "e", "initialBounds", "coords", "getScreenCoords", "endResize", "moveResize", "deltaX", "deltaY", "newWidth", "newHeight", "newBounds", "log", "title", "appName", "currentBoundsRef", "cleanupDrag", "cleanupResize", "includeSystemTopBar", "overlay", "createOverlay", "setupHandlers", "rawName", "getAppName", "response", "currentLocale", "setTitle", "data", "newLocale", "currentName", "setupCloseButton", "setupMinimizeButton", "setupToggleModeButton", "setupFloatingWindowControls", "mode", "bounds", "windowMode", "windowConfig", "initialBounds", "x", "y", "isMovable", "isResizable", "setupWindowDragging", "setupWindowResizing", "newBounds", "e", "injectOverlay", "setupDarkMode", "closeAppFrameView", "minimizeAppFrameView", "toggleAppFrameViewMode"]
|
|
7
7
|
}
|