@hienlh/ppm 0.9.0-beta.8 → 0.9.1

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 (159) hide show
  1. package/CHANGELOG.md +238 -0
  2. package/bun.lock +17 -0
  3. package/dist/web/assets/api-settings-BUvk6Saw.js +1 -0
  4. package/dist/web/assets/arrow-up-BYhx9ckd.js +1 -0
  5. package/dist/web/assets/browser-tab-CrkhFCaw.js +1 -0
  6. package/dist/web/assets/chat-tab-C6jpiwh7.js +8 -0
  7. package/dist/web/assets/chevron-right-5HgK6l7K.js +1 -0
  8. package/dist/web/assets/code-editor-CBIPzlP2.js +2 -0
  9. package/dist/web/assets/columns-2-cEVJHYd7.js +1 -0
  10. package/dist/web/assets/createLucideIcon-PuMiQgHl.js +1 -0
  11. package/dist/web/assets/{csv-preview-DLqYtXxt.js → csv-preview-ncSOnJSC.js} +2 -2
  12. package/dist/web/assets/database-viewer-BqOJR_zi.js +1 -0
  13. package/dist/web/assets/diff-viewer-CcLyp4eY.js +4 -0
  14. package/dist/web/assets/{dist-CALwEtco.js → dist-DIV6WgAG.js} +1 -1
  15. package/dist/web/assets/{dist-DGDPTxs1.js → dist-ovWkrgO-.js} +1 -1
  16. package/dist/web/assets/extension-webview-NiZ7Ybvv.js +3 -0
  17. package/dist/web/assets/git-graph-CoTvMrIo.js +1 -0
  18. package/dist/web/assets/index-C8byznLO.js +37 -0
  19. package/dist/web/assets/index-KwC2YrG4.css +2 -0
  20. package/dist/web/assets/jsx-runtime-kMwlnEGE.js +1 -0
  21. package/dist/web/assets/keybindings-store-DPYzBe_M.js +1 -0
  22. package/dist/web/assets/{markdown-renderer-DklUd_Gv.js → markdown-renderer-DPLdR9xc.js} +4 -4
  23. package/dist/web/assets/postgres-viewer-BeiK4lCa.js +1 -0
  24. package/dist/web/assets/settings-tab-D3AvU4lu.js +1 -0
  25. package/dist/web/assets/sqlite-viewer-nA2sD4Yv.js +1 -0
  26. package/dist/web/assets/tab-store-BOgTrqRr.js +1 -0
  27. package/dist/web/assets/table-DFevCOMd.js +1 -0
  28. package/dist/web/assets/tag-CXMT0QB6.js +1 -0
  29. package/dist/web/assets/{terminal-tab-CqRuiIFn.js → terminal-tab-BBi0pEji.js} +2 -2
  30. package/dist/web/assets/{use-monaco-theme-Dcz3aLAE.js → use-monaco-theme-B5pG2d1w.js} +1 -1
  31. package/dist/web/index.html +8 -8
  32. package/dist/web/monacoeditorwork/css.worker.bundle.js +122 -122
  33. package/dist/web/monacoeditorwork/editor.worker.bundle.js +78 -78
  34. package/dist/web/monacoeditorwork/html.worker.bundle.js +110 -110
  35. package/dist/web/monacoeditorwork/json.worker.bundle.js +108 -108
  36. package/dist/web/monacoeditorwork/ts.worker.bundle.js +81 -81
  37. package/dist/web/sw.js +1 -1
  38. package/docs/code-standards.md +128 -1
  39. package/docs/codebase-summary.md +79 -12
  40. package/docs/extension-development-guide.md +532 -0
  41. package/docs/project-changelog.md +51 -1
  42. package/docs/project-roadmap.md +9 -3
  43. package/docs/streaming-input-guide.md +267 -0
  44. package/docs/system-architecture.md +432 -3
  45. package/package.json +6 -3
  46. package/packages/ext-database/package.json +41 -0
  47. package/packages/ext-database/src/connection-tree.ts +142 -0
  48. package/packages/ext-database/src/extension.ts +346 -0
  49. package/packages/ext-database/src/query-panel.ts +120 -0
  50. package/packages/ext-database/src/table-viewer-panel.ts +410 -0
  51. package/packages/ext-database/tsconfig.json +8 -0
  52. package/packages/vscode-compat/package.json +16 -0
  53. package/packages/vscode-compat/src/commands.ts +39 -0
  54. package/packages/vscode-compat/src/context.ts +65 -0
  55. package/packages/vscode-compat/src/disposable.ts +21 -0
  56. package/packages/vscode-compat/src/env.ts +20 -0
  57. package/packages/vscode-compat/src/event-emitter.ts +28 -0
  58. package/packages/vscode-compat/src/index.ts +93 -0
  59. package/packages/vscode-compat/src/not-supported.ts +15 -0
  60. package/packages/vscode-compat/src/types.ts +167 -0
  61. package/packages/vscode-compat/src/uri.ts +65 -0
  62. package/packages/vscode-compat/src/window.ts +229 -0
  63. package/packages/vscode-compat/src/workspace.ts +76 -0
  64. package/packages/vscode-compat/tsconfig.json +10 -0
  65. package/snapshot-state.md +1526 -0
  66. package/src/cli/commands/autostart.ts +1 -1
  67. package/src/cli/commands/ext-cmd.ts +121 -0
  68. package/src/cli/commands/restart.ts +9 -1
  69. package/src/cli/commands/status.ts +19 -0
  70. package/src/index.ts +5 -3
  71. package/src/providers/claude-agent-sdk.ts +221 -17
  72. package/src/providers/cli-provider-base.ts +6 -0
  73. package/src/server/index.ts +55 -155
  74. package/src/server/routes/chat.ts +81 -11
  75. package/src/server/routes/extensions.ts +81 -0
  76. package/src/server/routes/project-scoped.ts +2 -0
  77. package/src/server/routes/settings.ts +27 -0
  78. package/src/server/routes/workspace.ts +35 -0
  79. package/src/server/ws/chat.ts +9 -3
  80. package/src/server/ws/extensions.ts +175 -0
  81. package/src/services/account-selector.service.ts +14 -5
  82. package/src/services/account.service.ts +20 -15
  83. package/src/services/claude-usage.service.ts +29 -24
  84. package/src/services/cloud-ws.service.ts +228 -0
  85. package/src/services/cloud.service.ts +11 -6
  86. package/src/services/contribution-registry.ts +110 -0
  87. package/src/services/db.service.ts +181 -4
  88. package/src/services/extension-host-worker.ts +160 -0
  89. package/src/services/extension-installer.ts +112 -0
  90. package/src/services/extension-manifest.ts +65 -0
  91. package/src/services/extension-rpc-handlers.ts +235 -0
  92. package/src/services/extension-rpc.ts +105 -0
  93. package/src/services/extension.service.ts +228 -0
  94. package/src/services/mcp-config.service.ts +15 -6
  95. package/src/services/supervisor.ts +271 -25
  96. package/src/types/api.ts +1 -0
  97. package/src/types/chat.ts +4 -0
  98. package/src/types/extension-messages.ts +64 -0
  99. package/src/types/extension.ts +131 -0
  100. package/src/web/app.tsx +69 -48
  101. package/src/web/components/chat/account-rotation-settings.tsx +163 -0
  102. package/src/web/components/chat/chat-history-bar.tsx +106 -10
  103. package/src/web/components/chat/chat-tab.tsx +15 -10
  104. package/src/web/components/chat/chat-welcome.tsx +148 -0
  105. package/src/web/components/chat/message-list.tsx +19 -6
  106. package/src/web/components/chat/session-picker.tsx +80 -32
  107. package/src/web/components/chat/usage-badge.tsx +68 -8
  108. package/src/web/components/editor/editor-breadcrumb.tsx +20 -29
  109. package/src/web/components/extensions/extension-inputbox.tsx +92 -0
  110. package/src/web/components/extensions/extension-quickpick.tsx +194 -0
  111. package/src/web/components/extensions/extension-tree-view.tsx +240 -0
  112. package/src/web/components/extensions/extension-webview.tsx +83 -0
  113. package/src/web/components/layout/command-palette.tsx +22 -2
  114. package/src/web/components/layout/editor-panel.tsx +163 -18
  115. package/src/web/components/layout/mobile-nav.tsx +2 -1
  116. package/src/web/components/layout/sidebar.tsx +21 -3
  117. package/src/web/components/layout/status-bar.tsx +64 -0
  118. package/src/web/components/layout/tab-bar.tsx +2 -0
  119. package/src/web/components/layout/tab-content.tsx +5 -0
  120. package/src/web/components/layout/upgrade-banner.tsx +15 -5
  121. package/src/web/components/settings/change-password-section.tsx +128 -0
  122. package/src/web/components/settings/extension-manager-section.tsx +214 -0
  123. package/src/web/components/settings/settings-tab.tsx +9 -2
  124. package/src/web/components/shared/connection-lost-overlay.tsx +89 -0
  125. package/src/web/hooks/use-chat.ts +28 -0
  126. package/src/web/hooks/use-extension-ws.ts +181 -0
  127. package/src/web/hooks/use-global-keybindings.ts +18 -2
  128. package/src/web/hooks/use-server-reload.ts +9 -0
  129. package/src/web/hooks/use-url-sync.ts +173 -21
  130. package/src/web/stores/connection-store.ts +39 -0
  131. package/src/web/stores/extension-store.ts +204 -0
  132. package/src/web/stores/panel-store.ts +63 -9
  133. package/src/web/stores/panel-utils.ts +145 -3
  134. package/src/web/stores/settings-store.ts +7 -2
  135. package/src/web/stores/tab-store.ts +2 -1
  136. package/test-session-ops.mjs +444 -0
  137. package/test-tokens.mjs +212 -0
  138. package/tsconfig.json +3 -1
  139. package/dist/web/assets/api-settings-D21InCnR.js +0 -1
  140. package/dist/web/assets/arrow-up--LjUXLEt.js +0 -1
  141. package/dist/web/assets/browser-tab-BEe89aSD.js +0 -1
  142. package/dist/web/assets/chat-tab-9lqvWozA.js +0 -7
  143. package/dist/web/assets/chevron-right-CHnjJt4E.js +0 -1
  144. package/dist/web/assets/code-editor-COAIZx-B.js +0 -2
  145. package/dist/web/assets/columns-2-DbesTfa7.js +0 -1
  146. package/dist/web/assets/database-viewer-aRR9n_Ui.js +0 -1
  147. package/dist/web/assets/diff-viewer-C4KMvpHr.js +0 -4
  148. package/dist/web/assets/dist-CVTST7Gc.js +0 -1
  149. package/dist/web/assets/git-graph-CfJjl4E3.js +0 -1
  150. package/dist/web/assets/index-Db8uky1a.css +0 -2
  151. package/dist/web/assets/index-DxZuwBDe.js +0 -37
  152. package/dist/web/assets/jsx-runtime-BRW_vwa9.js +0 -1
  153. package/dist/web/assets/keybindings-store-_uWVCZMv.js +0 -1
  154. package/dist/web/assets/postgres-viewer-DEAvAyaX.js +0 -1
  155. package/dist/web/assets/settings-tab-BQedc-No.js +0 -1
  156. package/dist/web/assets/sqlite-viewer-BPA5idzT.js +0 -1
  157. package/dist/web/assets/tab-store-DhK6EpBT.js +0 -1
  158. package/dist/web/assets/table-CQVQM2SB.js +0 -1
  159. package/dist/web/assets/tag-Q2dZiSPX.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":"073204f9dceb35ffa3afb19ce6c40ec5","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"eb9818b9094675c0c5d303168f273345","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"9af0be92dcefdc1f1290441cb5ff5d9b","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"a261b429c39dbb75ae97972d7d005e6d","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"79953d804e1bbacecfd79b85fd679016","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"fdcba0d09aac31df7a0bc652f6e739bd","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":null,"url":"assets/xychartDiagram-JWTSCODW-DRa_TH4B.js"},{"revision":null,"url":"assets/vennDiagram-LZ73GAT5-s9Z71fz-.js"},{"revision":null,"url":"assets/utils-BNytJOb1.js"},{"revision":null,"url":"assets/use-monaco-theme-Dcz3aLAE.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-B2Xkyv-K.js"},{"revision":null,"url":"assets/timeline-definition-YZTLITO2-DwZqB3nn.js"},{"revision":null,"url":"assets/terminal-tab-CqRuiIFn.js"},{"revision":null,"url":"assets/terminal-tab-BrP-ENHg.css"},{"revision":null,"url":"assets/tag-Q2dZiSPX.js"},{"revision":null,"url":"assets/table-CQVQM2SB.js"},{"revision":null,"url":"assets/tab-store-DhK6EpBT.js"},{"revision":null,"url":"assets/stateDiagram-v2-FVOUBMTO-BGVqj_g9.js"},{"revision":null,"url":"assets/stateDiagram-RAJIS63D-66vhiIuk.js"},{"revision":null,"url":"assets/src-BqX54PbV.js"},{"revision":null,"url":"assets/sqlite-viewer-BPA5idzT.js"},{"revision":null,"url":"assets/settings-tab-BQedc-No.js"},{"revision":null,"url":"assets/sequenceDiagram-2WXFIKYE-BQDJ4CVs.js"},{"revision":null,"url":"assets/sankeyDiagram-WA2Y5GQK-T6RgG-N8.js"},{"revision":null,"url":"assets/rough.esm-JX0wREDd.js"},{"revision":null,"url":"assets/requirementDiagram-Z7DCOOCP-pQyah6WB.js"},{"revision":null,"url":"assets/react-nm2Ru1Pt.js"},{"revision":null,"url":"assets/react-dom-Bpkvzu3U.js"},{"revision":null,"url":"assets/react-SKk5z-bm.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-DH0AOkUy.js"},{"revision":null,"url":"assets/quadrantDiagram-337W2JSQ-C8bzJCjQ.js"},{"revision":null,"url":"assets/preload-helper-Bf_JiD2A.js"},{"revision":null,"url":"assets/postgres-viewer-DEAvAyaX.js"},{"revision":null,"url":"assets/pieDiagram-SKSYHLDU-C1Gjrtzy.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-BHncZutv.js"},{"revision":null,"url":"assets/path-6uRLdFF7.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-DY5PNnZU.js"},{"revision":null,"url":"assets/ordinal-_K3x1fkz.js"},{"revision":null,"url":"assets/mindmap-definition-YRQLILUH-x0MTutJp.js"},{"revision":null,"url":"assets/mermaid-parser.core-C7UwoIh6.js"},{"revision":null,"url":"assets/math-069Z4SuC.js"},{"revision":null,"url":"assets/markdown-renderer-DklUd_Gv.js"},{"revision":null,"url":"assets/linear-DP4mkX3m.js"},{"revision":null,"url":"assets/line-CVvo3dRu.js"},{"revision":null,"url":"assets/lib-BQ34Db2e.js"},{"revision":null,"url":"assets/keybindings-store-_uWVCZMv.js"},{"revision":null,"url":"assets/katex-Bqvo_ZG0.js"},{"revision":null,"url":"assets/kanban-definition-K7BYSVSG-CZ535BbZ.js"},{"revision":null,"url":"assets/jsx-runtime-BRW_vwa9.js"},{"revision":null,"url":"assets/journeyDiagram-4ABVD52K-B_L20qMe.js"},{"revision":null,"url":"assets/ishikawaDiagram-PHBUUO56-D05_LyL7.js"},{"revision":null,"url":"assets/isEmpty-bnrF3Qbc.js"},{"revision":null,"url":"assets/isArrayLikeObject-B_v2FtYn.js"},{"revision":null,"url":"assets/init-DlZdxViB.js"},{"revision":null,"url":"assets/infoDiagram-LFFYTUFH-DWwumDkq.js"},{"revision":null,"url":"assets/info-3K5VOQVL-_vRxVNUm.js"},{"revision":null,"url":"assets/index-DxZuwBDe.js"},{"revision":null,"url":"assets/index-Db8uky1a.css"},{"revision":null,"url":"assets/graphlib-BcsNnGcW.js"},{"revision":null,"url":"assets/gitGraphDiagram-K3NZZRJ6-CMoukSrY.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-Bwna3and.js"},{"revision":null,"url":"assets/git-graph-CfJjl4E3.js"},{"revision":null,"url":"assets/ganttDiagram-A5KZAMGK-DmL26q2P.js"},{"revision":null,"url":"assets/flowDiagram-PKNHOUZH-oYaovqyp.js"},{"revision":null,"url":"assets/erDiagram-INFDFZHY-BSh2z9Df.js"},{"revision":null,"url":"assets/dist-DGDPTxs1.js"},{"revision":null,"url":"assets/dist-CVTST7Gc.js"},{"revision":null,"url":"assets/dist-CSJdAyA9.js"},{"revision":null,"url":"assets/dist-CALwEtco.js"},{"revision":null,"url":"assets/diff-viewer-C4KMvpHr.js"},{"revision":null,"url":"assets/diagram-P4PSJMXO-C8tjJsev.js"},{"revision":null,"url":"assets/diagram-IFDJBPK2-xKoeuiJx.js"},{"revision":null,"url":"assets/diagram-E7M64L7V-_db4pBVA.js"},{"revision":null,"url":"assets/defaultLocale-5eAKkKJC.js"},{"revision":null,"url":"assets/database-viewer-aRR9n_Ui.js"},{"revision":null,"url":"assets/dagre-KLK3FWXG-BdJr7Byp.js"},{"revision":null,"url":"assets/dagre-DHq9bhnd.js"},{"revision":null,"url":"assets/cytoscape.esm-BW-DbntU.js"},{"revision":null,"url":"assets/csv-preview-DLqYtXxt.js"},{"revision":null,"url":"assets/cose-bilkent-S5V4N54A-B_AWZsOP.js"},{"revision":null,"url":"assets/columns-2-DbesTfa7.js"},{"revision":null,"url":"assets/code-editor-COAIZx-B.js"},{"revision":null,"url":"assets/clone-LRxlvnMj.js"},{"revision":null,"url":"assets/classDiagram-v2-RAHNMMFH-DjYu-6mn.js"},{"revision":null,"url":"assets/classDiagram-VBA2DB6C-BA8Nj-_C.js"},{"revision":null,"url":"assets/chunk-YBOYWFTD-rQG3QH5s.js"},{"revision":null,"url":"assets/chunk-XZSTWKYB-DxAOx4hG.js"},{"revision":null,"url":"assets/chunk-XPW4576I-BPQQBakK.js"},{"revision":null,"url":"assets/chunk-XIRO2GV7-Djlmrely.js"},{"revision":null,"url":"assets/chunk-WL4C6EOR-ByUrSRin.js"},{"revision":null,"url":"assets/chunk-R5LLSJPH-CFwSJijQ.js"},{"revision":null,"url":"assets/chunk-QZHKN3VN-CYaTbeZf.js"},{"revision":null,"url":"assets/chunk-PU5JKC2W-ek7k4QVB.js"},{"revision":null,"url":"assets/chunk-PQ6SQG4A-TF58UVMU.js"},{"revision":null,"url":"assets/chunk-OZEHJAEY-BXhYx3nO.js"},{"revision":null,"url":"assets/chunk-O4XLMI2P-nDhi_cVu.js"},{"revision":null,"url":"assets/chunk-NQ4KR5QH-z_blpjxi.js"},{"revision":null,"url":"assets/chunk-MX3YWQON-BpS_PtKp.js"},{"revision":null,"url":"assets/chunk-L3YUKLVL-C7qGJrfV.js"},{"revision":null,"url":"assets/chunk-KYZI473N-Bb0MCaIO.js"},{"revision":null,"url":"assets/chunk-KX2RTZJC-CRq1OBZv.js"},{"revision":null,"url":"assets/chunk-JSJVCQXG-99JzIdPr.js"},{"revision":null,"url":"assets/chunk-HHEYEP7N-C7vxA5i9.js"},{"revision":null,"url":"assets/chunk-GLR3WWYH-DKikpoJM.js"},{"revision":null,"url":"assets/chunk-GEFDOKGD-D-pKjlVd.js"},{"revision":null,"url":"assets/chunk-FMBD7UC4-DXncblvW.js"},{"revision":null,"url":"assets/chunk-EGIJ26TM-DzqmU2Z7.js"},{"revision":null,"url":"assets/chunk-CFjPhJqf.js"},{"revision":null,"url":"assets/chunk-C72U2L5F-D21mS_6G.js"},{"revision":null,"url":"assets/chunk-7R4GIKGN-Dv-4cAYn.js"},{"revision":null,"url":"assets/chunk-7E7YKBS2-CiyUJxNI.js"},{"revision":null,"url":"assets/chunk-55IACEB6-DJ6BynZ4.js"},{"revision":null,"url":"assets/chunk-4BX2VUAB-D4tOov49.js"},{"revision":null,"url":"assets/chevron-right-CHnjJt4E.js"},{"revision":null,"url":"assets/chat-tab-9lqvWozA.js"},{"revision":null,"url":"assets/channel-By7bn0Yq.js"},{"revision":null,"url":"assets/c4Diagram-IC4MRINW-0Vp0Jeas.js"},{"revision":null,"url":"assets/browser-tab-BEe89aSD.js"},{"revision":null,"url":"assets/blockDiagram-WCTKOSBZ-BCLqzhuZ.js"},{"revision":null,"url":"assets/arrow-up--LjUXLEt.js"},{"revision":null,"url":"assets/array-B9UHiPd-.js"},{"revision":null,"url":"assets/architectureDiagram-2XIMDMQ5-Z-4eN4za.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-DEO2f3VD.js"},{"revision":null,"url":"assets/arc-BAOivWpI.js"},{"revision":null,"url":"assets/api-settings-D21InCnR.js"},{"revision":null,"url":"assets/api-client-BfBM3I7n.js"},{"revision":null,"url":"assets/_baseUniq-BT4Ow4Kk.js"},{"revision":null,"url":"assets/_basePickBy-5PGDJbfF.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":"d5449d97ce56b324eb7a9340a7874de3","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-DRa_TH4B.js"},{"revision":null,"url":"assets/vennDiagram-LZ73GAT5-s9Z71fz-.js"},{"revision":null,"url":"assets/utils-BNytJOb1.js"},{"revision":null,"url":"assets/use-monaco-theme-B5pG2d1w.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-B2Xkyv-K.js"},{"revision":null,"url":"assets/timeline-definition-YZTLITO2-DwZqB3nn.js"},{"revision":null,"url":"assets/terminal-tab-BrP-ENHg.css"},{"revision":null,"url":"assets/terminal-tab-BBi0pEji.js"},{"revision":null,"url":"assets/tag-CXMT0QB6.js"},{"revision":null,"url":"assets/table-DFevCOMd.js"},{"revision":null,"url":"assets/tab-store-BOgTrqRr.js"},{"revision":null,"url":"assets/stateDiagram-v2-FVOUBMTO-BGVqj_g9.js"},{"revision":null,"url":"assets/stateDiagram-RAJIS63D-66vhiIuk.js"},{"revision":null,"url":"assets/src-BqX54PbV.js"},{"revision":null,"url":"assets/sqlite-viewer-nA2sD4Yv.js"},{"revision":null,"url":"assets/settings-tab-D3AvU4lu.js"},{"revision":null,"url":"assets/sequenceDiagram-2WXFIKYE-BQDJ4CVs.js"},{"revision":null,"url":"assets/sankeyDiagram-WA2Y5GQK-T6RgG-N8.js"},{"revision":null,"url":"assets/rough.esm-JX0wREDd.js"},{"revision":null,"url":"assets/requirementDiagram-Z7DCOOCP-pQyah6WB.js"},{"revision":null,"url":"assets/react-nm2Ru1Pt.js"},{"revision":null,"url":"assets/react-dom-Bpkvzu3U.js"},{"revision":null,"url":"assets/react-SKk5z-bm.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-DH0AOkUy.js"},{"revision":null,"url":"assets/quadrantDiagram-337W2JSQ-C8bzJCjQ.js"},{"revision":null,"url":"assets/preload-helper-Bf_JiD2A.js"},{"revision":null,"url":"assets/postgres-viewer-BeiK4lCa.js"},{"revision":null,"url":"assets/pieDiagram-SKSYHLDU-C1Gjrtzy.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-BHncZutv.js"},{"revision":null,"url":"assets/path-6uRLdFF7.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-DY5PNnZU.js"},{"revision":null,"url":"assets/ordinal-_K3x1fkz.js"},{"revision":null,"url":"assets/mindmap-definition-YRQLILUH-x0MTutJp.js"},{"revision":null,"url":"assets/mermaid-parser.core-C7UwoIh6.js"},{"revision":null,"url":"assets/math-069Z4SuC.js"},{"revision":null,"url":"assets/markdown-renderer-DPLdR9xc.js"},{"revision":null,"url":"assets/linear-DP4mkX3m.js"},{"revision":null,"url":"assets/line-CVvo3dRu.js"},{"revision":null,"url":"assets/lib-BQ34Db2e.js"},{"revision":null,"url":"assets/keybindings-store-DPYzBe_M.js"},{"revision":null,"url":"assets/katex-Bqvo_ZG0.js"},{"revision":null,"url":"assets/kanban-definition-K7BYSVSG-CZ535BbZ.js"},{"revision":null,"url":"assets/jsx-runtime-kMwlnEGE.js"},{"revision":null,"url":"assets/journeyDiagram-4ABVD52K-B_L20qMe.js"},{"revision":null,"url":"assets/ishikawaDiagram-PHBUUO56-D05_LyL7.js"},{"revision":null,"url":"assets/isEmpty-bnrF3Qbc.js"},{"revision":null,"url":"assets/isArrayLikeObject-B_v2FtYn.js"},{"revision":null,"url":"assets/init-DlZdxViB.js"},{"revision":null,"url":"assets/infoDiagram-LFFYTUFH-DWwumDkq.js"},{"revision":null,"url":"assets/info-3K5VOQVL-_vRxVNUm.js"},{"revision":null,"url":"assets/index-KwC2YrG4.css"},{"revision":null,"url":"assets/index-C8byznLO.js"},{"revision":null,"url":"assets/graphlib-BcsNnGcW.js"},{"revision":null,"url":"assets/gitGraphDiagram-K3NZZRJ6-CMoukSrY.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-Bwna3and.js"},{"revision":null,"url":"assets/git-graph-CoTvMrIo.js"},{"revision":null,"url":"assets/ganttDiagram-A5KZAMGK-DmL26q2P.js"},{"revision":null,"url":"assets/flowDiagram-PKNHOUZH-oYaovqyp.js"},{"revision":null,"url":"assets/extension-webview-NiZ7Ybvv.js"},{"revision":null,"url":"assets/erDiagram-INFDFZHY-BSh2z9Df.js"},{"revision":null,"url":"assets/dist-ovWkrgO-.js"},{"revision":null,"url":"assets/dist-DIV6WgAG.js"},{"revision":null,"url":"assets/dist-CSJdAyA9.js"},{"revision":null,"url":"assets/diff-viewer-CcLyp4eY.js"},{"revision":null,"url":"assets/diagram-P4PSJMXO-C8tjJsev.js"},{"revision":null,"url":"assets/diagram-IFDJBPK2-xKoeuiJx.js"},{"revision":null,"url":"assets/diagram-E7M64L7V-_db4pBVA.js"},{"revision":null,"url":"assets/defaultLocale-5eAKkKJC.js"},{"revision":null,"url":"assets/database-viewer-BqOJR_zi.js"},{"revision":null,"url":"assets/dagre-KLK3FWXG-BdJr7Byp.js"},{"revision":null,"url":"assets/dagre-DHq9bhnd.js"},{"revision":null,"url":"assets/cytoscape.esm-BW-DbntU.js"},{"revision":null,"url":"assets/csv-preview-ncSOnJSC.js"},{"revision":null,"url":"assets/createLucideIcon-PuMiQgHl.js"},{"revision":null,"url":"assets/cose-bilkent-S5V4N54A-B_AWZsOP.js"},{"revision":null,"url":"assets/columns-2-cEVJHYd7.js"},{"revision":null,"url":"assets/code-editor-CBIPzlP2.js"},{"revision":null,"url":"assets/clone-LRxlvnMj.js"},{"revision":null,"url":"assets/classDiagram-v2-RAHNMMFH-DjYu-6mn.js"},{"revision":null,"url":"assets/classDiagram-VBA2DB6C-BA8Nj-_C.js"},{"revision":null,"url":"assets/chunk-YBOYWFTD-rQG3QH5s.js"},{"revision":null,"url":"assets/chunk-XZSTWKYB-DxAOx4hG.js"},{"revision":null,"url":"assets/chunk-XPW4576I-BPQQBakK.js"},{"revision":null,"url":"assets/chunk-XIRO2GV7-Djlmrely.js"},{"revision":null,"url":"assets/chunk-WL4C6EOR-ByUrSRin.js"},{"revision":null,"url":"assets/chunk-R5LLSJPH-CFwSJijQ.js"},{"revision":null,"url":"assets/chunk-QZHKN3VN-CYaTbeZf.js"},{"revision":null,"url":"assets/chunk-PU5JKC2W-ek7k4QVB.js"},{"revision":null,"url":"assets/chunk-PQ6SQG4A-TF58UVMU.js"},{"revision":null,"url":"assets/chunk-OZEHJAEY-BXhYx3nO.js"},{"revision":null,"url":"assets/chunk-O4XLMI2P-nDhi_cVu.js"},{"revision":null,"url":"assets/chunk-NQ4KR5QH-z_blpjxi.js"},{"revision":null,"url":"assets/chunk-MX3YWQON-BpS_PtKp.js"},{"revision":null,"url":"assets/chunk-L3YUKLVL-C7qGJrfV.js"},{"revision":null,"url":"assets/chunk-KYZI473N-Bb0MCaIO.js"},{"revision":null,"url":"assets/chunk-KX2RTZJC-CRq1OBZv.js"},{"revision":null,"url":"assets/chunk-JSJVCQXG-99JzIdPr.js"},{"revision":null,"url":"assets/chunk-HHEYEP7N-C7vxA5i9.js"},{"revision":null,"url":"assets/chunk-GLR3WWYH-DKikpoJM.js"},{"revision":null,"url":"assets/chunk-GEFDOKGD-D-pKjlVd.js"},{"revision":null,"url":"assets/chunk-FMBD7UC4-DXncblvW.js"},{"revision":null,"url":"assets/chunk-EGIJ26TM-DzqmU2Z7.js"},{"revision":null,"url":"assets/chunk-CFjPhJqf.js"},{"revision":null,"url":"assets/chunk-C72U2L5F-D21mS_6G.js"},{"revision":null,"url":"assets/chunk-7R4GIKGN-Dv-4cAYn.js"},{"revision":null,"url":"assets/chunk-7E7YKBS2-CiyUJxNI.js"},{"revision":null,"url":"assets/chunk-55IACEB6-DJ6BynZ4.js"},{"revision":null,"url":"assets/chunk-4BX2VUAB-D4tOov49.js"},{"revision":null,"url":"assets/chevron-right-5HgK6l7K.js"},{"revision":null,"url":"assets/chat-tab-C6jpiwh7.js"},{"revision":null,"url":"assets/channel-By7bn0Yq.js"},{"revision":null,"url":"assets/c4Diagram-IC4MRINW-0Vp0Jeas.js"},{"revision":null,"url":"assets/browser-tab-CrkhFCaw.js"},{"revision":null,"url":"assets/blockDiagram-WCTKOSBZ-BCLqzhuZ.js"},{"revision":null,"url":"assets/arrow-up-BYhx9ckd.js"},{"revision":null,"url":"assets/array-B9UHiPd-.js"},{"revision":null,"url":"assets/architectureDiagram-2XIMDMQ5-Z-4eN4za.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-DEO2f3VD.js"},{"revision":null,"url":"assets/arc-BAOivWpI.js"},{"revision":null,"url":"assets/api-settings-BUvk6Saw.js"},{"revision":null,"url":"assets/api-client-BfBM3I7n.js"},{"revision":null,"url":"assets/_baseUniq-BT4Ow4Kk.js"},{"revision":null,"url":"assets/_basePickBy-5PGDJbfF.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||`/`)}))});
@@ -745,6 +745,134 @@ if (options.share) {
745
745
 
746
746
  This keeps startup fast when features aren't used.
747
747
 
748
+ ---
749
+
750
+ ## Tab ID & URL Conventions (v0.8.77+)
751
+
752
+ ### Deterministic Tab IDs
753
+
754
+ Tab IDs are derived from type + metadata, not random:
755
+
756
+ ```typescript
757
+ // Format: "{type}:{identifier}" for most tabs, "{type}" for singletons
758
+ editor:src/index.ts // Editor tab with file path
759
+ chat:claude/abc123 // Chat with provider/session ID
760
+ terminal:1 // Terminal tab index
761
+ database:conn-1/users // Database: connection ID / table
762
+ git-graph // Singleton: no identifier
763
+ settings // Singleton: no identifier
764
+
765
+ // Derivation in panel-utils.ts
766
+ export function deriveTabId(type: TabType, metadata?: Record<string, unknown>): string {
767
+ switch (type) {
768
+ case "editor":
769
+ return `editor:${metadata?.filePath ?? "untitled"}`;
770
+ case "chat": {
771
+ const provider = metadata?.providerId ?? "default";
772
+ return `chat:${provider}/${metadata?.sessionId ?? randomId()}`;
773
+ }
774
+ case "terminal":
775
+ return `terminal:${metadata?.terminalIndex ?? 1}`;
776
+ case "git-graph":
777
+ return "git-graph"; // Singleton
778
+ // ... other cases
779
+ }
780
+ }
781
+ ```
782
+
783
+ ### URL Format
784
+
785
+ URLs are built from project name + deterministic tab ID:
786
+
787
+ ```typescript
788
+ // Format: /project/{projectName}/{type}/{identifier}
789
+ /project/ppm // Project root (no active tab)
790
+ /project/ppm/editor/src/index.ts // Open editor
791
+ /project/ppm/chat/claude/abc123 // Open chat
792
+ /project/ppm/terminal/1 // Open terminal
793
+ /project/ppm/database/conn-1/users // Open database
794
+ /project/ppm/git-graph // Git history (singleton)
795
+
796
+ // URL building in use-url-sync.ts
797
+ export function buildUrl(projectName: string, tabId: string | null): string {
798
+ const colonIdx = tabId?.indexOf(":");
799
+ if (colonIdx === -1) {
800
+ // Singleton
801
+ url += `/${tabId}`;
802
+ } else {
803
+ const [type, identifier] = tabId.split(":", 1);
804
+ url += `/${type}/${identifier}`;
805
+ }
806
+ return url;
807
+ }
808
+ ```
809
+
810
+ ### Deep Linking
811
+
812
+ When user navigates to a URL, parse it and auto-create tabs:
813
+
814
+ ```typescript
815
+ // In use-url-sync hook
816
+ export function parseUrlState(): UrlState {
817
+ const match = path.match(/^\/project\/([^/]+)(?:\/([^/]+)(\/.*)?)?/);
818
+ const [, projectName, tabType, tabIdentifierPath] = match;
819
+
820
+ // Build tab metadata from URL
821
+ const metadata = buildMetadataFromUrl(tabType, tabIdentifier, projectName);
822
+
823
+ // Auto-open tab if it doesn't exist
824
+ if (metadata) {
825
+ panelStore.openTab({
826
+ type: tabType,
827
+ title: getTabTitle(tabType, metadata),
828
+ metadata,
829
+ });
830
+ }
831
+ }
832
+ ```
833
+
834
+ ### Server-Side Workspace Persistence
835
+
836
+ Tab layouts are persisted in the `workspace_state` SQLite table:
837
+
838
+ ```typescript
839
+ // workspace.ts routes
840
+ GET /api/project/:name/workspace → { layout: PanelLayout, updatedAt: string }
841
+ PUT /api/project/:name/workspace → { updatedAt: string }
842
+
843
+ // PanelLayout structure
844
+ interface PanelLayout {
845
+ panels: Record<string, Panel>; // panelId → { tabs, activeTabId }
846
+ grid: string[][]; // Row/column grid of panel IDs
847
+ focusedPanelId: string;
848
+ }
849
+
850
+ // Sync is debounced (1.5s) client-side after layout changes
851
+ // Latest-wins: server timestamp compared with client localStorage
852
+ ```
853
+
854
+ ### Migration from Random IDs
855
+
856
+ Old tab IDs (tab-xxxx) are automatically migrated to deterministic format:
857
+
858
+ ```typescript
859
+ // In panel-utils.ts
860
+ export function migrateTabIdToDeterministic(tab: Tab): Tab {
861
+ if (tab.id.startsWith("tab-")) {
862
+ // Convert to deterministic ID
863
+ return {
864
+ ...tab,
865
+ id: deriveTabId(tab.type, tab.metadata),
866
+ };
867
+ }
868
+ return tab;
869
+ }
870
+ ```
871
+
872
+ This happens on first load per project; old URLs redirect to project root.
873
+
874
+ ---
875
+
748
876
  ## Provider Pattern (Multi-Provider Architecture)
749
877
 
750
878
  ### AIProvider Interface
@@ -898,4 +1026,3 @@ const available = await provider.isAvailable?.();
898
1026
  // List models
899
1027
  const models = await provider.listModels?.() ?? [];
900
1028
  ```
901
-
@@ -17,7 +17,8 @@
17
17
  ```
18
18
  src/
19
19
  ├── cli/
20
- │ ├── commands/ # 13 CLI commands (start, stop, init, config, chat, db, git, etc.)
20
+ │ ├── commands/ # 14 CLI commands (start, stop, init, config, chat, db, git, ext, etc.)
21
+ │ │ └── ext-cmd.ts # Extension CLI (install/remove/list/enable/disable/dev)
21
22
  │ └── utils/
22
23
  │ └── project-resolver.ts # Resolve project name -> path
23
24
  ├── server/
@@ -33,6 +34,7 @@ src/
33
34
  │ │ ├── git.ts # Git operations (status, commit, log, graph)
34
35
  │ │ ├── files.ts # File operations (read, write, tree)
35
36
  │ │ ├── mcp.ts # MCP server CRUD + import (GET, POST, PUT, DELETE)
37
+ │ │ ├── extensions.ts # Extension install/remove/list/enable/disable, contributions
36
38
  │ │ ├── upgrade.ts # Version checking, upgrade
37
39
  │ │ └── static.ts # Serve frontend (dist/web)
38
40
  │ ├── helpers/
@@ -48,16 +50,22 @@ src/
48
50
  │ ├── cli-provider-base.ts # Abstract base for CLI providers
49
51
  │ ├── mock-provider.ts # Test provider
50
52
  │ └── registry.ts # Provider routing (list() vs listAll())
51
- ├── services/ # Business logic (25+ files)
53
+ ├── services/ # Business logic (30+ files)
52
54
  │ ├── chat.service.ts # Session/message streaming
53
55
  │ ├── config.service.ts # Config loading/persistence
54
- │ ├── db.service.ts # SQLite CRUD (schema migrations)
56
+ │ ├── db.service.ts # SQLite CRUD (schema migrations, extension_storage)
55
57
  │ ├── file.service.ts # File operations
56
58
  │ ├── git.service.ts # Git commands
57
59
  │ ├── terminal.service.ts # PTY management
58
60
  │ ├── account.service.ts # Account CRUD & encryption
59
61
  │ ├── upgrade.service.ts # Version checking, installation
60
62
  │ ├── mcp-config.service.ts # MCP server CRUD (list, get, set, remove, import)
63
+ │ ├── extension.service.ts # Extension lifecycle, activation, state management
64
+ │ ├── extension-installer.ts # npm install, symlink, removal
65
+ │ ├── extension-manifest.ts # Parse + discover manifests
66
+ │ ├── extension-rpc.ts # RPC channel (request/response/events)
67
+ │ ├── extension-host-worker.ts # Worker-side extension loading
68
+ │ ├── contribution-registry.ts # Central registry for commands, views, config
61
69
  │ ├── database/
62
70
  │ │ ├── adapter-registry.ts # SQLite/Postgres adapter registry
63
71
  │ │ ├── sqlite-adapter.ts
@@ -74,6 +82,7 @@ src/
74
82
  │ ├── database.ts
75
83
  │ ├── git.ts
76
84
  │ ├── mcp.ts # McpServerConfig, McpTransportType, validation
85
+ │ ├── extension.ts # ExtensionManifest, ExtensionInfo, RpcMessage, ExtensionContext
77
86
  │ ├── project.ts
78
87
  │ └── terminal.ts
79
88
  └── web/ # React frontend (Vite + React 18)
@@ -526,21 +535,79 @@ ai:
526
535
 
527
536
  ---
528
537
 
529
- ## Recent Changes (v0.8.60)
538
+ ## Extension System (v0.9.0+)
539
+
540
+ ### Core Architecture
541
+
542
+ **Installation Directory:** `~/.ppm/extensions/node_modules/`
543
+ **State Storage:** SQLite `extension_storage` table (globalState + workspaceState)
544
+ **Worker Isolation:** Bun Worker threads per activated extension
545
+ **RPC Protocol:** Typed request/response/event messaging
546
+
547
+ ### New Files & Services
548
+ - `src/types/extension.ts` — ExtensionManifest, ExtensionContext, RpcMessage types
549
+ - `src/server/routes/extensions.ts` — REST API (GET/POST/DELETE/PATCH)
550
+ - `src/services/extension.service.ts` — Lifecycle, activation, state management (120 LOC)
551
+ - `src/services/extension-installer.ts` — npm install, symlink, removal (100 LOC)
552
+ - `src/services/extension-manifest.ts` — Parse + discover manifests (70 LOC)
553
+ - `src/services/extension-rpc.ts` — RPC channel implementation (120 LOC)
554
+ - `src/services/extension-host-worker.ts` — Worker-side extension loading (150 LOC)
555
+ - `src/services/contribution-registry.ts` — Central command/view/config registry (80 LOC)
556
+ - `src/cli/commands/ext-cmd.ts` — Extension CLI commands (121 LOC)
557
+
558
+ ### Manifest Example (package.json)
559
+ ```json
560
+ {
561
+ "name": "@ppm/ext-database",
562
+ "ppm": {
563
+ "displayName": "Database Browser",
564
+ "main": "dist/extension.js",
565
+ "activationEvents": ["onView:databases"],
566
+ "contributes": {
567
+ "commands": [{"command": "ppm.database.openConnection", "title": "..."}],
568
+ "views": {"explorer": [{"id": "databases", "name": "Databases"}]},
569
+ "configuration": {"properties": {"ppm.database.maxRows": {"type": "number"}}}
570
+ }
571
+ }
572
+ }
573
+ ```
574
+
575
+ ### REST API Endpoints
576
+ - `GET /api/extensions` — List installed
577
+ - `POST /api/extensions` — Install from npm
578
+ - `DELETE /api/extensions/:id` — Remove
579
+ - `PATCH /api/extensions/:id` — Enable/disable
580
+ - `GET /api/extensions/contributions` — List all contributions
581
+
582
+ ### CLI Commands
583
+ ```
584
+ ppm ext list # List extensions
585
+ ppm ext install @ppm/ext-db # Install
586
+ ppm ext remove @ppm/ext-db # Uninstall
587
+ ppm ext enable @ppm/ext-db # Enable
588
+ ppm ext disable @ppm/ext-db # Disable
589
+ ppm ext dev /path/to/src # Dev symlink
590
+ ```
591
+
592
+ ---
530
593
 
531
- ### Added
594
+ ## Recent Changes (v0.8.60+)
595
+
596
+ ### v0.9.0 (Extension System Phase 1)
597
+ - **Extension Framework** — VSCode-compatible npm-installable extensions
598
+ - **Worker Isolation** — Crash-safe extension execution in Bun Workers
599
+ - **RPC Protocol** — Bidirectional messaging (request/response/events)
600
+ - **State Management** — globalState + workspaceState persistence in SQLite
601
+ - **Contribution Registry** — Commands, views, configuration registry
602
+ - **CLI Support** — `ppm ext` commands for lifecycle management
603
+ - **Dev Mode** — Symlink local extensions for development
604
+
605
+ ### v0.8.60
532
606
  - **Dynamic Model Listing** — `listModels?()` on AIProvider interface
533
607
  - **Provider Models APIs** — Global and project-scoped endpoints
534
608
  - **AI Settings UI** — Per-provider tabs with dynamic model dropdowns
535
609
  - **Chat History Badges** — Provider-aware usage display
536
610
  - **13 new integration tests** for provider models API
537
611
 
538
- ### Technical Details
539
- - `ModelOption` type: `{ value: string; label: string }`
540
- - Claude: Hardcoded 2 models
541
- - Cursor: Subprocess with 5-min TTL cache, 10s timeout
542
- - Registry: `list()` vs `listAll()` distinction
543
- - Bootstrap: Auto-detect CLI providers on startup
544
-
545
612
  ---
546
613