@hienlh/ppm 0.9.91 → 0.9.93

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.
Files changed (29) hide show
  1. package/CHANGELOG.md +7 -1
  2. package/dist/web/assets/{chat-tab-BPoQy-Fp.js → chat-tab-CC721_mQ.js} +1 -1
  3. package/dist/web/assets/{code-editor-DDW9dlUL.js → code-editor-BZ0xwZ4Z.js} +1 -1
  4. package/dist/web/assets/{conflict-editor-Bt24HTjk.js → conflict-editor-Bwls2-yk.js} +1 -1
  5. package/dist/web/assets/{database-viewer-DbD8rfQF.js → database-viewer-DiXWqOJH.js} +1 -1
  6. package/dist/web/assets/{diff-viewer-DVWJoL2y.js → diff-viewer-CC-RmeV5.js} +1 -1
  7. package/dist/web/assets/extension-webview-C1d6fezE.js +3 -0
  8. package/dist/web/assets/{index-DK4yJlIj.js → index-BcIyrJiY.js} +3 -3
  9. package/dist/web/assets/keybindings-store-BIufrOzJ.js +1 -0
  10. package/dist/web/assets/{markdown-renderer-CCq6xBWp.js → markdown-renderer-C5UPA1-7.js} +1 -1
  11. package/dist/web/assets/{port-forwarding-tab-BBwfD-s_.js → port-forwarding-tab-DmifthYH.js} +1 -1
  12. package/dist/web/assets/{postgres-viewer-Dqnhi-ci.js → postgres-viewer-Bo7jEQfQ.js} +1 -1
  13. package/dist/web/assets/{settings-tab-DX9zkGvD.js → settings-tab-D9GicyA9.js} +1 -1
  14. package/dist/web/assets/{sql-query-editor-CxODOF9o.js → sql-query-editor-DaePHpQI.js} +1 -1
  15. package/dist/web/assets/{sqlite-viewer-DAgT72tD.js → sqlite-viewer-pacZlViY.js} +1 -1
  16. package/dist/web/assets/{terminal-tab-5ib6rUAO.js → terminal-tab-DpzE3yoD.js} +1 -1
  17. package/dist/web/assets/{use-monaco-theme-vmoBT6np.js → use-monaco-theme-CM4IMROI.js} +1 -1
  18. package/dist/web/index.html +1 -1
  19. package/dist/web/sw.js +1 -1
  20. package/package.json +1 -1
  21. package/packages/ext-git-graph/src/extension.ts +5 -20
  22. package/packages/vscode-compat/src/window.ts +14 -0
  23. package/src/server/ws/extensions.ts +12 -0
  24. package/src/services/extension-host-worker.ts +12 -0
  25. package/src/types/extension-messages.ts +1 -0
  26. package/src/web/components/extensions/extension-webview.tsx +24 -3
  27. package/src/web/hooks/use-extension-ws.ts +37 -10
  28. package/dist/web/assets/extension-webview-nq9rDNgj.js +0 -3
  29. package/dist/web/assets/keybindings-store-CpFk-yNF.js +0 -1
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":"070a95d5275afbec5378091f7214530d","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"948e060affb598c339be40d69e1f6f9c","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"a5d8a1acfc29c2a4c882a54ffc93def3","url":"monacoeditorwork/json.worker.bundle.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":null,"url":"assets/xychartDiagram-JWTSCODW-CtpjAakO.js"},{"revision":null,"url":"assets/x-Dw3TjeY_.js"},{"revision":null,"url":"assets/vennDiagram-LZ73GAT5-C-rkIUbo.js"},{"revision":null,"url":"assets/utils-DX8jb5qv.js"},{"revision":null,"url":"assets/use-monaco-theme-vmoBT6np.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-Kck06FKU.js"},{"revision":null,"url":"assets/trash-2-CNuB-htI.js"},{"revision":null,"url":"assets/timeline-definition-YZTLITO2-pMv1grvM.js"},{"revision":null,"url":"assets/text-wrap-D_OmSzhp.js"},{"revision":null,"url":"assets/terminal-tab-BrP-ENHg.css"},{"revision":null,"url":"assets/terminal-tab-5ib6rUAO.js"},{"revision":null,"url":"assets/table-Bi27fEaN.js"},{"revision":null,"url":"assets/stateDiagram-v2-FVOUBMTO-D6zvxf3M.js"},{"revision":null,"url":"assets/stateDiagram-RAJIS63D-ylr4HxPu.js"},{"revision":null,"url":"assets/src-CqyWLlNZ.js"},{"revision":null,"url":"assets/square-vBdqj0bF.js"},{"revision":null,"url":"assets/sqlite-viewer-DAgT72tD.js"},{"revision":null,"url":"assets/sql-query-editor-CxODOF9o.js"},{"revision":null,"url":"assets/sql-completion-provider-B8uUWWej.js"},{"revision":null,"url":"assets/settings-tab-DX9zkGvD.js"},{"revision":null,"url":"assets/sequenceDiagram-2WXFIKYE-B2D8IQDb.js"},{"revision":null,"url":"assets/scroll-area-BpXCNme3.js"},{"revision":null,"url":"assets/sankeyDiagram-WA2Y5GQK-BbRmhv0t.js"},{"revision":null,"url":"assets/rough.esm-eLccZ4OJ.js"},{"revision":null,"url":"assets/requirementDiagram-Z7DCOOCP-CuiiuGS9.js"},{"revision":null,"url":"assets/refresh-cw-Clk8fdUD.js"},{"revision":null,"url":"assets/react-nm2Ru1Pt.js"},{"revision":null,"url":"assets/react-dom-Bpkvzu3U.js"},{"revision":null,"url":"assets/react-0tkk-ztn.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-TqxBkWx-.js"},{"revision":null,"url":"assets/quadrantDiagram-337W2JSQ-TXe6cU_F.js"},{"revision":null,"url":"assets/preload-helper-mr3rCizq.js"},{"revision":null,"url":"assets/postgres-viewer-Dqnhi-ci.js"},{"revision":null,"url":"assets/port-forwarding-tab-BBwfD-s_.js"},{"revision":null,"url":"assets/plus-DQGIb4mQ.js"},{"revision":null,"url":"assets/pieDiagram-SKSYHLDU-Dovdlvhu.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-BPgAfmes.js"},{"revision":null,"url":"assets/path-INs8XTPH.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-BwpIpYB3.js"},{"revision":null,"url":"assets/ordinal-DpFn432U.js"},{"revision":null,"url":"assets/mindmap-definition-YRQLILUH-pYPWwASE.js"},{"revision":null,"url":"assets/mermaid-parser.core-CFdP1Z5_.js"},{"revision":null,"url":"assets/math-CRc16Nj6.js"},{"revision":null,"url":"assets/markdown-renderer-CCq6xBWp.js"},{"revision":null,"url":"assets/linear-DFN_MPsw.js"},{"revision":null,"url":"assets/line-CSuSrJ9J.js"},{"revision":null,"url":"assets/lib-DSLzfeW0.js"},{"revision":null,"url":"assets/keybindings-store-CpFk-yNF.js"},{"revision":null,"url":"assets/katex-DR0kdMDv.js"},{"revision":null,"url":"assets/kanban-definition-K7BYSVSG-miB0-_Zq.js"},{"revision":null,"url":"assets/jsx-runtime-BRW_vwa9.js"},{"revision":null,"url":"assets/journeyDiagram-4ABVD52K-CG_v5Aho.js"},{"revision":null,"url":"assets/ishikawaDiagram-PHBUUO56-CiVEvp8o.js"},{"revision":null,"url":"assets/isEmpty-BfLnxq-B.js"},{"revision":null,"url":"assets/isArrayLikeObject-ClzWCpcm.js"},{"revision":null,"url":"assets/input-BHj0veau.js"},{"revision":null,"url":"assets/init-0VJVrkRJ.js"},{"revision":null,"url":"assets/infoDiagram-LFFYTUFH-Diq4Cyc3.js"},{"revision":null,"url":"assets/info-3K5VOQVL-BDU2_bYD.js"},{"revision":null,"url":"assets/index-DK4yJlIj.js"},{"revision":null,"url":"assets/index-Chf0otez.css"},{"revision":null,"url":"assets/graphlib-BWe1iK_s.js"},{"revision":null,"url":"assets/gitGraphDiagram-K3NZZRJ6-BMgjjVys.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-OkvBPi6H.js"},{"revision":null,"url":"assets/ganttDiagram-A5KZAMGK-KSn4XAU4.js"},{"revision":null,"url":"assets/flowDiagram-PKNHOUZH-CFYAfZBx.js"},{"revision":null,"url":"assets/extension-webview-nq9rDNgj.js"},{"revision":null,"url":"assets/erDiagram-INFDFZHY-DSkriYZ9.js"},{"revision":null,"url":"assets/dist-DZmJeHOA.js"},{"revision":null,"url":"assets/dist-CM0oD8tQ.js"},{"revision":null,"url":"assets/diff-viewer-DVWJoL2y.js"},{"revision":null,"url":"assets/diagram-P4PSJMXO-CW0eCkwC.js"},{"revision":null,"url":"assets/diagram-IFDJBPK2-nUcO8sN8.js"},{"revision":null,"url":"assets/diagram-E7M64L7V-BZF0tSOr.js"},{"revision":null,"url":"assets/defaultLocale-ZeknFqNe.js"},{"revision":null,"url":"assets/database-viewer-DbD8rfQF.js"},{"revision":null,"url":"assets/database-CgTomMxt.js"},{"revision":null,"url":"assets/dagre-KLK3FWXG-Cnp996VG.js"},{"revision":null,"url":"assets/dagre-CkhlMHnx.js"},{"revision":null,"url":"assets/cytoscape.esm-C8i2jUzT.js"},{"revision":null,"url":"assets/csv-preview-BZRICDP0.js"},{"revision":null,"url":"assets/csv-parser-i7fjqP2H.js"},{"revision":null,"url":"assets/cose-bilkent-S5V4N54A-BGNPFv3x.js"},{"revision":null,"url":"assets/conflict-editor-Bt24HTjk.js"},{"revision":null,"url":"assets/columns-2-IeETSfON.js"},{"revision":null,"url":"assets/code-editor-DDW9dlUL.js"},{"revision":null,"url":"assets/clone--z5KLAuR.js"},{"revision":null,"url":"assets/classDiagram-v2-RAHNMMFH-BKe8_uda.js"},{"revision":null,"url":"assets/classDiagram-VBA2DB6C-mr-Cb1me.js"},{"revision":null,"url":"assets/chunk-YBOYWFTD-D_ILLe6_.js"},{"revision":null,"url":"assets/chunk-XZSTWKYB-DjV8xl5A.js"},{"revision":null,"url":"assets/chunk-XPW4576I-CgLyyW03.js"},{"revision":null,"url":"assets/chunk-XIRO2GV7-DZBoNl1_.js"},{"revision":null,"url":"assets/chunk-WL4C6EOR-B1iIvLOG.js"},{"revision":null,"url":"assets/chunk-R5LLSJPH-dRhXRnrb.js"},{"revision":null,"url":"assets/chunk-QZHKN3VN-N3VXx1VH.js"},{"revision":null,"url":"assets/chunk-PU5JKC2W-DD95Rx35.js"},{"revision":null,"url":"assets/chunk-PQ6SQG4A-Bik13fTV.js"},{"revision":null,"url":"assets/chunk-OZEHJAEY-lKq2SWjA.js"},{"revision":null,"url":"assets/chunk-O4XLMI2P-Vp_V4P-b.js"},{"revision":null,"url":"assets/chunk-NQ4KR5QH-DX32345Y.js"},{"revision":null,"url":"assets/chunk-MX3YWQON-B6g1ZH9X.js"},{"revision":null,"url":"assets/chunk-L3YUKLVL-DnSMmNFC.js"},{"revision":null,"url":"assets/chunk-KYZI473N-gqRLpJ4w.js"},{"revision":null,"url":"assets/chunk-KX2RTZJC-CHj8TnTB.js"},{"revision":null,"url":"assets/chunk-JSJVCQXG-23eG9mgt.js"},{"revision":null,"url":"assets/chunk-HHEYEP7N-C45i5G_3.js"},{"revision":null,"url":"assets/chunk-GLR3WWYH-Re-5eSlQ.js"},{"revision":null,"url":"assets/chunk-GEFDOKGD-86LFbsAC.js"},{"revision":null,"url":"assets/chunk-FMBD7UC4-Bog4cpN-.js"},{"revision":null,"url":"assets/chunk-EGIJ26TM-nant2LXl.js"},{"revision":null,"url":"assets/chunk-CFjPhJqf.js"},{"revision":null,"url":"assets/chunk-C72U2L5F-BHPkfQj2.js"},{"revision":null,"url":"assets/chunk-7R4GIKGN-y8bfHEy-.js"},{"revision":null,"url":"assets/chunk-7E7YKBS2-DZcnC7Ow.js"},{"revision":null,"url":"assets/chunk-55IACEB6-DhZGI1l3.js"},{"revision":null,"url":"assets/chunk-4BX2VUAB-CENmY7Kw.js"},{"revision":null,"url":"assets/chevron-right-DY_wImxB.js"},{"revision":null,"url":"assets/chat-tab-BPoQy-Fp.js"},{"revision":null,"url":"assets/channel-wumTB1if.js"},{"revision":null,"url":"assets/c4Diagram-IC4MRINW-BIymcNsg.js"},{"revision":null,"url":"assets/blockDiagram-WCTKOSBZ-Ct57Wtfk.js"},{"revision":null,"url":"assets/arrow-up-I9-21gkR.js"},{"revision":null,"url":"assets/array-BFDiaBgf.js"},{"revision":null,"url":"assets/architectureDiagram-2XIMDMQ5-D16OotsC.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-DDFO_NKq.js"},{"revision":null,"url":"assets/arc-CxgHJ7Z4.js"},{"revision":null,"url":"assets/api-settings-CUxg9RE5.js"},{"revision":null,"url":"assets/api-client-BvxmRZUi.js"},{"revision":null,"url":"assets/ai-settings-section-Bo9lCaTd.js"},{"revision":null,"url":"assets/_baseUniq-CyzdZeQH.js"},{"revision":null,"url":"assets/_basePickBy-Bj0dI1ei.js"},{"revision":null,"url":"assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2"},{"revision":null,"url":"assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2"},{"revision":null,"url":"assets/KaTeX_Size2-Regular-Dy4dx90m.woff2"},{"revision":null,"url":"assets/KaTeX_Size1-Regular-mCD8mA8B.woff2"},{"revision":null,"url":"assets/KaTeX_Script-Regular-D3wIWfF6.woff2"},{"revision":null,"url":"assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2"},{"revision":null,"url":"assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2"},{"revision":null,"url":"assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2"},{"revision":null,"url":"assets/KaTeX_Math-Italic-t53AETM-.woff2"},{"revision":null,"url":"assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2"},{"revision":null,"url":"assets/KaTeX_Main-Regular-B22Nviop.woff2"},{"revision":null,"url":"assets/KaTeX_Main-Italic-NWA7e6Wa.woff2"},{"revision":null,"url":"assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2"},{"revision":null,"url":"assets/KaTeX_Main-Bold-Cx986IdX.woff2"},{"revision":null,"url":"assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2"},{"revision":null,"url":"assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2"},{"revision":null,"url":"assets/KaTeX_AMS-Regular-BQhdFMY1.woff2"},{"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":"2acfba999ac6948556cd14fc22ee7ac9","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"948e060affb598c339be40d69e1f6f9c","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"a5d8a1acfc29c2a4c882a54ffc93def3","url":"monacoeditorwork/json.worker.bundle.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":null,"url":"assets/xychartDiagram-JWTSCODW-CtpjAakO.js"},{"revision":null,"url":"assets/x-Dw3TjeY_.js"},{"revision":null,"url":"assets/vennDiagram-LZ73GAT5-C-rkIUbo.js"},{"revision":null,"url":"assets/utils-DX8jb5qv.js"},{"revision":null,"url":"assets/use-monaco-theme-CM4IMROI.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-Kck06FKU.js"},{"revision":null,"url":"assets/trash-2-CNuB-htI.js"},{"revision":null,"url":"assets/timeline-definition-YZTLITO2-pMv1grvM.js"},{"revision":null,"url":"assets/text-wrap-D_OmSzhp.js"},{"revision":null,"url":"assets/terminal-tab-DpzE3yoD.js"},{"revision":null,"url":"assets/terminal-tab-BrP-ENHg.css"},{"revision":null,"url":"assets/table-Bi27fEaN.js"},{"revision":null,"url":"assets/stateDiagram-v2-FVOUBMTO-D6zvxf3M.js"},{"revision":null,"url":"assets/stateDiagram-RAJIS63D-ylr4HxPu.js"},{"revision":null,"url":"assets/src-CqyWLlNZ.js"},{"revision":null,"url":"assets/square-vBdqj0bF.js"},{"revision":null,"url":"assets/sqlite-viewer-pacZlViY.js"},{"revision":null,"url":"assets/sql-query-editor-DaePHpQI.js"},{"revision":null,"url":"assets/sql-completion-provider-B8uUWWej.js"},{"revision":null,"url":"assets/settings-tab-D9GicyA9.js"},{"revision":null,"url":"assets/sequenceDiagram-2WXFIKYE-B2D8IQDb.js"},{"revision":null,"url":"assets/scroll-area-BpXCNme3.js"},{"revision":null,"url":"assets/sankeyDiagram-WA2Y5GQK-BbRmhv0t.js"},{"revision":null,"url":"assets/rough.esm-eLccZ4OJ.js"},{"revision":null,"url":"assets/requirementDiagram-Z7DCOOCP-CuiiuGS9.js"},{"revision":null,"url":"assets/refresh-cw-Clk8fdUD.js"},{"revision":null,"url":"assets/react-nm2Ru1Pt.js"},{"revision":null,"url":"assets/react-dom-Bpkvzu3U.js"},{"revision":null,"url":"assets/react-0tkk-ztn.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-TqxBkWx-.js"},{"revision":null,"url":"assets/quadrantDiagram-337W2JSQ-TXe6cU_F.js"},{"revision":null,"url":"assets/preload-helper-mr3rCizq.js"},{"revision":null,"url":"assets/postgres-viewer-Bo7jEQfQ.js"},{"revision":null,"url":"assets/port-forwarding-tab-DmifthYH.js"},{"revision":null,"url":"assets/plus-DQGIb4mQ.js"},{"revision":null,"url":"assets/pieDiagram-SKSYHLDU-Dovdlvhu.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-BPgAfmes.js"},{"revision":null,"url":"assets/path-INs8XTPH.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-BwpIpYB3.js"},{"revision":null,"url":"assets/ordinal-DpFn432U.js"},{"revision":null,"url":"assets/mindmap-definition-YRQLILUH-pYPWwASE.js"},{"revision":null,"url":"assets/mermaid-parser.core-CFdP1Z5_.js"},{"revision":null,"url":"assets/math-CRc16Nj6.js"},{"revision":null,"url":"assets/markdown-renderer-C5UPA1-7.js"},{"revision":null,"url":"assets/linear-DFN_MPsw.js"},{"revision":null,"url":"assets/line-CSuSrJ9J.js"},{"revision":null,"url":"assets/lib-DSLzfeW0.js"},{"revision":null,"url":"assets/keybindings-store-BIufrOzJ.js"},{"revision":null,"url":"assets/katex-DR0kdMDv.js"},{"revision":null,"url":"assets/kanban-definition-K7BYSVSG-miB0-_Zq.js"},{"revision":null,"url":"assets/jsx-runtime-BRW_vwa9.js"},{"revision":null,"url":"assets/journeyDiagram-4ABVD52K-CG_v5Aho.js"},{"revision":null,"url":"assets/ishikawaDiagram-PHBUUO56-CiVEvp8o.js"},{"revision":null,"url":"assets/isEmpty-BfLnxq-B.js"},{"revision":null,"url":"assets/isArrayLikeObject-ClzWCpcm.js"},{"revision":null,"url":"assets/input-BHj0veau.js"},{"revision":null,"url":"assets/init-0VJVrkRJ.js"},{"revision":null,"url":"assets/infoDiagram-LFFYTUFH-Diq4Cyc3.js"},{"revision":null,"url":"assets/info-3K5VOQVL-BDU2_bYD.js"},{"revision":null,"url":"assets/index-Chf0otez.css"},{"revision":null,"url":"assets/index-BcIyrJiY.js"},{"revision":null,"url":"assets/graphlib-BWe1iK_s.js"},{"revision":null,"url":"assets/gitGraphDiagram-K3NZZRJ6-BMgjjVys.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-OkvBPi6H.js"},{"revision":null,"url":"assets/ganttDiagram-A5KZAMGK-KSn4XAU4.js"},{"revision":null,"url":"assets/flowDiagram-PKNHOUZH-CFYAfZBx.js"},{"revision":null,"url":"assets/extension-webview-C1d6fezE.js"},{"revision":null,"url":"assets/erDiagram-INFDFZHY-DSkriYZ9.js"},{"revision":null,"url":"assets/dist-DZmJeHOA.js"},{"revision":null,"url":"assets/dist-CM0oD8tQ.js"},{"revision":null,"url":"assets/diff-viewer-CC-RmeV5.js"},{"revision":null,"url":"assets/diagram-P4PSJMXO-CW0eCkwC.js"},{"revision":null,"url":"assets/diagram-IFDJBPK2-nUcO8sN8.js"},{"revision":null,"url":"assets/diagram-E7M64L7V-BZF0tSOr.js"},{"revision":null,"url":"assets/defaultLocale-ZeknFqNe.js"},{"revision":null,"url":"assets/database-viewer-DiXWqOJH.js"},{"revision":null,"url":"assets/database-CgTomMxt.js"},{"revision":null,"url":"assets/dagre-KLK3FWXG-Cnp996VG.js"},{"revision":null,"url":"assets/dagre-CkhlMHnx.js"},{"revision":null,"url":"assets/cytoscape.esm-C8i2jUzT.js"},{"revision":null,"url":"assets/csv-preview-BZRICDP0.js"},{"revision":null,"url":"assets/csv-parser-i7fjqP2H.js"},{"revision":null,"url":"assets/cose-bilkent-S5V4N54A-BGNPFv3x.js"},{"revision":null,"url":"assets/conflict-editor-Bwls2-yk.js"},{"revision":null,"url":"assets/columns-2-IeETSfON.js"},{"revision":null,"url":"assets/code-editor-BZ0xwZ4Z.js"},{"revision":null,"url":"assets/clone--z5KLAuR.js"},{"revision":null,"url":"assets/classDiagram-v2-RAHNMMFH-BKe8_uda.js"},{"revision":null,"url":"assets/classDiagram-VBA2DB6C-mr-Cb1me.js"},{"revision":null,"url":"assets/chunk-YBOYWFTD-D_ILLe6_.js"},{"revision":null,"url":"assets/chunk-XZSTWKYB-DjV8xl5A.js"},{"revision":null,"url":"assets/chunk-XPW4576I-CgLyyW03.js"},{"revision":null,"url":"assets/chunk-XIRO2GV7-DZBoNl1_.js"},{"revision":null,"url":"assets/chunk-WL4C6EOR-B1iIvLOG.js"},{"revision":null,"url":"assets/chunk-R5LLSJPH-dRhXRnrb.js"},{"revision":null,"url":"assets/chunk-QZHKN3VN-N3VXx1VH.js"},{"revision":null,"url":"assets/chunk-PU5JKC2W-DD95Rx35.js"},{"revision":null,"url":"assets/chunk-PQ6SQG4A-Bik13fTV.js"},{"revision":null,"url":"assets/chunk-OZEHJAEY-lKq2SWjA.js"},{"revision":null,"url":"assets/chunk-O4XLMI2P-Vp_V4P-b.js"},{"revision":null,"url":"assets/chunk-NQ4KR5QH-DX32345Y.js"},{"revision":null,"url":"assets/chunk-MX3YWQON-B6g1ZH9X.js"},{"revision":null,"url":"assets/chunk-L3YUKLVL-DnSMmNFC.js"},{"revision":null,"url":"assets/chunk-KYZI473N-gqRLpJ4w.js"},{"revision":null,"url":"assets/chunk-KX2RTZJC-CHj8TnTB.js"},{"revision":null,"url":"assets/chunk-JSJVCQXG-23eG9mgt.js"},{"revision":null,"url":"assets/chunk-HHEYEP7N-C45i5G_3.js"},{"revision":null,"url":"assets/chunk-GLR3WWYH-Re-5eSlQ.js"},{"revision":null,"url":"assets/chunk-GEFDOKGD-86LFbsAC.js"},{"revision":null,"url":"assets/chunk-FMBD7UC4-Bog4cpN-.js"},{"revision":null,"url":"assets/chunk-EGIJ26TM-nant2LXl.js"},{"revision":null,"url":"assets/chunk-CFjPhJqf.js"},{"revision":null,"url":"assets/chunk-C72U2L5F-BHPkfQj2.js"},{"revision":null,"url":"assets/chunk-7R4GIKGN-y8bfHEy-.js"},{"revision":null,"url":"assets/chunk-7E7YKBS2-DZcnC7Ow.js"},{"revision":null,"url":"assets/chunk-55IACEB6-DhZGI1l3.js"},{"revision":null,"url":"assets/chunk-4BX2VUAB-CENmY7Kw.js"},{"revision":null,"url":"assets/chevron-right-DY_wImxB.js"},{"revision":null,"url":"assets/chat-tab-CC721_mQ.js"},{"revision":null,"url":"assets/channel-wumTB1if.js"},{"revision":null,"url":"assets/c4Diagram-IC4MRINW-BIymcNsg.js"},{"revision":null,"url":"assets/blockDiagram-WCTKOSBZ-Ct57Wtfk.js"},{"revision":null,"url":"assets/arrow-up-I9-21gkR.js"},{"revision":null,"url":"assets/array-BFDiaBgf.js"},{"revision":null,"url":"assets/architectureDiagram-2XIMDMQ5-D16OotsC.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-DDFO_NKq.js"},{"revision":null,"url":"assets/arc-CxgHJ7Z4.js"},{"revision":null,"url":"assets/api-settings-CUxg9RE5.js"},{"revision":null,"url":"assets/api-client-BvxmRZUi.js"},{"revision":null,"url":"assets/ai-settings-section-Bo9lCaTd.js"},{"revision":null,"url":"assets/_baseUniq-CyzdZeQH.js"},{"revision":null,"url":"assets/_basePickBy-Bj0dI1ei.js"},{"revision":null,"url":"assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2"},{"revision":null,"url":"assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2"},{"revision":null,"url":"assets/KaTeX_Size2-Regular-Dy4dx90m.woff2"},{"revision":null,"url":"assets/KaTeX_Size1-Regular-mCD8mA8B.woff2"},{"revision":null,"url":"assets/KaTeX_Script-Regular-D3wIWfF6.woff2"},{"revision":null,"url":"assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2"},{"revision":null,"url":"assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2"},{"revision":null,"url":"assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2"},{"revision":null,"url":"assets/KaTeX_Math-Italic-t53AETM-.woff2"},{"revision":null,"url":"assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2"},{"revision":null,"url":"assets/KaTeX_Main-Regular-B22Nviop.woff2"},{"revision":null,"url":"assets/KaTeX_Main-Italic-NWA7e6Wa.woff2"},{"revision":null,"url":"assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2"},{"revision":null,"url":"assets/KaTeX_Main-Bold-Cx986IdX.woff2"},{"revision":null,"url":"assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2"},{"revision":null,"url":"assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2"},{"revision":null,"url":"assets/KaTeX_AMS-Regular-BQhdFMY1.woff2"},{"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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hienlh/ppm",
3
- "version": "0.9.91",
3
+ "version": "0.9.93",
4
4
  "description": "Personal Project Manager — mobile-first web IDE with AI assistance",
