@hienlh/ppm 0.13.78 → 0.13.80

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 (84) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/assets/skills/ppm/SKILL.md +1 -1
  3. package/assets/skills/ppm/references/http-api.md +1 -1
  4. package/dist/web/assets/{api-settings-BJTjIG4U.js → api-settings-CQWMP6tw.js} +1 -1
  5. package/dist/web/assets/architecture-PBZL5I3N-zg_XUpAf.js +1 -0
  6. package/dist/web/assets/{audio-preview-DFrv27cv.js → audio-preview-BnX8NIsE.js} +1 -1
  7. package/dist/web/assets/chat-tab-BUirKQ4S.js +16 -0
  8. package/dist/web/assets/code-editor-D2pokrVT.js +10 -0
  9. package/dist/web/assets/{conflict-editor-DGm0Z6Mc.js → conflict-editor-Cb0fYF_-.js} +1 -1
  10. package/dist/web/assets/{csv-preview-asMfgR0r.js → csv-preview-DqoFTfkO.js} +1 -1
  11. package/dist/web/assets/{data-grid-overlay-editor-DGjqvYn6.js → data-grid-overlay-editor-DZGHoBdv.js} +1 -1
  12. package/dist/web/assets/{database-viewer-D1nO6a11.js → database-viewer-DecyPfgQ.js} +1 -1
  13. package/dist/web/assets/diff-viewer-B4g62Spc.js +4 -0
  14. package/dist/web/assets/{docx-preview-BRpopR6E.js → docx-preview-DkHLPuP6.js} +1 -1
  15. package/dist/web/assets/{esm-xVTUq__o.js → esm-A3ZetkGj.js} +1 -1
  16. package/dist/web/assets/{extension-webview-BXeDxyVt.js → extension-webview-uY-shXbu.js} +1 -1
  17. package/dist/web/assets/{git-log-panel-B5n35kot.js → git-log-panel-B01kljlC.js} +1 -1
  18. package/dist/web/assets/gitGraph-HDMCJU4V-CAfOBCyo.js +1 -0
  19. package/dist/web/assets/{glide-data-grid-4mwS1Swl.js → glide-data-grid-C6pJGtR4.js} +7 -7
  20. package/dist/web/assets/{image-preview-Bu5XcdqW.js → image-preview-ptN8ieUy.js} +1 -1
  21. package/dist/web/assets/{index-CuOntRL_.js → index-BGYnwVhe.js} +15 -15
  22. package/dist/web/assets/index-DXxsPKPw.css +2 -0
  23. package/dist/web/assets/info-3K5VOQVL-CevMMhkM.js +1 -0
  24. package/dist/web/assets/{input-CArJe9WS.js → input-BDYfKz0A.js} +1 -1
  25. package/dist/web/assets/keybindings-store-Cw3Lglzq.js +1 -0
  26. package/dist/web/assets/{markdown-renderer-Be-gcsCi.js → markdown-renderer-Bcv82eST.js} +3 -3
  27. package/dist/web/assets/notification-store-Bx4JtvpX.js +1 -0
  28. package/dist/web/assets/{number-overlay-editor-DtUBprPW.js → number-overlay-editor-DSno9uQL.js} +1 -1
  29. package/dist/web/assets/packet-RMMSAZCW-CBPKYQg3.js +1 -0
  30. package/dist/web/assets/{panel-store-C9VAhbZz.js → panel-store-BETELS-N.js} +1 -1
  31. package/dist/web/assets/{pdf-preview-hiA6Dkic.js → pdf-preview-BmeAT0uQ.js} +1 -1
  32. package/dist/web/assets/pie-UPGHQEXC-BA4yGjJM.js +1 -0
  33. package/dist/web/assets/{port-forwarding-tab-DTPLT4nk.js → port-forwarding-tab-7Kf5w4YY.js} +1 -1
  34. package/dist/web/assets/{postgres-viewer-LimIiFby.js → postgres-viewer-FCmpTue5.js} +3 -3
  35. package/dist/web/assets/{project-store-DlbHpIq0.js → project-store-Byuc-f31.js} +1 -1
  36. package/dist/web/assets/radar-KQ55EAFF-0aJoWjiU.js +1 -0
  37. package/dist/web/assets/settings-store-BL2a9FtJ.js +2 -0
  38. package/dist/web/assets/settings-tab-CikbBtzb.js +1 -0
  39. package/dist/web/assets/{sql-query-editor-DGcroNAs.js → sql-query-editor-BjQxcBDR.js} +1 -1
  40. package/dist/web/assets/{sqlite-viewer-DIfCI2va.js → sqlite-viewer-KXkg83Jr.js} +1 -1
  41. package/dist/web/assets/{system-monitor-tab-CIVm3sgY.js → system-monitor-tab-CTZjF0H0.js} +1 -1
  42. package/dist/web/assets/{tab-store-CIcbSn0c.js → tab-store-B_Kf29se.js} +1 -1
  43. package/dist/web/assets/{terminal-tab-Dj9xDdbc.js → terminal-tab-B_Y_f0sq.js} +2 -2
  44. package/dist/web/assets/treemap-KZPCXAKY-C2M84arV.js +1 -0
  45. package/dist/web/assets/{use-blob-url-DrPfBQBM.js → use-blob-url-BiQjyxOy.js} +1 -1
  46. package/dist/web/assets/{use-monaco-theme-BLIgarH5.js → use-monaco-theme-B9wG8s0C.js} +1 -1
  47. package/dist/web/assets/{vendor-mermaid-DkqjpqJK.js → vendor-mermaid-Bfbv_YGB.js} +2 -2
  48. package/dist/web/assets/{video-preview-CnRJmbG8.js → video-preview-CRIWCfhS.js} +1 -1
  49. package/dist/web/index.html +13 -13
  50. package/dist/web/sw.js +1 -1
  51. package/package.json +1 -1
  52. package/src/services/cloud-ws.service.ts +3 -2
  53. package/src/services/db.service.ts +0 -8
  54. package/src/web/components/layout/tab-bar.tsx +37 -16
  55. package/src/web/components/settings/settings-tab.tsx +16 -2
  56. package/src/web/stores/settings-store.ts +10 -0
  57. package/dist/web/assets/architecture-PBZL5I3N-CkdUQjA_.js +0 -1
  58. package/dist/web/assets/chat-tab-DNmhvaZ_.js +0 -16
  59. package/dist/web/assets/code-editor-CHwXYDhx.js +0 -10
  60. package/dist/web/assets/diff-viewer-Blji3pAc.js +0 -4
  61. package/dist/web/assets/gitGraph-HDMCJU4V-D3UR56AG.js +0 -1
  62. package/dist/web/assets/index-fyMt5gpO.css +0 -2
  63. package/dist/web/assets/info-3K5VOQVL-DUhLSKI2.js +0 -1
  64. package/dist/web/assets/keybindings-store-Clt4mfff.js +0 -1
  65. package/dist/web/assets/notification-store-B0D4A68q.js +0 -1
  66. package/dist/web/assets/packet-RMMSAZCW-BIpeVUGW.js +0 -1
  67. package/dist/web/assets/pie-UPGHQEXC-CNoizzjb.js +0 -1
  68. package/dist/web/assets/radar-KQ55EAFF-7dns-ho5.js +0 -1
  69. package/dist/web/assets/settings-store-DQUFTPk2.js +0 -2
  70. package/dist/web/assets/settings-tab-B1wiEtFH.js +0 -1
  71. package/dist/web/assets/text-wrap-DJz9Bgpa.js +0 -1
  72. package/dist/web/assets/treemap-KZPCXAKY-D3DZCLoE.js +0 -1
  73. /package/dist/web/assets/{api-client-BK4NPNoY.js → api-client-bbJLzRVE.js} +0 -0
  74. /package/dist/web/assets/{csv-parser-D1b_lg2T.js → csv-parser-B9nz_FWE.js} +0 -0
  75. /package/dist/web/assets/{data-grid-types-DzL5W2em.js → data-grid-types-DcEKQO3y.js} +0 -0
  76. /package/dist/web/assets/{dist-CohudVKa.js → dist-B5ErTtYs.js} +0 -0
  77. /package/dist/web/assets/{dist-BM2EHhLH.js → dist-JYGF-20y.js} +0 -0
  78. /package/dist/web/assets/{katex-CHaeM9QC.js → katex-DxcN2mZR.js} +0 -0
  79. /package/dist/web/assets/{lib-LPmTkMu4.js → lib-D4CEhqqn.js} +0 -0
  80. /package/dist/web/assets/{react-DHBl6KRc.js → react-9ZmE0_ty.js} +0 -0
  81. /package/dist/web/assets/{utils-CSCvNZxE.js → utils-B1vxU5xS.js} +0 -0
  82. /package/dist/web/assets/{vendor-xterm-t3d5xZdz.js → vendor-xterm-vh96p1Au.js} +0 -0
  83. /package/dist/web/assets/{wifi-CgM9T6HR.js → wifi-cAuzu8sM.js} +0 -0
  84. /package/dist/web/assets/{x-Dx3jsRgu.js → x-BVxklgnd.js} +0 -0
