termbeam 1.20.4 → 1.21.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 (71) hide show
  1. package/CHANGELOG.md +637 -0
  2. package/package.json +3 -2
  3. package/public/assets/{_basePickBy-BLefhu0l.js → _basePickBy-BIHCnP-C.js} +1 -1
  4. package/public/assets/{_baseUniq-DaY_Bc3O.js → _baseUniq-DnMFuvsx.js} +1 -1
  5. package/public/assets/{arc-DmuNthMW.js → arc-BNbndmGK.js} +1 -1
  6. package/public/assets/{architectureDiagram-Q4EWVU46-D_3Wy2pQ.js → architectureDiagram-Q4EWVU46-BmFTw0nZ.js} +1 -1
  7. package/public/assets/{blockDiagram-DXYQGD6D-BcStipzf.js → blockDiagram-DXYQGD6D-wN2o-9_g.js} +1 -1
  8. package/public/assets/{c4Diagram-AHTNJAMY-BwE7ZnCD.js → c4Diagram-AHTNJAMY-BYDCN8H0.js} +1 -1
  9. package/public/assets/channel-DSjdyO61.js +1 -0
  10. package/public/assets/{chunk-4BX2VUAB-CxYOWomN.js → chunk-4BX2VUAB-Cob7CgE_.js} +1 -1
  11. package/public/assets/{chunk-4TB4RGXK-D1SjwnL0.js → chunk-4TB4RGXK-DDonZyK6.js} +1 -1
  12. package/public/assets/{chunk-55IACEB6-CCtV1y23.js → chunk-55IACEB6-BTW1fQoW.js} +1 -1
  13. package/public/assets/{chunk-EDXVE4YY-CwJdMkPT.js → chunk-EDXVE4YY-BgWTXLsq.js} +1 -1
  14. package/public/assets/{chunk-FMBD7UC4-CL6X-Bgf.js → chunk-FMBD7UC4-CxmTHyai.js} +1 -1
  15. package/public/assets/{chunk-OYMX7WX6-Nt-YAKKo.js → chunk-OYMX7WX6-v5mXWXoC.js} +1 -1
  16. package/public/assets/{chunk-QZHKN3VN-JqEPJ-I8.js → chunk-QZHKN3VN-CyNtEZcY.js} +1 -1
  17. package/public/assets/{chunk-YZCP3GAM-B2BkSOHZ.js → chunk-YZCP3GAM-qiJvjghT.js} +1 -1
  18. package/public/assets/classDiagram-6PBFFD2Q-DRtX5Ta8.js +1 -0
  19. package/public/assets/classDiagram-v2-HSJHXN6E-DRtX5Ta8.js +1 -0
  20. package/public/assets/clone-iFtwY3RV.js +1 -0
  21. package/public/assets/{cose-bilkent-S5V4N54A-B2XXKALr.js → cose-bilkent-S5V4N54A-CsbF4Rbc.js} +1 -1
  22. package/public/assets/{dagre-KV5264BT-BbosVmxG.js → dagre-KV5264BT-CiBddJE9.js} +1 -1
  23. package/public/assets/{diagram-5BDNPKRD-DwScs67g.js → diagram-5BDNPKRD-4Km3IxIT.js} +1 -1
  24. package/public/assets/{diagram-G4DWMVQ6--1gv_wcM.js → diagram-G4DWMVQ6-DD5Ucpcn.js} +1 -1
  25. package/public/assets/{diagram-MMDJMWI5-C1yHkOFA.js → diagram-MMDJMWI5-B6-WK_TJ.js} +1 -1
  26. package/public/assets/{diagram-TYMM5635-Dl7dRWkC.js → diagram-TYMM5635-CLYhOm9a.js} +1 -1
  27. package/public/assets/{erDiagram-SMLLAGMA-DLmNKAuD.js → erDiagram-SMLLAGMA-DgukEqTQ.js} +1 -1
  28. package/public/assets/{flowDiagram-DWJPFMVM-CZa_uY2_.js → flowDiagram-DWJPFMVM-DUlTxDrh.js} +1 -1
  29. package/public/assets/{ganttDiagram-T4ZO3ILL-BnT7GCzh.js → ganttDiagram-T4ZO3ILL-D5Ik9clK.js} +1 -1
  30. package/public/assets/{gitGraphDiagram-UUTBAWPF-D0of7G0H.js → gitGraphDiagram-UUTBAWPF-CouNbB0H.js} +1 -1
  31. package/public/assets/{graph-DQMLsVKn.js → graph-DY36UTy7.js} +1 -1
  32. package/public/assets/index-CwjgIG7M.js +463 -0
  33. package/public/assets/index-DWaSRzf6.css +32 -0
  34. package/public/assets/{infoDiagram-42DDH7IO-CCYTG5TW.js → infoDiagram-42DDH7IO-CTZf-XaE.js} +1 -1
  35. package/public/assets/{ishikawaDiagram-UXIWVN3A-6aQrUmM1.js → ishikawaDiagram-UXIWVN3A-DZdSiihk.js} +1 -1
  36. package/public/assets/{journeyDiagram-VCZTEJTY-CJTv8kT4.js → journeyDiagram-VCZTEJTY-Cx-gOesl.js} +1 -1
  37. package/public/assets/{kanban-definition-6JOO6SKY-BcvXQPfh.js → kanban-definition-6JOO6SKY-NjVvkzyg.js} +1 -1
  38. package/public/assets/{layout-ThSqQjtq.js → layout-Bcu4s7Ho.js} +1 -1
  39. package/public/assets/{linear-DCFOEcB6.js → linear-s0Mg7155.js} +1 -1
  40. package/public/assets/{mindmap-definition-QFDTVHPH-Bb4AuZN4.js → mindmap-definition-QFDTVHPH-DQUtHqQ6.js} +1 -1
  41. package/public/assets/{pieDiagram-DEJITSTG-DQqclfI2.js → pieDiagram-DEJITSTG-DlYgVpVr.js} +1 -1
  42. package/public/assets/{quadrantDiagram-34T5L4WZ-pb0aN3QY.js → quadrantDiagram-34T5L4WZ-DloaxY2h.js} +1 -1
  43. package/public/assets/{requirementDiagram-MS252O5E-CkL3sbnK.js → requirementDiagram-MS252O5E-fSM1Pi3V.js} +1 -1
  44. package/public/assets/{sankeyDiagram-XADWPNL6-CP6XoGCk.js → sankeyDiagram-XADWPNL6-BHPnOiHK.js} +1 -1
  45. package/public/assets/{sequenceDiagram-FGHM5R23-CoFyaUFj.js → sequenceDiagram-FGHM5R23-Dnl-W6jS.js} +1 -1
  46. package/public/assets/{stateDiagram-FHFEXIEX-WQkLynRi.js → stateDiagram-FHFEXIEX-X9kal6wR.js} +1 -1
  47. package/public/assets/stateDiagram-v2-QKLJ7IA2-C7M79J7F.js +1 -0
  48. package/public/assets/{timeline-definition-GMOUNBTQ-Dcb9ue8q.js → timeline-definition-GMOUNBTQ-C3o7gZFF.js} +1 -1
  49. package/public/assets/{vennDiagram-DHZGUBPP-KqcKNQ1-.js → vennDiagram-DHZGUBPP-DoHPigKa.js} +1 -1
  50. package/public/assets/{wardley-RL74JXVD-DmgKZSUh.js → wardley-RL74JXVD-BEjx3hAD.js} +1 -1
  51. package/public/assets/{wardleyDiagram-NUSXRM2D-4y-iyT2D.js → wardleyDiagram-NUSXRM2D-Dsy9JWUf.js} +1 -1
  52. package/public/assets/{xychartDiagram-5P7HB3ND-Bdcd_98G.js → xychartDiagram-5P7HB3ND-cd-6HXrN.js} +1 -1
  53. package/public/index.html +3 -3
  54. package/public/sw.js +1 -1
  55. package/src/cli/index.js +62 -31
  56. package/src/cli/service.js +22 -9
  57. package/src/server/routes.js +31 -0
  58. package/src/tunnel/index.js +24 -7
  59. package/src/tunnel/install.js +3 -2
  60. package/src/utils/agents.js +23 -18
  61. package/src/utils/git.js +6 -2
  62. package/src/utils/shells.js +1 -0
  63. package/src/utils/update-executor.js +14 -9
  64. package/src/utils/version.js +1 -0
  65. package/public/assets/channel-Bz1ES3Md.js +0 -1
  66. package/public/assets/classDiagram-6PBFFD2Q-C0Xsg2c2.js +0 -1
  67. package/public/assets/classDiagram-v2-HSJHXN6E-C0Xsg2c2.js +0 -1
  68. package/public/assets/clone-DTHql6BK.js +0 -1
  69. package/public/assets/index-Bp7KnjkK.js +0 -455
  70. package/public/assets/index-KBnPi8DC.css +0 -32
  71. package/public/assets/stateDiagram-v2-QKLJ7IA2-D1F0xws2.js +0 -1
