@hienlh/ppm 0.11.6 → 0.11.8
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/CHANGELOG.md +21 -0
- package/dist/web/assets/{ai-settings-section-D2vqiydT.js → ai-settings-section-C6FDY8qE.js} +1 -1
- package/dist/web/assets/{api-settings-2eTz4SgY.js → api-settings-C__hxGX2.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-XX6_EZsC.js +1 -0
- package/dist/web/assets/audio-preview--VaB403K.js +1 -0
- package/dist/web/assets/{chat-tab-2znvnxzD.js → chat-tab-DS455Mwt.js} +4 -4
- package/dist/web/assets/code-editor-BsUsDjJz.js +8 -0
- package/dist/web/assets/{conflict-editor-DXnqiS4c.js → conflict-editor-DTMT0ZxI.js} +1 -1
- package/dist/web/assets/{csv-preview-D37K2LRd.js → csv-preview-BEBJD4a_.js} +1 -1
- package/dist/web/assets/{database-viewer-DK4PfwVJ.js → database-viewer-B7aIs1XX.js} +1 -1
- package/dist/web/assets/{diff-viewer-Cy4oX3mb.js → diff-viewer-C9unqCxZ.js} +1 -1
- package/dist/web/assets/{esm-B99v94EE.js → esm-K1XIK4vc.js} +1 -1
- package/dist/web/assets/{extension-store-CkyOvGbF.js → extension-store-3yZYn07W.js} +1 -1
- package/dist/web/assets/{extension-webview-DIVrmdfu.js → extension-webview-DUs8mqO_.js} +1 -1
- package/dist/web/assets/file-exclamation-point-BwzaQ50n.js +1 -0
- package/dist/web/assets/gitGraph-HDMCJU4V-BhjTKsbg.js +1 -0
- package/dist/web/assets/image-preview-CoiyMXuX.js +1 -0
- package/dist/web/assets/{index-oqP6ldWs.js → index-B1GZswlR.js} +4 -4
- package/dist/web/assets/index-C3ZstZ9f.css +2 -0
- package/dist/web/assets/info-3K5VOQVL-CzgVqYTx.js +1 -0
- package/dist/web/assets/{input-CHRMley8.js → input-ClhO__YM.js} +1 -1
- package/dist/web/assets/keybindings-store-BkZjvU9J.js +1 -0
- package/dist/web/assets/{keybindings-store-CpP5_miA.js → keybindings-store-C9KsBH7z.js} +1 -1
- package/dist/web/assets/{markdown-renderer-BLhcNL42.js → markdown-renderer-4LYdtPZU.js} +3 -3
- package/dist/web/assets/packet-RMMSAZCW-C7agXrtd.js +1 -0
- package/dist/web/assets/pdf-preview-CFO6CjHG.js +1 -0
- package/dist/web/assets/pie-UPGHQEXC-BRZ7alnf.js +1 -0
- package/dist/web/assets/{port-forwarding-tab-iZost0RL.js → port-forwarding-tab-DpoVwtlp.js} +1 -1
- package/dist/web/assets/{postgres-viewer-CabnbH06.js → postgres-viewer-Ku3X9rJQ.js} +3 -3
- package/dist/web/assets/{project-store-CczGNZyf.js → project-store-BYmQ0fDC.js} +1 -1
- package/dist/web/assets/radar-KQ55EAFF-DSn_ekR5.js +1 -0
- package/dist/web/assets/{scroll-area-DwWF9FpN.js → scroll-area-DW7L4Gnc.js} +1 -1
- package/dist/web/assets/{settings-store-CuYjM0FF.js → settings-store-B9axDbuA.js} +2 -2
- package/dist/web/assets/settings-tab-l-SopAs4.js +1 -0
- package/dist/web/assets/{sql-query-editor-CVEi0jLM.js → sql-query-editor-BnpKNGG0.js} +1 -1
- package/dist/web/assets/{sqlite-viewer-cGe2bGlF.js → sqlite-viewer-DzS8-nbv.js} +1 -1
- package/dist/web/assets/{tab-store-Jvy1eZGM.js → tab-store-B3M9hjho.js} +1 -1
- package/dist/web/assets/{terminal-tab-CPAMJoNK.js → terminal-tab-ERPwhU5O.js} +1 -1
- package/dist/web/assets/treemap-KZPCXAKY-C8puYVyN.js +1 -0
- package/dist/web/assets/use-blob-url-BK7zshV7.js +1 -0
- package/dist/web/assets/{use-monaco-theme-kjiAwvOp.js → use-monaco-theme-BERjR8IA.js} +1 -1
- package/dist/web/assets/{vendor-mermaid-CylkVm4U.js → vendor-mermaid-BlWh9BJO.js} +2 -2
- package/dist/web/assets/video-preview-BZenXc_U.js +1 -0
- package/dist/web/index.html +17 -17
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
- package/src/services/autostart-generator.ts +2 -0
- package/src/services/supervisor.ts +41 -10
- package/src/web/components/editor/audio-preview.tsx +26 -0
- package/src/web/components/editor/code-editor.tsx +21 -81
- package/src/web/components/editor/image-preview.tsx +23 -0
- package/src/web/components/editor/pdf-preview.tsx +32 -0
- package/src/web/components/editor/use-blob-url.ts +35 -0
- package/src/web/components/editor/video-preview.tsx +23 -0
- package/dist/web/assets/architecture-PBZL5I3N-BRW4VwMk.js +0 -1
- package/dist/web/assets/code-editor-CUyFYiwJ.js +0 -8
- package/dist/web/assets/gitGraph-HDMCJU4V-Bt68dqWT.js +0 -1
- package/dist/web/assets/index-iZHWllzQ.css +0 -2
- package/dist/web/assets/info-3K5VOQVL-ySD5z855.js +0 -1
- package/dist/web/assets/keybindings-store-qfYScgY0.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-CLxaXgIf.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-C9wPZfkn.js +0 -1
- package/dist/web/assets/radar-KQ55EAFF-DxEpzVN_.js +0 -1
- package/dist/web/assets/settings-tab-D2th4Hfj.js +0 -1
- package/dist/web/assets/treemap-KZPCXAKY-yelcZZqO.js +0 -1
- /package/dist/web/assets/{api-client-C3tXCh0r.js → api-client-Bn-Pi9k5.js} +0 -0
- /package/dist/web/assets/{csv-parser-BAa56Nnn.js → csv-parser--2WJNgS7.js} +0 -0
- /package/dist/web/assets/{dist-On3hz9_g.js → dist-im4ynINo.js} +0 -0
- /package/dist/web/assets/{katex-Bbu770d9.js → katex-CKoArbIw.js} +0 -0
- /package/dist/web/assets/{lib-BqkcKGFq.js → lib-DQHnkzGy.js} +0 -0
- /package/dist/web/assets/{react-BkWDCPD7.js → react-GqWghJ-L.js} +0 -0
- /package/dist/web/assets/{refresh-cw-CSFrDtiu.js → refresh-cw-LlbZDJpO.js} +0 -0
- /package/dist/web/assets/{sql-completion-provider-D3acAhav.js → sql-completion-provider-C3cq9j99.js} +0 -0
- /package/dist/web/assets/{table-DbSviOmw.js → table-Dq575bPF.js} +0 -0
- /package/dist/web/assets/{text-wrap-DzvCTq_i.js → text-wrap-Cn6BNQfq.js} +0 -0
- /package/dist/web/assets/{trash-2-BgDIBl6f.js → trash-2-CJYoLw7Q.js} +0 -0
- /package/dist/web/assets/{utils-ChWX7pZv.js → utils-CTg5uAYR.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-B9BUAFKA.js → vendor-xterm-CU2c3f0A.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{b as e}from"./vendor-markdown-0Mxgxy0L.js";import{t}from"./file-exclamation-point-BwzaQ50n.js";import"./api-client-Bn-Pi9k5.js";import{M as n}from"./index-B1GZswlR.js";import{t as r}from"./use-blob-url-BK7zshV7.js";var i=e();function a({filePath:e,projectName:a}){let{blobUrl:o,error:s}=r(e,a);return s?(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary`,children:[(0,i.jsx)(t,{className:`size-10 text-text-subtle`}),(0,i.jsx)(`p`,{className:`text-sm`,children:`Failed to load video.`})]}):o?(0,i.jsx)(`div`,{className:`flex items-center justify-center h-full p-4 bg-surface overflow-auto`,children:(0,i.jsx)(`video`,{src:o,controls:!0,className:`max-w-full max-h-full`})}):(0,i.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,i.jsx)(n,{className:`size-5 animate-spin text-text-subtle`})})}export{a as VideoPreview};
|
package/dist/web/index.html
CHANGED
|
@@ -39,32 +39,32 @@
|
|
|
39
39
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
40
40
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
41
41
|
<link href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500;600;700&family=Geist:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
|
42
|
-
<script type="module" crossorigin src="/assets/index-
|
|
42
|
+
<script type="module" crossorigin src="/assets/index-B1GZswlR.js"></script>
|
|
43
43
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-FhOqtrmT.js">
|
|
44
|
-
<link rel="modulepreload" crossorigin href="/assets/vendor-mermaid-
|
|
44
|
+
<link rel="modulepreload" crossorigin href="/assets/vendor-mermaid-BlWh9BJO.js">
|
|
45
45
|
<link rel="modulepreload" crossorigin href="/assets/vendor-markdown-0Mxgxy0L.js">
|
|
46
46
|
<link rel="modulepreload" crossorigin href="/assets/vendor-ui-B-T_damt.js">
|
|
47
|
-
<link rel="modulepreload" crossorigin href="/assets/utils-
|
|
47
|
+
<link rel="modulepreload" crossorigin href="/assets/utils-CTg5uAYR.js">
|
|
48
48
|
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-BjHrJDVb.js">
|
|
49
49
|
<link rel="modulepreload" crossorigin href="/assets/x-DlFGzN8d.js">
|
|
50
|
-
<link rel="modulepreload" crossorigin href="/assets/input-
|
|
51
|
-
<link rel="modulepreload" crossorigin href="/assets/scroll-area-
|
|
50
|
+
<link rel="modulepreload" crossorigin href="/assets/input-ClhO__YM.js">
|
|
51
|
+
<link rel="modulepreload" crossorigin href="/assets/scroll-area-DW7L4Gnc.js">
|
|
52
52
|
<link rel="modulepreload" crossorigin href="/assets/dist-C5IgeqrV.js">
|
|
53
53
|
<link rel="modulepreload" crossorigin href="/assets/plus-51UQ45rf.js">
|
|
54
|
-
<link rel="modulepreload" crossorigin href="/assets/refresh-cw-
|
|
55
|
-
<link rel="modulepreload" crossorigin href="/assets/trash-2-
|
|
56
|
-
<link rel="modulepreload" crossorigin href="/assets/api-client-
|
|
57
|
-
<link rel="modulepreload" crossorigin href="/assets/api-settings-
|
|
58
|
-
<link rel="modulepreload" crossorigin href="/assets/ai-settings-section-
|
|
54
|
+
<link rel="modulepreload" crossorigin href="/assets/refresh-cw-LlbZDJpO.js">
|
|
55
|
+
<link rel="modulepreload" crossorigin href="/assets/trash-2-CJYoLw7Q.js">
|
|
56
|
+
<link rel="modulepreload" crossorigin href="/assets/api-client-Bn-Pi9k5.js">
|
|
57
|
+
<link rel="modulepreload" crossorigin href="/assets/api-settings-C__hxGX2.js">
|
|
58
|
+
<link rel="modulepreload" crossorigin href="/assets/ai-settings-section-C6FDY8qE.js">
|
|
59
59
|
<link rel="modulepreload" crossorigin href="/assets/chevron-right-BzAdxJRG.js">
|
|
60
60
|
<link rel="modulepreload" crossorigin href="/assets/database-D4DIhgi-.js">
|
|
61
|
-
<link rel="modulepreload" crossorigin href="/assets/react-
|
|
62
|
-
<link rel="modulepreload" crossorigin href="/assets/extension-store-
|
|
63
|
-
<link rel="modulepreload" crossorigin href="/assets/keybindings-store-
|
|
64
|
-
<link rel="modulepreload" crossorigin href="/assets/tab-store-
|
|
65
|
-
<link rel="modulepreload" crossorigin href="/assets/project-store-
|
|
66
|
-
<link rel="modulepreload" crossorigin href="/assets/settings-store-
|
|
67
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
61
|
+
<link rel="modulepreload" crossorigin href="/assets/react-GqWghJ-L.js">
|
|
62
|
+
<link rel="modulepreload" crossorigin href="/assets/extension-store-3yZYn07W.js">
|
|
63
|
+
<link rel="modulepreload" crossorigin href="/assets/keybindings-store-C9KsBH7z.js">
|
|
64
|
+
<link rel="modulepreload" crossorigin href="/assets/tab-store-B3M9hjho.js">
|
|
65
|
+
<link rel="modulepreload" crossorigin href="/assets/project-store-BYmQ0fDC.js">
|
|
66
|
+
<link rel="modulepreload" crossorigin href="/assets/settings-store-B9axDbuA.js">
|
|
67
|
+
<link rel="stylesheet" crossorigin href="/assets/index-C3ZstZ9f.css">
|
|
68
68
|
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
|
|
69
69
|
<body class="bg-[#0f1419] text-[#e5e7eb] font-sans antialiased">
|
|
70
70
|
<div id="root"></div>
|
package/dist/web/sw.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}function B(e){O().precache(e)}function V(e,t){B(e),z(t)}V([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"3e294bb82e02c2ea8cb5efe532598c1c","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":null,"url":"assets/lib-BqkcKGFq.js"},{"revision":null,"url":"assets/input-CHRMley8.js"},{"revision":null,"url":"assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2"},{"revision":null,"url":"assets/KaTeX_AMS-Regular-BQhdFMY1.woff2"},{"revision":null,"url":"assets/tab-store-Jvy1eZGM.js"},{"revision":null,"url":"assets/database-D4DIhgi-.js"},{"revision":null,"url":"assets/x-DlFGzN8d.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-Bt68dqWT.js"},{"revision":null,"url":"assets/terminal-tab-CPAMJoNK.js"},{"revision":null,"url":"assets/port-forwarding-tab-iZost0RL.js"},{"revision":null,"url":"assets/postgres-viewer-CabnbH06.js"},{"revision":null,"url":"assets/KaTeX_Main-Regular-B22Nviop.woff2"},{"revision":null,"url":"assets/ai-settings-section-D2vqiydT.js"},{"revision":null,"url":"assets/database-viewer-DK4PfwVJ.js"},{"revision":null,"url":"assets/index-oqP6ldWs.js"},{"revision":null,"url":"assets/vendor-ui-B-T_damt.js"},{"revision":null,"url":"assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2"},{"revision":null,"url":"assets/settings-store-CuYjM0FF.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-C9wPZfkn.js"},{"revision":null,"url":"assets/chevron-right-BzAdxJRG.js"},{"revision":null,"url":"assets/sql-query-editor-CVEi0jLM.js"},{"revision":null,"url":"assets/settings-tab-D2th4Hfj.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-CLxaXgIf.js"},{"revision":null,"url":"assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2"},{"revision":null,"url":"assets/vendor-markdown-0Mxgxy0L.js"},{"revision":null,"url":"assets/KaTeX_Main-Italic-NWA7e6Wa.woff2"},{"revision":null,"url":"assets/trash-2-BgDIBl6f.js"},{"revision":null,"url":"assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2"},{"revision":null,"url":"assets/dist-C5IgeqrV.js"},{"revision":null,"url":"assets/plus-51UQ45rf.js"},{"revision":null,"url":"assets/esm-B99v94EE.js"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2"},{"revision":null,"url":"assets/api-settings-2eTz4SgY.js"},{"revision":null,"url":"assets/arrow-up-Dtrfv490.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-DxEpzVN_.js"},{"revision":null,"url":"assets/refresh-cw-CSFrDtiu.js"},{"revision":null,"url":"assets/vendor-xterm-B9BUAFKA.js"},{"revision":null,"url":"assets/rolldown-runtime-FhOqtrmT.js"},{"revision":null,"url":"assets/api-client-C3tXCh0r.js"},{"revision":null,"url":"assets/code-editor-CUyFYiwJ.js"},{"revision":null,"url":"assets/KaTeX_Math-Italic-t53AETM-.woff2"},{"revision":null,"url":"assets/use-monaco-theme-kjiAwvOp.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2"},{"revision":null,"url":"assets/KaTeX_Script-Regular-D3wIWfF6.woff2"},{"revision":null,"url":"assets/extension-store-CkyOvGbF.js"},{"revision":null,"url":"assets/conflict-editor-DXnqiS4c.js"},{"revision":null,"url":"assets/info-3K5VOQVL-ySD5z855.js"},{"revision":null,"url":"assets/columns-2-4fQcE4PF.js"},{"revision":null,"url":"assets/KaTeX_Main-Bold-Cx986IdX.woff2"},{"revision":null,"url":"assets/sql-completion-provider-D3acAhav.js"},{"revision":null,"url":"assets/react-BkWDCPD7.js"},{"revision":null,"url":"assets/KaTeX_Size2-Regular-Dy4dx90m.woff2"},{"revision":null,"url":"assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2"},{"revision":null,"url":"assets/KaTeX_Size1-Regular-mCD8mA8B.woff2"},{"revision":null,"url":"assets/markdown-renderer-BLhcNL42.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-BRW4VwMk.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-yelcZZqO.js"},{"revision":null,"url":"assets/sqlite-viewer-cGe2bGlF.js"},{"revision":null,"url":"assets/chat-tab-2znvnxzD.js"},{"revision":null,"url":"assets/createLucideIcon-BjHrJDVb.js"},{"revision":null,"url":"assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2"},{"revision":null,"url":"assets/code-CuravVys.js"},{"revision":null,"url":"assets/csv-parser-BAa56Nnn.js"},{"revision":null,"url":"assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2"},{"revision":null,"url":"assets/project-store-CczGNZyf.js"},{"revision":null,"url":"assets/katex-Bbu770d9.js"},{"revision":null,"url":"assets/keybindings-store-qfYScgY0.js"},{"revision":null,"url":"assets/extension-webview-DIVrmdfu.js"},{"revision":null,"url":"assets/utils-ChWX7pZv.js"},{"revision":null,"url":"assets/text-wrap-DzvCTq_i.js"},{"revision":null,"url":"assets/diff-viewer-Cy4oX3mb.js"},{"revision":null,"url":"assets/vendor-xterm-BrP-ENHg.css"},{"revision":null,"url":"assets/scroll-area-DwWF9FpN.js"},{"revision":null,"url":"assets/index-iZHWllzQ.css"},{"revision":null,"url":"assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2"},{"revision":null,"url":"assets/keybindings-store-CpP5_miA.js"},{"revision":null,"url":"assets/csv-preview-D37K2LRd.js"},{"revision":null,"url":"assets/vendor-mermaid-CylkVm4U.js"},{"revision":null,"url":"assets/table-DbSviOmw.js"},{"revision":null,"url":"assets/dist-On3hz9_g.js"},{"revision":"d0f94ce046cf8cf09605ee7664dac557","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"a424156a79b9c1b907db93aa3180585a","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"b3a7f967560c9816492a1567b3f7f0dc","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":"a5d8a1acfc29c2a4c882a54ffc93def3","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"948e060affb598c339be40d69e1f6f9c","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"79c8870653c8f419f2e3323085e1f4be","url":"manifest.webmanifest"}]),self.addEventListener(`push`,e=>{e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{if(t.some(e=>e.visibilityState===`visible`))return;let n=e.data?.json()??{title:`PPM`,body:`Chat completed`};return self.registration.showNotification(n.title,{body:n.body,icon:`/icon-192.png`,badge:`/icon-192.png`,tag:`ppm-chat-done`,silent:!1,data:{url:self.location.origin}})}))}),self.addEventListener(`notificationclick`,e=>{e.notification.close(),e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{for(let e of t)if(e.url.includes(self.location.origin)&&`focus`in e)return e.focus();return self.clients.openWindow(e.notification.data?.url||`/`)}))});
|
|
1
|
+
try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}function B(e){O().precache(e)}function V(e,t){B(e),z(t)}V([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"ff071aa161c8548ee3f427470d37187e","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":null,"url":"assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2"},{"revision":null,"url":"assets/input-ClhO__YM.js"},{"revision":null,"url":"assets/KaTeX_AMS-Regular-BQhdFMY1.woff2"},{"revision":null,"url":"assets/diff-viewer-C9unqCxZ.js"},{"revision":null,"url":"assets/database-D4DIhgi-.js"},{"revision":null,"url":"assets/csv-parser--2WJNgS7.js"},{"revision":null,"url":"assets/x-DlFGzN8d.js"},{"revision":null,"url":"assets/video-preview-BZenXc_U.js"},{"revision":null,"url":"assets/conflict-editor-DTMT0ZxI.js"},{"revision":null,"url":"assets/csv-preview-BEBJD4a_.js"},{"revision":null,"url":"assets/vendor-xterm-CU2c3f0A.js"},{"revision":null,"url":"assets/keybindings-store-C9KsBH7z.js"},{"revision":null,"url":"assets/KaTeX_Main-Regular-B22Nviop.woff2"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-BhjTKsbg.js"},{"revision":null,"url":"assets/refresh-cw-LlbZDJpO.js"},{"revision":null,"url":"assets/sql-query-editor-BnpKNGG0.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-XX6_EZsC.js"},{"revision":null,"url":"assets/react-GqWghJ-L.js"},{"revision":null,"url":"assets/pdf-preview-CFO6CjHG.js"},{"revision":null,"url":"assets/vendor-ui-B-T_damt.js"},{"revision":null,"url":"assets/markdown-renderer-4LYdtPZU.js"},{"revision":null,"url":"assets/katex-CKoArbIw.js"},{"revision":null,"url":"assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2"},{"revision":null,"url":"assets/chevron-right-BzAdxJRG.js"},{"revision":null,"url":"assets/chat-tab-DS455Mwt.js"},{"revision":null,"url":"assets/index-B1GZswlR.js"},{"revision":null,"url":"assets/extension-store-3yZYn07W.js"},{"revision":null,"url":"assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2"},{"revision":null,"url":"assets/project-store-BYmQ0fDC.js"},{"revision":null,"url":"assets/scroll-area-DW7L4Gnc.js"},{"revision":null,"url":"assets/vendor-markdown-0Mxgxy0L.js"},{"revision":null,"url":"assets/postgres-viewer-Ku3X9rJQ.js"},{"revision":null,"url":"assets/vendor-mermaid-BlWh9BJO.js"},{"revision":null,"url":"assets/dist-im4ynINo.js"},{"revision":null,"url":"assets/KaTeX_Main-Italic-NWA7e6Wa.woff2"},{"revision":null,"url":"assets/table-Dq575bPF.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-C7agXrtd.js"},{"revision":null,"url":"assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2"},{"revision":null,"url":"assets/dist-C5IgeqrV.js"},{"revision":null,"url":"assets/keybindings-store-BkZjvU9J.js"},{"revision":null,"url":"assets/plus-51UQ45rf.js"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2"},{"revision":null,"url":"assets/use-monaco-theme-BERjR8IA.js"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2"},{"revision":null,"url":"assets/arrow-up-Dtrfv490.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-DSn_ekR5.js"},{"revision":null,"url":"assets/rolldown-runtime-FhOqtrmT.js"},{"revision":null,"url":"assets/ai-settings-section-C6FDY8qE.js"},{"revision":null,"url":"assets/info-3K5VOQVL-CzgVqYTx.js"},{"revision":null,"url":"assets/KaTeX_Math-Italic-t53AETM-.woff2"},{"revision":null,"url":"assets/text-wrap-Cn6BNQfq.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2"},{"revision":null,"url":"assets/KaTeX_Script-Regular-D3wIWfF6.woff2"},{"revision":null,"url":"assets/trash-2-CJYoLw7Q.js"},{"revision":null,"url":"assets/code-editor-BsUsDjJz.js"},{"revision":null,"url":"assets/extension-webview-DUs8mqO_.js"},{"revision":null,"url":"assets/file-exclamation-point-BwzaQ50n.js"},{"revision":null,"url":"assets/terminal-tab-ERPwhU5O.js"},{"revision":null,"url":"assets/api-settings-C__hxGX2.js"},{"revision":null,"url":"assets/index-C3ZstZ9f.css"},{"revision":null,"url":"assets/utils-CTg5uAYR.js"},{"revision":null,"url":"assets/columns-2-4fQcE4PF.js"},{"revision":null,"url":"assets/KaTeX_Main-Bold-Cx986IdX.woff2"},{"revision":null,"url":"assets/sqlite-viewer-DzS8-nbv.js"},{"revision":null,"url":"assets/KaTeX_Size2-Regular-Dy4dx90m.woff2"},{"revision":null,"url":"assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2"},{"revision":null,"url":"assets/KaTeX_Size1-Regular-mCD8mA8B.woff2"},{"revision":null,"url":"assets/audio-preview--VaB403K.js"},{"revision":null,"url":"assets/image-preview-CoiyMXuX.js"},{"revision":null,"url":"assets/tab-store-B3M9hjho.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-C8puYVyN.js"},{"revision":null,"url":"assets/api-client-Bn-Pi9k5.js"},{"revision":null,"url":"assets/createLucideIcon-BjHrJDVb.js"},{"revision":null,"url":"assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2"},{"revision":null,"url":"assets/code-CuravVys.js"},{"revision":null,"url":"assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2"},{"revision":null,"url":"assets/sql-completion-provider-C3cq9j99.js"},{"revision":null,"url":"assets/settings-store-B9axDbuA.js"},{"revision":null,"url":"assets/use-blob-url-BK7zshV7.js"},{"revision":null,"url":"assets/esm-K1XIK4vc.js"},{"revision":null,"url":"assets/settings-tab-l-SopAs4.js"},{"revision":null,"url":"assets/vendor-xterm-BrP-ENHg.css"},{"revision":null,"url":"assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2"},{"revision":null,"url":"assets/port-forwarding-tab-DpoVwtlp.js"},{"revision":null,"url":"assets/lib-DQHnkzGy.js"},{"revision":null,"url":"assets/database-viewer-B7aIs1XX.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-BRZ7alnf.js"},{"revision":"d0f94ce046cf8cf09605ee7664dac557","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"a424156a79b9c1b907db93aa3180585a","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"b3a7f967560c9816492a1567b3f7f0dc","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":"a5d8a1acfc29c2a4c882a54ffc93def3","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"948e060affb598c339be40d69e1f6f9c","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"79c8870653c8f419f2e3323085e1f4be","url":"manifest.webmanifest"}]),self.addEventListener(`push`,e=>{e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{if(t.some(e=>e.visibilityState===`visible`))return;let n=e.data?.json()??{title:`PPM`,body:`Chat completed`};return self.registration.showNotification(n.title,{body:n.body,icon:`/icon-192.png`,badge:`/icon-192.png`,tag:`ppm-chat-done`,silent:!1,data:{url:self.location.origin}})}))}),self.addEventListener(`notificationclick`,e=>{e.notification.close(),e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{for(let e of t)if(e.url.includes(self.location.origin)&&`focus`in e)return e.focus();return self.clients.openWindow(e.notification.data?.url||`/`)}))});
|
package/package.json
CHANGED
|
@@ -75,9 +75,8 @@ function log(level: string, msg: string) {
|
|
|
75
75
|
const ts = new Date().toISOString();
|
|
76
76
|
const line = `[${ts}] [${level}] [supervisor] ${msg}\n`;
|
|
77
77
|
try { appendFileSync(logFile(), line); } catch {}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
78
|
+
// Always write supervisor logs to stderr so journalctl captures them
|
|
79
|
+
try { process.stderr.write(line); } catch {}
|
|
81
80
|
}
|
|
82
81
|
|
|
83
82
|
// ─── Backoff calc ──────────────────────────────────────────────────────
|
|
@@ -243,7 +242,18 @@ export async function spawnTunnel(port: number): Promise<void> {
|
|
|
243
242
|
tunnelChild = null;
|
|
244
243
|
|
|
245
244
|
if (shuttingDown) return;
|
|
245
|
+
|
|
246
|
+
const now = Date.now();
|
|
247
|
+
if (now - lastTunnelCrash > STABLE_WINDOW_MS) tunnelRestarts = 0;
|
|
248
|
+
lastTunnelCrash = now;
|
|
246
249
|
tunnelRestarts++;
|
|
250
|
+
|
|
251
|
+
if (tunnelRestarts > MAX_RESTARTS) {
|
|
252
|
+
log("ERROR", `Tunnel exceeded ${MAX_RESTARTS} URL extraction failures, disabling tunnel`);
|
|
253
|
+
updateStatus({ shareUrl: null, tunnelPid: null });
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
247
257
|
const delay = backoffDelay(tunnelRestarts);
|
|
248
258
|
log("WARN", `Tunnel failed, retry in ${delay}ms (#${tunnelRestarts})`);
|
|
249
259
|
await Bun.sleep(delay);
|
|
@@ -276,7 +286,7 @@ export async function spawnTunnel(port: number): Promise<void> {
|
|
|
276
286
|
}
|
|
277
287
|
|
|
278
288
|
const delay = backoffDelay(tunnelRestarts);
|
|
279
|
-
log("WARN", `Tunnel
|
|
289
|
+
log("WARN", `Tunnel process exited (code=${exitCode}, signal=${tunnelChild === null ? "killed" : "self"}, url=${deadUrl}), restart in ${delay}ms (#${tunnelRestarts})`);
|
|
280
290
|
await Bun.sleep(delay);
|
|
281
291
|
|
|
282
292
|
if (!shuttingDown) return spawnTunnel(port);
|
|
@@ -734,9 +744,20 @@ export function shutdown() {
|
|
|
734
744
|
if (upgradeDelayTimer) clearTimeout(upgradeDelayTimer);
|
|
735
745
|
if (cloudMonitorTimer) clearInterval(cloudMonitorTimer);
|
|
736
746
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
if (
|
|
747
|
+
// Use SIGKILL for children — SIGTERM leaves grandchildren (Claude SDK, etc.)
|
|
748
|
+
// alive, causing systemd to wait 90s then SIGKILL the entire cgroup
|
|
749
|
+
if (serverChild) {
|
|
750
|
+
log("INFO", `Killing server child (PID: ${serverChild.pid})`);
|
|
751
|
+
try { serverChild.kill("SIGKILL"); } catch {}
|
|
752
|
+
}
|
|
753
|
+
if (tunnelChild) {
|
|
754
|
+
log("INFO", `Killing tunnel child (PID: ${tunnelChild.pid})`);
|
|
755
|
+
try { tunnelChild.kill("SIGKILL"); } catch {}
|
|
756
|
+
}
|
|
757
|
+
if (adoptedTunnelPid) {
|
|
758
|
+
log("INFO", `Killing adopted tunnel (PID: ${adoptedTunnelPid})`);
|
|
759
|
+
try { process.kill(adoptedTunnelPid, "SIGKILL"); } catch {}
|
|
760
|
+
}
|
|
740
761
|
}
|
|
741
762
|
|
|
742
763
|
// ─── Main entry ────────────────────────────────────────────────────────
|
|
@@ -788,9 +809,19 @@ export async function runSupervisor(opts: {
|
|
|
788
809
|
_logFd = logFd;
|
|
789
810
|
_opts = { port: opts.port, host: opts.host, share: opts.share };
|
|
790
811
|
|
|
791
|
-
// Signal handlers
|
|
792
|
-
|
|
793
|
-
|
|
812
|
+
// Signal handlers — force exit after 5s if process.exit doesn't work
|
|
813
|
+
const forceShutdown = (signal: string) => {
|
|
814
|
+
log("INFO", `${signal} received`);
|
|
815
|
+
shutdown();
|
|
816
|
+
// Safety net: force kill self if process.exit(0) doesn't terminate
|
|
817
|
+
setTimeout(() => {
|
|
818
|
+
log("WARN", `Force exit after ${signal} — process.exit(0) did not terminate`);
|
|
819
|
+
try { process.kill(process.pid, "SIGKILL"); } catch {}
|
|
820
|
+
}, 5000).unref();
|
|
821
|
+
process.exit(0);
|
|
822
|
+
};
|
|
823
|
+
process.on("SIGTERM", () => forceShutdown("SIGTERM"));
|
|
824
|
+
process.on("SIGINT", () => forceShutdown("SIGINT"));
|
|
794
825
|
|
|
795
826
|
// SIGUSR2 = command file dispatch OR graceful server restart
|
|
796
827
|
process.on("SIGUSR2", () => {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Loader2, FileWarning, Music } from "lucide-react";
|
|
2
|
+
import { useBlobUrl } from "./use-blob-url";
|
|
3
|
+
import { basename } from "@/lib/utils";
|
|
4
|
+
|
|
5
|
+
export function AudioPreview({ filePath, projectName }: { filePath: string; projectName: string }) {
|
|
6
|
+
const { blobUrl, error } = useBlobUrl(filePath, projectName);
|
|
7
|
+
|
|
8
|
+
if (error) {
|
|
9
|
+
return (
|
|
10
|
+
<div className="flex flex-col items-center justify-center h-full gap-3 text-text-secondary">
|
|
11
|
+
<FileWarning className="size-10 text-text-subtle" />
|
|
12
|
+
<p className="text-sm">Failed to load audio.</p>
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
if (!blobUrl) {
|
|
17
|
+
return <div className="flex items-center justify-center h-full"><Loader2 className="size-5 animate-spin text-text-subtle" /></div>;
|
|
18
|
+
}
|
|
19
|
+
return (
|
|
20
|
+
<div className="flex flex-col items-center justify-center h-full gap-4 p-4 bg-surface">
|
|
21
|
+
<Music className="size-16 text-text-subtle" />
|
|
22
|
+
<p className="text-sm text-text-secondary truncate max-w-xs">{basename(filePath)}</p>
|
|
23
|
+
<audio src={blobUrl} controls className="w-full max-w-md" />
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { useEffect, useState, useCallback, useRef, useMemo, memo, lazy, Suspense } from "react";
|
|
2
2
|
import Editor, { type OnMount } from "@monaco-editor/react";
|
|
3
3
|
import type * as MonacoType from "monaco-editor";
|
|
4
|
-
import { api, projectUrl
|
|
4
|
+
import { api, projectUrl } from "@/lib/api-client";
|
|
5
5
|
import { useShallow } from "zustand/react/shallow";
|
|
6
6
|
import { useTabStore } from "@/stores/tab-store";
|
|
7
7
|
import { usePanelStore } from "@/stores/panel-store";
|
|
8
8
|
import { useSettingsStore } from "@/stores/settings-store";
|
|
9
9
|
import { basename } from "@/lib/utils";
|
|
10
10
|
import { useMonacoTheme } from "@/lib/use-monaco-theme";
|
|
11
|
-
import { Loader2, FileWarning,
|
|
11
|
+
import { Loader2, FileWarning, Play, Database } from "lucide-react";
|
|
12
12
|
import { EditorBreadcrumb } from "./editor-breadcrumb";
|
|
13
13
|
import { EditorToolbar } from "./editor-toolbar";
|
|
14
14
|
import { SaveAsDialog } from "./save-as-dialog";
|
|
@@ -19,9 +19,17 @@ const MarkdownRenderer = lazy(() =>
|
|
|
19
19
|
import("@/components/shared/markdown-renderer").then((m) => ({ default: m.MarkdownRenderer }))
|
|
20
20
|
);
|
|
21
21
|
const CsvPreview = lazy(() => import("./csv-preview").then((m) => ({ default: m.CsvPreview })));
|
|
22
|
+
const ImagePreview = lazy(() => import("./image-preview").then((m) => ({ default: m.ImagePreview })));
|
|
23
|
+
const PdfPreview = lazy(() => import("./pdf-preview").then((m) => ({ default: m.PdfPreview })));
|
|
24
|
+
const VideoPreview = lazy(() => import("./video-preview").then((m) => ({ default: m.VideoPreview })));
|
|
25
|
+
const AudioPreview = lazy(() => import("./audio-preview").then((m) => ({ default: m.AudioPreview })));
|
|
22
26
|
|
|
23
27
|
/** Image extensions renderable inline */
|
|
24
28
|
const IMAGE_EXTS = new Set(["png", "jpg", "jpeg", "gif", "webp", "svg", "ico"]);
|
|
29
|
+
/** Video extensions playable inline */
|
|
30
|
+
const VIDEO_EXTS = new Set(["mp4", "webm", "mov", "ogg", "avi", "mkv"]);
|
|
31
|
+
/** Audio extensions playable inline */
|
|
32
|
+
const AUDIO_EXTS = new Set(["mp3", "wav", "flac", "aac", "m4a", "wma"]);
|
|
25
33
|
/** SQLite extensions — redirect to sqlite viewer */
|
|
26
34
|
const SQLITE_EXTS = new Set(["db", "sqlite", "sqlite3"]);
|
|
27
35
|
|
|
@@ -75,6 +83,8 @@ export const CodeEditor = memo(function CodeEditor({ metadata, tabId }: CodeEdit
|
|
|
75
83
|
const ext = filePath ? getFileExt(filePath) : "";
|
|
76
84
|
const isImage = IMAGE_EXTS.has(ext);
|
|
77
85
|
const isPdf = ext === "pdf";
|
|
86
|
+
const isVideo = VIDEO_EXTS.has(ext);
|
|
87
|
+
const isAudio = AUDIO_EXTS.has(ext);
|
|
78
88
|
const isSqlite = SQLITE_EXTS.has(ext);
|
|
79
89
|
const isMarkdown = ext === "md" || ext === "mdx";
|
|
80
90
|
const isCsv = ext === "csv";
|
|
@@ -215,7 +225,7 @@ export const CodeEditor = memo(function CodeEditor({ metadata, tabId }: CodeEdit
|
|
|
215
225
|
}
|
|
216
226
|
if (!filePath) return;
|
|
217
227
|
if (!isExternalFile && !projectName) return;
|
|
218
|
-
if (isImage || isPdf) { setLoading(false); return; }
|
|
228
|
+
if (isImage || isPdf || isVideo || isAudio) { setLoading(false); return; }
|
|
219
229
|
|
|
220
230
|
setLoading(true);
|
|
221
231
|
setError(null);
|
|
@@ -451,8 +461,10 @@ export const CodeEditor = memo(function CodeEditor({ metadata, tabId }: CodeEdit
|
|
|
451
461
|
);
|
|
452
462
|
}
|
|
453
463
|
|
|
454
|
-
if (isImage) return <ImagePreview filePath={filePath!} projectName={projectName!}
|
|
455
|
-
if (isPdf) return <PdfPreview filePath={filePath!} projectName={projectName!}
|
|
464
|
+
if (isImage) return <Suspense fallback={<LoadingSpinner />}><ImagePreview filePath={filePath!} projectName={projectName!} /></Suspense>;
|
|
465
|
+
if (isPdf) return <Suspense fallback={<LoadingSpinner />}><PdfPreview filePath={filePath!} projectName={projectName!} /></Suspense>;
|
|
466
|
+
if (isVideo) return <Suspense fallback={<LoadingSpinner />}><VideoPreview filePath={filePath!} projectName={projectName!} /></Suspense>;
|
|
467
|
+
if (isAudio) return <Suspense fallback={<LoadingSpinner />}><AudioPreview filePath={filePath!} projectName={projectName!} /></Suspense>;
|
|
456
468
|
|
|
457
469
|
if (encoding === "base64") {
|
|
458
470
|
return (
|
|
@@ -580,6 +592,10 @@ export const CodeEditor = memo(function CodeEditor({ metadata, tabId }: CodeEdit
|
|
|
580
592
|
);
|
|
581
593
|
});
|
|
582
594
|
|
|
595
|
+
function LoadingSpinner() {
|
|
596
|
+
return <div className="flex items-center justify-center h-full"><Loader2 className="size-5 animate-spin text-text-subtle" /></div>;
|
|
597
|
+
}
|
|
598
|
+
|
|
583
599
|
function MarkdownPreview({ content }: { content: string }) {
|
|
584
600
|
return (
|
|
585
601
|
<Suspense fallback={<div className="animate-pulse h-4 bg-muted rounded m-4" />}>
|
|
@@ -588,79 +604,3 @@ function MarkdownPreview({ content }: { content: string }) {
|
|
|
588
604
|
);
|
|
589
605
|
}
|
|
590
606
|
|
|
591
|
-
function ImagePreview({ filePath, projectName }: { filePath: string; projectName: string }) {
|
|
592
|
-
const [blobUrl, setBlobUrl] = useState<string | null>(null);
|
|
593
|
-
const [error, setError] = useState(false);
|
|
594
|
-
|
|
595
|
-
useEffect(() => {
|
|
596
|
-
let revoke: string | undefined;
|
|
597
|
-
const url = `${projectUrl(projectName)}/files/raw?path=${encodeURIComponent(filePath)}`;
|
|
598
|
-
const token = getAuthToken();
|
|
599
|
-
fetch(url, { headers: token ? { Authorization: `Bearer ${token}` } : {} })
|
|
600
|
-
.then((r) => { if (!r.ok) throw new Error("Failed"); return r.blob(); })
|
|
601
|
-
.then((blob) => { const u = URL.createObjectURL(blob); revoke = u; setBlobUrl(u); })
|
|
602
|
-
.catch(() => setError(true));
|
|
603
|
-
return () => { if (revoke) URL.revokeObjectURL(revoke); };
|
|
604
|
-
}, [filePath, projectName]);
|
|
605
|
-
|
|
606
|
-
if (error) {
|
|
607
|
-
return (
|
|
608
|
-
<div className="flex flex-col items-center justify-center h-full gap-3 text-text-secondary">
|
|
609
|
-
<FileWarning className="size-10 text-text-subtle" />
|
|
610
|
-
<p className="text-sm">Failed to load image.</p>
|
|
611
|
-
</div>
|
|
612
|
-
);
|
|
613
|
-
}
|
|
614
|
-
if (!blobUrl) {
|
|
615
|
-
return <div className="flex items-center justify-center h-full"><Loader2 className="size-5 animate-spin text-text-subtle" /></div>;
|
|
616
|
-
}
|
|
617
|
-
return (
|
|
618
|
-
<div className="flex items-center justify-center h-full p-4 bg-surface overflow-auto">
|
|
619
|
-
<img src={blobUrl} alt={filePath} className="max-w-full max-h-full object-contain" />
|
|
620
|
-
</div>
|
|
621
|
-
);
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
function PdfPreview({ filePath, projectName }: { filePath: string; projectName: string }) {
|
|
625
|
-
const [blobUrl, setBlobUrl] = useState<string | null>(null);
|
|
626
|
-
const [error, setError] = useState(false);
|
|
627
|
-
|
|
628
|
-
useEffect(() => {
|
|
629
|
-
let revoke: string | undefined;
|
|
630
|
-
const url = `${projectUrl(projectName)}/files/raw?path=${encodeURIComponent(filePath)}`;
|
|
631
|
-
const token = getAuthToken();
|
|
632
|
-
fetch(url, { headers: token ? { Authorization: `Bearer ${token}` } : {} })
|
|
633
|
-
.then((r) => { if (!r.ok) throw new Error("Failed"); return r.blob(); })
|
|
634
|
-
.then((blob) => {
|
|
635
|
-
const u = URL.createObjectURL(new Blob([blob], { type: "application/pdf" }));
|
|
636
|
-
revoke = u; setBlobUrl(u);
|
|
637
|
-
})
|
|
638
|
-
.catch(() => setError(true));
|
|
639
|
-
return () => { if (revoke) URL.revokeObjectURL(revoke); };
|
|
640
|
-
}, [filePath, projectName]);
|
|
641
|
-
|
|
642
|
-
const openInNewTab = useCallback(() => { if (blobUrl) window.open(blobUrl, "_blank"); }, [blobUrl]);
|
|
643
|
-
|
|
644
|
-
if (error) {
|
|
645
|
-
return (
|
|
646
|
-
<div className="flex flex-col items-center justify-center h-full gap-3 text-text-secondary">
|
|
647
|
-
<FileWarning className="size-10 text-text-subtle" />
|
|
648
|
-
<p className="text-sm">Failed to load PDF.</p>
|
|
649
|
-
</div>
|
|
650
|
-
);
|
|
651
|
-
}
|
|
652
|
-
if (!blobUrl) {
|
|
653
|
-
return <div className="flex items-center justify-center h-full"><Loader2 className="size-5 animate-spin text-text-subtle" /></div>;
|
|
654
|
-
}
|
|
655
|
-
return (
|
|
656
|
-
<div className="flex flex-col h-full">
|
|
657
|
-
<div className="flex items-center justify-between px-3 py-1.5 border-b border-border bg-background shrink-0">
|
|
658
|
-
<span className="text-xs text-text-secondary truncate">{filePath}</span>
|
|
659
|
-
<button onClick={openInNewTab} className="flex items-center gap-1 text-xs text-text-secondary hover:text-text-primary transition-colors">
|
|
660
|
-
<ExternalLink className="size-3" /> Open in new tab
|
|
661
|
-
</button>
|
|
662
|
-
</div>
|
|
663
|
-
<iframe src={blobUrl} title={filePath} className="flex-1 w-full border-none" />
|
|
664
|
-
</div>
|
|
665
|
-
);
|
|
666
|
-
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Loader2, FileWarning } from "lucide-react";
|
|
2
|
+
import { useBlobUrl } from "./use-blob-url";
|
|
3
|
+
|
|
4
|
+
export function ImagePreview({ filePath, projectName }: { filePath: string; projectName: string }) {
|
|
5
|
+
const { blobUrl, error } = useBlobUrl(filePath, projectName);
|
|
6
|
+
|
|
7
|
+
if (error) {
|
|
8
|
+
return (
|
|
9
|
+
<div className="flex flex-col items-center justify-center h-full gap-3 text-text-secondary">
|
|
10
|
+
<FileWarning className="size-10 text-text-subtle" />
|
|
11
|
+
<p className="text-sm">Failed to load image.</p>
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
if (!blobUrl) {
|
|
16
|
+
return <div className="flex items-center justify-center h-full"><Loader2 className="size-5 animate-spin text-text-subtle" /></div>;
|
|
17
|
+
}
|
|
18
|
+
return (
|
|
19
|
+
<div className="flex items-center justify-center h-full p-4 bg-surface overflow-auto">
|
|
20
|
+
<img src={blobUrl} alt={filePath} className="max-w-full max-h-full object-contain" />
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { Loader2, FileWarning, ExternalLink } from "lucide-react";
|
|
3
|
+
import { useBlobUrl } from "./use-blob-url";
|
|
4
|
+
|
|
5
|
+
export function PdfPreview({ filePath, projectName }: { filePath: string; projectName: string }) {
|
|
6
|
+
const { blobUrl, error } = useBlobUrl(filePath, projectName, "application/pdf");
|
|
7
|
+
|
|
8
|
+
const openInNewTab = useCallback(() => { if (blobUrl) window.open(blobUrl, "_blank"); }, [blobUrl]);
|
|
9
|
+
|
|
10
|
+
if (error) {
|
|
11
|
+
return (
|
|
12
|
+
<div className="flex flex-col items-center justify-center h-full gap-3 text-text-secondary">
|
|
13
|
+
<FileWarning className="size-10 text-text-subtle" />
|
|
14
|
+
<p className="text-sm">Failed to load PDF.</p>
|
|
15
|
+
</div>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
if (!blobUrl) {
|
|
19
|
+
return <div className="flex items-center justify-center h-full"><Loader2 className="size-5 animate-spin text-text-subtle" /></div>;
|
|
20
|
+
}
|
|
21
|
+
return (
|
|
22
|
+
<div className="flex flex-col h-full">
|
|
23
|
+
<div className="flex items-center justify-between px-3 py-1.5 border-b border-border bg-background shrink-0">
|
|
24
|
+
<span className="text-xs text-text-secondary truncate">{filePath}</span>
|
|
25
|
+
<button onClick={openInNewTab} className="flex items-center gap-1 text-xs text-text-secondary hover:text-text-primary transition-colors">
|
|
26
|
+
<ExternalLink className="size-3" /> Open in new tab
|
|
27
|
+
</button>
|
|
28
|
+
</div>
|
|
29
|
+
<iframe src={blobUrl} title={filePath} className="flex-1 w-full border-none" />
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { projectUrl, getAuthToken } from "@/lib/api-client";
|
|
3
|
+
|
|
4
|
+
/** Shared hook: fetch a project file as a blob URL via /files/raw endpoint. */
|
|
5
|
+
export function useBlobUrl(
|
|
6
|
+
filePath: string,
|
|
7
|
+
projectName: string,
|
|
8
|
+
mimeOverride?: string,
|
|
9
|
+
) {
|
|
10
|
+
const [blobUrl, setBlobUrl] = useState<string | null>(null);
|
|
11
|
+
const [error, setError] = useState(false);
|
|
12
|
+
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
let revoke: string | undefined;
|
|
15
|
+
const url = `${projectUrl(projectName)}/files/raw?path=${encodeURIComponent(filePath)}`;
|
|
16
|
+
const token = getAuthToken();
|
|
17
|
+
fetch(url, { headers: token ? { Authorization: `Bearer ${token}` } : {} })
|
|
18
|
+
.then((r) => {
|
|
19
|
+
if (!r.ok) throw new Error("Failed");
|
|
20
|
+
return r.blob();
|
|
21
|
+
})
|
|
22
|
+
.then((blob) => {
|
|
23
|
+
const final = mimeOverride ? new Blob([blob], { type: mimeOverride }) : blob;
|
|
24
|
+
const u = URL.createObjectURL(final);
|
|
25
|
+
revoke = u;
|
|
26
|
+
setBlobUrl(u);
|
|
27
|
+
})
|
|
28
|
+
.catch(() => setError(true));
|
|
29
|
+
return () => {
|
|
30
|
+
if (revoke) URL.revokeObjectURL(revoke);
|
|
31
|
+
};
|
|
32
|
+
}, [filePath, projectName, mimeOverride]);
|
|
33
|
+
|
|
34
|
+
return { blobUrl, error };
|
|
35
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Loader2, FileWarning } from "lucide-react";
|
|
2
|
+
import { useBlobUrl } from "./use-blob-url";
|
|
3
|
+
|
|
4
|
+
export function VideoPreview({ filePath, projectName }: { filePath: string; projectName: string }) {
|
|
5
|
+
const { blobUrl, error } = useBlobUrl(filePath, projectName);
|
|
6
|
+
|
|
7
|
+
if (error) {
|
|
8
|
+
return (
|
|
9
|
+
<div className="flex flex-col items-center justify-center h-full gap-3 text-text-secondary">
|
|
10
|
+
<FileWarning className="size-10 text-text-subtle" />
|
|
11
|
+
<p className="text-sm">Failed to load video.</p>
|
|
12
|
+
</div>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
if (!blobUrl) {
|
|
16
|
+
return <div className="flex items-center justify-center h-full"><Loader2 className="size-5 animate-spin text-text-subtle" /></div>;
|
|
17
|
+
}
|
|
18
|
+
return (
|
|
19
|
+
<div className="flex items-center justify-center h-full p-4 bg-surface overflow-auto">
|
|
20
|
+
<video src={blobUrl} controls className="max-w-full max-h-full" />
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{W as e}from"./vendor-mermaid-CylkVm4U.js";export{e as createArchitectureServices};
|