@@ -1 +1 @@
1
- import{b as e}from"./vendor-markdown-0Mxgxy0L.js";import{t}from"./file-exclamation-point-Baz81y5z.js";import"./api-client-BK4NPNoY.js";import{pt as n}from"./index-CuOntRL_.js";import{t as r}from"./use-blob-url-DrPfBQBM.js";var i=e();function a({filePath:e,projectName:a}){let{blobUrl:o,error:s}=r(e,a);return s?(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary`,children:[(0,i.jsx)(t,{className:`size-10 text-text-subtle`}),(0,i.jsx)(`p`,{className:`text-sm`,children:`Failed to load video.`})]}):o?(0,i.jsx)(`div`,{className:`flex items-center justify-center h-full p-4 bg-surface overflow-auto`,children:(0,i.jsx)(`video`,{src:o,controls:!0,className:`max-w-full max-h-full`})}):(0,i.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,i.jsx)(n,{className:`size-5 animate-spin text-text-subtle`})})}export{a as VideoPreview};
1
+ import{b as e}from"./vendor-markdown-0Mxgxy0L.js";import{t}from"./file-exclamation-point-Baz81y5z.js";import"./api-client-bbJLzRVE.js";import{mt as n}from"./index-BGYnwVhe.js";import{t as r}from"./use-blob-url-BiQjyxOy.js";var i=e();function a({filePath:e,projectName:a}){let{blobUrl:o,error:s}=r(e,a);return s?(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary`,children:[(0,i.jsx)(t,{className:`size-10 text-text-subtle`}),(0,i.jsx)(`p`,{className:`text-sm`,children:`Failed to load video.`})]}):o?(0,i.jsx)(`div`,{className:`flex items-center justify-center h-full p-4 bg-surface overflow-auto`,children:(0,i.jsx)(`video`,{src:o,controls:!0,className:`max-w-full max-h-full`})}):(0,i.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,i.jsx)(n,{className:`size-5 animate-spin text-text-subtle`})})}export{a as VideoPreview};
@@ -39,29 +39,29 @@
39
39
  <link rel="preconnect" href="https://fonts.googleapis.com" />