5
5
  "author": "hienlh",
6
6
  "license": "MIT",
@@ -133,14 +133,12 @@ function openGitGraph(
133
133
  context: ExtensionContext,
134
134
  projectPath: string,
135
135
  ): void {
136
- // If panel exists and project changed, reload data in the existing panel
137
- if (activePanel && activeProjectPath !== projectPath) {
138
- activeProjectPath = projectPath;
139
- reloadPanelData(vscode, activePanel, projectPath, context);
140
- return;
136
+ // Always dispose stale panel to avoid browser/server desync.
137
+ // On page reload the browser's WS close message can be lost, leaving
138
+ // activePanel referencing a panel the browser no longer knows about.
139
+ if (activePanel) {
140
+ activePanel.dispose(); // fires onDidDispose → clears activePanel & timers
141
141
  }
142
- // If panel exists with same project, nothing to do
143
- if (activePanel) return;
144
142
 
145
143
  activeProjectPath = projectPath;
146
144
  const dirName = projectPath.split(/[\\/]/).filter(Boolean).pop() || "Git Graph";
@@ -383,19 +381,6 @@ function openGitGraph(
383
381
  });
384
382
  }
385
383
 
386
- /** Reload all data in existing panel for a new project path */
387
- async function reloadPanelData(
388
- vscode: VscodeApi,
389
- panel: ReturnType<VscodeApi["window"]["createWebviewPanel"]>,
390
- projectPath: string,
391
- context: ExtensionContext,
392
- ): Promise<void> {
393
- await handleRepoInfo(vscode, panel, projectPath);
394
- await handleRequestCommits(vscode, panel, projectPath, context);
395
- handleUncommittedStatus(vscode, panel, projectPath);
396
- handleWorktrees(vscode, panel, projectPath);
397
- handleStashes(vscode, panel, projectPath);
398
- }
399
384
 