package/public/sw.js CHANGED
@@ -1,2 +1,2 @@
1
1
  try{self["workbox:core:7.3.0"]&&_()}catch{}const G=(s,...e)=>{let t=s;return e.length>0&&(t+=` :: ${JSON.stringify(e)}`),t},Q=G;class h extends Error{constructor(e,t){const n=Q(e,t);super(n),this.name=e,this.details=t}}const d={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:typeof registration<"u"?registration.scope:""},E=s=>[d.prefix,s,d.suffix].filter(e=>e&&e.length>0).join("-"),z=s=>{for(const e of Object.keys(d))s(e)},b={updateDetails:s=>{z(e=>{typeof s[e]=="string"&&(d[e]=s[e])})},getGoogleAnalyticsName:s=>s||E(d.googleAnalytics),getPrecacheName:s=>s||E(d.precache),getPrefix:()=>d.prefix,getRuntimeName:s=>s||E(d.runtime),getSuffix:()=>d.suffix};function v(s,e){const t=e();return s.waitUntil(t),t}try{self["workbox:precaching:7.3.0"]&&_()}catch{}const J="__WB_REVISION__";function X(s){if(!s)throw new h("add-to-cache-list-unexpected-type",{entry:s});if(typeof s=="string"){const i=new URL(s,location.href);return{cacheKey:i.href,url:i.href}}const{revision:e,url:t}=s;if(!t)throw new h("add-to-cache-list-unexpected-type",{entry:s});if(!e){const i=new URL(t,location.href);return{cacheKey:i.href,url:i.href}}const n=new URL(t,location.href),a=new URL(t,location.href);return n.searchParams.set(J,e),{cacheKey:n.href,url:a.href}}class Y{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){const a=t.originalRequest.url;n?this.notUpdatedURLs.push(a):this.updatedURLs.push(a)}return n}}}class Z{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:t,params:n})=>{const a=(n==null?void 0:n.cacheKey)||this._precacheController.getCacheKeyForURL(t.url);return a?new Request(a,{headers:t.headers}):t},this._precacheController=e}}let m;function ee(){if(m===void 0){const s=new Response("");if("body"in s)try{new Response(s.body),m=!0}catch{m=!1}m=!1}return m}async function te(s,e){let t=null;if(s.url&&(t=new URL(s.url).origin),t!==self.location.origin)throw new h("cross-origin-copy-response",{origin:t});const n=s.clone(),i={headers:new Headers(n.headers),status:n.status,statusText:n.statusText},r=ee()?n.body:await n.blob();return new Response(r,i)}const se=s=>new URL(String(s),location.href).href.replace(new RegExp(`^${location.origin}`),"");function M(s,e){const t=new URL(s);for(const n of e)t.searchParams.delete(n);return t.href}async function ne(s,e,t,n){const a=M(e.url,t);if(e.url===a)return s.match(e,n);const i=Object.assign(Object.assign({},n),{ignoreSearch:!0}),r=await s.keys(e,i);for(const c of r){const o=M(c.url,t);if(a===o)return s.match(c,n)}}class ae{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}}const B=new Set;async function ie(){for(const s of B)await s()}function re(s){return new Promise(e=>setTimeout(e,s))}try{self["workbox:strategies:7.3.0"]&&_()}catch{}function C(s){return typeof s=="string"?new Request(s):s}class ce{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new ae,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(const n of this._plugins)this._pluginStateMap.set(n,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){const{event:t}=this;let n=C(e);if(n.mode==="navigate"&&t instanceof FetchEvent&&t.preloadResponse){const r=await t.preloadResponse;if(r)return r}const a=this.hasCallback("fetchDidFail")?n.clone():null;try{for(const r of this.iterateCallbacks("requestWillFetch"))n=await r({request:n.clone(),event:t})}catch(r){if(r instanceof Error)throw new h("plugin-error-request-will-fetch",{thrownErrorMessage:r.message})}const i=n.clone();try{let r;r=await fetch(n,n.mode==="navigate"?void 0:this._strategy.fetchOptions);for(const c of this.iterateCallbacks("fetchDidSucceed"))r=await c({event:t,request:i,response:r});return r}catch(r){throw a&&await this.runCallbacks("fetchDidFail",{error:r,event:t,originalRequest:a.clone(),request:i.clone()}),r}}async fetchAndCachePut(e){const t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){const t=C(e);let n;const{cacheName:a,matchOptions:i}=this._strategy,r=await this.getCacheKey(t,"read"),c=Object.assign(Object.assign({},i),{cacheName:a});n=await caches.match(r,c);for(const o of this.iterateCallbacks("cachedResponseWillBeUsed"))n=await o({cacheName:a,matchOptions:i,cachedResponse:n,request:r,event:this.event})||void 0;return n}async cachePut(e,t){const n=C(e);await re(0);const a=await this.getCacheKey(n,"write");if(!t)throw new h("cache-put-with-no-response",{url:se(a.url)});const i=await this._ensureResponseSafeToCache(t);if(!i)return!1;const{cacheName:r,matchOptions:c}=this._strategy,o=await self.caches.open(r),l=this.hasCallback("cacheDidUpdate"),g=l?await ne(o,a.clone(),["__WB_REVISION__"],c):null;try{await o.put(a,l?i.clone():i)}catch(u){if(u instanceof Error)throw u.name==="QuotaExceededError"&&await ie(),u}for(const u of this.iterateCallbacks("cacheDidUpdate"))await u({cacheName:r,oldResponse:g,newResponse:i.clone(),request:a,event:this.event});return!0}async getCacheKey(e,t){const n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let a=e;for(const i of this.iterateCallbacks("cacheKeyWillBeUsed"))a=C(await i({mode:t,request:a,event:this.event,params:this.params}));this._cacheKeys[n]=a}return this._cacheKeys[n]}hasCallback(e){for(const t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(const n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(const t of this._strategy.plugins)if(typeof t[e]=="function"){const n=this._pluginStateMap.get(t);yield i=>{const r=Object.assign(Object.assign({},i),{state:n});return t[e](r)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){const e=this._extendLifetimePromises.splice(0),n=(await Promise.allSettled(e)).find(a=>a.status==="rejected");if(n)throw n.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(const a of this.iterateCallbacks("cacheWillUpdate"))if(t=await a({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}}class W{constructor(e={}){this.cacheName=b.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){const[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});const t=e.event,n=typeof e.request=="string"?new Request(e.request):e.request,a="params"in e?e.params:void 0,i=new ce(this,{event:t,request:n,params:a}),r=this._getResponse(i,n,t),c=this._awaitComplete(r,i,n,t);return[r,c]}async _getResponse(e,t,n){await e.runCallbacks("handlerWillStart",{event:n,request:t});let a;try{if(a=await this._handle(t,e),!a||a.type==="error")throw new h("no-response",{url:t.url})}catch(i){if(i instanceof Error){for(const r of e.iterateCallbacks("handlerDidError"))if(a=await r({error:i,event:n,request:t}),a)break}if(!a)throw i}for(const i of e.iterateCallbacks("handlerWillRespond"))a=await i({event:n,request:t,response:a});return a}async _awaitComplete(e,t,n,a){let i,r;try{i=await e}catch{}try{await t.runCallbacks("handlerDidRespond",{event:a,request:n,response:i}),await t.doneWaiting()}catch(c){c instanceof Error&&(r=c)}if(await t.runCallbacks("handlerDidComplete",{event:a,request:n,response:i,error:r}),t.destroy(),r)throw r}}class p extends W{constructor(e={}){e.cacheName=b.getPrecacheName(e.cacheName),super(e),this._fallbackToNetwork=e.fallbackToNetwork!==!1,this.plugins.push(p.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){const n=await t.cacheMatch(e);return n||(t.event&&t.event.type==="install"?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,t){let n;const a=t.params||{};if(this._fallbackToNetwork){const i=a.integrity,r=e.integrity,c=!r||r===i;n=await t.fetch(new Request(e,{integrity:e.mode!=="no-cors"?r||i:void 0})),i&&c&&e.mode!=="no-cors"&&(this._useDefaultCacheabilityPluginIfNeeded(),await t.cachePut(e,n.clone()))}else throw new h("missing-precache-entry",{cacheName:this.cacheName,url:e.url});return n}async _handleInstall(e,t){this._useDefaultCacheabilityPluginIfNeeded();const n=await t.fetch(e);if(!await t.cachePut(e,n.clone()))throw new h("bad-precaching-response",{url:e.url,status:n.status});return n}_useDefaultCacheabilityPluginIfNeeded(){let e=null,t=0;for(const[n,a]of this.plugins.entries())a!==p.copyRedirectedCacheableResponsesPlugin&&(a===p.defaultPrecacheCacheabilityPlugin&&(e=n),a.cacheWillUpdate&&t++);t===0?this.plugins.push(p.defaultPrecacheCacheabilityPlugin):t>1&&e!==null&&this.plugins.splice(e,1)}}p.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:s}){return!s||s.status>=400?null:s}};p.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:s}){return s.redirected?await te(s):s}};class oe{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new p({cacheName:b.getPrecacheName(e),plugins:[...t,new Z({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),this._installAndActiveListenersAdded=!0)}addToCacheList(e){const t=[];for(const n of e){typeof n=="string"?t.push(n):n&&n.revision===void 0&&t.push(n.url);const{cacheKey:a,url:i}=X(n),r=typeof n!="string"&&n.revision?"reload":"default";if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==a)throw new h("add-to-cache-list-conflicting-entries",{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:a});if(typeof n!="string"&&n.integrity){if(this._cacheKeysToIntegrities.has(a)&&this._cacheKeysToIntegrities.get(a)!==n.integrity)throw new h("add-to-cache-list-conflicting-integrities",{url:i});this._cacheKeysToIntegrities.set(a,n.integrity)}if(this._urlsToCacheKeys.set(i,a),this._urlsToCacheModes.set(i,r),t.length>0){const c=`Workbox is precaching URLs without revision info: ${t.join(", ")}
2
- This is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(c)}}}install(e){return v(e,async()=>{const t=new Y;this.strategy.plugins.push(t);for(const[i,r]of this._urlsToCacheKeys){const c=this._cacheKeysToIntegrities.get(r),o=this._urlsToCacheModes.get(i),l=new Request(i,{integrity:c,cache:o,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:r},request:l,event:e}))}const{updatedURLs:n,notUpdatedURLs:a}=t;return{updatedURLs:n,notUpdatedURLs:a}})}activate(e){return v(e,async()=>{const t=await self.caches.open(this.strategy.cacheName),n=await t.keys(),a=new Set(this._urlsToCacheKeys.values()),i=[];for(const r of n)a.has(r.url)||(await t.delete(r),i.push(r.url));return{deletedURLs:i}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){const t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){const 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){const t=this.getCacheKeyForURL(e);if(!t)throw new h("non-precached-url",{url:e});return n=>(n.request=new Request(e),n.params=Object.assign({cacheKey:t},n.params),this.strategy.handle(n))}}let D;const j=()=>(D||(D=new oe),D);try{self["workbox:routing:7.3.0"]&&_()}catch{}const F="GET",x=s=>s&&typeof s=="object"?s:{handle:s};class R{constructor(e,t,n=F){this.handler=x(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=x(e)}}class le extends R{constructor(e,t,n){const a=({url:i})=>{const r=e.exec(i.href);if(r&&!(i.origin!==location.origin&&r.index!==0))return r.slice(1)};super(a,t,n)}}class he{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener("fetch",(e=>{const{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"){const{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(a=>{typeof a=="string"&&(a=[a]);const i=new Request(...a);return this.handleRequest({request:i,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){const n=new URL(e.url,location.href);if(!n.protocol.startsWith("http"))return;const a=n.origin===location.origin,{params:i,route:r}=this.findMatchingRoute({event:t,request:e,sameOrigin:a,url:n});let c=r&&r.handler;const o=e.method;if(!c&&this._defaultHandlerMap.has(o)&&(c=this._defaultHandlerMap.get(o)),!c)return;let l;try{l=c.handle({url:n,request:e,event:t,params:i})}catch(u){l=Promise.reject(u)}const g=r&&r.catchHandler;return l instanceof Promise&&(this._catchHandler||g)&&(l=l.catch(async u=>{if(g)try{return await g.handle({url:n,request:e,event:t,params:i})}catch(N){N instanceof Error&&(u=N)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw u})),l}findMatchingRoute({url:e,sameOrigin:t,request:n,event:a}){const i=this._routes.get(n.method)||[];for(const r of i){let c;const o=r.match({url:e,sameOrigin:t,request:n,event:a});if(o)return c=o,(Array.isArray(c)&&c.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o=="boolean")&&(c=void 0),{route:r,params:c}}return{}}setDefaultHandler(e,t=F){this._defaultHandlerMap.set(t,x(e))}setCatchHandler(e){this._catchHandler=x(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 h("unregister-route-but-not-found-with-method",{method:e.method});const t=this._routes.get(e.method).indexOf(e);if(t>-1)this._routes.get(e.method).splice(t,1);else throw new h("unregister-route-route-not-registered")}}let y;const ue=()=>(y||(y=new he,y.addFetchListener(),y.addCacheListener()),y);function q(s,e,t){let n;if(typeof s=="string"){const i=new URL(s,location.href),r=({url:c})=>c.href===i.href;n=new R(r,e,t)}else if(s instanceof RegExp)n=new le(s,e,t);else if(typeof s=="function")n=new R(s,e,t);else if(s instanceof R)n=s;else throw new h("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});return ue().registerRoute(n),n}function de(s,e=[]){for(const t of[...s.searchParams.keys()])e.some(n=>n.test(t))&&s.searchParams.delete(t);return s}function*fe(s,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:t="index.html",cleanURLs:n=!0,urlManipulation:a}={}){const i=new URL(s,location.href);i.hash="",yield i.href;const r=de(i,e);if(yield r.href,t&&r.pathname.endsWith("/")){const c=new URL(r.href);c.pathname+=t,yield c.href}if(n){const c=new URL(r.href);c.pathname+=".html",yield c.href}if(a){const c=a({url:i});for(const o of c)yield o.href}}class pe extends R{constructor(e,t){const n=({request:a})=>{const i=e.getURLsToCacheKeys();for(const r of fe(a.url,t)){const c=i.get(r);if(c){const o=e.getIntegrityForCacheKey(c);return{cacheKey:c,integrity:o}}}};super(n,e.strategy)}}function ge(s){const e=j(),t=new pe(e,s);q(t)}const me="-precache-",ye=async(s,e=me)=>{const n=(await self.caches.keys()).filter(a=>a.includes(e)&&a.includes(self.registration.scope)&&a!==s);return await Promise.all(n.map(a=>self.caches.delete(a))),n};function we(){self.addEventListener("activate",(s=>{const e=b.getPrecacheName();s.waitUntil(ye(e).then(t=>{}))}))}function _e(s){j().precache(s)}function Re(s,e){_e(s),ge(e)}class be extends W{async _handle(e,t){let n=await t.cacheMatch(e),a;if(!n)try{n=await t.fetchAndCachePut(e)}catch(i){i instanceof Error&&(a=i)}if(!n)throw new h("no-response",{url:e.url,error:a});return n}}function H(s){s.then(()=>{})}const Ce=(s,e)=>e.some(t=>s instanceof t);let A,K;function xe(){return A||(A=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])}function Ee(){return K||(K=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])}const V=new WeakMap,k=new WeakMap,$=new WeakMap,L=new WeakMap,P=new WeakMap;function De(s){const e=new Promise((t,n)=>{const a=()=>{s.removeEventListener("success",i),s.removeEventListener("error",r)},i=()=>{t(f(s.result)),a()},r=()=>{n(s.error),a()};s.addEventListener("success",i),s.addEventListener("error",r)});return e.then(t=>{t instanceof IDBCursor&&V.set(t,s)}).catch(()=>{}),P.set(e,s),e}function Le(s){if(k.has(s))return;const e=new Promise((t,n)=>{const a=()=>{s.removeEventListener("complete",i),s.removeEventListener("error",r),s.removeEventListener("abort",r)},i=()=>{t(),a()},r=()=>{n(s.error||new DOMException("AbortError","AbortError")),a()};s.addEventListener("complete",i),s.addEventListener("error",r),s.addEventListener("abort",r)});k.set(s,e)}let I={get(s,e,t){if(s instanceof IDBTransaction){if(e==="done")return k.get(s);if(e==="objectStoreNames")return s.objectStoreNames||$.get(s);if(e==="store")return t.objectStoreNames[1]?void 0:t.objectStore(t.objectStoreNames[0])}return f(s[e])},set(s,e,t){return s[e]=t,!0},has(s,e){return s instanceof IDBTransaction&&(e==="done"||e==="store")?!0:e in s}};function Ue(s){I=s(I)}function Te(s){return s===IDBDatabase.prototype.transaction&&!("objectStoreNames"in IDBTransaction.prototype)?function(e,...t){const n=s.call(U(this),e,...t);return $.set(n,e.sort?e.sort():[e]),f(n)}:Ee().includes(s)?function(...e){return s.apply(U(this),e),f(V.get(this))}:function(...e){return f(s.apply(U(this),e))}}function ke(s){return typeof s=="function"?Te(s):(s instanceof IDBTransaction&&Le(s),Ce(s,xe())?new Proxy(s,I):s)}function f(s){if(s instanceof IDBRequest)return De(s);if(L.has(s))return L.get(s);const e=ke(s);return e!==s&&(L.set(s,e),P.set(e,s)),e}const U=s=>P.get(s);function Ie(s,e,{blocked:t,upgrade:n,blocking:a,terminated:i}={}){const r=indexedDB.open(s,e),c=f(r);return n&&r.addEventListener("upgradeneeded",o=>{n(f(r.result),o.oldVersion,o.newVersion,f(r.transaction),o)}),t&&r.addEventListener("blocked",o=>t(o.oldVersion,o.newVersion,o)),c.then(o=>{i&&o.addEventListener("close",()=>i()),a&&o.addEventListener("versionchange",l=>a(l.oldVersion,l.newVersion,l))}).catch(()=>{}),c}function Pe(s,{blocked:e}={}){const t=indexedDB.deleteDatabase(s);return e&&t.addEventListener("blocked",n=>e(n.oldVersion,n)),f(t).then(()=>{})}const Ne=["get","getKey","getAll","getAllKeys","count"],ve=["put","add","delete","clear"],T=new Map;function O(s,e){if(!(s instanceof IDBDatabase&&!(e in s)&&typeof e=="string"))return;if(T.get(e))return T.get(e);const t=e.replace(/FromIndex$/,""),n=e!==t,a=ve.includes(t);if(!(t in(n?IDBIndex:IDBObjectStore).prototype)||!(a||Ne.includes(t)))return;const i=async function(r,...c){const o=this.transaction(r,a?"readwrite":"readonly");let l=o.store;return n&&(l=l.index(c.shift())),(await Promise.all([l[t](...c),a&&o.done]))[0]};return T.set(e,i),i}Ue(s=>({...s,get:(e,t,n)=>O(e,t)||s.get(e,t,n),has:(e,t)=>!!O(e,t)||s.has(e,t)}));try{self["workbox:expiration:7.3.0"]&&_()}catch{}const Me="workbox-expiration",w="cache-entries",S=s=>{const e=new URL(s,location.href);return e.hash="",e.href};class Ae{constructor(e){this._db=null,this._cacheName=e}_upgradeDb(e){const t=e.createObjectStore(w,{keyPath:"id"});t.createIndex("cacheName","cacheName",{unique:!1}),t.createIndex("timestamp","timestamp",{unique:!1})}_upgradeDbAndDeleteOldDbs(e){this._upgradeDb(e),this._cacheName&&Pe(this._cacheName)}async setTimestamp(e,t){e=S(e);const n={url:e,timestamp:t,cacheName:this._cacheName,id:this._getId(e)},i=(await this.getDb()).transaction(w,"readwrite",{durability:"relaxed"});await i.store.put(n),await i.done}async getTimestamp(e){const n=await(await this.getDb()).get(w,this._getId(e));return n==null?void 0:n.timestamp}async expireEntries(e,t){const n=await this.getDb();let a=await n.transaction(w).store.index("timestamp").openCursor(null,"prev");const i=[];let r=0;for(;a;){const o=a.value;o.cacheName===this._cacheName&&(e&&o.timestamp<e||t&&r>=t?i.push(a.value):r++),a=await a.continue()}const c=[];for(const o of i)await n.delete(w,o.id),c.push(o.url);return c}_getId(e){return this._cacheName+"|"+S(e)}async getDb(){return this._db||(this._db=await Ie(Me,1,{upgrade:this._upgradeDbAndDeleteOldDbs.bind(this)})),this._db}}class Ke{constructor(e,t={}){this._isRunning=!1,this._rerunRequested=!1,this._maxEntries=t.maxEntries,this._maxAgeSeconds=t.maxAgeSeconds,this._matchOptions=t.matchOptions,this._cacheName=e,this._timestampModel=new Ae(e)}async expireEntries(){if(this._isRunning){this._rerunRequested=!0;return}this._isRunning=!0;const e=this._maxAgeSeconds?Date.now()-this._maxAgeSeconds*1e3:0,t=await this._timestampModel.expireEntries(e,this._maxEntries),n=await self.caches.open(this._cacheName);for(const a of t)await n.delete(a,this._matchOptions);this._isRunning=!1,this._rerunRequested&&(this._rerunRequested=!1,H(this.expireEntries()))}async updateTimestamp(e){await this._timestampModel.setTimestamp(e,Date.now())}async isURLExpired(e){if(this._maxAgeSeconds){const t=await this._timestampModel.getTimestamp(e),n=Date.now()-this._maxAgeSeconds*1e3;return t!==void 0?t<n:!0}else return!1}async delete(){this._rerunRequested=!1,await this._timestampModel.expireEntries(1/0)}}function Oe(s){B.add(s)}class Se{constructor(e={}){this.cachedResponseWillBeUsed=async({event:t,request:n,cacheName:a,cachedResponse:i})=>{if(!i)return null;const r=this._isResponseDateFresh(i),c=this._getCacheExpiration(a);H(c.expireEntries());const o=c.updateTimestamp(n.url);if(t)try{t.waitUntil(o)}catch{}return r?i:null},this.cacheDidUpdate=async({cacheName:t,request:n})=>{const a=this._getCacheExpiration(t);await a.updateTimestamp(n.url),await a.expireEntries()},this._config=e,this._maxAgeSeconds=e.maxAgeSeconds,this._cacheExpirations=new Map,e.purgeOnQuotaError&&Oe(()=>this.deleteCacheAndMetadata())}_getCacheExpiration(e){if(e===b.getRuntimeName())throw new h("expire-custom-caches-only");let t=this._cacheExpirations.get(e);return t||(t=new Ke(e,this._config),this._cacheExpirations.set(e,t)),t}_isResponseDateFresh(e){if(!this._maxAgeSeconds)return!0;const t=this._getDateHeaderTimestamp(e);if(t===null)return!0;const n=Date.now();return t>=n-this._maxAgeSeconds*1e3}_getDateHeaderTimestamp(e){if(!e.headers.has("date"))return null;const t=e.headers.get("date"),a=new Date(t).getTime();return isNaN(a)?null:a}async deleteCacheAndMetadata(){for(const[e,t]of this._cacheExpirations)await self.caches.delete(e),await t.delete();this._cacheExpirations=new Map}}Re([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"0f93805414c783a30b72e0ce88f2c7c4","url":"icons/icon.svg"},{"revision":"5dee5ddcd8e8533edb348118334d9756","url":"icons/icon-512.png"},{"revision":"75734e6b38a556148f51b9e10eeb01c8","url":"icons/icon-192.png"},{"revision":"0362e0eb00358646fd4c97674945adba","url":"icons/icon-180.png"},{"revision":null,"url":"assets/xychartDiagram-5P7HB3ND-Bdcd_98G.js"},{"revision":null,"url":"assets/wardleyDiagram-NUSXRM2D-4y-iyT2D.js"},{"revision":null,"url":"assets/wardley-RL74JXVD-DmgKZSUh.js"},{"revision":null,"url":"assets/vennDiagram-DHZGUBPP-KqcKNQ1-.js"},{"revision":null,"url":"assets/timeline-definition-GMOUNBTQ-Dcb9ue8q.js"},{"revision":null,"url":"assets/stateDiagram-v2-QKLJ7IA2-D1F0xws2.js"},{"revision":null,"url":"assets/stateDiagram-FHFEXIEX-WQkLynRi.js"},{"revision":null,"url":"assets/sequenceDiagram-FGHM5R23-CoFyaUFj.js"},{"revision":null,"url":"assets/sankeyDiagram-XADWPNL6-CP6XoGCk.js"},{"revision":null,"url":"assets/requirementDiagram-MS252O5E-CkL3sbnK.js"},{"revision":null,"url":"assets/quadrantDiagram-34T5L4WZ-pb0aN3QY.js"},{"revision":null,"url":"assets/pieDiagram-DEJITSTG-DQqclfI2.js"},{"revision":null,"url":"assets/ordinal-Cboi1Yqb.js"},{"revision":null,"url":"assets/mindmap-definition-QFDTVHPH-Bb4AuZN4.js"},{"revision":null,"url":"assets/linear-DCFOEcB6.js"},{"revision":null,"url":"assets/layout-ThSqQjtq.js"},{"revision":null,"url":"assets/katex-B1X10hvy.js"},{"revision":null,"url":"assets/kanban-definition-6JOO6SKY-BcvXQPfh.js"},{"revision":null,"url":"assets/journeyDiagram-VCZTEJTY-CJTv8kT4.js"},{"revision":null,"url":"assets/ishikawaDiagram-UXIWVN3A-6aQrUmM1.js"},{"revision":null,"url":"assets/init-Gi6I4Gst.js"},{"revision":null,"url":"assets/infoDiagram-42DDH7IO-CCYTG5TW.js"},{"revision":null,"url":"assets/index-KBnPi8DC.css"},{"revision":null,"url":"assets/index-Bp7KnjkK.js"},{"revision":null,"url":"assets/graph-DQMLsVKn.js"},{"revision":null,"url":"assets/gitGraphDiagram-UUTBAWPF-D0of7G0H.js"},{"revision":null,"url":"assets/ganttDiagram-T4ZO3ILL-BnT7GCzh.js"},{"revision":null,"url":"assets/flowDiagram-DWJPFMVM-CZa_uY2_.js"},{"revision":null,"url":"assets/erDiagram-SMLLAGMA-DLmNKAuD.js"},{"revision":null,"url":"assets/diagram-TYMM5635-Dl7dRWkC.js"},{"revision":null,"url":"assets/diagram-MMDJMWI5-C1yHkOFA.js"},{"revision":null,"url":"assets/diagram-G4DWMVQ6--1gv_wcM.js"},{"revision":null,"url":"assets/diagram-5BDNPKRD-DwScs67g.js"},{"revision":null,"url":"assets/defaultLocale-DX6XiGOO.js"},{"revision":null,"url":"assets/dagre-KV5264BT-BbosVmxG.js"},{"revision":null,"url":"assets/cytoscape.esm-BQaXIfA_.js"},{"revision":null,"url":"assets/cose-bilkent-S5V4N54A-B2XXKALr.js"},{"revision":null,"url":"assets/clone-DTHql6BK.js"},{"revision":null,"url":"assets/classDiagram-v2-HSJHXN6E-C0Xsg2c2.js"},{"revision":null,"url":"assets/classDiagram-6PBFFD2Q-C0Xsg2c2.js"},{"revision":null,"url":"assets/chunk-YZCP3GAM-B2BkSOHZ.js"},{"revision":null,"url":"assets/chunk-QZHKN3VN-JqEPJ-I8.js"},{"revision":null,"url":"assets/chunk-OYMX7WX6-Nt-YAKKo.js"},{"revision":null,"url":"assets/chunk-FMBD7UC4-CL6X-Bgf.js"},{"revision":null,"url":"assets/chunk-EDXVE4YY-CwJdMkPT.js"},{"revision":null,"url":"assets/chunk-55IACEB6-CCtV1y23.js"},{"revision":null,"url":"assets/chunk-4TB4RGXK-D1SjwnL0.js"},{"revision":null,"url":"assets/chunk-4BX2VUAB-CxYOWomN.js"},{"revision":null,"url":"assets/channel-Bz1ES3Md.js"},{"revision":null,"url":"assets/c4Diagram-AHTNJAMY-BwE7ZnCD.js"},{"revision":null,"url":"assets/blockDiagram-DXYQGD6D-BcStipzf.js"},{"revision":null,"url":"assets/architectureDiagram-Q4EWVU46-D_3Wy2pQ.js"},{"revision":null,"url":"assets/arc-DmuNthMW.js"},{"revision":null,"url":"assets/_baseUniq-DaY_Bc3O.js"},{"revision":null,"url":"assets/_basePickBy-BLefhu0l.js"},{"revision":"0362e0eb00358646fd4c97674945adba","url":"icons/icon-180.png"},{"revision":"75734e6b38a556148f51b9e10eeb01c8","url":"icons/icon-192.png"},{"revision":"5dee5ddcd8e8533edb348118334d9756","url":"icons/icon-512.png"},{"revision":"b0747e8d6cde0d45e05be8e5c731729e","url":"manifest.webmanifest"}]);we();q(({url:s})=>s.hostname==="cdn.jsdelivr.net"&&s.pathname.endsWith(".ttf"),new be({cacheName:"termbeam-fonts",plugins:[new Se({maxEntries:5,maxAgeSeconds:365*24*60*60})]}));self.addEventListener("message",s=>{var e;((e=s.data)==null?void 0:e.type)==="CLEAR_CACHES"&&caches.keys().then(t=>{for(const n of t)n!=="workbox-precache-v2"&&caches.delete(n)})});self.addEventListener("install",()=>{self.skipWaiting()});self.addEventListener("activate",s=>{s.waitUntil(caches.delete("termbeam-navigation").then(()=>self.clients.claim()))});self.addEventListener("push",s=>{let e={title:"Command finished",body:"TermBeam"};if(s.data)try{e=s.data.json()}catch{}s.waitUntil(self.clients.matchAll({type:"window",includeUncontrolled:!0}).then(async t=>{if(t.some(i=>i.url.includes(self.location.origin)&&i.focused))return;const a={body:e.body||"A command has completed",icon:"/icons/icon-192.png",badge:"/icons/icon-192.png",tag:e.tag||"termbeam-cmd",renotify:!0,data:{url:e.url||"/",type:e.type||"command-complete",sessionId:e.sessionId},vibrate:[200,100,200]};try{await self.navigator.setAppBadge(1)}catch{}return self.registration.showNotification(e.title||"Command finished",a)}))});self.addEventListener("notificationclick",s=>{s.notification.close();try{self.navigator.clearAppBadge()}catch{}const e=s.notification.data||{},t=e.url||"/",n=e.type||"";s.waitUntil(self.clients.matchAll({type:"window",includeUncontrolled:!0}).then(a=>{for(const i of a)if(i.url.includes(self.location.origin)&&"focus"in i)return n&&i.postMessage({type:"NOTIFICATION_CLICKED",notificationType:n,sessionId:e.sessionId}),i.focus();return self.clients.openWindow(t)}))});
2
+ This is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(c)}}}install(e){return v(e,async()=>{const t=new Y;this.strategy.plugins.push(t);for(const[i,r]of this._urlsToCacheKeys){const c=this._cacheKeysToIntegrities.get(r),o=this._urlsToCacheModes.get(i),l=new Request(i,{integrity:c,cache:o,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:r},request:l,event:e}))}const{updatedURLs:n,notUpdatedURLs:a}=t;return{updatedURLs:n,notUpdatedURLs:a}})}activate(e){return v(e,async()=>{const t=await self.caches.open(this.strategy.cacheName),n=await t.keys(),a=new Set(this._urlsToCacheKeys.values()),i=[];for(const r of n)a.has(r.url)||(await t.delete(r),i.push(r.url));return{deletedURLs:i}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){const t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){const 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){const t=this.getCacheKeyForURL(e);if(!t)throw new h("non-precached-url",{url:e});return n=>(n.request=new Request(e),n.params=Object.assign({cacheKey:t},n.params),this.strategy.handle(n))}}let D;const j=()=>(D||(D=new oe),D);try{self["workbox:routing:7.3.0"]&&_()}catch{}const F="GET",x=s=>s&&typeof s=="object"?s:{handle:s};class R{constructor(e,t,n=F){this.handler=x(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=x(e)}}class le extends R{constructor(e,t,n){const a=({url:i})=>{const r=e.exec(i.href);if(r&&!(i.origin!==location.origin&&r.index!==0))return r.slice(1)};super(a,t,n)}}class he{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener("fetch",(e=>{const{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"){const{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(a=>{typeof a=="string"&&(a=[a]);const i=new Request(...a);return this.handleRequest({request:i,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){const n=new URL(e.url,location.href);if(!n.protocol.startsWith("http"))return;const a=n.origin===location.origin,{params:i,route:r}=this.findMatchingRoute({event:t,request:e,sameOrigin:a,url:n});let c=r&&r.handler;const o=e.method;if(!c&&this._defaultHandlerMap.has(o)&&(c=this._defaultHandlerMap.get(o)),!c)return;let l;try{l=c.handle({url:n,request:e,event:t,params:i})}catch(u){l=Promise.reject(u)}const g=r&&r.catchHandler;return l instanceof Promise&&(this._catchHandler||g)&&(l=l.catch(async u=>{if(g)try{return await g.handle({url:n,request:e,event:t,params:i})}catch(N){N instanceof Error&&(u=N)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw u})),l}findMatchingRoute({url:e,sameOrigin:t,request:n,event:a}){const i=this._routes.get(n.method)||[];for(const r of i){let c;const o=r.match({url:e,sameOrigin:t,request:n,event:a});if(o)return c=o,(Array.isArray(c)&&c.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o=="boolean")&&(c=void 0),{route:r,params:c}}return{}}setDefaultHandler(e,t=F){this._defaultHandlerMap.set(t,x(e))}setCatchHandler(e){this._catchHandler=x(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 h("unregister-route-but-not-found-with-method",{method:e.method});const t=this._routes.get(e.method).indexOf(e);if(t>-1)this._routes.get(e.method).splice(t,1);else throw new h("unregister-route-route-not-registered")}}let y;const ue=()=>(y||(y=new he,y.addFetchListener(),y.addCacheListener()),y);function q(s,e,t){let n;if(typeof s=="string"){const i=new URL(s,location.href),r=({url:c})=>c.href===i.href;n=new R(r,e,t)}else if(s instanceof RegExp)n=new le(s,e,t);else if(typeof s=="function")n=new R(s,e,t);else if(s instanceof R)n=s;else throw new h("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});return ue().registerRoute(n),n}function de(s,e=[]){for(const t of[...s.searchParams.keys()])e.some(n=>n.test(t))&&s.searchParams.delete(t);return s}function*fe(s,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:t="index.html",cleanURLs:n=!0,urlManipulation:a}={}){const i=new URL(s,location.href);i.hash="",yield i.href;const r=de(i,e);if(yield r.href,t&&r.pathname.endsWith("/")){const c=new URL(r.href);c.pathname+=t,yield c.href}if(n){const c=new URL(r.href);c.pathname+=".html",yield c.href}if(a){const c=a({url:i});for(const o of c)yield o.href}}class pe extends R{constructor(e,t){const n=({request:a})=>{const i=e.getURLsToCacheKeys();for(const r of fe(a.url,t)){const c=i.get(r);if(c){const o=e.getIntegrityForCacheKey(c);return{cacheKey:c,integrity:o}}}};super(n,e.strategy)}}function ge(s){const e=j(),t=new pe(e,s);q(t)}const me="-precache-",ye=async(s,e=me)=>{const n=(await self.caches.keys()).filter(a=>a.includes(e)&&a.includes(self.registration.scope)&&a!==s);return await Promise.all(n.map(a=>self.caches.delete(a))),n};function we(){self.addEventListener("activate",(s=>{const e=b.getPrecacheName();s.waitUntil(ye(e).then(t=>{}))}))}function _e(s){j().precache(s)}function Re(s,e){_e(s),ge(e)}class be extends W{async _handle(e,t){let n=await t.cacheMatch(e),a;if(!n)try{n=await t.fetchAndCachePut(e)}catch(i){i instanceof Error&&(a=i)}if(!n)throw new h("no-response",{url:e.url,error:a});return n}}function H(s){s.then(()=>{})}const Ce=(s,e)=>e.some(t=>s instanceof t);let A,K;function xe(){return A||(A=[IDBDatabase,IDBObjectStore,IDBIndex,IDBCursor,IDBTransaction])}function Ee(){return K||(K=[IDBCursor.prototype.advance,IDBCursor.prototype.continue,IDBCursor.prototype.continuePrimaryKey])}const V=new WeakMap,k=new WeakMap,$=new WeakMap,L=new WeakMap,P=new WeakMap;function De(s){const e=new Promise((t,n)=>{const a=()=>{s.removeEventListener("success",i),s.removeEventListener("error",r)},i=()=>{t(f(s.result)),a()},r=()=>{n(s.error),a()};s.addEventListener("success",i),s.addEventListener("error",r)});return e.then(t=>{t instanceof IDBCursor&&V.set(t,s)}).catch(()=>{}),P.set(e,s),e}function Le(s){if(k.has(s))return;const e=new Promise((t,n)=>{const a=()=>{s.removeEventListener("complete",i),s.removeEventListener("error",r),s.removeEventListener("abort",r)},i=()=>{t(),a()},r=()=>{n(s.error||new DOMException("AbortError","AbortError")),a()};s.addEventListener("complete",i),s.addEventListener("error",r),s.addEventListener("abort",r)});k.set(s,e)}let I={get(s,e,t){if(s instanceof IDBTransaction){if(e==="done")return k.get(s);if(e==="objectStoreNames")return s.objectStoreNames||$.get(s);if(e==="store")return t.objectStoreNames[1]?void 0:t.objectStore(t.objectStoreNames[0])}return f(s[e])},set(s,e,t){return s[e]=t,!0},has(s,e){return s instanceof IDBTransaction&&(e==="done"||e==="store")?!0:e in s}};function Ue(s){I=s(I)}function Te(s){return s===IDBDatabase.prototype.transaction&&!("objectStoreNames"in IDBTransaction.prototype)?function(e,...t){const n=s.call(U(this),e,...t);return $.set(n,e.sort?e.sort():[e]),f(n)}:Ee().includes(s)?function(...e){return s.apply(U(this),e),f(V.get(this))}:function(...e){return f(s.apply(U(this),e))}}function ke(s){return typeof s=="function"?Te(s):(s instanceof IDBTransaction&&Le(s),Ce(s,xe())?new Proxy(s,I):s)}function f(s){if(s instanceof IDBRequest)return De(s);if(L.has(s))return L.get(s);const e=ke(s);return e!==s&&(L.set(s,e),P.set(e,s)),e}const U=s=>P.get(s);function Ie(s,e,{blocked:t,upgrade:n,blocking:a,terminated:i}={}){const r=indexedDB.open(s,e),c=f(r);return n&&r.addEventListener("upgradeneeded",o=>{n(f(r.result),o.oldVersion,o.newVersion,f(r.transaction),o)}),t&&r.addEventListener("blocked",o=>t(o.oldVersion,o.newVersion,o)),c.then(o=>{i&&o.addEventListener("close",()=>i()),a&&o.addEventListener("versionchange",l=>a(l.oldVersion,l.newVersion,l))}).catch(()=>{}),c}function Pe(s,{blocked:e}={}){const t=indexedDB.deleteDatabase(s);return e&&t.addEventListener("blocked",n=>e(n.oldVersion,n)),f(t).then(()=>{})}const Ne=["get","getKey","getAll","getAllKeys","count"],ve=["put","add","delete","clear"],T=new Map;function O(s,e){if(!(s instanceof IDBDatabase&&!(e in s)&&typeof e=="string"))return;if(T.get(e))return T.get(e);const t=e.replace(/FromIndex$/,""),n=e!==t,a=ve.includes(t);if(!(t in(n?IDBIndex:IDBObjectStore).prototype)||!(a||Ne.includes(t)))return;const i=async function(r,...c){const o=this.transaction(r,a?"readwrite":"readonly");let l=o.store;return n&&(l=l.index(c.shift())),(await Promise.all([l[t](...c),a&&o.done]))[0]};return T.set(e,i),i}Ue(s=>({...s,get:(e,t,n)=>O(e,t)||s.get(e,t,n),has:(e,t)=>!!O(e,t)||s.has(e,t)}));try{self["workbox:expiration:7.3.0"]&&_()}catch{}const Me="workbox-expiration",w="cache-entries",S=s=>{const e=new URL(s,location.href);return e.hash="",e.href};class Ae{constructor(e){this._db=null,this._cacheName=e}_upgradeDb(e){const t=e.createObjectStore(w,{keyPath:"id"});t.createIndex("cacheName","cacheName",{unique:!1}),t.createIndex("timestamp","timestamp",{unique:!1})}_upgradeDbAndDeleteOldDbs(e){this._upgradeDb(e),this._cacheName&&Pe(this._cacheName)}async setTimestamp(e,t){e=S(e);const n={url:e,timestamp:t,cacheName:this._cacheName,id:this._getId(e)},i=(await this.getDb()).transaction(w,"readwrite",{durability:"relaxed"});await i.store.put(n),await i.done}async getTimestamp(e){const n=await(await this.getDb()).get(w,this._getId(e));return n==null?void 0:n.timestamp}async expireEntries(e,t){const n=await this.getDb();let a=await n.transaction(w).store.index("timestamp").openCursor(null,"prev");const i=[];let r=0;for(;a;){const o=a.value;o.cacheName===this._cacheName&&(e&&o.timestamp<e||t&&r>=t?i.push(a.value):r++),a=await a.continue()}const c=[];for(const o of i)await n.delete(w,o.id),c.push(o.url);return c}_getId(e){return this._cacheName+"|"+S(e)}async getDb(){return this._db||(this._db=await Ie(Me,1,{upgrade:this._upgradeDbAndDeleteOldDbs.bind(this)})),this._db}}class Ke{constructor(e,t={}){this._isRunning=!1,this._rerunRequested=!1,this._maxEntries=t.maxEntries,this._maxAgeSeconds=t.maxAgeSeconds,this._matchOptions=t.matchOptions,this._cacheName=e,this._timestampModel=new Ae(e)}async expireEntries(){if(this._isRunning){this._rerunRequested=!0;return}this._isRunning=!0;const e=this._maxAgeSeconds?Date.now()-this._maxAgeSeconds*1e3:0,t=await this._timestampModel.expireEntries(e,this._maxEntries),n=await self.caches.open(this._cacheName);for(const a of t)await n.delete(a,this._matchOptions);this._isRunning=!1,this._rerunRequested&&(this._rerunRequested=!1,H(this.expireEntries()))}async updateTimestamp(e){await this._timestampModel.setTimestamp(e,Date.now())}async isURLExpired(e){if(this._maxAgeSeconds){const t=await this._timestampModel.getTimestamp(e),n=Date.now()-this._maxAgeSeconds*1e3;return t!==void 0?t<n:!0}else return!1}async delete(){this._rerunRequested=!1,await this._timestampModel.expireEntries(1/0)}}function Oe(s){B.add(s)}class Se{constructor(e={}){this.cachedResponseWillBeUsed=async({event:t,request:n,cacheName:a,cachedResponse:i})=>{if(!i)return null;const r=this._isResponseDateFresh(i),c=this._getCacheExpiration(a);H(c.expireEntries());const o=c.updateTimestamp(n.url);if(t)try{t.waitUntil(o)}catch{}return r?i:null},this.cacheDidUpdate=async({cacheName:t,request:n})=>{const a=this._getCacheExpiration(t);await a.updateTimestamp(n.url),await a.expireEntries()},this._config=e,this._maxAgeSeconds=e.maxAgeSeconds,this._cacheExpirations=new Map,e.purgeOnQuotaError&&Oe(()=>this.deleteCacheAndMetadata())}_getCacheExpiration(e){if(e===b.getRuntimeName())throw new h("expire-custom-caches-only");let t=this._cacheExpirations.get(e);return t||(t=new Ke(e,this._config),this._cacheExpirations.set(e,t)),t}_isResponseDateFresh(e){if(!this._maxAgeSeconds)return!0;const t=this._getDateHeaderTimestamp(e);if(t===null)return!0;const n=Date.now();return t>=n-this._maxAgeSeconds*1e3}_getDateHeaderTimestamp(e){if(!e.headers.has("date"))return null;const t=e.headers.get("date"),a=new Date(t).getTime();return isNaN(a)?null:a}async deleteCacheAndMetadata(){for(const[e,t]of this._cacheExpirations)await self.caches.delete(e),await t.delete();this._cacheExpirations=new Map}}Re([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"0f93805414c783a30b72e0ce88f2c7c4","url":"icons/icon.svg"},{"revision":"5dee5ddcd8e8533edb348118334d9756","url":"icons/icon-512.png"},{"revision":"75734e6b38a556148f51b9e10eeb01c8","url":"icons/icon-192.png"},{"revision":"0362e0eb00358646fd4c97674945adba","url":"icons/icon-180.png"},{"revision":null,"url":"assets/xychartDiagram-5P7HB3ND-cd-6HXrN.js"},{"revision":null,"url":"assets/wardleyDiagram-NUSXRM2D-Dsy9JWUf.js"},{"revision":null,"url":"assets/wardley-RL74JXVD-BEjx3hAD.js"},{"revision":null,"url":"assets/vennDiagram-DHZGUBPP-DoHPigKa.js"},{"revision":null,"url":"assets/timeline-definition-GMOUNBTQ-C3o7gZFF.js"},{"revision":null,"url":"assets/stateDiagram-v2-QKLJ7IA2-C7M79J7F.js"},{"revision":null,"url":"assets/stateDiagram-FHFEXIEX-X9kal6wR.js"},{"revision":null,"url":"assets/sequenceDiagram-FGHM5R23-Dnl-W6jS.js"},{"revision":null,"url":"assets/sankeyDiagram-XADWPNL6-BHPnOiHK.js"},{"revision":null,"url":"assets/requirementDiagram-MS252O5E-fSM1Pi3V.js"},{"revision":null,"url":"assets/quadrantDiagram-34T5L4WZ-DloaxY2h.js"},{"revision":null,"url":"assets/pieDiagram-DEJITSTG-DlYgVpVr.js"},{"revision":null,"url":"assets/ordinal-Cboi1Yqb.js"},{"revision":null,"url":"assets/mindmap-definition-QFDTVHPH-DQUtHqQ6.js"},{"revision":null,"url":"assets/linear-s0Mg7155.js"},{"revision":null,"url":"assets/layout-Bcu4s7Ho.js"},{"revision":null,"url":"assets/katex-B1X10hvy.js"},{"revision":null,"url":"assets/kanban-definition-6JOO6SKY-NjVvkzyg.js"},{"revision":null,"url":"assets/journeyDiagram-VCZTEJTY-Cx-gOesl.js"},{"revision":null,"url":"assets/ishikawaDiagram-UXIWVN3A-DZdSiihk.js"},{"revision":null,"url":"assets/init-Gi6I4Gst.js"},{"revision":null,"url":"assets/infoDiagram-42DDH7IO-CTZf-XaE.js"},{"revision":null,"url":"assets/index-DWaSRzf6.css"},{"revision":null,"url":"assets/index-CwjgIG7M.js"},{"revision":null,"url":"assets/graph-DY36UTy7.js"},{"revision":null,"url":"assets/gitGraphDiagram-UUTBAWPF-CouNbB0H.js"},{"revision":null,"url":"assets/ganttDiagram-T4ZO3ILL-D5Ik9clK.js"},{"revision":null,"url":"assets/flowDiagram-DWJPFMVM-DUlTxDrh.js"},{"revision":null,"url":"assets/erDiagram-SMLLAGMA-DgukEqTQ.js"},{"revision":null,"url":"assets/diagram-TYMM5635-CLYhOm9a.js"},{"revision":null,"url":"assets/diagram-MMDJMWI5-B6-WK_TJ.js"},{"revision":null,"url":"assets/diagram-G4DWMVQ6-DD5Ucpcn.js"},{"revision":null,"url":"assets/diagram-5BDNPKRD-4Km3IxIT.js"},{"revision":null,"url":"assets/defaultLocale-DX6XiGOO.js"},{"revision":null,"url":"assets/dagre-KV5264BT-CiBddJE9.js"},{"revision":null,"url":"assets/cytoscape.esm-BQaXIfA_.js"},{"revision":null,"url":"assets/cose-bilkent-S5V4N54A-CsbF4Rbc.js"},{"revision":null,"url":"assets/clone-iFtwY3RV.js"},{"revision":null,"url":"assets/classDiagram-v2-HSJHXN6E-DRtX5Ta8.js"},{"revision":null,"url":"assets/classDiagram-6PBFFD2Q-DRtX5Ta8.js"},{"revision":null,"url":"assets/chunk-YZCP3GAM-qiJvjghT.js"},{"revision":null,"url":"assets/chunk-QZHKN3VN-CyNtEZcY.js"},{"revision":null,"url":"assets/chunk-OYMX7WX6-v5mXWXoC.js"},{"revision":null,"url":"assets/chunk-FMBD7UC4-CxmTHyai.js"},{"revision":null,"url":"assets/chunk-EDXVE4YY-BgWTXLsq.js"},{"revision":null,"url":"assets/chunk-55IACEB6-BTW1fQoW.js"},{"revision":null,"url":"assets/chunk-4TB4RGXK-DDonZyK6.js"},{"revision":null,"url":"assets/chunk-4BX2VUAB-Cob7CgE_.js"},{"revision":null,"url":"assets/channel-DSjdyO61.js"},{"revision":null,"url":"assets/c4Diagram-AHTNJAMY-BYDCN8H0.js"},{"revision":null,"url":"assets/blockDiagram-DXYQGD6D-wN2o-9_g.js"},{"revision":null,"url":"assets/architectureDiagram-Q4EWVU46-BmFTw0nZ.js"},{"revision":null,"url":"assets/arc-BNbndmGK.js"},{"revision":null,"url":"assets/_baseUniq-DnMFuvsx.js"},{"revision":null,"url":"assets/_basePickBy-BIHCnP-C.js"},{"revision":"0362e0eb00358646fd4c97674945adba","url":"icons/icon-180.png"},{"revision":"75734e6b38a556148f51b9e10eeb01c8","url":"icons/icon-192.png"},{"revision":"5dee5ddcd8e8533edb348118334d9756","url":"icons/icon-512.png"},{"revision":"b0747e8d6cde0d45e05be8e5c731729e","url":"manifest.webmanifest"}]);we();q(({url:s})=>s.hostname==="cdn.jsdelivr.net"&&s.pathname.endsWith(".ttf"),new be({cacheName:"termbeam-fonts",plugins:[new Se({maxEntries:5,maxAgeSeconds:365*24*60*60})]}));self.addEventListener("message",s=>{var e;((e=s.data)==null?void 0:e.type)==="CLEAR_CACHES"&&caches.keys().then(t=>{for(const n of t)n!=="workbox-precache-v2"&&caches.delete(n)})});self.addEventListener("install",()=>{self.skipWaiting()});self.addEventListener("activate",s=>{s.waitUntil(caches.delete("termbeam-navigation").then(()=>self.clients.claim()))});self.addEventListener("push",s=>{let e={title:"Command finished",body:"TermBeam"};if(s.data)try{e=s.data.json()}catch{}s.waitUntil(self.clients.matchAll({type:"window",includeUncontrolled:!0}).then(async t=>{if(t.some(i=>i.url.includes(self.location.origin)&&i.focused))return;const a={body:e.body||"A command has completed",icon:"/icons/icon-192.png",badge:"/icons/icon-192.png",tag:e.tag||"termbeam-cmd",renotify:!0,data:{url:e.url||"/",type:e.type||"command-complete",sessionId:e.sessionId},vibrate:[200,100,200]};try{await self.navigator.setAppBadge(1)}catch{}return self.registration.showNotification(e.title||"Command finished",a)}))});self.addEventListener("notificationclick",s=>{s.notification.close();try{self.navigator.clearAppBadge()}catch{}const e=s.notification.data||{},t=e.url||"/",n=e.type||"";s.waitUntil(self.clients.matchAll({type:"window",includeUncontrolled:!0}).then(a=>{for(const i of a)if(i.url.includes(self.location.origin)&&"focus"in i)return n&&i.postMessage({type:"NOTIFICATION_CLICKED",notificationType:n,sessionId:e.sessionId}),i.focus();return self.clients.openWindow(t)}))});
package/src/cli/index.js CHANGED
@@ -75,48 +75,66 @@ function getWindowsAncestors(startPid, maxDepth = 4) {
75
75
  const safePid = parseInt(startPid, 10);
76
76
  if (!Number.isFinite(safePid) || safePid <= 0) return names;
77
77
 
78
+ // Strategy 1: wmic (available on older Windows builds)
78
79
  try {
79
80
  const result = execFileSync(
80
81
  'wmic',
81
82
  ['process', 'get', 'Name,ParentProcessId,ProcessId', '/format:csv'],
82
- { stdio: ['pipe', 'pipe', 'ignore'], encoding: 'utf8', timeout: 5000 },
83
+ { stdio: ['pipe', 'pipe', 'ignore'], encoding: 'utf8', timeout: 5000, windowsHide: true },
83
84
  );
84
85
 
85
- // Parse CSV output — first non-empty line is the header
86
86
  const lines = result.split(/\r?\n/).filter((l) => l.trim());
87
- if (lines.length === 0) return names;
88
-
89
- const header = lines[0].split(',').map((h) => h.trim());
90
- const nameIdx = header.indexOf('Name');
91
- const pidIdx = header.indexOf('ProcessId');
92
- const ppidIdx = header.indexOf('ParentProcessId');
93
- if (nameIdx === -1 || pidIdx === -1 || ppidIdx === -1) return names;
94
-
95
- const processes = new Map();
96
- for (let i = 1; i < lines.length; i++) {
97
- const cols = lines[i].split(',');
98
- if (cols.length <= Math.max(nameIdx, pidIdx, ppidIdx)) continue;
99
- const pid = parseInt(cols[pidIdx], 10);
100
- if (Number.isFinite(pid)) {
101
- processes.set(pid, {
102
- name: cols[nameIdx].trim().toLowerCase(),
103
- ppid: parseInt(cols[ppidIdx], 10),
104
- });
87
+ if (lines.length > 0) {
88
+ const header = lines[0].split(',').map((h) => h.trim());
89
+ const nameIdx = header.indexOf('Name');
90
+ const pidIdx = header.indexOf('ProcessId');
91
+ const ppidIdx = header.indexOf('ParentProcessId');
92
+ if (nameIdx !== -1 && pidIdx !== -1 && ppidIdx !== -1) {
93
+ const processes = new Map();
94
+ for (let i = 1; i < lines.length; i++) {
95
+ const cols = lines[i].split(',');
96
+ if (cols.length <= Math.max(nameIdx, pidIdx, ppidIdx)) continue;
97
+ const pid = parseInt(cols[pidIdx], 10);
98
+ if (Number.isFinite(pid)) {
99
+ processes.set(pid, {
100
+ name: cols[nameIdx].trim().toLowerCase(),
101
+ ppid: parseInt(cols[ppidIdx], 10),
102
+ });
103
+ }
104
+ }
105
+
106
+ let currentPid = safePid;
107
+ for (let i = 0; i < maxDepth; i++) {
108
+ const proc = processes.get(currentPid);
109
+ if (!proc) break;
110
+ log.debug(`Process tree: ${proc.name}`);
111
+ names.push(proc.name);
112
+ if (!Number.isFinite(proc.ppid) || proc.ppid === 0 || proc.ppid === currentPid) break;
113
+ currentPid = proc.ppid;
114
+ }
115
+ if (names.length > 0) return names;
105
116
  }
106
117
  }
118
+ } catch (err) {
119
+ log.debug(`wmic not available: ${err.message}`);
120
+ }
107
121
 
108
- // Walk up the tree in memory no more subprocess calls
109
- let currentPid = safePid;
110
- for (let i = 0; i < maxDepth; i++) {
111
- const proc = processes.get(currentPid);
112
- if (!proc) break;
113
- log.debug(`Process tree: ${proc.name}`);
114
- names.push(proc.name);
115
- if (!Number.isFinite(proc.ppid) || proc.ppid === 0 || proc.ppid === currentPid) break;
116
- currentPid = proc.ppid;
122
+ // Strategy 2: tasklist for direct parent name (always available on Windows)
123
+ try {
124
+ const result = execFileSync('tasklist', ['/FI', `PID eq ${safePid}`, '/FO', 'CSV', '/NH'], {
125
+ stdio: ['pipe', 'pipe', 'ignore'],
126
+ encoding: 'utf8',
127
+ timeout: 5000,
128
+ windowsHide: true,
129
+ });
130
+ const match = result.match(/"([^"]+)"/);
131
+ if (match) {
132
+ const name = match[1].toLowerCase();
133
+ log.debug(`Process tree (tasklist): ${name}`);
134
+ names.push(name);
117
135
  }
118
136
  } catch (err) {
119
- log.debug(`Could not query process tree: ${err.message}`);
137
+ log.debug(`tasklist failed: ${err.message}`);
120
138
  }
121
139
 
122
140
  return names;
@@ -188,6 +206,19 @@ function getDefaultShell() {
188
206
  log.debug(`Using detected shell: cmd.exe`);
189
207
  return 'cmd.exe';
190
208
  }
209
+
210
+ // Heuristic: PSModulePath env var is set by PowerShell and inherited by children.
211
+ // When the tree walk only found intermediaries (node.exe), this detects the real shell.
212
+ const psModulePath = (process.env.PSModulePath || '').toLowerCase();
213
+ if (psModulePath.includes('\\powershell\\')) {
214
+ log.debug('Detected pwsh.exe via PSModulePath');
215
+ return 'pwsh.exe';
216
+ }
217
+ if (psModulePath.includes('\\windowspowershell\\')) {
218
+ log.debug('Detected powershell.exe via PSModulePath');
219
+ return 'powershell.exe';
220
+ }
221
+
191
222
  const fallback = process.env.COMSPEC || 'cmd.exe';
192
223
  log.debug(`Falling back to: ${fallback}`);
193
224
  return fallback;
@@ -384,4 +415,4 @@ function parseArgs() {
384
415
  return config;
385
416
  }
386
417
 
387
- module.exports = { parseArgs, printHelp, isKnownShell, getWindowsAncestors };
418
+ module.exports = { parseArgs, printHelp, isKnownShell, getWindowsAncestors, getDefaultShell };
@@ -32,6 +32,7 @@ function findPm2() {
32
32
  encoding: 'utf8',
33
33
  stdio: ['pipe', 'pipe', 'ignore'],
34
34
  timeout: 5000,
35
+ windowsHide: true,
35
36
  });
36
37
  return result.trim().split('\n')[0].trim();
37
38
  } catch {
@@ -43,10 +44,13 @@ function installPm2Global() {
43
44
  log.info('Installing PM2 globally');
44
45
  console.log(yellow('\nInstalling PM2 globally...'));
45
46
  try {
46
- execFileSync('npm', ['install', '-g', 'pm2'], {
47
+ const isWin = os.platform() === 'win32';
48
+ const cmd = isWin ? process.env.ComSpec || 'cmd.exe' : 'npm';
49
+ const cmdArgs = isWin ? ['/c', 'npm', 'install', '-g', 'pm2'] : ['install', '-g', 'pm2'];
50
+ execFileSync(cmd, cmdArgs, {
47
51
  stdio: 'inherit',
48
52
  timeout: 120000,
49
- shell: os.platform() === 'win32',
53
+ windowsHide: true,
50
54
  });
51
55
  console.log(green('✓ PM2 installed successfully.\n'));
52
56
  return true;
@@ -141,13 +145,17 @@ function readEcosystemName() {
141
145
 
142
146
  function pm2Exec(args, opts = {}) {
143
147
  log.debug(`PM2 command: pm2 ${args.join(' ')}`);
148
+ const isWin = os.platform() === 'win32';
149
+ // Windows npm globals are .cmd wrappers — use cmd.exe /c to resolve them
150
+ // without shell:true (which triggers DEP0190 when combined with args).
151
+ const cmd = isWin ? process.env.ComSpec || 'cmd.exe' : 'pm2';
152
+ const cmdArgs = isWin ? ['/c', 'pm2', ...args] : args;
144
153
  try {
145
- return execFileSync('pm2', args, {
154
+ return execFileSync(cmd, cmdArgs, {
146
155
  encoding: 'utf8',
147
156
  stdio: opts.inherit ? 'inherit' : ['pipe', 'pipe', 'pipe'],
148
157
  timeout: 30000,
149
- // Windows npm globals are .cmd wrappers; execFileSync needs shell to resolve them
150
- shell: os.platform() === 'win32',
158
+ windowsHide: true,
151
159
  ...opts,
152
160
  });
153
161
  } catch (err) {
@@ -347,8 +355,9 @@ async function actionInstall() {
347
355
  config.cwd = await ask(rl, 'Working directory:', process.cwd());
348
356
  decisions.push({ label: 'Directory', value: config.cwd });
349
357
 
350
- // Shell — use current shell automatically
351
- config.shell = process.env.SHELL || (os.platform() === 'win32' ? process.env.COMSPEC : '/bin/sh');
358
+ // Shell — detect the actual shell the user is running from
359
+ const { getDefaultShell } = require('./index');
360
+ config.shell = getDefaultShell();
352
361
  decisions.push({ label: 'Shell', value: config.shell });
353
362
 
354
363
  // Log level
@@ -665,9 +674,13 @@ function actionLogs() {
665
674
  process.exit(1);
666
675
  }
667
676
  const { spawn } = require('child_process');
668
- const child = spawn('pm2', ['logs', readEcosystemName(), '--lines', '200'], {
677
+ const isWin = os.platform() === 'win32';
678
+ const cmd = isWin ? process.env.ComSpec || 'cmd.exe' : 'pm2';
679
+ const logsArgs = ['logs', readEcosystemName(), '--lines', '200'];
680
+ const cmdArgs = isWin ? ['/c', 'pm2', ...logsArgs] : logsArgs;
681
+ const child = spawn(cmd, cmdArgs, {
669
682
  stdio: 'inherit',
670
- shell: os.platform() === 'win32',
683
+ windowsHide: true,
671
684
  });
672
685
  child.on('error', (err) => {
673
686
  console.error(red(`✗ Failed to stream logs: ${err.message}`));
@@ -156,6 +156,37 @@ function setupRoutes(app, { auth, sessions, config, state, pushManager, copilotS
156
156
  res.json({ version: getVersion() });
157
157
  });
158
158
 
159
+ // Changelog — served from repo CHANGELOG.md (bundled with the npm package).
160
+ // Falls back to GitHub raw if the file isn't present locally.
161
+ // Cached for 1 hour since it only changes on release.
162
+ app.get('/api/changelog', apiRateLimit, auth.middleware, async (_req, res) => {
163
+ const changelogPath = path.join(__dirname, '..', '..', 'CHANGELOG.md');
164
+ fs.readFile(changelogPath, 'utf8', async (err, data) => {
165
+ if (!err) {
166
+ res.set('Cache-Control', 'private, max-age=3600');
167
+ return res.type('text/markdown').send(data);
168
+ }
169
+ if (err.code !== 'ENOENT') {
170
+ log.warn('Failed to read local CHANGELOG.md', { code: err.code });
171
+ return res.status(500).json({ error: 'Failed to read changelog' });
172
+ }
173
+ try {
174
+ const response = await fetch(
175
+ 'https://raw.githubusercontent.com/dorlugasigal/TermBeam/main/CHANGELOG.md',
176
+ { signal: AbortSignal.timeout(5000) },
177
+ );
178
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
179
+ const text = await response.text();
180
+ res.set('Cache-Control', 'private, max-age=3600');
181
+ res.type('text/markdown').send(text);
182
+ } catch (fetchErr) {
183
+ const msg = fetchErr instanceof Error ? fetchErr.message : String(fetchErr);
184
+ log.debug('Changelog not available', { err: msg });
185
+ res.status(404).json({ error: 'Changelog not available' });
186
+ }
187
+ });
188
+ });
189
+
159
190
  // Public config — no auth required
160
191
  app.get('/api/config', (_req, res) => {
161
192
  res.json({ passwordRequired: !!auth.password });
@@ -106,6 +106,7 @@ function isLoggedIn() {
106
106
  encoding: 'utf-8',
107
107
  stdio: ['pipe', 'pipe', 'pipe'],
108
108
  timeout: 10_000,
109
+ windowsHide: true,
109
110
  });
110
111
  return out && !out.toLowerCase().includes('not logged in');
111
112
  } catch {
@@ -119,6 +120,7 @@ function getLoginInfo() {
119
120
  encoding: 'utf-8',
120
121
  stdio: ['pipe', 'pipe', 'pipe'],
121
122
  timeout: 10_000,
123
+ windowsHide: true,
122
124
  });
123
125
  return parseLoginInfo(out);
124
126
  } catch {
@@ -148,6 +150,7 @@ function deviceCodeLogin(cmd) {
148
150
  return new Promise((resolve, reject) => {
149
151
  const proc = spawn(cmd, ['user', 'login', '-e', '-d'], {
150
152
  stdio: ['inherit', 'pipe', 'pipe'],
153
+ windowsHide: true,
151
154
  });
152
155
 
153
156
  let gotOutput = false;
@@ -197,7 +200,7 @@ function deviceCodeLogin(cmd) {
197
200
  function findDevtunnel() {
198
201
  // Try devtunnel directly
199
202
  try {
200
- execSync('devtunnel --version', { stdio: 'pipe' });
203
+ execSync('devtunnel --version', { stdio: 'pipe', windowsHide: true });
201
204
  return 'devtunnel';
202
205
  } catch {}
203
206
 
@@ -222,7 +225,7 @@ function findDevtunnel() {
222
225
  );
223
226
  if (fs.existsSync(homeBin)) {
224
227
  try {
225
- execFileSync(homeBin, ['--version'], { stdio: 'pipe' });
228
+ execFileSync(homeBin, ['--version'], { stdio: 'pipe', windowsHide: true });
226
229
  return homeBin;
227
230
  } catch {}
228
231
  }
@@ -253,6 +256,7 @@ function isTunnelValid(id) {
253
256
  execFileSync(devtunnelCmd, ['show', id, '--json'], {
254
257
  encoding: 'utf-8',
255
258
  stdio: ['pipe', 'pipe', 'pipe'],
259
+ windowsHide: true,
256
260
  });
257
261
  return true;
258
262
  } catch {
@@ -273,7 +277,7 @@ function checkTunnelHealth() {
273
277
  execFile(
274
278
  devtunnelCmd,
275
279
  ['show', tunnelId],
276
- { encoding: 'utf-8', signal: abortCtrl.signal },
280
+ { encoding: 'utf-8', signal: abortCtrl.signal, windowsHide: true },
277
281
  (err, stdout) => {
278
282
  clearTimeout(timer);
279
283
 
@@ -401,6 +405,7 @@ function killTunnelProc() {
401
405
  execFileSync('taskkill', ['/pid', String(tunnelProc.pid), '/T', '/F'], {
402
406
  stdio: 'pipe',
403
407
  timeout: 5000,
408
+ windowsHide: true,
404
409
  });
405
410
  } catch {
406
411
  /* best effort */
@@ -566,6 +571,7 @@ function scheduleRestart() {
566
571
  function hostTunnel() {
567
572
  const hostProc = spawn(devtunnelCmd, ['host', tunnelId], {
568
573
  stdio: ['pipe', 'pipe', 'pipe'],
574
+ windowsHide: true,
569
575
  });
570
576
  tunnelProc = hostProc;
571
577
 
@@ -657,7 +663,11 @@ async function startTunnel(port, options = {}) {
657
663
  if (!loggedIn) {
658
664
  log.info('Logging in to DevTunnel with Microsoft Entra (recommended for long sessions)...');
659
665
  try {
660
- execFileSync(devtunnelCmd, ['user', 'login', '-e'], { stdio: 'inherit', timeout: 30000 });
666
+ execFileSync(devtunnelCmd, ['user', 'login', '-e'], {
667
+ stdio: 'inherit',
668
+ timeout: 30000,
669
+ windowsHide: true,
670
+ });
661
671
  } catch {
662
672
  log.info('Browser login failed or unavailable, falling back to device code flow...');
663
673
  log.info('A code will be displayed — open the URL on any device to authenticate.');
@@ -694,6 +704,7 @@ async function startTunnel(port, options = {}) {
694
704
  }
695
705
  const createOut = execFileSync(devtunnelCmd, ['create', '--expiration', '30d', '--json'], {
696
706
  encoding: 'utf-8',
707
+ windowsHide: true,
697
708
  });
698
709
  const tunnelData = JSON.parse(createOut);
699
710
  tunnelId = tunnelData.tunnel.tunnelId;
@@ -706,6 +717,7 @@ async function startTunnel(port, options = {}) {
706
717
  // Ephemeral tunnel — create fresh, will be deleted on shutdown
707
718
  const createOut = execFileSync(devtunnelCmd, ['create', '--expiration', '1d', '--json'], {
708
719
  encoding: 'utf-8',
720
+ windowsHide: true,
709
721
  });
710
722
  const tunnelData = JSON.parse(createOut);
711
723
  tunnelId = tunnelData.tunnel.tunnelId;
@@ -717,7 +729,7 @@ async function startTunnel(port, options = {}) {
717
729
  execFileSync(
718
730
  devtunnelCmd,
719
731
  ['port', 'create', tunnelId, '-p', String(port), '--protocol', 'http'],
720
- { stdio: 'pipe' },
732
+ { stdio: 'pipe', windowsHide: true },
721
733
  );
722
734
  } catch {}
723
735
  // Set tunnel access: public (anonymous) or private (owner-only via Microsoft login)
@@ -726,7 +738,7 @@ async function startTunnel(port, options = {}) {
726
738
  execFileSync(
727
739
  devtunnelCmd,
728
740
  ['access', 'create', tunnelId, '-p', String(port), '--anonymous'],
729
- { stdio: 'pipe' },
741
+ { stdio: 'pipe', windowsHide: true },
730
742
  );
731
743
  } catch {}
732
744
  log.info('Tunnel access: public (anonymous)');
@@ -735,6 +747,7 @@ async function startTunnel(port, options = {}) {
735
747
  try {
736
748
  execFileSync(devtunnelCmd, ['access', 'reset', tunnelId], {
737
749
  stdio: 'pipe',
750
+ windowsHide: true,
738
751
  });
739
752
  } catch {}
740
753
  log.info('Tunnel access: private (owner-only via Microsoft login)');
@@ -773,7 +786,11 @@ function cleanupTunnel() {
773
786
  log.info('Tunnel host stopped (tunnel preserved for reuse)');
774
787
  } else {
775
788
  try {
776
- execFileSync(devtunnelCmd, ['delete', id, '-f'], { stdio: 'pipe', timeout: 10000 });
789
+ execFileSync(devtunnelCmd, ['delete', id, '-f'], {
790
+ stdio: 'pipe',
791
+ timeout: 10000,
792
+ windowsHide: true,
793
+ });
777
794
  log.info('Tunnel cleaned up');
778
795
  } catch {
779
796
  /* best effort — tunnel will expire on its own */
@@ -98,7 +98,7 @@ async function installDevtunnel() {
98
98
  function findInstalledBinary() {
99
99
  // Check PATH first
100
100
  try {
101
- execSync('devtunnel --version', { stdio: 'pipe', timeout: 10000 });
101
+ execSync('devtunnel --version', { stdio: 'pipe', timeout: 10000, windowsHide: true });
102
102
  return 'devtunnel';
103
103
  } catch {}
104
104
 
@@ -110,6 +110,7 @@ function findInstalledBinary() {
110
110
  encoding: 'utf-8',
111
111
  stdio: 'pipe',
112
112
  timeout: 10000,
113
+ windowsHide: true,
113
114
  })
114
115
  .trim()
115
116
  .split(/\r?\n/)[0];
@@ -130,7 +131,7 @@ function findInstalledBinary() {
130
131
  const homeBin = path.join(os.homedir(), 'bin', getBinaryName());
131
132
  if (fs.existsSync(homeBin)) {
132
133
  try {
133
- execFileSync(homeBin, ['--version'], { stdio: 'pipe', timeout: 10000 });
134
+ execFileSync(homeBin, ['--version'], { stdio: 'pipe', timeout: 10000, windowsHide: true });
134
135
  return homeBin;
135
136
  } catch {}
136
137
  }
@@ -62,24 +62,29 @@ function tryDetectAgent(agent) {
62
62
  let remaining = candidates.length;
63
63
 
64
64
  for (const bin of candidates) {
65
- child_process.execFile(bin, args, { timeout: 5000, encoding: 'utf8' }, (err, stdout) => {
66
- remaining--;
67
- if (resolved) return;
68
- if (!err) {
69
- resolved = true;
70
- const version = (stdout || '').trim().split('\n')[0] || 'unknown';
71
- resolve({
72
- id: agent.id,
73
- name: agent.name,
74
- cmd: agent.cmd,
75
- args: agent.args || [],
76
- icon: agent.icon,
77
- version,
78
- });
79
- } else if (remaining === 0) {
80
- resolve(null);
81
- }
82
- });
65
+ child_process.execFile(
66
+ bin,
67
+ args,
68
+ { timeout: 5000, encoding: 'utf8', windowsHide: true },
69
+ (err, stdout) => {
70
+ remaining--;
71
+ if (resolved) return;
72
+ if (!err) {
73
+ resolved = true;
74
+ const version = (stdout || '').trim().split('\n')[0] || 'unknown';
75
+ resolve({
76
+ id: agent.id,
77
+ name: agent.name,
78
+ cmd: agent.cmd,
79
+ args: agent.args || [],
80
+ icon: agent.icon,
81
+ version,
82
+ });
83
+ } else if (remaining === 0) {
84
+ resolve(null);
85
+ }
86
+ },
87
+ );
83
88
  }
84
89
  });
85
90
  }
package/src/utils/git.js CHANGED
@@ -3,7 +3,9 @@ const path = require('path');
3
3
  const log = require('./logger');
4
4
 
5
5
  function git(cmd, cwd) {
6
- return execSync(`git ${cmd}`, { cwd, stdio: 'pipe', timeout: 3000 }).toString().trim();
6
+ return execSync(`git ${cmd}`, { cwd, stdio: 'pipe', timeout: 3000, windowsHide: true })
7
+ .toString()
8
+ .trim();
7
9
  }
8
10
 
9
11
  function getGitInfo(cwd) {
@@ -144,7 +146,7 @@ async function getGitRoot(cwd) {
144
146
  require('child_process').execFile(
145
147
  'git',
146
148
  ['rev-parse', '--show-toplevel'],
147
- { cwd, timeout: GIT_TIMEOUT },
149
+ { cwd, timeout: GIT_TIMEOUT, windowsHide: true },
148
150
  (err, stdout) => {
149
151
  if (err) return reject(err);
150
152
  resolve(stdout.trim());
@@ -167,6 +169,7 @@ async function gitAsync(args, cwd, options = {}) {
167
169
  cwd,
168
170
  timeout: options.timeout || GIT_TIMEOUT,
169
171
  maxBuffer: options.maxBuffer || MAX_DIFF_BUFFER,
172
+ windowsHide: true,
170
173
  },
171
174
  (err, stdout) => {
172
175
  if (err) return reject(err);
@@ -343,6 +346,7 @@ async function getFileDiff(cwd, filePath, options = {}) {
343
346
  cwd: root,
344
347
  timeout: GIT_TIMEOUT,
345
348
  maxBuffer: MAX_DIFF_BUFFER,
349
+ windowsHide: true,
346
350
  },
347
351
  (err, stdout) => {
348
352
  // git diff --no-index exits with 1 when files differ — that's expected
@@ -25,6 +25,7 @@ function detectWindowsShells() {
25
25
  stdio: ['pipe', 'pipe', 'ignore'],
26
26
  encoding: 'utf8',
27
27
  timeout: 3000,
28
+ windowsHide: true,
28
29
  });
29
30
  const fullPath = result.trim().split('\n')[0].trim();
30
31
  if (fullPath) {