40
40
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
41
41
  <link href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500;600;700&family=Geist:wght@400;500;600;700&display=swap" rel="stylesheet" />
42
- <script type="module" crossorigin src="/assets/index-CuOntRL_.js"></script>
42
+ <script type="module" crossorigin src="/assets/index-BGYnwVhe.js"></script>
43
43
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-FhOqtrmT.js">
44
- <link rel="modulepreload" crossorigin href="/assets/vendor-mermaid-DkqjpqJK.js">
44
+ <link rel="modulepreload" crossorigin href="/assets/vendor-mermaid-Bfbv_YGB.js">
45
45
  <link rel="modulepreload" crossorigin href="/assets/vendor-markdown-0Mxgxy0L.js">
46
46
  <link rel="modulepreload" crossorigin href="/assets/vendor-ui-UXCWAcmi.js">
47
- <link rel="modulepreload" crossorigin href="/assets/utils-CSCvNZxE.js">
47
+ <link rel="modulepreload" crossorigin href="/assets/utils-B1vxU5xS.js">
48
48
  <link rel="modulepreload" crossorigin href="/assets/createLucideIcon-BjHrJDVb.js">
49
- <link rel="modulepreload" crossorigin href="/assets/x-Dx3jsRgu.js">
50
- <link rel="modulepreload" crossorigin href="/assets/input-CArJe9WS.js">
51
- <link rel="modulepreload" crossorigin href="/assets/react-DHBl6KRc.js">
52
- <link rel="modulepreload" crossorigin href="/assets/api-client-BK4NPNoY.js">
53
- <link rel="modulepreload" crossorigin href="/assets/settings-store-DQUFTPk2.js">
49
+ <link rel="modulepreload" crossorigin href="/assets/x-BVxklgnd.js">
50
+ <link rel="modulepreload" crossorigin href="/assets/input-BDYfKz0A.js">
51
+ <link rel="modulepreload" crossorigin href="/assets/react-9ZmE0_ty.js">
52
+ <link rel="modulepreload" crossorigin href="/assets/api-client-bbJLzRVE.js">
53
+ <link rel="modulepreload" crossorigin href="/assets/settings-store-BL2a9FtJ.js">
54
54
  <link rel="modulepreload" crossorigin href="/assets/eye-off-BacF7RVS.js">
55
55
  <link rel="modulepreload" crossorigin href="/assets/chevron-down-CiFNPrfI.js">
56
56
  <link rel="modulepreload" crossorigin href="/assets/database-NmqHg29g.js">
57
57
  <link rel="modulepreload" crossorigin href="/assets/chevron-right-BzAdxJRG.js">
58
58
  <link rel="modulepreload" crossorigin href="/assets/search-BEy08Exr.js">
59
59
  <link rel="modulepreload" crossorigin href="/assets/trash-2-D5P4y8p_.js">
60
- <link rel="modulepreload" crossorigin href="/assets/api-settings-BJTjIG4U.js">
61
- <link rel="modulepreload" crossorigin href="/assets/panel-store-C9VAhbZz.js">
62
- <link rel="modulepreload" crossorigin href="/assets/project-store-DlbHpIq0.js">
63
- <link rel="modulepreload" crossorigin href="/assets/tab-store-CIcbSn0c.js">
64
- <link rel="stylesheet" crossorigin href="/assets/index-fyMt5gpO.css">
60
+ <link rel="modulepreload" crossorigin href="/assets/api-settings-CQWMP6tw.js">
61
+ <link rel="modulepreload" crossorigin href="/assets/panel-store-BETELS-N.js">
62
+ <link rel="modulepreload" crossorigin href="/assets/project-store-Byuc-f31.js">
63
+ <link rel="modulepreload" crossorigin href="/assets/tab-store-B_Kf29se.js">
64
+ <link rel="stylesheet" crossorigin href="/assets/index-DXxsPKPw.css">
65
65
  <link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
66
66
  <body class="bg-[#0f1419] text-[#e5e7eb] font-sans antialiased">
67
67
  <div id="portal" style="position: fixed; left: 0; top: 0; z-index: 9999;" /></div>