400
385
  async function handleRepoInfo(
401
386
  vscode: VscodeApi,
@@ -14,6 +14,8 @@ export class WindowService {
14
14
  private _idCounter = 0;
15
15
  /** @internal Panel emitters keyed by panelId — for webview message delivery */
16
16
  private _panelEmitters = new Map<string, EventEmitter<unknown>>();
17
+ /** @internal Panel dispose emitters keyed by panelId — for browser-initiated disposal */
18
+ private _panelDisposeEmitters = new Map<string, EventEmitter<void>>();
17
19
  /** @internal Tree providers keyed by viewId — for tree expand/refresh */
18
20
  private _treeProviders = new Map<string, { provider: any }>();
19
21
  /** @internal Cache original tree elements by ID so getChildren receives the real object */
@@ -31,6 +33,16 @@ export class WindowService {
31
33
  return false;
32
34
  }
33
35
 
36
+ /** @internal Dispose a panel by ID (called when browser closes the tab) */
37
+ _disposePanel(panelId: string): boolean {
38
+ if (!this._panelEmitters.has(panelId)) return false;
39
+ const disposeEvent = this._panelDisposeEmitters?.get(panelId);
40
+ if (disposeEvent) { disposeEvent.fire(); disposeEvent.dispose(); }
41
+ this._panelEmitters.delete(panelId);
42
+ this._panelDisposeEmitters?.delete(panelId);
43
+ return true;
44
+ }
45
+
34
46
  /** @internal Get tree children for a viewId (used by Worker for tree:expand) */
35
47
  async _getTreeChildren(viewId: string, parentId?: string): Promise<unknown[]> {
36
48
  const entry = this._treeProviders.get(viewId);
@@ -205,6 +217,7 @@ export class WindowService {
205
217
  const onDidDispose = new EventEmitter<void>();
206
218
  const onDidReceiveMessage = new EventEmitter<unknown>();
207
219
  this._panelEmitters.set(panelId, onDidReceiveMessage);
220
+ this._panelDisposeEmitters.set(panelId, onDidDispose);
208
221
 
209
222
  let currentHtml = "";
210
223
  const webview = {
@@ -229,6 +242,7 @@ export class WindowService {
229
242
  reveal() {},
230
243
  dispose: () => {
231
244
  this._panelEmitters.delete(panelId);
245
+ this._panelDisposeEmitters.delete(panelId);
232
246
  rpc.request("window:webview:dispose", panelId);
233
247
  onDidDispose.fire();
234
248
  onDidDispose.dispose();
@@ -173,6 +173,18 @@ async function handleMessage(ws: ExtWsSocket, raw: string | Buffer): Promise<voi
173
173
  break;
174
174
  }
175
175
 
176
+ case "webview:close": {
177
+ try {
178
+ const { extensionService } = await import("../../services/extension.service.ts");
179
+ if (extensionService["rpc"]) {
180
+ await extensionService["rpc"].sendRequest("ext:webview:close", msg.panelId);
181
+ }
182
+ } catch (e) {
183
+ console.error(`[ExtWS] webview:close error:`, e);
184
+ }
185
+ break;
186
+ }
187
+
176
188
  case "tree:expand": {
177
189
  try {
178
190
  const { extensionService } = await import("../../services/extension.service.ts");
@@ -123,6 +123,18 @@ rpc.onRequest("ext:command:execute", async (params) => {
123
123
  return { ok: false, error: `Command not found: ${command}` };
124
124
  });
125
125
 
126
+ // Browser closed a webview panel tab → fire onDidDispose in the extension
127
+ rpc.onRequest("ext:webview:close", async (params) => {
128
+ const [panelId] = params as [string];
129
+ for (const [, ext] of activeExtensions) {
130
+ if (!ext.window) continue;
131
+ if ((ext.window as any)._disposePanel(panelId)) {
132
+ return { ok: true };
133
+ }
134
+ }
135
+ return { ok: false, error: `No panel found: ${panelId}` };
136
+ });
137
+
126
138
  // Deliver webview messages from browser → extension's onDidReceiveMessage
127
139
  rpc.onRequest("ext:webview:message", async (params) => {
128
140
  const [panelId, message] = params as [string, unknown];
@@ -61,6 +61,7 @@ export type ExtClientMsg =
61
61
  | { type: "tree:expand"; viewId: string; itemId: string }
62
62
  | { type: "tree:click"; viewId: string; itemId: string; command?: string }
63
63
  | { type: "webview:message"; panelId: string; message: unknown }
64
+ | { type: "webview:close"; panelId: string }
64
65
  | { type: "quickpick:resolve"; requestId: string; selected: QuickPickItemMsg[] | null }
65
66
  | { type: "inputbox:resolve"; requestId: string; value: string | null }
66
67
  | { type: "notification:action"; id: string; action: string | null };
@@ -30,7 +30,8 @@ export function ExtensionWebview({ metadata }: ExtensionWebviewProps) {
30
30
  const panelId = metadata?.panelId as string | undefined;
31
31
  const viewType = metadata?.viewType as string | undefined;
32
32
  const currentProject = useTabStore((s) => s.currentProject);
33
- const projectName = (metadata?.projectName as string | undefined) || currentProject || undefined;
33
+ // Prefer currentProject (reflects URL/active project) over stale tab metadata
34
+ const projectName = currentProject || (metadata?.projectName as string | undefined) || undefined;
34
35
  const [timedOut, setTimedOut] = useState(false);
35
36
 
36
37
  // Match panel: prefer panelId (exact), fallback to viewType match (reload recovery)
@@ -57,6 +58,8 @@ export function ExtensionWebview({ metadata }: ExtensionWebviewProps) {
57
58
  // Retry needed because WS connection may not be ready on first attempt
58
59
  useEffect(() => {
59
60
  if (panel || !viewType) return;
61
+ // Mark project as "dispatched" so project-sync effect doesn't double-dispatch
62
+ if (projectName) prevProjectRef.current = projectName;
60
63
  const command = viewType.includes(".") ? viewType : `${viewType}.view`;
61
64
  let cancelled = false;
62
65
  let resolvedArgs: unknown[] | null = null;
@@ -150,6 +153,21 @@ export function ExtensionWebview({ metadata }: ExtensionWebviewProps) {
150
153
  })();
151
154
  }, [viewType, projectName]);
152
155
 
156
+ // On unmount: notify server to dispose the panel so extension clears activePanel state
157
+ const panelIdForCleanup = useRef<string | null>(null);
158
+ useEffect(() => {
159
+ panelIdForCleanup.current = resolvedPanelId ?? null;
160
+ }, [resolvedPanelId]);
161
+ useEffect(() => {
162
+ return () => {
163
+ const id = panelIdForCleanup.current;
164
+ if (id) {
165
+ useExtensionStore.getState().removeWebviewPanel(id);
166
+ window.dispatchEvent(new CustomEvent("ext:webview:close", { detail: { panelId: id } }));
167
+ }
168
+ };
169
+ }, []);
170
+
153
171
  // Timeout: if panel doesn't appear within 10s, show error
154
172
  useEffect(() => {
155
173
  if (panel) { setTimedOut(false); return; }
@@ -184,8 +202,10 @@ export function ExtensionWebview({ metadata }: ExtensionWebviewProps) {
184
202
  return () => window.removeEventListener("ext:webview:message", handler);
185
203
  }, [resolvedPanelId]);
186
204
 
187
- // Loading state — waiting for extension to create the panel
188
- if (!panel) {
205
+ // Loading state — waiting for extension to create the panel AND deliver HTML.
206
+ // We must wait for HTML before mounting the iframe because browsers don't
207
+ // re-execute scripts when React updates the srcDoc attribute from "" to content.
208
+ if (!panel || !rawHtml) {
189
209
  return (
190
210
  <div className="flex flex-col items-center justify-center h-full gap-3 text-sm text-text-subtle">
191
211
  {timedOut ? (
@@ -215,6 +235,7 @@ export function ExtensionWebview({ metadata }: ExtensionWebviewProps) {
215
235
  <div className="h-full w-full relative">
216
236
  <iframe
217
237
  ref={iframeRef}
238
+ key={resolvedPanelId}
218
239
  srcDoc={html}
219
240
  sandbox="allow-scripts"
220
241
  className="w-full h-full border-0 bg-white dark:bg-zinc-900"
@@ -2,6 +2,7 @@ import { useEffect, useCallback, useRef } from "react";
2
2
  import { WsClient } from "@/lib/ws-client";
3
3
  import { useExtensionStore } from "@/stores/extension-store";
4
4
  import { useTabStore } from "@/stores/tab-store";
5
+ import { usePanelStore } from "@/stores/panel-store";
5
6
  import { getAuthToken } from "@/lib/api-client";
6
7
  import type { ExtServerMsg, ExtClientMsg } from "../../types/extension-messages.ts";
7
8
  import { toast } from "sonner";
@@ -128,16 +129,34 @@ export function useExtensionWs(enabled = true) {
128
129
  title: msg.title,
129
130
  html: "",
130
131
  });
131
- // Open a tab use stable viewType slug as identifier (survives reload)
132
- // Include projectName so reload can resolve project path for re-trigger
133
- const currentProject = useTabStore.getState().currentProject;
134
- useTabStore.getState().openTab({
135
- type: "extension",
136
- title: msg.title,
137
- projectId: null,
138
- closable: true,
139
- metadata: { viewType: viewTypeSlug, panelId: msg.panelId, extensionId: msg.extensionId, ...(currentProject && { projectName: currentProject }) },
140
- });
132
+ // Check if a tab for this viewType already exists in current grid
133
+ // (prevents infinite tab creation on project switch / panel recreate)
134
+ const baseTabId = `extension:${viewTypeSlug}`;
135
+ const ps = usePanelStore.getState();
136
+ const gridPanelIds = new Set(ps.grid.flat());
137
+ let existingTabId: string | null = null;
138
+ for (const pid of gridPanelIds) {
139
+ const p = ps.panels[pid];
140
+ if (!p) continue;
141
+ const t = p.tabs.find(tab => tab.id === baseTabId || tab.id.startsWith(`${baseTabId}@`));
142
+ if (t) { existingTabId = t.id; break; }
143
+ }
144
+ if (existingTabId) {
145
+ // Tab already exists — update metadata with new panelId (panel was recreated)
146
+ useTabStore.getState().updateTab(existingTabId, {
147
+ title: msg.title,
148
+ metadata: { viewType: viewTypeSlug, panelId: msg.panelId, extensionId: msg.extensionId },
149
+ });
150
+ } else {
151
+ const currentProject = useTabStore.getState().currentProject;
152
+ useTabStore.getState().openTab({
153
+ type: "extension",
154
+ title: msg.title,
155
+ projectId: null,
156
+ closable: true,
157
+ metadata: { viewType: viewTypeSlug, panelId: msg.panelId, extensionId: msg.extensionId, ...(currentProject && { projectName: currentProject }) },
158
+ });
159
+ }
141
160
  break;
142
161
  }
143
162
 
@@ -192,12 +211,20 @@ export function useExtensionWs(enabled = true) {
192
211
  };
193
212
  window.addEventListener("ext:command:execute", commandHandler);
194
213
 
214
+ // Listen for webview close requests (dispatched by ExtensionWebview on unmount)
215
+ const webviewCloseHandler = (e: Event) => {
216
+ const { panelId } = (e as CustomEvent).detail;
217
+ client.send(JSON.stringify({ type: "webview:close", panelId }));
218
+ };
219
+ window.addEventListener("ext:webview:close", webviewCloseHandler);
220
+
195
221
  client.connect();
196
222
 
197
223
  return () => {
198
224
  window.removeEventListener("ext:webview:send", webviewSendHandler);
199
225
  window.removeEventListener("ext:tree:expand", treeExpandHandler);
200
226
  window.removeEventListener("ext:command:execute", commandHandler);
227
+ window.removeEventListener("ext:webview:close", webviewCloseHandler);
201
228
  client.disconnect();
202
229
  clientRef.current = null;
203
230
  };
@@ -1,3 +0,0 @@
1
- import{o as e}from"./chunk-CFjPhJqf.js";import{t}from"./react-nm2Ru1Pt.js";import{t as n}from"./jsx-runtime-BRW_vwa9.js";import{B as r,E as i,v as a}from"./index-DK4yJlIj.js";var o=e(t(),1),s=n(),c=`<script>
2
- function acquireVsCodeApi(){return{postMessage:function(m){window.parent.postMessage(m,"*")},getState:function(){try{return JSON.parse(sessionStorage.getItem("vscode-state")||"null")}catch{return null}},setState:function(s){sessionStorage.setItem("vscode-state",JSON.stringify(s));return s}}}
3
- <\/script>`;function l(e){if(!e)return e;let t=e.indexOf(`<head>`);return t===-1?c+e:e.slice(0,t+6)+c+e.slice(t+6)}function u({metadata:e}){let t=e?.panelId,n=e?.viewType,c=i(e=>e.currentProject),u=e?.projectName||c||void 0,[d,f]=(0,o.useState)(!1),p=a(e=>{if(t&&e.webviewPanels[t])return e.webviewPanels[t];if(n){let t=n.includes(`.`)?n:`${n}.view`;return Object.values(e.webviewPanels).find(e=>e.viewType===n||e.viewType===t)}}),m=p?.id??t,h=(0,o.useRef)(null),g=l(p?.html??``);(0,o.useEffect)(()=>{if(p||!n)return;let e=n.includes(`.`)?n:`${n}.view`,t=!1,r=null;async function i(){if(r)return r;if(!u)return[];try{let e=(await(await fetch(`/api/projects`)).json()).data?.find(e=>e.name===u);r=e?[e.path]:[]}catch{r=[]}return r}async function a(){let n=await i();t||window.dispatchEvent(new CustomEvent(`ext:command:execute`,{detail:{command:e,args:n}}))}let o=setTimeout(()=>{t||a()},500),s=setInterval(()=>{t||a()},2e3);return()=>{t=!0,clearTimeout(o),clearInterval(s)}},[p,n,u]);let _=(0,o.useRef)(null);(0,o.useEffect)(()=>{if(!p||!n||!u||u===_.current)return;_.current=u;let e=n.includes(`.`)?n:`${n}.view`;(async()=>{try{let t=(await(await fetch(`/api/projects`)).json()).data?.find(e=>e.name===u);t&&window.dispatchEvent(new CustomEvent(`ext:command:execute`,{detail:{command:e,args:[t.path]}}))}catch{}})()},[p,n,u]);let v=e?.extensionId,y=a(e=>{if(v&&e.activationErrors[v])return e.activationErrors[v];if(n){for(let[t,r]of Object.entries(e.activationErrors))if(t===`ext-${n}`)return r}}),b=(0,o.useCallback)(()=>{if(f(!1),!n)return;let e=n.includes(`.`)?n:`${n}.view`;(async()=>{try{let t=(await(await fetch(`/api/projects`)).json()).data?.find(e=>e.name===u),n=t?[t.path]:[];window.dispatchEvent(new CustomEvent(`ext:command:execute`,{detail:{command:e,args:n}}))}catch{}})()},[n,u]);return(0,o.useEffect)(()=>{if(p){f(!1);return}let e=setTimeout(()=>f(!0),1e4);return()=>clearTimeout(e)},[p]),(0,o.useEffect)(()=>{if(!m)return;let e=e=>{h.current&&e.source===h.current.contentWindow&&window.dispatchEvent(new CustomEvent(`ext:webview:send`,{detail:{panelId:m,message:e.data}}))};return window.addEventListener(`message`,e),()=>window.removeEventListener(`message`,e)},[m]),(0,o.useEffect)(()=>{if(!m)return;let e=e=>{let{panelId:t,message:n}=e.detail;t===m&&h.current?.contentWindow?.postMessage(n,`*`)};return window.addEventListener(`ext:webview:message`,e),()=>window.removeEventListener(`ext:webview:message`,e)},[m]),p?(0,s.jsx)(`div`,{className:`h-full w-full relative`,children:(0,s.jsx)(`iframe`,{ref:h,srcDoc:g,sandbox:`allow-scripts`,className:`w-full h-full border-0 bg-white dark:bg-zinc-900`,title:p.title})}):(0,s.jsx)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-sm text-text-subtle`,children:d?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(`span`,{className:`text-destructive font-medium`,children:`Extension failed to load`}),y&&(0,s.jsx)(`span`,{className:`text-xs text-muted-foreground max-w-md text-center`,children:y}),(0,s.jsx)(`button`,{onClick:b,className:`text-xs text-primary hover:underline`,children:`Retry`})]}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r,{className:`size-5 animate-spin`}),(0,s.jsx)(`span`,{children:`Loading extension...`})]})})}export{u as ExtensionWebview};
@@ -1 +0,0 @@
1
- import"./react-nm2Ru1Pt.js";import"./api-client-BvxmRZUi.js";import{w as e}from"./index-DK4yJlIj.js";export{e as useKeybindingsStore};