@hienlh/ppm 0.9.0-beta.4 → 0.9.0-beta.5
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.
Potentially problematic release.
This version of @hienlh/ppm might be problematic. Click here for more details.
- package/CHANGELOG.md +21 -8
- package/dist/web/assets/browser-tab-CEYAwJUI.js +1 -0
- package/dist/web/assets/chat-tab-C8bt4tdL.js +7 -0
- package/dist/web/assets/{code-editor-BRMOypkX.js → code-editor-BVt8uVtX.js} +1 -1
- package/dist/web/assets/{database-viewer-CEoDpzPz.js → database-viewer-CNi9B6tN.js} +1 -1
- package/dist/web/assets/{diff-viewer-jDU2bcGj.js → diff-viewer-CnjvJhwy.js} +1 -1
- package/dist/web/assets/{git-graph-DMQzw4Sp.js → git-graph-BNbraUOe.js} +1 -1
- package/dist/web/assets/{index-QiSWS6f-.js → index-CKvJPAPG.js} +3 -3
- package/dist/web/assets/keybindings-store-Cmf2viOa.js +1 -0
- package/dist/web/assets/{markdown-renderer-BCjJbGP8.js → markdown-renderer-CFW_zoSR.js} +1 -1
- package/dist/web/assets/{postgres-viewer-s0snZ9CL.js → postgres-viewer-Dg23WW__.js} +1 -1
- package/dist/web/assets/{settings-tab-2YkgmrY0.js → settings-tab-rB971cXs.js} +1 -1
- package/dist/web/assets/{sqlite-viewer-B5GNwXaG.js → sqlite-viewer-D3N938wy.js} +1 -1
- package/dist/web/assets/{terminal-tab-MRg8y1xF.js → terminal-tab-BdHlIi8e.js} +2 -2
- package/dist/web/index.html +1 -1
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
- package/src/providers/claude-agent-sdk.ts +212 -76
- package/src/server/ws/chat.ts +103 -73
- package/src/types/api.ts +1 -1
- package/src/types/chat.ts +2 -0
- package/src/web/components/chat/chat-tab.tsx +3 -3
- package/src/web/components/chat/message-input.tsx +41 -4
- package/src/web/hooks/use-chat.ts +21 -9
- package/dist/web/assets/browser-tab-BhTdeeZd.js +0 -1
- package/dist/web/assets/chat-tab-ZiiUVOxM.js +0 -7
- package/dist/web/assets/keybindings-store-BplH-yiN.js +0 -1
package/dist/web/sw.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}function B(e){O().precache(e)}function V(e,t){B(e),z(t)}V([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"449f8c10830c0468fda5727a6f347626","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"eb9818b9094675c0c5d303168f273345","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"9af0be92dcefdc1f1290441cb5ff5d9b","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"a261b429c39dbb75ae97972d7d005e6d","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"79953d804e1bbacecfd79b85fd679016","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"fdcba0d09aac31df7a0bc652f6e739bd","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":null,"url":"assets/xychartDiagram-JWTSCODW-BRvXOVlG.js"},{"revision":null,"url":"assets/vennDiagram-LZ73GAT5-DfYFnniI.js"},{"revision":null,"url":"assets/utils-Bslrbb-G.js"},{"revision":null,"url":"assets/use-monaco-theme-BQzvItNE.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-BL9OJq3X.js"},{"revision":null,"url":"assets/timeline-definition-YZTLITO2-DrjxCpEM.js"},{"revision":null,"url":"assets/terminal-tab-MRg8y1xF.js"},{"revision":null,"url":"assets/terminal-tab-BrP-ENHg.css"},{"revision":null,"url":"assets/tag-CENGyt_L.js"},{"revision":null,"url":"assets/table-C9jDaRl2.js"},{"revision":null,"url":"assets/tab-store-DSz5PQI0.js"},{"revision":null,"url":"assets/switch-mjGtIVDJ.js"},{"revision":null,"url":"assets/stateDiagram-v2-FVOUBMTO-D7qSAjnK.js"},{"revision":null,"url":"assets/stateDiagram-RAJIS63D-C16aO8tn.js"},{"revision":null,"url":"assets/src-CLWraeNW.js"},{"revision":null,"url":"assets/sqlite-viewer-B5GNwXaG.js"},{"revision":null,"url":"assets/settings-tab-2YkgmrY0.js"},{"revision":null,"url":"assets/settings-store-D3dJqGhB.js"},{"revision":null,"url":"assets/sequenceDiagram-2WXFIKYE-BtRvoUTC.js"},{"revision":null,"url":"assets/sankeyDiagram-WA2Y5GQK-DEGGYsk7.js"},{"revision":null,"url":"assets/rough.esm-c4PR5shF.js"},{"revision":null,"url":"assets/requirementDiagram-Z7DCOOCP-1WWjMQB_.js"},{"revision":null,"url":"assets/react-nm2Ru1Pt.js"},{"revision":null,"url":"assets/react-BPIfZRKM.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-CHptMqVT.js"},{"revision":null,"url":"assets/quadrantDiagram-337W2JSQ-BaRFqlsA.js"},{"revision":null,"url":"assets/preload-helper-CsoeaaUJ.js"},{"revision":null,"url":"assets/postgres-viewer-s0snZ9CL.js"},{"revision":null,"url":"assets/pieDiagram-SKSYHLDU-seSK40d1.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-B0h6hM1j.js"},{"revision":null,"url":"assets/path-CuyvWNAH.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-BbzPU9BK.js"},{"revision":null,"url":"assets/ordinal-CIoJK3nc.js"},{"revision":null,"url":"assets/mindmap-definition-YRQLILUH-DIv-LMXG.js"},{"revision":null,"url":"assets/mermaid-parser.core-BY8JfkE_.js"},{"revision":null,"url":"assets/math-a44lmFDa.js"},{"revision":null,"url":"assets/markdown-renderer-BCjJbGP8.js"},{"revision":null,"url":"assets/linear-BdqW7iQu.js"},{"revision":null,"url":"assets/line--xyfYP3x.js"},{"revision":null,"url":"assets/keybindings-store-BplH-yiN.js"},{"revision":null,"url":"assets/katex-C3cZrCvP.js"},{"revision":null,"url":"assets/kanban-definition-K7BYSVSG-BMUhjxqj.js"},{"revision":null,"url":"assets/jsx-runtime-BRW_vwa9.js"},{"revision":null,"url":"assets/journeyDiagram-4ABVD52K-DFQXUZsc.js"},{"revision":null,"url":"assets/ishikawaDiagram-PHBUUO56-cW7SMLa_.js"},{"revision":null,"url":"assets/isEmpty-DXomfd7J.js"},{"revision":null,"url":"assets/isArrayLikeObject-DvHDmeBe.js"},{"revision":null,"url":"assets/input-DGlv6gt_.js"},{"revision":null,"url":"assets/init-vVpfz1D6.js"},{"revision":null,"url":"assets/infoDiagram-LFFYTUFH-DFh9c-S2.js"},{"revision":null,"url":"assets/info-3K5VOQVL-CbpovIYU.js"},{"revision":null,"url":"assets/index-QiSWS6f-.js"},{"revision":null,"url":"assets/index-B4Iz1Wbi.css"},{"revision":null,"url":"assets/graphlib-BbbiUImY.js"},{"revision":null,"url":"assets/gitGraphDiagram-K3NZZRJ6-L7sj3Bs-.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-D5qEPjgs.js"},{"revision":null,"url":"assets/git-graph-DMQzw4Sp.js"},{"revision":null,"url":"assets/ganttDiagram-A5KZAMGK-BVlftqyZ.js"},{"revision":null,"url":"assets/flowDiagram-PKNHOUZH-B9h_Ba-v.js"},{"revision":null,"url":"assets/erDiagram-INFDFZHY-DK4QEZYh.js"},{"revision":null,"url":"assets/dist-Ckxnw5rl.js"},{"revision":null,"url":"assets/dist-CMmNEgEP.js"},{"revision":null,"url":"assets/diff-viewer-jDU2bcGj.js"},{"revision":null,"url":"assets/diagram-P4PSJMXO--nUaNiyB.js"},{"revision":null,"url":"assets/diagram-IFDJBPK2-NvhckwcA.js"},{"revision":null,"url":"assets/diagram-E7M64L7V-CkDC2uAj.js"},{"revision":null,"url":"assets/defaultLocale-D_VMtRaY.js"},{"revision":null,"url":"assets/database-viewer-CEoDpzPz.js"},{"revision":null,"url":"assets/dagre-KLK3FWXG-Br4t5TRV.js"},{"revision":null,"url":"assets/dagre-CWo8w9wK.js"},{"revision":null,"url":"assets/cytoscape.esm-B-QQuWwK.js"},{"revision":null,"url":"assets/cose-bilkent-S5V4N54A-C1QJ6GPW.js"},{"revision":null,"url":"assets/columns-2-Bcg3QJBg.js"},{"revision":null,"url":"assets/code-editor-BRMOypkX.js"},{"revision":null,"url":"assets/clone-DNDy9Sms.js"},{"revision":null,"url":"assets/classDiagram-v2-RAHNMMFH-Bo5WN2ok.js"},{"revision":null,"url":"assets/classDiagram-VBA2DB6C-CqaIqYPn.js"},{"revision":null,"url":"assets/chunk-YBOYWFTD-COdZIaX4.js"},{"revision":null,"url":"assets/chunk-XZSTWKYB-5W2emiq4.js"},{"revision":null,"url":"assets/chunk-XPW4576I-CsGTseUr.js"},{"revision":null,"url":"assets/chunk-XIRO2GV7-DUmQrLsF.js"},{"revision":null,"url":"assets/chunk-WL4C6EOR-BHFnnXOt.js"},{"revision":null,"url":"assets/chunk-R5LLSJPH-LdG7RqsM.js"},{"revision":null,"url":"assets/chunk-QZHKN3VN-gaBt0Rbd.js"},{"revision":null,"url":"assets/chunk-PU5JKC2W-D3thuSok.js"},{"revision":null,"url":"assets/chunk-PQ6SQG4A-EdgQyTqa.js"},{"revision":null,"url":"assets/chunk-OZEHJAEY-LfXT4p8B.js"},{"revision":null,"url":"assets/chunk-O4XLMI2P-BdXwVXjJ.js"},{"revision":null,"url":"assets/chunk-NQ4KR5QH-BRj25yO7.js"},{"revision":null,"url":"assets/chunk-MX3YWQON-BnPzQK-O.js"},{"revision":null,"url":"assets/chunk-L3YUKLVL-DNFj84V6.js"},{"revision":null,"url":"assets/chunk-KYZI473N-CBRPKraG.js"},{"revision":null,"url":"assets/chunk-KX2RTZJC-BRj-ZEvL.js"},{"revision":null,"url":"assets/chunk-JSJVCQXG-Pb-JMOgO.js"},{"revision":null,"url":"assets/chunk-HHEYEP7N-BnRVfNc5.js"},{"revision":null,"url":"assets/chunk-GLR3WWYH-Bx2UL5jF.js"},{"revision":null,"url":"assets/chunk-GEFDOKGD-B82RP9ow.js"},{"revision":null,"url":"assets/chunk-FMBD7UC4-JCLgVcaC.js"},{"revision":null,"url":"assets/chunk-EGIJ26TM-Cgt-qg75.js"},{"revision":null,"url":"assets/chunk-CFjPhJqf.js"},{"revision":null,"url":"assets/chunk-C72U2L5F-CcEW1AMZ.js"},{"revision":null,"url":"assets/chunk-7R4GIKGN-DvbvLUIN.js"},{"revision":null,"url":"assets/chunk-7E7YKBS2-CuYKSUgJ.js"},{"revision":null,"url":"assets/chunk-55IACEB6-Dp0pTM5r.js"},{"revision":null,"url":"assets/chunk-4BX2VUAB-0YMkpW2S.js"},{"revision":null,"url":"assets/chat-tab-ZiiUVOxM.js"},{"revision":null,"url":"assets/channel-CKNZAqoN.js"},{"revision":null,"url":"assets/c4Diagram-IC4MRINW-DzjR91sM.js"},{"revision":null,"url":"assets/browser-tab-BhTdeeZd.js"},{"revision":null,"url":"assets/blockDiagram-WCTKOSBZ-CU2t4NHJ.js"},{"revision":null,"url":"assets/arrow-left-C_j9Ki73.js"},{"revision":null,"url":"assets/array-CLwNaqU1.js"},{"revision":null,"url":"assets/architectureDiagram-2XIMDMQ5-BVEUkQYB.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-281eTKQ3.js"},{"revision":null,"url":"assets/arc-D0bJaFyD.js"},{"revision":null,"url":"assets/api-settings-CuUkz5gb.js"},{"revision":null,"url":"assets/api-client-icCZ-07C.js"},{"revision":null,"url":"assets/_baseUniq-DCb0mkTp.js"},{"revision":null,"url":"assets/_basePickBy-COwDPZl_.js"},{"revision":"79c8870653c8f419f2e3323085e1f4be","url":"manifest.webmanifest"}]),self.addEventListener(`push`,e=>{e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{if(t.some(e=>e.visibilityState===`visible`))return;let n=e.data?.json()??{title:`PPM`,body:`Chat completed`};return self.registration.showNotification(n.title,{body:n.body,icon:`/icon-192.png`,badge:`/icon-192.png`,tag:`ppm-chat-done`,silent:!1,data:{url:self.location.origin}})}))}),self.addEventListener(`notificationclick`,e=>{e.notification.close(),e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{for(let e of t)if(e.url.includes(self.location.origin)&&`focus`in e)return e.focus();return self.clients.openWindow(e.notification.data?.url||`/`)}))});
|
|
1
|
+
try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}function B(e){O().precache(e)}function V(e,t){B(e),z(t)}V([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"d7aed6bbe50b5c895ef7f95d52f2cc4d","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"eb9818b9094675c0c5d303168f273345","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"9af0be92dcefdc1f1290441cb5ff5d9b","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"a261b429c39dbb75ae97972d7d005e6d","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"79953d804e1bbacecfd79b85fd679016","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"fdcba0d09aac31df7a0bc652f6e739bd","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":null,"url":"assets/xychartDiagram-JWTSCODW-BRvXOVlG.js"},{"revision":null,"url":"assets/vennDiagram-LZ73GAT5-DfYFnniI.js"},{"revision":null,"url":"assets/utils-Bslrbb-G.js"},{"revision":null,"url":"assets/use-monaco-theme-BQzvItNE.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-BL9OJq3X.js"},{"revision":null,"url":"assets/timeline-definition-YZTLITO2-DrjxCpEM.js"},{"revision":null,"url":"assets/terminal-tab-BrP-ENHg.css"},{"revision":null,"url":"assets/terminal-tab-BdHlIi8e.js"},{"revision":null,"url":"assets/tag-CENGyt_L.js"},{"revision":null,"url":"assets/table-C9jDaRl2.js"},{"revision":null,"url":"assets/tab-store-DSz5PQI0.js"},{"revision":null,"url":"assets/switch-mjGtIVDJ.js"},{"revision":null,"url":"assets/stateDiagram-v2-FVOUBMTO-D7qSAjnK.js"},{"revision":null,"url":"assets/stateDiagram-RAJIS63D-C16aO8tn.js"},{"revision":null,"url":"assets/src-CLWraeNW.js"},{"revision":null,"url":"assets/sqlite-viewer-D3N938wy.js"},{"revision":null,"url":"assets/settings-tab-rB971cXs.js"},{"revision":null,"url":"assets/settings-store-D3dJqGhB.js"},{"revision":null,"url":"assets/sequenceDiagram-2WXFIKYE-BtRvoUTC.js"},{"revision":null,"url":"assets/sankeyDiagram-WA2Y5GQK-DEGGYsk7.js"},{"revision":null,"url":"assets/rough.esm-c4PR5shF.js"},{"revision":null,"url":"assets/requirementDiagram-Z7DCOOCP-1WWjMQB_.js"},{"revision":null,"url":"assets/react-nm2Ru1Pt.js"},{"revision":null,"url":"assets/react-BPIfZRKM.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-CHptMqVT.js"},{"revision":null,"url":"assets/quadrantDiagram-337W2JSQ-BaRFqlsA.js"},{"revision":null,"url":"assets/preload-helper-CsoeaaUJ.js"},{"revision":null,"url":"assets/postgres-viewer-Dg23WW__.js"},{"revision":null,"url":"assets/pieDiagram-SKSYHLDU-seSK40d1.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-B0h6hM1j.js"},{"revision":null,"url":"assets/path-CuyvWNAH.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-BbzPU9BK.js"},{"revision":null,"url":"assets/ordinal-CIoJK3nc.js"},{"revision":null,"url":"assets/mindmap-definition-YRQLILUH-DIv-LMXG.js"},{"revision":null,"url":"assets/mermaid-parser.core-BY8JfkE_.js"},{"revision":null,"url":"assets/math-a44lmFDa.js"},{"revision":null,"url":"assets/markdown-renderer-CFW_zoSR.js"},{"revision":null,"url":"assets/linear-BdqW7iQu.js"},{"revision":null,"url":"assets/line--xyfYP3x.js"},{"revision":null,"url":"assets/keybindings-store-Cmf2viOa.js"},{"revision":null,"url":"assets/katex-C3cZrCvP.js"},{"revision":null,"url":"assets/kanban-definition-K7BYSVSG-BMUhjxqj.js"},{"revision":null,"url":"assets/jsx-runtime-BRW_vwa9.js"},{"revision":null,"url":"assets/journeyDiagram-4ABVD52K-DFQXUZsc.js"},{"revision":null,"url":"assets/ishikawaDiagram-PHBUUO56-cW7SMLa_.js"},{"revision":null,"url":"assets/isEmpty-DXomfd7J.js"},{"revision":null,"url":"assets/isArrayLikeObject-DvHDmeBe.js"},{"revision":null,"url":"assets/input-DGlv6gt_.js"},{"revision":null,"url":"assets/init-vVpfz1D6.js"},{"revision":null,"url":"assets/infoDiagram-LFFYTUFH-DFh9c-S2.js"},{"revision":null,"url":"assets/info-3K5VOQVL-CbpovIYU.js"},{"revision":null,"url":"assets/index-CKvJPAPG.js"},{"revision":null,"url":"assets/index-B4Iz1Wbi.css"},{"revision":null,"url":"assets/graphlib-BbbiUImY.js"},{"revision":null,"url":"assets/gitGraphDiagram-K3NZZRJ6-L7sj3Bs-.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-D5qEPjgs.js"},{"revision":null,"url":"assets/git-graph-BNbraUOe.js"},{"revision":null,"url":"assets/ganttDiagram-A5KZAMGK-BVlftqyZ.js"},{"revision":null,"url":"assets/flowDiagram-PKNHOUZH-B9h_Ba-v.js"},{"revision":null,"url":"assets/erDiagram-INFDFZHY-DK4QEZYh.js"},{"revision":null,"url":"assets/dist-Ckxnw5rl.js"},{"revision":null,"url":"assets/dist-CMmNEgEP.js"},{"revision":null,"url":"assets/diff-viewer-CnjvJhwy.js"},{"revision":null,"url":"assets/diagram-P4PSJMXO--nUaNiyB.js"},{"revision":null,"url":"assets/diagram-IFDJBPK2-NvhckwcA.js"},{"revision":null,"url":"assets/diagram-E7M64L7V-CkDC2uAj.js"},{"revision":null,"url":"assets/defaultLocale-D_VMtRaY.js"},{"revision":null,"url":"assets/database-viewer-CNi9B6tN.js"},{"revision":null,"url":"assets/dagre-KLK3FWXG-Br4t5TRV.js"},{"revision":null,"url":"assets/dagre-CWo8w9wK.js"},{"revision":null,"url":"assets/cytoscape.esm-B-QQuWwK.js"},{"revision":null,"url":"assets/cose-bilkent-S5V4N54A-C1QJ6GPW.js"},{"revision":null,"url":"assets/columns-2-Bcg3QJBg.js"},{"revision":null,"url":"assets/code-editor-BVt8uVtX.js"},{"revision":null,"url":"assets/clone-DNDy9Sms.js"},{"revision":null,"url":"assets/classDiagram-v2-RAHNMMFH-Bo5WN2ok.js"},{"revision":null,"url":"assets/classDiagram-VBA2DB6C-CqaIqYPn.js"},{"revision":null,"url":"assets/chunk-YBOYWFTD-COdZIaX4.js"},{"revision":null,"url":"assets/chunk-XZSTWKYB-5W2emiq4.js"},{"revision":null,"url":"assets/chunk-XPW4576I-CsGTseUr.js"},{"revision":null,"url":"assets/chunk-XIRO2GV7-DUmQrLsF.js"},{"revision":null,"url":"assets/chunk-WL4C6EOR-BHFnnXOt.js"},{"revision":null,"url":"assets/chunk-R5LLSJPH-LdG7RqsM.js"},{"revision":null,"url":"assets/chunk-QZHKN3VN-gaBt0Rbd.js"},{"revision":null,"url":"assets/chunk-PU5JKC2W-D3thuSok.js"},{"revision":null,"url":"assets/chunk-PQ6SQG4A-EdgQyTqa.js"},{"revision":null,"url":"assets/chunk-OZEHJAEY-LfXT4p8B.js"},{"revision":null,"url":"assets/chunk-O4XLMI2P-BdXwVXjJ.js"},{"revision":null,"url":"assets/chunk-NQ4KR5QH-BRj25yO7.js"},{"revision":null,"url":"assets/chunk-MX3YWQON-BnPzQK-O.js"},{"revision":null,"url":"assets/chunk-L3YUKLVL-DNFj84V6.js"},{"revision":null,"url":"assets/chunk-KYZI473N-CBRPKraG.js"},{"revision":null,"url":"assets/chunk-KX2RTZJC-BRj-ZEvL.js"},{"revision":null,"url":"assets/chunk-JSJVCQXG-Pb-JMOgO.js"},{"revision":null,"url":"assets/chunk-HHEYEP7N-BnRVfNc5.js"},{"revision":null,"url":"assets/chunk-GLR3WWYH-Bx2UL5jF.js"},{"revision":null,"url":"assets/chunk-GEFDOKGD-B82RP9ow.js"},{"revision":null,"url":"assets/chunk-FMBD7UC4-JCLgVcaC.js"},{"revision":null,"url":"assets/chunk-EGIJ26TM-Cgt-qg75.js"},{"revision":null,"url":"assets/chunk-CFjPhJqf.js"},{"revision":null,"url":"assets/chunk-C72U2L5F-CcEW1AMZ.js"},{"revision":null,"url":"assets/chunk-7R4GIKGN-DvbvLUIN.js"},{"revision":null,"url":"assets/chunk-7E7YKBS2-CuYKSUgJ.js"},{"revision":null,"url":"assets/chunk-55IACEB6-Dp0pTM5r.js"},{"revision":null,"url":"assets/chunk-4BX2VUAB-0YMkpW2S.js"},{"revision":null,"url":"assets/chat-tab-C8bt4tdL.js"},{"revision":null,"url":"assets/channel-CKNZAqoN.js"},{"revision":null,"url":"assets/c4Diagram-IC4MRINW-DzjR91sM.js"},{"revision":null,"url":"assets/browser-tab-CEYAwJUI.js"},{"revision":null,"url":"assets/blockDiagram-WCTKOSBZ-CU2t4NHJ.js"},{"revision":null,"url":"assets/arrow-left-C_j9Ki73.js"},{"revision":null,"url":"assets/array-CLwNaqU1.js"},{"revision":null,"url":"assets/architectureDiagram-2XIMDMQ5-BVEUkQYB.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-281eTKQ3.js"},{"revision":null,"url":"assets/arc-D0bJaFyD.js"},{"revision":null,"url":"assets/api-settings-CuUkz5gb.js"},{"revision":null,"url":"assets/api-client-icCZ-07C.js"},{"revision":null,"url":"assets/_baseUniq-DCb0mkTp.js"},{"revision":null,"url":"assets/_basePickBy-COwDPZl_.js"},{"revision":"79c8870653c8f419f2e3323085e1f4be","url":"manifest.webmanifest"}]),self.addEventListener(`push`,e=>{e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{if(t.some(e=>e.visibilityState===`visible`))return;let n=e.data?.json()??{title:`PPM`,body:`Chat completed`};return self.registration.showNotification(n.title,{body:n.body,icon:`/icon-192.png`,badge:`/icon-192.png`,tag:`ppm-chat-done`,silent:!1,data:{url:self.location.origin}})}))}),self.addEventListener(`notificationclick`,e=>{e.notification.close(),e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{for(let e of t)if(e.url.includes(self.location.origin)&&`focus`in e)return e.focus();return self.clients.openWindow(e.notification.data?.url||`/`)}))});
|
package/package.json
CHANGED
|
@@ -25,6 +25,84 @@ function getSdkSessionId(ppmId: string): string {
|
|
|
25
25
|
return getSessionMapping(ppmId) ?? ppmId;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
// ── Streaming Input: message channel for persistent query ──
|
|
29
|
+
|
|
30
|
+
interface MessageController {
|
|
31
|
+
push(msg: any): void;
|
|
32
|
+
done(): void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function createMessageChannel(): {
|
|
36
|
+
generator: AsyncGenerator<any, void, undefined>;
|
|
37
|
+
controller: MessageController;
|
|
38
|
+
} {
|
|
39
|
+
const queue: any[] = [];
|
|
40
|
+
let resolve: ((msg: any) => void) | null = null;
|
|
41
|
+
let isDone = false;
|
|
42
|
+
|
|
43
|
+
async function* gen(): AsyncGenerator<any, void, undefined> {
|
|
44
|
+
while (!isDone) {
|
|
45
|
+
if (queue.length > 0) {
|
|
46
|
+
yield queue.shift()!;
|
|
47
|
+
} else {
|
|
48
|
+
const msg = await new Promise<any>((r) => { resolve = r; });
|
|
49
|
+
if (!isDone) yield msg;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
generator: gen(),
|
|
56
|
+
controller: {
|
|
57
|
+
push(msg: any) {
|
|
58
|
+
if (isDone) return;
|
|
59
|
+
if (resolve) {
|
|
60
|
+
const r = resolve;
|
|
61
|
+
resolve = null;
|
|
62
|
+
r(msg);
|
|
63
|
+
} else {
|
|
64
|
+
queue.push(msg);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
done() {
|
|
68
|
+
isDone = true;
|
|
69
|
+
if (resolve) {
|
|
70
|
+
const r = resolve;
|
|
71
|
+
resolve = null;
|
|
72
|
+
r(null); // Unblock pending promise; isDone prevents yield
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Build a MessageParam with optional image content blocks */
|
|
80
|
+
function buildMessageParam(
|
|
81
|
+
text: string,
|
|
82
|
+
images?: Array<{ data: string; mediaType: string }>,
|
|
83
|
+
): { role: 'user'; content: string | any[] } {
|
|
84
|
+
if (!images || images.length === 0) {
|
|
85
|
+
return { role: 'user' as const, content: text };
|
|
86
|
+
}
|
|
87
|
+
const blocks: any[] = [];
|
|
88
|
+
for (const img of images) {
|
|
89
|
+
blocks.push({
|
|
90
|
+
type: 'image',
|
|
91
|
+
source: { type: 'base64', media_type: img.mediaType, data: img.data },
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (text.trim()) {
|
|
95
|
+
blocks.push({ type: 'text', text });
|
|
96
|
+
}
|
|
97
|
+
return { role: 'user' as const, content: blocks };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
interface StreamingSession {
|
|
101
|
+
meta: Session;
|
|
102
|
+
query: any;
|
|
103
|
+
controller: MessageController;
|
|
104
|
+
}
|
|
105
|
+
|
|
28
106
|
/**
|
|
29
107
|
* Pending approval: canUseTool callback creates a promise,
|
|
30
108
|
* yields an approval_request event, then awaits resolution from FE.
|
|
@@ -50,6 +128,8 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
50
128
|
private activeQueries = new Map<string, { close: () => void }>();
|
|
51
129
|
/** Fork source: ppmSessionId → sourceSessionId (used on first message to fork) */
|
|
52
130
|
private forkSources = new Map<string, string>();
|
|
131
|
+
/** Streaming sessions: persistent query + message channel per session */
|
|
132
|
+
private streamingSessions = new Map<string, StreamingSession>();
|
|
53
133
|
|
|
54
134
|
/** Auth-related env keys for diagnostic logging */
|
|
55
135
|
private readonly AUTH_ENV_KEYS = ["ANTHROPIC_API_KEY", "ANTHROPIC_BASE_URL", "ANTHROPIC_AUTH_TOKEN"];
|
|
@@ -220,6 +300,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
220
300
|
}
|
|
221
301
|
|
|
222
302
|
async deleteSession(sessionId: string): Promise<void> {
|
|
303
|
+
this.closeStreamingSession(sessionId);
|
|
223
304
|
this.activeSessions.delete(sessionId);
|
|
224
305
|
this.messageCount.delete(sessionId);
|
|
225
306
|
}
|
|
@@ -260,11 +341,63 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
260
341
|
}
|
|
261
342
|
}
|
|
262
343
|
|
|
344
|
+
/**
|
|
345
|
+
* Push a follow-up message into an existing streaming session's generator.
|
|
346
|
+
* Called by WS handler for follow-up messages (Phase 2).
|
|
347
|
+
*/
|
|
348
|
+
pushMessage(sessionId: string, content: string, opts?: { priority?: 'now' | 'next' | 'later'; images?: Array<{ data: string; mediaType: string }> }): void {
|
|
349
|
+
const ss = this.streamingSessions.get(sessionId);
|
|
350
|
+
if (!ss) {
|
|
351
|
+
console.warn(`[sdk] pushMessage: no streaming session for ${sessionId}`);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const msgContent = buildMessageParam(content, opts?.images);
|
|
355
|
+
ss.controller.push({
|
|
356
|
+
type: 'user',
|
|
357
|
+
message: msgContent,
|
|
358
|
+
parent_tool_use_id: null,
|
|
359
|
+
session_id: sessionId,
|
|
360
|
+
priority: opts?.priority ?? 'next',
|
|
361
|
+
});
|
|
362
|
+
console.log(`[sdk] pushMessage: session=${sessionId} priority=${opts?.priority ?? 'next'}`);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/** Close a streaming session — generator + query cleanup */
|
|
366
|
+
closeStreamingSession(sessionId: string): void {
|
|
367
|
+
const ss = this.streamingSessions.get(sessionId);
|
|
368
|
+
if (ss) {
|
|
369
|
+
ss.controller.done();
|
|
370
|
+
ss.query.close();
|
|
371
|
+
this.streamingSessions.delete(sessionId);
|
|
372
|
+
console.log(`[sdk] closeStreamingSession: session=${sessionId}`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/** Check if a streaming session is active for a given session ID */
|
|
377
|
+
hasStreamingSession(sessionId: string): boolean {
|
|
378
|
+
return this.streamingSessions.has(sessionId);
|
|
379
|
+
}
|
|
380
|
+
|
|
263
381
|
async *sendMessage(
|
|
264
382
|
sessionId: string,
|
|
265
383
|
message: string,
|
|
266
|
-
opts?: import("./provider.interface.ts").SendMessageOpts & { forkSession?: boolean },
|
|
384
|
+
opts?: import("./provider.interface.ts").SendMessageOpts & { forkSession?: boolean; priority?: 'now' | 'next' | 'later'; images?: Array<{ data: string; mediaType: string }> },
|
|
267
385
|
): AsyncIterable<ChatEvent> {
|
|
386
|
+
// Follow-up: push into existing streaming session, yield nothing
|
|
387
|
+
const existingStream = this.streamingSessions.get(sessionId);
|
|
388
|
+
if (existingStream) {
|
|
389
|
+
const msgContent = buildMessageParam(message, opts?.images);
|
|
390
|
+
existingStream.controller.push({
|
|
391
|
+
type: 'user',
|
|
392
|
+
message: msgContent,
|
|
393
|
+
parent_tool_use_id: null,
|
|
394
|
+
session_id: sessionId,
|
|
395
|
+
priority: opts?.priority ?? 'next',
|
|
396
|
+
});
|
|
397
|
+
console.log(`[sdk] sendMessage follow-up: session=${sessionId} pushed to generator`);
|
|
398
|
+
return; // Events flow through first-message's consumer loop
|
|
399
|
+
}
|
|
400
|
+
|
|
268
401
|
if (!this.activeSessions.has(sessionId)) {
|
|
269
402
|
await this.resumeSession(sessionId);
|
|
270
403
|
}
|
|
@@ -387,6 +520,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
387
520
|
let resultSubtype: string | undefined;
|
|
388
521
|
let resultNumTurns: number | undefined;
|
|
389
522
|
let resultContextWindowPct: number | undefined;
|
|
523
|
+
let yieldedDone = false;
|
|
390
524
|
try {
|
|
391
525
|
// Resolve SDK's actual session ID for resume (may differ from PPM's UUID)
|
|
392
526
|
// For fork: use the source session's SDK id
|
|
@@ -458,14 +592,25 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
458
592
|
includePartialMessages: true,
|
|
459
593
|
};
|
|
460
594
|
|
|
595
|
+
// Streaming input: create message channel and persistent query
|
|
596
|
+
const { generator: streamGen, controller: streamCtrl } = createMessageChannel();
|
|
597
|
+
const firstMsg = {
|
|
598
|
+
type: 'user' as const,
|
|
599
|
+
message: buildMessageParam(message),
|
|
600
|
+
parent_tool_use_id: null,
|
|
601
|
+
session_id: sessionId,
|
|
602
|
+
};
|
|
603
|
+
streamCtrl.push(firstMsg);
|
|
604
|
+
|
|
461
605
|
const q = query({
|
|
462
|
-
prompt:
|
|
606
|
+
prompt: streamGen,
|
|
463
607
|
options: {
|
|
464
608
|
...queryOptions,
|
|
465
609
|
...(permissionHooks && { hooks: permissionHooks }),
|
|
466
610
|
canUseTool,
|
|
467
611
|
} as any,
|
|
468
612
|
});
|
|
613
|
+
this.streamingSessions.set(sessionId, { meta, query: q, controller: streamCtrl });
|
|
469
614
|
this.activeQueries.set(sessionId, q);
|
|
470
615
|
let eventSource: AsyncIterable<any> = q;
|
|
471
616
|
|
|
@@ -480,22 +625,29 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
480
625
|
let retryCount = 0;
|
|
481
626
|
let authRetried = false;
|
|
482
627
|
|
|
628
|
+
let hadAnyEvents = false;
|
|
483
629
|
retryLoop: while (true) {
|
|
484
630
|
let sdkEventCount = 0;
|
|
485
631
|
for await (const msg of eventSource) {
|
|
486
632
|
sdkEventCount++;
|
|
633
|
+
hadAnyEvents = true;
|
|
487
634
|
if (sdkEventCount === 1) {
|
|
488
635
|
console.log(`[sdk] first event received: type=${(msg as any).type} subtype=${(msg as any).subtype ?? "none"}`);
|
|
489
636
|
// Detect immediate failure: first event is a result with error + 0 turns
|
|
490
637
|
if ((msg as any).type === "result" && (msg as any).subtype === "error_during_execution" && ((msg as any).num_turns ?? 0) === 0 && retryCount < MAX_RETRIES) {
|
|
491
638
|
retryCount++;
|
|
492
639
|
console.warn(`[sdk] transient error on first event — retrying (attempt ${retryCount}/${MAX_RETRIES})`);
|
|
493
|
-
//
|
|
640
|
+
// Close failed query and old channel, create new channel + query for retry
|
|
641
|
+
streamCtrl.done();
|
|
642
|
+
q.close();
|
|
643
|
+
const { generator: retryGen, controller: retryCtrl } = createMessageChannel();
|
|
644
|
+
retryCtrl.push(firstMsg);
|
|
494
645
|
const retryOpts = { ...queryOptions, sessionId: undefined, resume: undefined };
|
|
495
646
|
const rq = query({
|
|
496
|
-
prompt:
|
|
647
|
+
prompt: retryGen,
|
|
497
648
|
options: { ...retryOpts, ...(permissionHooks && { hooks: permissionHooks }), canUseTool } as any,
|
|
498
649
|
});
|
|
650
|
+
this.streamingSessions.set(sessionId, { meta, query: rq, controller: retryCtrl });
|
|
499
651
|
this.activeQueries.set(sessionId, rq);
|
|
500
652
|
eventSource = rq;
|
|
501
653
|
continue retryLoop;
|
|
@@ -641,11 +793,17 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
641
793
|
const refreshedAccount = accountService.getWithTokens(account.id);
|
|
642
794
|
if (refreshedAccount) {
|
|
643
795
|
const retryEnv = this.buildQueryEnv(meta.projectPath, refreshedAccount);
|
|
796
|
+
// Close failed query and old channel, create new channel + query with refreshed token
|
|
797
|
+
streamCtrl.done();
|
|
798
|
+
q.close();
|
|
799
|
+
const { generator: authRetryGen, controller: authRetryCtrl } = createMessageChannel();
|
|
800
|
+
authRetryCtrl.push(firstMsg);
|
|
644
801
|
const retryOpts = { ...queryOptions, sessionId: undefined, resume: undefined, env: retryEnv };
|
|
645
802
|
const rq = query({
|
|
646
|
-
prompt:
|
|
803
|
+
prompt: authRetryGen,
|
|
647
804
|
options: { ...retryOpts, ...(permissionHooks && { hooks: permissionHooks }), canUseTool } as any,
|
|
648
805
|
});
|
|
806
|
+
this.streamingSessions.set(sessionId, { meta, query: rq, controller: authRetryCtrl });
|
|
649
807
|
this.activeQueries.set(sessionId, rq);
|
|
650
808
|
eventSource = rq;
|
|
651
809
|
continue retryLoop;
|
|
@@ -717,9 +875,9 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
717
875
|
const errCode = this.detectResultErrorCode(msg);
|
|
718
876
|
if (errCode === 429) {
|
|
719
877
|
accountSelector.onRateLimit(account.id);
|
|
720
|
-
// Post-stream 429
|
|
878
|
+
// Post-stream 429 — surface error, continue waiting for next turn
|
|
721
879
|
yield { type: "error", message: "Rate limited. This account is now on cooldown. Please retry." };
|
|
722
|
-
|
|
880
|
+
continue;
|
|
723
881
|
} else if (errCode === 401) {
|
|
724
882
|
// Try refresh once
|
|
725
883
|
try {
|
|
@@ -827,7 +985,26 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
827
985
|
}
|
|
828
986
|
}
|
|
829
987
|
}
|
|
830
|
-
|
|
988
|
+
|
|
989
|
+
// Streaming input: yield done for this turn, then continue for next turn
|
|
990
|
+
yieldedDone = true;
|
|
991
|
+
yield {
|
|
992
|
+
type: "done",
|
|
993
|
+
sessionId,
|
|
994
|
+
resultSubtype: resultSubtype as any,
|
|
995
|
+
numTurns: resultNumTurns,
|
|
996
|
+
contextWindowPct: resultContextWindowPct,
|
|
997
|
+
};
|
|
998
|
+
|
|
999
|
+
// Reset per-turn state for next turn
|
|
1000
|
+
lastPartialText = "";
|
|
1001
|
+
pendingToolCount = 0;
|
|
1002
|
+
assistantContent = "";
|
|
1003
|
+
resultSubtype = undefined;
|
|
1004
|
+
resultNumTurns = undefined;
|
|
1005
|
+
resultContextWindowPct = undefined;
|
|
1006
|
+
sdkEventCount = 0;
|
|
1007
|
+
continue; // Wait for next turn from generator
|
|
831
1008
|
}
|
|
832
1009
|
}
|
|
833
1010
|
|
|
@@ -836,7 +1013,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
836
1013
|
yield approvalEvents.shift()!;
|
|
837
1014
|
}
|
|
838
1015
|
|
|
839
|
-
if (
|
|
1016
|
+
if (!hadAnyEvents) {
|
|
840
1017
|
yield { type: "error", message: "Claude did not respond. Check that 'claude' CLI works in your terminal." };
|
|
841
1018
|
}
|
|
842
1019
|
break; // Exit retryLoop — normal completion
|
|
@@ -846,88 +1023,47 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
846
1023
|
console.error(`[sdk] session=${sessionId} cwd=${meta.projectPath} error: ${msg}`);
|
|
847
1024
|
if (msg.includes("abort") || msg.includes("closed")) {
|
|
848
1025
|
// User-initiated abort or WS closed — nothing to report
|
|
849
|
-
} else if (
|
|
850
|
-
//
|
|
851
|
-
console.warn(`[sdk] session
|
|
852
|
-
|
|
853
|
-
const providerConfig = this.getProviderConfig();
|
|
854
|
-
const effectiveCwd = meta.projectPath || homedir();
|
|
855
|
-
const retryAccount = accountSelector.isEnabled() ? accountSelector.next() : null;
|
|
856
|
-
const queryEnv = this.buildQueryEnv(meta.projectPath, retryAccount);
|
|
857
|
-
const retryOptions = {
|
|
858
|
-
...(process.platform === "win32" && { executable: "node" }),
|
|
859
|
-
cwd: effectiveCwd,
|
|
860
|
-
systemPrompt: systemPromptOpt,
|
|
861
|
-
settingSources: ["user", "project"],
|
|
862
|
-
env: queryEnv,
|
|
863
|
-
settings: { permissions: { allow: [], deny: [] } },
|
|
864
|
-
allowedTools,
|
|
865
|
-
permissionMode,
|
|
866
|
-
allowDangerouslySkipPermissions: isBypass,
|
|
867
|
-
...(providerConfig.model && { model: providerConfig.model }),
|
|
868
|
-
maxTurns: providerConfig.max_turns ?? 100,
|
|
869
|
-
includePartialMessages: true,
|
|
870
|
-
};
|
|
871
|
-
const retryQuery = query({
|
|
872
|
-
prompt: message,
|
|
873
|
-
options: {
|
|
874
|
-
...retryOptions,
|
|
875
|
-
...(permissionHooks && { hooks: permissionHooks }),
|
|
876
|
-
canUseTool,
|
|
877
|
-
} as any,
|
|
878
|
-
});
|
|
879
|
-
this.activeQueries.set(sessionId, retryQuery);
|
|
880
|
-
for await (const retryMsg of retryQuery) {
|
|
881
|
-
if (retryMsg.type === "system") continue;
|
|
882
|
-
if (retryMsg.type === "result") {
|
|
883
|
-
const r = retryMsg as any;
|
|
884
|
-
if (r.subtype && r.subtype !== "success") {
|
|
885
|
-
const retryErrors = Array.isArray(r.errors) ? r.errors.join("\n") : "";
|
|
886
|
-
yield { type: "error", message: retryErrors || `Agent stopped: ${r.subtype}` };
|
|
887
|
-
}
|
|
888
|
-
resultSubtype = r.subtype;
|
|
889
|
-
resultNumTurns = r.num_turns;
|
|
890
|
-
break;
|
|
891
|
-
}
|
|
892
|
-
if ((retryMsg as any).type === "assistant") {
|
|
893
|
-
const content = (retryMsg as any).message?.content;
|
|
894
|
-
if (Array.isArray(content)) {
|
|
895
|
-
for (const block of content) {
|
|
896
|
-
if (block.type === "text" && typeof block.text === "string") {
|
|
897
|
-
yield { type: "text", content: block.text };
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
} catch (retryErr) {
|
|
904
|
-
const retryMsg = (retryErr as Error).message ?? String(retryErr);
|
|
905
|
-
console.error(`[sdk] retry also failed: ${retryMsg}`);
|
|
906
|
-
yield { type: "error", message: `SDK error: ${msg}` };
|
|
907
|
-
}
|
|
1026
|
+
} else if (msg.includes("exited with code")) {
|
|
1027
|
+
// Subprocess crashed — session will auto-recover on next message
|
|
1028
|
+
console.warn(`[sdk] session=${sessionId} subprocess crashed: ${msg}`);
|
|
1029
|
+
yield { type: "error", message: `SDK subprocess crashed. Send another message to auto-recover.` };
|
|
908
1030
|
} else {
|
|
909
1031
|
yield { type: "error", message: `SDK error: ${msg}` };
|
|
910
1032
|
}
|
|
911
1033
|
} finally {
|
|
912
1034
|
this.activeQueries.delete(sessionId);
|
|
1035
|
+
this.streamingSessions.delete(sessionId);
|
|
1036
|
+
console.log(`[sdk] session=${sessionId} streaming session ended`);
|
|
913
1037
|
}
|
|
914
1038
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
1039
|
+
// Final done event when query ends (crash, close, generator done)
|
|
1040
|
+
// Skip if we already yielded done from the result handler (avoid duplicate)
|
|
1041
|
+
if (!yieldedDone) {
|
|
1042
|
+
yield {
|
|
1043
|
+
type: "done",
|
|
1044
|
+
sessionId,
|
|
1045
|
+
resultSubtype: resultSubtype as any,
|
|
1046
|
+
numTurns: resultNumTurns,
|
|
1047
|
+
contextWindowPct: resultContextWindowPct,
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
922
1050
|
}
|
|
923
1051
|
|
|
924
1052
|
|
|
925
|
-
/**
|
|
1053
|
+
/** Interrupt the current turn — session stays alive for the next message */
|
|
926
1054
|
abortQuery(sessionId: string): void {
|
|
1055
|
+
const ss = this.streamingSessions.get(sessionId);
|
|
1056
|
+
if (ss && typeof ss.query.interrupt === "function") {
|
|
1057
|
+
ss.query.interrupt().catch(() => {});
|
|
1058
|
+
console.log(`[sdk] abortQuery: interrupted session=${sessionId}`);
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
// Fallback: close query entirely and clean up streaming session
|
|
927
1062
|
const q = this.activeQueries.get(sessionId);
|
|
928
1063
|
if (q) {
|
|
929
1064
|
q.close();
|
|
930
1065
|
this.activeQueries.delete(sessionId);
|
|
1066
|
+
this.streamingSessions.delete(sessionId);
|
|
931
1067
|
}
|
|
932
1068
|
}
|
|
933
1069
|
|