package/dist/web/sw.js CHANGED
@@ -1 +1 @@
1
- try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}function B(e){O().precache(e)}function V(e,t){B(e),z(t)}V([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"93dce4eb86e16c19a6622c9a6b554b39","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":null,"url":"assets/project-store-DlbHpIq0.js"},{"revision":null,"url":"assets/utils-CSCvNZxE.js"},{"revision":null,"url":"assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2"},{"revision":null,"url":"assets/KaTeX_AMS-Regular-BQhdFMY1.woff2"},{"revision":null,"url":"assets/glide-data-grid-4mwS1Swl.js"},{"revision":null,"url":"assets/conflict-editor-DGm0Z6Mc.js"},{"revision":null,"url":"assets/katex-CHaeM9QC.js"},{"revision":null,"url":"assets/arrow-down-D825m4vm.js"},{"revision":null,"url":"assets/index-fyMt5gpO.css"},{"revision":null,"url":"assets/api-settings-BJTjIG4U.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-CNoizzjb.js"},{"revision":null,"url":"assets/x-Dx3jsRgu.js"},{"revision":null,"url":"assets/esm-xVTUq__o.js"},{"revision":null,"url":"assets/index-CuOntRL_.js"},{"revision":null,"url":"assets/chat-tab-DNmhvaZ_.js"},{"revision":null,"url":"assets/table-BzjWcs87.js"},{"revision":null,"url":"assets/text-wrap-DJz9Bgpa.js"},{"revision":null,"url":"assets/KaTeX_Main-Regular-B22Nviop.woff2"},{"revision":null,"url":"assets/keybindings-store-Clt4mfff.js"},{"revision":null,"url":"assets/trash-2-D5P4y8p_.js"},{"revision":null,"url":"assets/markdown-renderer-Be-gcsCi.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-7dns-ho5.js"},{"revision":null,"url":"assets/sparkles-CulWHe4c.js"},{"revision":null,"url":"assets/react-DHBl6KRc.js"},{"revision":null,"url":"assets/file-exclamation-point-Baz81y5z.js"},{"revision":null,"url":"assets/github.min-D2BCvnWf.css"},{"revision":null,"url":"assets/sql-query-editor-DGcroNAs.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-D3DZCLoE.js"},{"revision":null,"url":"assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2"},{"revision":null,"url":"assets/port-forwarding-tab-DTPLT4nk.js"},{"revision":null,"url":"assets/chevron-right-BzAdxJRG.js"},{"revision":null,"url":"assets/dist-CohudVKa.js"},{"revision":null,"url":"assets/glide-data-grid-nthEL3fk.css"},{"revision":null,"url":"assets/settings-store-DQUFTPk2.js"},{"revision":null,"url":"assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2"},{"revision":null,"url":"assets/shield-off-C_MK1u09.js"},{"revision":null,"url":"assets/vendor-markdown-0Mxgxy0L.js"},{"revision":null,"url":"assets/pdf-preview-hiA6Dkic.js"},{"revision":null,"url":"assets/audio-preview-DFrv27cv.js"},{"revision":null,"url":"assets/wifi-CgM9T6HR.js"},{"revision":null,"url":"assets/sqlite-viewer-DIfCI2va.js"},{"revision":null,"url":"assets/tab-store-CIcbSn0c.js"},{"revision":null,"url":"assets/KaTeX_Main-Italic-NWA7e6Wa.woff2"},{"revision":null,"url":"assets/video-preview-CnRJmbG8.js"},{"revision":null,"url":"assets/use-monaco-theme-BLIgarH5.js"},{"revision":null,"url":"assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2"},{"revision":null,"url":"assets/panel-store-C9VAhbZz.js"},{"revision":null,"url":"assets/data-grid-types-DzL5W2em.js"},{"revision":null,"url":"assets/database-NmqHg29g.js"},{"revision":null,"url":"assets/chevron-down-CiFNPrfI.js"},{"revision":null,"url":"assets/docx-preview-BRpopR6E.js"},{"revision":null,"url":"assets/notification-store-B0D4A68q.js"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2"},{"revision":null,"url":"assets/data-grid-overlay-editor-DGjqvYn6.js"},{"revision":null,"url":"assets/settings-tab-B1wiEtFH.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-D3UR56AG.js"},{"revision":null,"url":"assets/rolldown-runtime-FhOqtrmT.js"},{"revision":null,"url":"assets/vendor-ui-UXCWAcmi.js"},{"revision":null,"url":"assets/git-log-panel-B5n35kot.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-BIpeVUGW.js"},{"revision":null,"url":"assets/KaTeX_Math-Italic-t53AETM-.woff2"},{"revision":null,"url":"assets/github-dark-dimmed.min-BrpRStFV.css"},{"revision":null,"url":"assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2"},{"revision":null,"url":"assets/KaTeX_Script-Regular-D3wIWfF6.woff2"},{"revision":null,"url":"assets/arrow-up-Rcw6_KKu.js"},{"revision":null,"url":"assets/eye-off-BacF7RVS.js"},{"revision":null,"url":"assets/system-monitor-tab-CIVm3sgY.js"},{"revision":null,"url":"assets/vendor-mermaid-DkqjpqJK.js"},{"revision":null,"url":"assets/lib-LPmTkMu4.js"},{"revision":null,"url":"assets/KaTeX_Main-Bold-Cx986IdX.woff2"},{"revision":null,"url":"assets/diff-viewer-Blji3pAc.js"},{"revision":null,"url":"assets/database-viewer-D1nO6a11.js"},{"revision":null,"url":"assets/KaTeX_Size2-Regular-Dy4dx90m.woff2"},{"revision":null,"url":"assets/vendor-xterm-t3d5xZdz.js"},{"revision":null,"url":"assets/code-editor-CHwXYDhx.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2"},{"revision":null,"url":"assets/KaTeX_Size1-Regular-mCD8mA8B.woff2"},{"revision":null,"url":"assets/architecture-PBZL5I3N-CkdUQjA_.js"},{"revision":null,"url":"assets/number-overlay-editor-DtUBprPW.js"},{"revision":null,"url":"assets/csv-preview-asMfgR0r.js"},{"revision":null,"url":"assets/createLucideIcon-BjHrJDVb.js"},{"revision":null,"url":"assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2"},{"revision":null,"url":"assets/code-CuravVys.js"},{"revision":null,"url":"assets/use-blob-url-DrPfBQBM.js"},{"revision":null,"url":"assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2"},{"revision":null,"url":"assets/image-preview-Bu5XcdqW.js"},{"revision":null,"url":"assets/postgres-viewer-LimIiFby.js"},{"revision":null,"url":"assets/search-BEy08Exr.js"},{"revision":null,"url":"assets/extension-webview-BXeDxyVt.js"},{"revision":null,"url":"assets/api-client-BK4NPNoY.js"},{"revision":null,"url":"assets/shield-check-77W0OMbn.js"},{"revision":null,"url":"assets/terminal-tab-Dj9xDdbc.js"},{"revision":null,"url":"assets/input-CArJe9WS.js"},{"revision":null,"url":"assets/vendor-xterm-BrP-ENHg.css"},{"revision":null,"url":"assets/info-3K5VOQVL-DUhLSKI2.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2"},{"revision":null,"url":"assets/dist-BM2EHhLH.js"},{"revision":null,"url":"assets/csv-parser-D1b_lg2T.js"},{"revision":"d0f94ce046cf8cf09605ee7664dac557","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"a424156a79b9c1b907db93aa3180585a","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"b3a7f967560c9816492a1567b3f7f0dc","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":"a5d8a1acfc29c2a4c882a54ffc93def3","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"948e060affb598c339be40d69e1f6f9c","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"26dccd02a2ef7522892015154f5e3680","url":"manifest.webmanifest"}]);
1
+ try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}function B(e){O().precache(e)}function V(e,t){B(e),z(t)}V([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"f3369d1ac27e8b19c851423d4f63ea88","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":null,"url":"assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2"},{"revision":null,"url":"assets/api-settings-CQWMP6tw.js"},{"revision":null,"url":"assets/KaTeX_AMS-Regular-BQhdFMY1.woff2"},{"revision":null,"url":"assets/sql-query-editor-BjQxcBDR.js"},{"revision":null,"url":"assets/csv-preview-DqoFTfkO.js"},{"revision":null,"url":"assets/react-9ZmE0_ty.js"},{"revision":null,"url":"assets/utils-B1vxU5xS.js"},{"revision":null,"url":"assets/arrow-down-D825m4vm.js"},{"revision":null,"url":"assets/docx-preview-DkHLPuP6.js"},{"revision":null,"url":"assets/table-BzjWcs87.js"},{"revision":null,"url":"assets/KaTeX_Main-Regular-B22Nviop.woff2"},{"revision":null,"url":"assets/trash-2-D5P4y8p_.js"},{"revision":null,"url":"assets/system-monitor-tab-CTZjF0H0.js"},{"revision":null,"url":"assets/sparkles-CulWHe4c.js"},{"revision":null,"url":"assets/settings-tab-CikbBtzb.js"},{"revision":null,"url":"assets/file-exclamation-point-Baz81y5z.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-CBPKYQg3.js"},{"revision":null,"url":"assets/dist-JYGF-20y.js"},{"revision":null,"url":"assets/github.min-D2BCvnWf.css"},{"revision":null,"url":"assets/wifi-cAuzu8sM.js"},{"revision":null,"url":"assets/dist-B5ErTtYs.js"},{"revision":null,"url":"assets/terminal-tab-B_Y_f0sq.js"},{"revision":null,"url":"assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2"},{"revision":null,"url":"assets/csv-parser-B9nz_FWE.js"},{"revision":null,"url":"assets/katex-DxcN2mZR.js"},{"revision":null,"url":"assets/chevron-right-BzAdxJRG.js"},{"revision":null,"url":"assets/glide-data-grid-nthEL3fk.css"},{"revision":null,"url":"assets/code-editor-D2pokrVT.js"},{"revision":null,"url":"assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2"},{"revision":null,"url":"assets/shield-off-C_MK1u09.js"},{"revision":null,"url":"assets/vendor-markdown-0Mxgxy0L.js"},{"revision":null,"url":"assets/vendor-xterm-vh96p1Au.js"},{"revision":null,"url":"assets/database-viewer-DecyPfgQ.js"},{"revision":null,"url":"assets/KaTeX_Main-Italic-NWA7e6Wa.woff2"},{"revision":null,"url":"assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2"},{"revision":null,"url":"assets/api-client-bbJLzRVE.js"},{"revision":null,"url":"assets/chat-tab-BUirKQ4S.js"},{"revision":null,"url":"assets/database-NmqHg29g.js"},{"revision":null,"url":"assets/chevron-down-CiFNPrfI.js"},{"revision":null,"url":"assets/pdf-preview-BmeAT0uQ.js"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2"},{"revision":null,"url":"assets/esm-A3ZetkGj.js"},{"revision":null,"url":"assets/tab-store-B_Kf29se.js"},{"revision":null,"url":"assets/project-store-Byuc-f31.js"},{"revision":null,"url":"assets/input-BDYfKz0A.js"},{"revision":null,"url":"assets/rolldown-runtime-FhOqtrmT.js"},{"revision":null,"url":"assets/panel-store-BETELS-N.js"},{"revision":null,"url":"assets/vendor-ui-UXCWAcmi.js"},{"revision":null,"url":"assets/info-3K5VOQVL-CevMMhkM.js"},{"revision":null,"url":"assets/KaTeX_Math-Italic-t53AETM-.woff2"},{"revision":null,"url":"assets/github-dark-dimmed.min-BrpRStFV.css"},{"revision":null,"url":"assets/pie-UPGHQEXC-BA4yGjJM.js"},{"revision":null,"url":"assets/keybindings-store-Cw3Lglzq.js"},{"revision":null,"url":"assets/extension-webview-uY-shXbu.js"},{"revision":null,"url":"assets/use-blob-url-BiQjyxOy.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2"},{"revision":null,"url":"assets/KaTeX_Script-Regular-D3wIWfF6.woff2"},{"revision":null,"url":"assets/arrow-up-Rcw6_KKu.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-CAfOBCyo.js"},{"revision":null,"url":"assets/eye-off-BacF7RVS.js"},{"revision":null,"url":"assets/postgres-viewer-FCmpTue5.js"},{"revision":null,"url":"assets/KaTeX_Main-Bold-Cx986IdX.woff2"},{"revision":null,"url":"assets/KaTeX_Size2-Regular-Dy4dx90m.woff2"},{"revision":null,"url":"assets/x-BVxklgnd.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2"},{"revision":null,"url":"assets/sqlite-viewer-KXkg83Jr.js"},{"revision":null,"url":"assets/KaTeX_Size1-Regular-mCD8mA8B.woff2"},{"revision":null,"url":"assets/notification-store-Bx4JtvpX.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-zg_XUpAf.js"},{"revision":null,"url":"assets/data-grid-overlay-editor-DZGHoBdv.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-0aJoWjiU.js"},{"revision":null,"url":"assets/createLucideIcon-BjHrJDVb.js"},{"revision":null,"url":"assets/git-log-panel-B01kljlC.js"},{"revision":null,"url":"assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2"},{"revision":null,"url":"assets/index-BGYnwVhe.js"},{"revision":null,"url":"assets/conflict-editor-Cb0fYF_-.js"},{"revision":null,"url":"assets/code-CuravVys.js"},{"revision":null,"url":"assets/data-grid-types-DcEKQO3y.js"},{"revision":null,"url":"assets/settings-store-BL2a9FtJ.js"},{"revision":null,"url":"assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2"},{"revision":null,"url":"assets/index-DXxsPKPw.css"},{"revision":null,"url":"assets/search-BEy08Exr.js"},{"revision":null,"url":"assets/number-overlay-editor-DSno9uQL.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-C2M84arV.js"},{"revision":null,"url":"assets/vendor-mermaid-Bfbv_YGB.js"},{"revision":null,"url":"assets/markdown-renderer-Bcv82eST.js"},{"revision":null,"url":"assets/glide-data-grid-C6pJGtR4.js"},{"revision":null,"url":"assets/diff-viewer-B4g62Spc.js"},{"revision":null,"url":"assets/shield-check-77W0OMbn.js"},{"revision":null,"url":"assets/use-monaco-theme-B9wG8s0C.js"},{"revision":null,"url":"assets/lib-D4CEhqqn.js"},{"revision":null,"url":"assets/vendor-xterm-BrP-ENHg.css"},{"revision":null,"url":"assets/video-preview-CRIWCfhS.js"},{"revision":null,"url":"assets/image-preview-ptN8ieUy.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2"},{"revision":null,"url":"assets/port-forwarding-tab-7Kf5w4YY.js"},{"revision":null,"url":"assets/audio-preview-BnX8NIsE.js"},{"revision":"d0f94ce046cf8cf09605ee7664dac557","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"a424156a79b9c1b907db93aa3180585a","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"b3a7f967560c9816492a1567b3f7f0dc","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":"a5d8a1acfc29c2a4c882a54ffc93def3","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"948e060affb598c339be40d69e1f6f9c","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"26dccd02a2ef7522892015154f5e3680","url":"manifest.webmanifest"}]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hienlh/ppm",
3
- "version": "0.13.78",
3
+ "version": "0.13.80",
4
4
  "description": "Personal Project Manager — mobile-first web IDE with AI assistance",
5
5
  "author": "hienlh",
6
6
  "license": "MIT",
@@ -150,11 +150,12 @@ export function sendNotification(payload: {
150
150
  sessionTitle?: string;
151
151
  notificationType: "done" | "approval_request" | "question";
152
152
  }): void {
153
- send({
153
+ const msg: NotificationMsg = {
154
154
  type: "notification",
155
155
  ...payload,
156
156
  timestamp: new Date().toISOString(),
157
- } as NotificationMsg);
157
+ };
158
+ send(msg);
158
159
  }
159
160
 
160
161
  // ─── Internal ───────────────────────────────────────
@@ -83,14 +83,6 @@ function runMigrations(database: Database): void {
83
83
  created_at TEXT DEFAULT (datetime('now'))
84
84
  );
85
85
 
86
- CREATE TABLE IF NOT EXISTS push_subscriptions (
87
- endpoint TEXT PRIMARY KEY,
88
- p256dh TEXT NOT NULL,
89
- auth TEXT NOT NULL,
90
- expiration_time TEXT,
91
- created_at TEXT DEFAULT (datetime('now'))
92
- );
93
-
94
86
  CREATE TABLE IF NOT EXISTS session_logs (
95
87
  id INTEGER PRIMARY KEY AUTOINCREMENT,
96
88
  session_id TEXT NOT NULL,
@@ -34,11 +34,19 @@ import { basename } from "@/lib/utils";
34
34
  import { useNotificationStore, notificationColor } from "@/stores/notification-store";
35
35
  import { useStreamingStore } from "@/stores/streaming-store";
36
36
  import { useTabOverflow, getHiddenUnreadDirection } from "@/hooks/use-tab-overflow";
37
+ import { useSettingsStore } from "@/stores/settings-store";
37
38
  import { DraggableTab } from "./draggable-tab";
38
39
  import { cn } from "@/lib/utils";
39
40
  import type { Tab } from "@/stores/tab-store";
40
41
  import { downloadFile } from "@/lib/file-download";
41
42
  import { FileActions } from "@/components/explorer/file-actions";
43
+ import {
44
+ ContextMenu as BarContextMenu,
45
+ ContextMenuContent as BarContextMenuContent,
46
+ ContextMenuItem as BarContextMenuItem,
47
+ ContextMenuTrigger as BarContextMenuTrigger,
48
+ ContextMenuSeparator as BarContextMenuSeparator,
49
+ } from "@/components/ui/context-menu";
42
50
 
43
51
  const TAB_ICONS: Record<TabType, React.ElementType> = {
44
52
  terminal: Terminal,
@@ -112,6 +120,9 @@ export const TabBar = memo(function TabBar({ panelId }: TabBarProps) {
112
120
 
113
121
  const notifications = useNotificationStore((s) => s.notifications);
114
122
  const streamingSessions = useStreamingStore((s) => s.sessions);
123
+ const tabWrap = useSettingsStore((s) => s.tabWrap);
124
+ const toggleTabWrap = useSettingsStore((s) => s.toggleTabWrap);
125
+
115
126
  const { canScrollLeft, canScrollRight, scrollLeft: doScrollLeft, scrollRight: doScrollRight } =
116
127
  useTabOverflow(scrollRef);
117
128
 
@@ -269,25 +280,21 @@ export const TabBar = memo(function TabBar({ panelId }: TabBarProps) {
269
280
  openCommandPalette();
270
281
  }
271
282
 
272
- /** Right-click on empty bar area → open command palette */
273
- function handleBarContextMenu(e: React.MouseEvent) {
274
- const target = e.target as HTMLElement;
275
- if (target.closest("[data-tab-item]")) return;
276
- e.preventDefault();
277
- openCommandPalette();
278
- }
279
-
280
283
  return (
281
284
  <>
285
+ <BarContextMenu>
286
+ <BarContextMenuTrigger asChild>
282
287
  <div
283
- className="hidden md:flex items-center h-10 border-b border-border bg-background relative"
288
+ className={cn(
289
+ "hidden md:flex items-center border-b border-border bg-background relative",
290
+ tabWrap ? "min-h-10 flex-wrap" : "h-10",
291
+ )}
284
292
  onDragOver={handleDragOverBar}
285
293
  onDrop={handleDrop}
286
294
  onDoubleClick={handleBarDoubleClick}
287
- onContextMenu={handleBarContextMenu}
288
295
  >
289
- {/* Left scroll arrow */}
290
- {canScrollLeft && (
296
+ {/* Left scroll arrow (hidden in wrap mode) */}
297
+ {!tabWrap && canScrollLeft && (
291
298
  <button
292
299
  onClick={doScrollLeft}
293
300
  className="absolute left-0 z-10 flex items-center justify-center size-8 bg-gradient-to-r from-background via-background to-transparent"
@@ -304,9 +311,12 @@ export const TabBar = memo(function TabBar({ panelId }: TabBarProps) {
304
311
  {/* Scrollable tabs + sticky + button */}
305
312
  <div
306
313
  ref={scrollRef}
307
- className="flex-1 overflow-x-auto overflow-y-hidden min-w-0 scrollbar-none"
314
+ className={cn(
315
+ "flex-1 min-w-0 scrollbar-none",
316
+ tabWrap ? "overflow-y-auto overflow-x-hidden" : "overflow-x-auto overflow-y-hidden",
317
+ )}
308
318
  >
309
- <div className="flex items-center h-10">
319
+ <div className={cn("flex items-center", tabWrap ? "flex-wrap min-h-10" : "h-10")}>
310
320
  {tabs.map((tab, i) => {
311
321
  const sessionId = tab.type === "chat" ? (tab.metadata?.sessionId as string) : undefined;
312
322
  const entry = sessionId ? notifications.get(sessionId) : undefined;
@@ -392,8 +402,8 @@ export const TabBar = memo(function TabBar({ panelId }: TabBarProps) {
392
402
  </div>
393
403
  </div>
394
404
 
395
- {/* Right scroll arrow */}
396
- {canScrollRight && (
405
+ {/* Right scroll arrow (hidden in wrap mode) */}
406
+ {!tabWrap && canScrollRight && (
397
407
  <button
398
408
  onClick={doScrollRight}
399
409
  className="absolute right-10 z-10 flex items-center justify-center size-8 bg-gradient-to-l from-background via-background to-transparent"
@@ -407,6 +417,17 @@ export const TabBar = memo(function TabBar({ panelId }: TabBarProps) {
407
417
  </button>
408
418
  )}
409
419
  </div>
420
+ </BarContextMenuTrigger>
421
+ <BarContextMenuContent>
422
+ <BarContextMenuItem onClick={toggleTabWrap}>
423
+ {tabWrap ? "Scroll Tabs" : "Wrap Tabs"}
424
+ </BarContextMenuItem>
425
+ <BarContextMenuSeparator />
426
+ <BarContextMenuItem onClick={() => openCommandPalette()}>
427
+ Open Command Palette
428
+ </BarContextMenuItem>
429
+ </BarContextMenuContent>
430
+ </BarContextMenu>
410
431
 
411
432
  {fileActionState && (
412
433
  <FileActions
@@ -1,7 +1,7 @@
1
1
  import { useState, useCallback, useRef } from "react";
2
2
  import {
3
3
  Moon, Sun, Monitor, Bell, Check, ChevronRight, ArrowLeft,
4
- Bot, BellRing, Keyboard, Globe, Plug, Puzzle, Bug, FolderSearch,
4
+ Bot, BellRing, Keyboard, Globe, Plug, Puzzle, Bug, FolderSearch, WrapText,
5
5
  } from "lucide-react";
6
6
  import { Button } from "@/components/ui/button";
7
7
  import { Input } from "@/components/ui/input";
@@ -40,7 +40,7 @@ const CATEGORIES: { value: SettingsCategory; label: string; subtitle: string; ic
40
40
  ];
41
41
 
42
42
  export function SettingsTab() {
43
- const { theme, setTheme, deviceName, setDeviceName, version, jiraEnabled, setJiraEnabled } = useSettingsStore(useShallow((s) => ({ theme: s.theme, setTheme: s.setTheme, deviceName: s.deviceName, setDeviceName: s.setDeviceName, version: s.version, jiraEnabled: s.jiraEnabled, setJiraEnabled: s.setJiraEnabled })));
43
+ const { theme, setTheme, deviceName, setDeviceName, version, jiraEnabled, setJiraEnabled, tabWrap, toggleTabWrap } = useSettingsStore(useShallow((s) => ({ theme: s.theme, setTheme: s.setTheme, deviceName: s.deviceName, setDeviceName: s.setDeviceName, version: s.version, jiraEnabled: s.jiraEnabled, setJiraEnabled: s.setJiraEnabled, tabWrap: s.tabWrap, toggleTabWrap: s.toggleTabWrap })));
44
44
  const [activeCategory, setActiveCategory] = useState<SettingsCategory | null>(null);
45
45
  const [nameInput, setNameInput] = useState(deviceName ?? "");
46
46
  const [nameSaving, setNameSaving] = useState(false);
@@ -176,6 +176,20 @@ export function SettingsTab() {
176
176
  </div>
177
177
  </section>
178
178
 
179
+ {/* Wrap Tabs toggle */}
180
+ <section className="space-y-1">
181
+ <div className="flex items-center justify-between">
182
+ <div className="flex items-center gap-2">
183
+ <WrapText className="size-4 text-muted-foreground" />
184
+ <div>
185
+ <p className="text-xs font-medium">Wrap Tabs</p>
186
+ <p className="text-[11px] text-muted-foreground">Stack tabs in rows instead of scrolling</p>
187
+ </div>
188
+ </div>
189
+ <Switch checked={tabWrap} onCheckedChange={toggleTabWrap} />
190
+ </div>
191
+ </section>
192
+
179
193
  <Separator />
180
194
 
181
195
  {/* Category navigation list */}
@@ -15,6 +15,7 @@ interface SettingsState {
15
15
  sidebarWidth: number;
16
16
  gitStatusViewMode: GitStatusViewMode;
17
17
  wordWrap: boolean;
18
+ tabWrap: boolean;
18
19
  sidebarActiveTab: SidebarActiveTab;
19
20
  jiraEnabled: boolean;
20
21
  deviceName: string | null;
@@ -26,6 +27,7 @@ interface SettingsState {
26
27
  setSidebarWidth: (width: number) => void;
27
28
  setGitStatusViewMode: (mode: GitStatusViewMode) => void;
28
29
  toggleWordWrap: () => void;
30
+ toggleTabWrap: () => void;
29
31
  setSidebarActiveTab: (tab: SidebarActiveTab) => void;
30
32
  fetchServerInfo: () => Promise<void>;
31
33
  }
@@ -36,6 +38,7 @@ interface PersistedSettings {
36
38
  sidebarWidth?: number;
37
39
  gitStatusViewMode?: GitStatusViewMode;
38
40
  wordWrap?: boolean;
41
+ tabWrap?: boolean;
39
42
  sidebarActiveTab?: SidebarActiveTab;
40
43
  jiraEnabled?: boolean;
41
44
  }
@@ -108,6 +111,7 @@ export const useSettingsStore = create<SettingsState>((set, get) => ({
108
111
  sidebarWidth: _initial.sidebarWidth ?? 280,
109
112
  gitStatusViewMode: _initial.gitStatusViewMode === "flat" ? "flat" : "tree",
110
113
  wordWrap: _initial.wordWrap ?? false,
114
+ tabWrap: _initial.tabWrap ?? false,
111
115
  sidebarActiveTab: isValidSidebarTab(_initial.sidebarActiveTab) ? _initial.sidebarActiveTab : "explorer",
112
116
  jiraEnabled: _initial.jiraEnabled ?? false,
113
117
  deviceName: null,
@@ -174,6 +178,12 @@ export const useSettingsStore = create<SettingsState>((set, get) => ({
174
178
  set({ wordWrap: next });
175
179
  },
176
180
 
181
+ toggleTabWrap: () => {
182
+ const next = !get().tabWrap;
183
+ persistSettings({ tabWrap: next });
184
+ set({ tabWrap: next });
185
+ },
186
+
177
187
  setSidebarActiveTab: (tab) => {
178
188
  persistSettings({ sidebarActiveTab: tab });
179
189
  set({ sidebarActiveTab: tab });
@@ -1 +0,0 @@
1
- import{G as e}from"./vendor-mermaid-DkqjpqJK.js";export{e as createArchitectureServices};