@hienlh/ppm 0.9.0-beta.2 → 0.9.0-beta.3
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.
- package/CHANGELOG.md +19 -0
- package/dist/web/assets/chat-tab-DxkvWelV.js +7 -0
- package/dist/web/assets/{code-editor-CQ7gq0Vj.js → code-editor-D3VJc1tY.js} +1 -1
- package/dist/web/assets/{database-viewer-B27aRtdQ.js → database-viewer-qlwORhh0.js} +1 -1
- package/dist/web/assets/{diff-viewer-BjtTemkK.js → diff-viewer-D5vGZJnH.js} +1 -1
- package/dist/web/assets/{git-graph-BGXo0o-J.js → git-graph-B2fHtKEc.js} +1 -1
- package/dist/web/assets/{index-CfClIVo2.js → index-Ccq6zi2E.js} +3 -3
- package/dist/web/assets/keybindings-store-e3pqlQbf.js +1 -0
- package/dist/web/assets/{markdown-renderer-BtPXdzTv.js → markdown-renderer-DcGMlbRm.js} +1 -1
- package/dist/web/assets/{postgres-viewer-BMg-qFcO.js → postgres-viewer-CZzbMFtb.js} +1 -1
- package/dist/web/assets/{settings-tab-NPuwQHzs.js → settings-tab-BOmLAhkD.js} +1 -1
- package/dist/web/assets/{sqlite-viewer-CAsUczio.js → sqlite-viewer-CrrzHXqq.js} +1 -1
- package/dist/web/assets/{terminal-tab--Gw14HP3.js → terminal-tab-DHMITI3S.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 -72
- 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/chat-tab-DmF14O6G.js +0 -7
- package/dist/web/assets/keybindings-store-nDbczFnq.js +0 -1
- package/snapshot-state.md +0 -1526
- package/test-tokens.mjs +0 -212
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":"d727287b574458f5a539d893cd93db9e","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-DhUL86qT.js"},{"revision":null,"url":"assets/vennDiagram-LZ73GAT5-DqbKNRD9.js"},{"revision":null,"url":"assets/utils-btZ8C8-R.js"},{"revision":null,"url":"assets/use-monaco-theme-DHbyUrzJ.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-2_y-mhkz.js"},{"revision":null,"url":"assets/timeline-definition-YZTLITO2-DYfwJ1jM.js"},{"revision":null,"url":"assets/terminal-tab-BrP-ENHg.css"},{"revision":null,"url":"assets/terminal-tab--Gw14HP3.js"},{"revision":null,"url":"assets/tag-CaC1ng2E.js"},{"revision":null,"url":"assets/table-Yo02WRH-.js"},{"revision":null,"url":"assets/tab-store-dpsCvqhH.js"},{"revision":null,"url":"assets/stateDiagram-v2-FVOUBMTO-CMN4M2Em.js"},{"revision":null,"url":"assets/stateDiagram-RAJIS63D-DfRBcaBu.js"},{"revision":null,"url":"assets/src-BoSBNdA_.js"},{"revision":null,"url":"assets/sqlite-viewer-CAsUczio.js"},{"revision":null,"url":"assets/settings-tab-NPuwQHzs.js"},{"revision":null,"url":"assets/settings-store-Bbhg_ptG.js"},{"revision":null,"url":"assets/sequenceDiagram-2WXFIKYE-fyWIrHiG.js"},{"revision":null,"url":"assets/sankeyDiagram-WA2Y5GQK-BA9EFAAe.js"},{"revision":null,"url":"assets/rough.esm-VLpapkIG.js"},{"revision":null,"url":"assets/requirementDiagram-Z7DCOOCP-D_5GXNRo.js"},{"revision":null,"url":"assets/react-nm2Ru1Pt.js"},{"revision":null,"url":"assets/react-BGf7KNLk.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-C4PnyG7_.js"},{"revision":null,"url":"assets/quadrantDiagram-337W2JSQ-B7zgALOL.js"},{"revision":null,"url":"assets/preload-helper-qlgyTAkD.js"},{"revision":null,"url":"assets/postgres-viewer-BMg-qFcO.js"},{"revision":null,"url":"assets/pieDiagram-SKSYHLDU-Bkh2E4zE.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-Bm5LiD-6.js"},{"revision":null,"url":"assets/path-DZF-JdEe.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-CdYSLjRL.js"},{"revision":null,"url":"assets/ordinal-CCj7PWgZ.js"},{"revision":null,"url":"assets/mindmap-definition-YRQLILUH-DoT7m4Sz.js"},{"revision":null,"url":"assets/mermaid-parser.core-BKiGOTjR.js"},{"revision":null,"url":"assets/math-DwgHI-Cu.js"},{"revision":null,"url":"assets/markdown-renderer-BtPXdzTv.js"},{"revision":null,"url":"assets/linear-BLFWatDe.js"},{"revision":null,"url":"assets/line-DBLLF7lH.js"},{"revision":null,"url":"assets/keybindings-store-nDbczFnq.js"},{"revision":null,"url":"assets/katex-Bbu770d9.js"},{"revision":null,"url":"assets/kanban-definition-K7BYSVSG-BBXbI37U.js"},{"revision":null,"url":"assets/jsx-runtime-BRW_vwa9.js"},{"revision":null,"url":"assets/journeyDiagram-4ABVD52K-CttDH9bb.js"},{"revision":null,"url":"assets/ishikawaDiagram-PHBUUO56-olazD6dZ.js"},{"revision":null,"url":"assets/isEmpty-C0YYdhYj.js"},{"revision":null,"url":"assets/isArrayLikeObject-B4pdpV8V.js"},{"revision":null,"url":"assets/input-Brjz2Vv-.js"},{"revision":null,"url":"assets/init-B8gtcn7T.js"},{"revision":null,"url":"assets/infoDiagram-LFFYTUFH-BzqyoqXw.js"},{"revision":null,"url":"assets/info-3K5VOQVL-ce_pi3En.js"},{"revision":null,"url":"assets/index-CfClIVo2.js"},{"revision":null,"url":"assets/index-BAioKo_2.css"},{"revision":null,"url":"assets/graphlib-DhOZxqsh.js"},{"revision":null,"url":"assets/gitGraphDiagram-K3NZZRJ6-yEWZbdf_.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-CEee2FCA.js"},{"revision":null,"url":"assets/git-graph-BGXo0o-J.js"},{"revision":null,"url":"assets/ganttDiagram-A5KZAMGK-DIX0pLbk.js"},{"revision":null,"url":"assets/flowDiagram-PKNHOUZH-14ohZ1M1.js"},{"revision":null,"url":"assets/erDiagram-INFDFZHY-mCvUFSn6.js"},{"revision":null,"url":"assets/dist-T0Vhi0Mh.js"},{"revision":null,"url":"assets/dist-Cce3efmT.js"},{"revision":null,"url":"assets/diff-viewer-BjtTemkK.js"},{"revision":null,"url":"assets/diagram-P4PSJMXO-D1eW1dkL.js"},{"revision":null,"url":"assets/diagram-IFDJBPK2-ChB_paPo.js"},{"revision":null,"url":"assets/diagram-E7M64L7V-CzKYZM0Y.js"},{"revision":null,"url":"assets/defaultLocale-CRZydyG6.js"},{"revision":null,"url":"assets/database-viewer-B27aRtdQ.js"},{"revision":null,"url":"assets/dagre-KLK3FWXG-ChenfPp1.js"},{"revision":null,"url":"assets/dagre-CNtSxiE_.js"},{"revision":null,"url":"assets/cytoscape.esm-Ccan6xou.js"},{"revision":null,"url":"assets/cose-bilkent-S5V4N54A-CHHjH2dV.js"},{"revision":null,"url":"assets/columns-2-ChOTgl3e.js"},{"revision":null,"url":"assets/code-editor-CQ7gq0Vj.js"},{"revision":null,"url":"assets/clone-BSi6cgDh.js"},{"revision":null,"url":"assets/classDiagram-v2-RAHNMMFH-Bj8gIhkP.js"},{"revision":null,"url":"assets/classDiagram-VBA2DB6C-BpJ6Oog2.js"},{"revision":null,"url":"assets/chunk-YBOYWFTD-Dx_fX35n.js"},{"revision":null,"url":"assets/chunk-XZSTWKYB-BYxFzZwS.js"},{"revision":null,"url":"assets/chunk-XPW4576I-CtcaMb09.js"},{"revision":null,"url":"assets/chunk-XIRO2GV7-kqQ0g6wW.js"},{"revision":null,"url":"assets/chunk-WL4C6EOR-_2CBOJdI.js"},{"revision":null,"url":"assets/chunk-R5LLSJPH-euR2RxLN.js"},{"revision":null,"url":"assets/chunk-QZHKN3VN-DwSXwtjH.js"},{"revision":null,"url":"assets/chunk-PU5JKC2W-B66ELkQm.js"},{"revision":null,"url":"assets/chunk-PQ6SQG4A-BxtUGYhW.js"},{"revision":null,"url":"assets/chunk-OZEHJAEY-YTn24bGg.js"},{"revision":null,"url":"assets/chunk-O4XLMI2P-BurQy8tt.js"},{"revision":null,"url":"assets/chunk-NQ4KR5QH-DLrZwBEm.js"},{"revision":null,"url":"assets/chunk-MX3YWQON-BgjSEzus.js"},{"revision":null,"url":"assets/chunk-L3YUKLVL-3wBgkSvL.js"},{"revision":null,"url":"assets/chunk-KYZI473N-BKO5gMeU.js"},{"revision":null,"url":"assets/chunk-KX2RTZJC-BCxGmbzy.js"},{"revision":null,"url":"assets/chunk-JSJVCQXG-BSrqCL_3.js"},{"revision":null,"url":"assets/chunk-HHEYEP7N-Dld5BpGB.js"},{"revision":null,"url":"assets/chunk-GLR3WWYH-D9pZakqr.js"},{"revision":null,"url":"assets/chunk-GEFDOKGD-DwVPiYfW.js"},{"revision":null,"url":"assets/chunk-FMBD7UC4-C_1aG0eb.js"},{"revision":null,"url":"assets/chunk-EGIJ26TM-D0KJTa_T.js"},{"revision":null,"url":"assets/chunk-CFjPhJqf.js"},{"revision":null,"url":"assets/chunk-C72U2L5F-DOtEiN5f.js"},{"revision":null,"url":"assets/chunk-7R4GIKGN-DXaGAn_K.js"},{"revision":null,"url":"assets/chunk-7E7YKBS2-6xAQfBwa.js"},{"revision":null,"url":"assets/chunk-55IACEB6-C4mUdyio.js"},{"revision":null,"url":"assets/chunk-4BX2VUAB-BptTlTyl.js"},{"revision":null,"url":"assets/chat-tab-DmF14O6G.js"},{"revision":null,"url":"assets/channel-w7yboq56.js"},{"revision":null,"url":"assets/c4Diagram-IC4MRINW-BNP2L9r_.js"},{"revision":null,"url":"assets/blockDiagram-WCTKOSBZ-CKGufRTy.js"},{"revision":null,"url":"assets/array-BGFCBI0e.js"},{"revision":null,"url":"assets/architectureDiagram-2XIMDMQ5-Jq91S_rs.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-ChOahOB7.js"},{"revision":null,"url":"assets/arc-C2Qaz-ch.js"},{"revision":null,"url":"assets/api-settings--eVrUeZM.js"},{"revision":null,"url":"assets/api-client-DpGMOZNf.js"},{"revision":null,"url":"assets/_baseUniq-ClnvscgW.js"},{"revision":null,"url":"assets/_basePickBy-CZovQgWd.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":"266fd88e14f238a28bd538c7394afe05","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-DhUL86qT.js"},{"revision":null,"url":"assets/vennDiagram-LZ73GAT5-DqbKNRD9.js"},{"revision":null,"url":"assets/utils-btZ8C8-R.js"},{"revision":null,"url":"assets/use-monaco-theme-DHbyUrzJ.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-2_y-mhkz.js"},{"revision":null,"url":"assets/timeline-definition-YZTLITO2-DYfwJ1jM.js"},{"revision":null,"url":"assets/terminal-tab-DHMITI3S.js"},{"revision":null,"url":"assets/terminal-tab-BrP-ENHg.css"},{"revision":null,"url":"assets/tag-CaC1ng2E.js"},{"revision":null,"url":"assets/table-Yo02WRH-.js"},{"revision":null,"url":"assets/tab-store-dpsCvqhH.js"},{"revision":null,"url":"assets/stateDiagram-v2-FVOUBMTO-CMN4M2Em.js"},{"revision":null,"url":"assets/stateDiagram-RAJIS63D-DfRBcaBu.js"},{"revision":null,"url":"assets/src-BoSBNdA_.js"},{"revision":null,"url":"assets/sqlite-viewer-CrrzHXqq.js"},{"revision":null,"url":"assets/settings-tab-BOmLAhkD.js"},{"revision":null,"url":"assets/settings-store-Bbhg_ptG.js"},{"revision":null,"url":"assets/sequenceDiagram-2WXFIKYE-fyWIrHiG.js"},{"revision":null,"url":"assets/sankeyDiagram-WA2Y5GQK-BA9EFAAe.js"},{"revision":null,"url":"assets/rough.esm-VLpapkIG.js"},{"revision":null,"url":"assets/requirementDiagram-Z7DCOOCP-D_5GXNRo.js"},{"revision":null,"url":"assets/react-nm2Ru1Pt.js"},{"revision":null,"url":"assets/react-BGf7KNLk.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-C4PnyG7_.js"},{"revision":null,"url":"assets/quadrantDiagram-337W2JSQ-B7zgALOL.js"},{"revision":null,"url":"assets/preload-helper-qlgyTAkD.js"},{"revision":null,"url":"assets/postgres-viewer-CZzbMFtb.js"},{"revision":null,"url":"assets/pieDiagram-SKSYHLDU-Bkh2E4zE.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-Bm5LiD-6.js"},{"revision":null,"url":"assets/path-DZF-JdEe.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-CdYSLjRL.js"},{"revision":null,"url":"assets/ordinal-CCj7PWgZ.js"},{"revision":null,"url":"assets/mindmap-definition-YRQLILUH-DoT7m4Sz.js"},{"revision":null,"url":"assets/mermaid-parser.core-BKiGOTjR.js"},{"revision":null,"url":"assets/math-DwgHI-Cu.js"},{"revision":null,"url":"assets/markdown-renderer-DcGMlbRm.js"},{"revision":null,"url":"assets/linear-BLFWatDe.js"},{"revision":null,"url":"assets/line-DBLLF7lH.js"},{"revision":null,"url":"assets/keybindings-store-e3pqlQbf.js"},{"revision":null,"url":"assets/katex-Bbu770d9.js"},{"revision":null,"url":"assets/kanban-definition-K7BYSVSG-BBXbI37U.js"},{"revision":null,"url":"assets/jsx-runtime-BRW_vwa9.js"},{"revision":null,"url":"assets/journeyDiagram-4ABVD52K-CttDH9bb.js"},{"revision":null,"url":"assets/ishikawaDiagram-PHBUUO56-olazD6dZ.js"},{"revision":null,"url":"assets/isEmpty-C0YYdhYj.js"},{"revision":null,"url":"assets/isArrayLikeObject-B4pdpV8V.js"},{"revision":null,"url":"assets/input-Brjz2Vv-.js"},{"revision":null,"url":"assets/init-B8gtcn7T.js"},{"revision":null,"url":"assets/infoDiagram-LFFYTUFH-BzqyoqXw.js"},{"revision":null,"url":"assets/info-3K5VOQVL-ce_pi3En.js"},{"revision":null,"url":"assets/index-Ccq6zi2E.js"},{"revision":null,"url":"assets/index-BAioKo_2.css"},{"revision":null,"url":"assets/graphlib-DhOZxqsh.js"},{"revision":null,"url":"assets/gitGraphDiagram-K3NZZRJ6-yEWZbdf_.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-CEee2FCA.js"},{"revision":null,"url":"assets/git-graph-B2fHtKEc.js"},{"revision":null,"url":"assets/ganttDiagram-A5KZAMGK-DIX0pLbk.js"},{"revision":null,"url":"assets/flowDiagram-PKNHOUZH-14ohZ1M1.js"},{"revision":null,"url":"assets/erDiagram-INFDFZHY-mCvUFSn6.js"},{"revision":null,"url":"assets/dist-T0Vhi0Mh.js"},{"revision":null,"url":"assets/dist-Cce3efmT.js"},{"revision":null,"url":"assets/diff-viewer-D5vGZJnH.js"},{"revision":null,"url":"assets/diagram-P4PSJMXO-D1eW1dkL.js"},{"revision":null,"url":"assets/diagram-IFDJBPK2-ChB_paPo.js"},{"revision":null,"url":"assets/diagram-E7M64L7V-CzKYZM0Y.js"},{"revision":null,"url":"assets/defaultLocale-CRZydyG6.js"},{"revision":null,"url":"assets/database-viewer-qlwORhh0.js"},{"revision":null,"url":"assets/dagre-KLK3FWXG-ChenfPp1.js"},{"revision":null,"url":"assets/dagre-CNtSxiE_.js"},{"revision":null,"url":"assets/cytoscape.esm-Ccan6xou.js"},{"revision":null,"url":"assets/cose-bilkent-S5V4N54A-CHHjH2dV.js"},{"revision":null,"url":"assets/columns-2-ChOTgl3e.js"},{"revision":null,"url":"assets/code-editor-D3VJc1tY.js"},{"revision":null,"url":"assets/clone-BSi6cgDh.js"},{"revision":null,"url":"assets/classDiagram-v2-RAHNMMFH-Bj8gIhkP.js"},{"revision":null,"url":"assets/classDiagram-VBA2DB6C-BpJ6Oog2.js"},{"revision":null,"url":"assets/chunk-YBOYWFTD-Dx_fX35n.js"},{"revision":null,"url":"assets/chunk-XZSTWKYB-BYxFzZwS.js"},{"revision":null,"url":"assets/chunk-XPW4576I-CtcaMb09.js"},{"revision":null,"url":"assets/chunk-XIRO2GV7-kqQ0g6wW.js"},{"revision":null,"url":"assets/chunk-WL4C6EOR-_2CBOJdI.js"},{"revision":null,"url":"assets/chunk-R5LLSJPH-euR2RxLN.js"},{"revision":null,"url":"assets/chunk-QZHKN3VN-DwSXwtjH.js"},{"revision":null,"url":"assets/chunk-PU5JKC2W-B66ELkQm.js"},{"revision":null,"url":"assets/chunk-PQ6SQG4A-BxtUGYhW.js"},{"revision":null,"url":"assets/chunk-OZEHJAEY-YTn24bGg.js"},{"revision":null,"url":"assets/chunk-O4XLMI2P-BurQy8tt.js"},{"revision":null,"url":"assets/chunk-NQ4KR5QH-DLrZwBEm.js"},{"revision":null,"url":"assets/chunk-MX3YWQON-BgjSEzus.js"},{"revision":null,"url":"assets/chunk-L3YUKLVL-3wBgkSvL.js"},{"revision":null,"url":"assets/chunk-KYZI473N-BKO5gMeU.js"},{"revision":null,"url":"assets/chunk-KX2RTZJC-BCxGmbzy.js"},{"revision":null,"url":"assets/chunk-JSJVCQXG-BSrqCL_3.js"},{"revision":null,"url":"assets/chunk-HHEYEP7N-Dld5BpGB.js"},{"revision":null,"url":"assets/chunk-GLR3WWYH-D9pZakqr.js"},{"revision":null,"url":"assets/chunk-GEFDOKGD-DwVPiYfW.js"},{"revision":null,"url":"assets/chunk-FMBD7UC4-C_1aG0eb.js"},{"revision":null,"url":"assets/chunk-EGIJ26TM-D0KJTa_T.js"},{"revision":null,"url":"assets/chunk-CFjPhJqf.js"},{"revision":null,"url":"assets/chunk-C72U2L5F-DOtEiN5f.js"},{"revision":null,"url":"assets/chunk-7R4GIKGN-DXaGAn_K.js"},{"revision":null,"url":"assets/chunk-7E7YKBS2-6xAQfBwa.js"},{"revision":null,"url":"assets/chunk-55IACEB6-C4mUdyio.js"},{"revision":null,"url":"assets/chunk-4BX2VUAB-BptTlTyl.js"},{"revision":null,"url":"assets/chat-tab-DxkvWelV.js"},{"revision":null,"url":"assets/channel-w7yboq56.js"},{"revision":null,"url":"assets/c4Diagram-IC4MRINW-BNP2L9r_.js"},{"revision":null,"url":"assets/blockDiagram-WCTKOSBZ-CKGufRTy.js"},{"revision":null,"url":"assets/array-BGFCBI0e.js"},{"revision":null,"url":"assets/architectureDiagram-2XIMDMQ5-Jq91S_rs.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-ChOahOB7.js"},{"revision":null,"url":"assets/arc-C2Qaz-ch.js"},{"revision":null,"url":"assets/api-settings--eVrUeZM.js"},{"revision":null,"url":"assets/api-client-DpGMOZNf.js"},{"revision":null,"url":"assets/_baseUniq-ClnvscgW.js"},{"revision":null,"url":"assets/_basePickBy-CZovQgWd.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
|
@@ -24,6 +24,84 @@ function getSdkSessionId(ppmId: string): string {
|
|
|
24
24
|
return getSessionMapping(ppmId) ?? ppmId;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
// ── Streaming Input: message channel for persistent query ──
|
|
28
|
+
|
|
29
|
+
interface MessageController {
|
|
30
|
+
push(msg: any): void;
|
|
31
|
+
done(): void;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function createMessageChannel(): {
|
|
35
|
+
generator: AsyncGenerator<any, void, undefined>;
|
|
36
|
+
controller: MessageController;
|
|
37
|
+
} {
|
|
38
|
+
const queue: any[] = [];
|
|
39
|
+
let resolve: ((msg: any) => void) | null = null;
|
|
40
|
+
let isDone = false;
|
|
41
|
+
|
|
42
|
+
async function* gen(): AsyncGenerator<any, void, undefined> {
|
|
43
|
+
while (!isDone) {
|
|
44
|
+
if (queue.length > 0) {
|
|
45
|
+
yield queue.shift()!;
|
|
46
|
+
} else {
|
|
47
|
+
const msg = await new Promise<any>((r) => { resolve = r; });
|
|
48
|
+
if (!isDone) yield msg;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
generator: gen(),
|
|
55
|
+
controller: {
|
|
56
|
+
push(msg: any) {
|
|
57
|
+
if (isDone) return;
|
|
58
|
+
if (resolve) {
|
|
59
|
+
const r = resolve;
|
|
60
|
+
resolve = null;
|
|
61
|
+
r(msg);
|
|
62
|
+
} else {
|
|
63
|
+
queue.push(msg);
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
done() {
|
|
67
|
+
isDone = true;
|
|
68
|
+
if (resolve) {
|
|
69
|
+
const r = resolve;
|
|
70
|
+
resolve = null;
|
|
71
|
+
r(null); // Unblock pending promise; isDone prevents yield
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Build a MessageParam with optional image content blocks */
|
|
79
|
+
function buildMessageParam(
|
|
80
|
+
text: string,
|
|
81
|
+
images?: Array<{ data: string; mediaType: string }>,
|
|
82
|
+
): { role: 'user'; content: string | any[] } {
|
|
83
|
+
if (!images || images.length === 0) {
|
|
84
|
+
return { role: 'user' as const, content: text };
|
|
85
|
+
}
|
|
86
|
+
const blocks: any[] = [];
|
|
87
|
+
for (const img of images) {
|
|
88
|
+
blocks.push({
|
|
89
|
+
type: 'image',
|
|
90
|
+
source: { type: 'base64', media_type: img.mediaType, data: img.data },
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
if (text.trim()) {
|
|
94
|
+
blocks.push({ type: 'text', text });
|
|
95
|
+
}
|
|
96
|
+
return { role: 'user' as const, content: blocks };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
interface StreamingSession {
|
|
100
|
+
meta: Session;
|
|
101
|
+
query: any;
|
|
102
|
+
controller: MessageController;
|
|
103
|
+
}
|
|
104
|
+
|
|
27
105
|
/**
|
|
28
106
|
* Pending approval: canUseTool callback creates a promise,
|
|
29
107
|
* yields an approval_request event, then awaits resolution from FE.
|
|
@@ -49,6 +127,8 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
49
127
|
private activeQueries = new Map<string, { close: () => void }>();
|
|
50
128
|
/** Fork source: ppmSessionId → sourceSessionId (used on first message to fork) */
|
|
51
129
|
private forkSources = new Map<string, string>();
|
|
130
|
+
/** Streaming sessions: persistent query + message channel per session */
|
|
131
|
+
private streamingSessions = new Map<string, StreamingSession>();
|
|
52
132
|
|
|
53
133
|
/** Auth-related env keys for diagnostic logging */
|
|
54
134
|
private readonly AUTH_ENV_KEYS = ["ANTHROPIC_API_KEY", "ANTHROPIC_BASE_URL", "ANTHROPIC_AUTH_TOKEN"];
|
|
@@ -219,6 +299,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
219
299
|
}
|
|
220
300
|
|
|
221
301
|
async deleteSession(sessionId: string): Promise<void> {
|
|
302
|
+
this.closeStreamingSession(sessionId);
|
|
222
303
|
this.activeSessions.delete(sessionId);
|
|
223
304
|
this.messageCount.delete(sessionId);
|
|
224
305
|
}
|
|
@@ -251,11 +332,63 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
251
332
|
}
|
|
252
333
|
}
|
|
253
334
|
|
|
335
|
+
/**
|
|
336
|
+
* Push a follow-up message into an existing streaming session's generator.
|
|
337
|
+
* Called by WS handler for follow-up messages (Phase 2).
|
|
338
|
+
*/
|
|
339
|
+
pushMessage(sessionId: string, content: string, opts?: { priority?: 'now' | 'next' | 'later'; images?: Array<{ data: string; mediaType: string }> }): void {
|
|
340
|
+
const ss = this.streamingSessions.get(sessionId);
|
|
341
|
+
if (!ss) {
|
|
342
|
+
console.warn(`[sdk] pushMessage: no streaming session for ${sessionId}`);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
const msgContent = buildMessageParam(content, opts?.images);
|
|
346
|
+
ss.controller.push({
|
|
347
|
+
type: 'user',
|
|
348
|
+
message: msgContent,
|
|
349
|
+
parent_tool_use_id: null,
|
|
350
|
+
session_id: sessionId,
|
|
351
|
+
priority: opts?.priority ?? 'next',
|
|
352
|
+
});
|
|
353
|
+
console.log(`[sdk] pushMessage: session=${sessionId} priority=${opts?.priority ?? 'next'}`);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/** Close a streaming session — generator + query cleanup */
|
|
357
|
+
closeStreamingSession(sessionId: string): void {
|
|
358
|
+
const ss = this.streamingSessions.get(sessionId);
|
|
359
|
+
if (ss) {
|
|
360
|
+
ss.controller.done();
|
|
361
|
+
ss.query.close();
|
|
362
|
+
this.streamingSessions.delete(sessionId);
|
|
363
|
+
console.log(`[sdk] closeStreamingSession: session=${sessionId}`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** Check if a streaming session is active for a given session ID */
|
|
368
|
+
hasStreamingSession(sessionId: string): boolean {
|
|
369
|
+
return this.streamingSessions.has(sessionId);
|
|
370
|
+
}
|
|
371
|
+
|
|
254
372
|
async *sendMessage(
|
|
255
373
|
sessionId: string,
|
|
256
374
|
message: string,
|
|
257
|
-
opts?: import("./provider.interface.ts").SendMessageOpts & { forkSession?: boolean },
|
|
375
|
+
opts?: import("./provider.interface.ts").SendMessageOpts & { forkSession?: boolean; priority?: 'now' | 'next' | 'later'; images?: Array<{ data: string; mediaType: string }> },
|
|
258
376
|
): AsyncIterable<ChatEvent> {
|
|
377
|
+
// Follow-up: push into existing streaming session, yield nothing
|
|
378
|
+
const existingStream = this.streamingSessions.get(sessionId);
|
|
379
|
+
if (existingStream) {
|
|
380
|
+
const msgContent = buildMessageParam(message, opts?.images);
|
|
381
|
+
existingStream.controller.push({
|
|
382
|
+
type: 'user',
|
|
383
|
+
message: msgContent,
|
|
384
|
+
parent_tool_use_id: null,
|
|
385
|
+
session_id: sessionId,
|
|
386
|
+
priority: opts?.priority ?? 'next',
|
|
387
|
+
});
|
|
388
|
+
console.log(`[sdk] sendMessage follow-up: session=${sessionId} pushed to generator`);
|
|
389
|
+
return; // Events flow through first-message's consumer loop
|
|
390
|
+
}
|
|
391
|
+
|
|
259
392
|
if (!this.activeSessions.has(sessionId)) {
|
|
260
393
|
await this.resumeSession(sessionId);
|
|
261
394
|
}
|
|
@@ -378,6 +511,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
378
511
|
let resultSubtype: string | undefined;
|
|
379
512
|
let resultNumTurns: number | undefined;
|
|
380
513
|
let resultContextWindowPct: number | undefined;
|
|
514
|
+
let yieldedDone = false;
|
|
381
515
|
try {
|
|
382
516
|
// Resolve SDK's actual session ID for resume (may differ from PPM's UUID)
|
|
383
517
|
// For fork: use the source session's SDK id
|
|
@@ -449,14 +583,25 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
449
583
|
includePartialMessages: true,
|
|
450
584
|
};
|
|
451
585
|
|
|
586
|
+
// Streaming input: create message channel and persistent query
|
|
587
|
+
const { generator: streamGen, controller: streamCtrl } = createMessageChannel();
|
|
588
|
+
const firstMsg = {
|
|
589
|
+
type: 'user' as const,
|
|
590
|
+
message: buildMessageParam(message),
|
|
591
|
+
parent_tool_use_id: null,
|
|
592
|
+
session_id: sessionId,
|
|
593
|
+
};
|
|
594
|
+
streamCtrl.push(firstMsg);
|
|
595
|
+
|
|
452
596
|
const q = query({
|
|
453
|
-
prompt:
|
|
597
|
+
prompt: streamGen,
|
|
454
598
|
options: {
|
|
455
599
|
...queryOptions,
|
|
456
600
|
...(permissionHooks && { hooks: permissionHooks }),
|
|
457
601
|
canUseTool,
|
|
458
602
|
} as any,
|
|
459
603
|
});
|
|
604
|
+
this.streamingSessions.set(sessionId, { meta, query: q, controller: streamCtrl });
|
|
460
605
|
this.activeQueries.set(sessionId, q);
|
|
461
606
|
let eventSource: AsyncIterable<any> = q;
|
|
462
607
|
|
|
@@ -471,22 +616,29 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
471
616
|
let retryCount = 0;
|
|
472
617
|
let authRetried = false;
|
|
473
618
|
|
|
619
|
+
let hadAnyEvents = false;
|
|
474
620
|
retryLoop: while (true) {
|
|
475
621
|
let sdkEventCount = 0;
|
|
476
622
|
for await (const msg of eventSource) {
|
|
477
623
|
sdkEventCount++;
|
|
624
|
+
hadAnyEvents = true;
|
|
478
625
|
if (sdkEventCount === 1) {
|
|
479
626
|
console.log(`[sdk] first event received: type=${(msg as any).type} subtype=${(msg as any).subtype ?? "none"}`);
|
|
480
627
|
// Detect immediate failure: first event is a result with error + 0 turns
|
|
481
628
|
if ((msg as any).type === "result" && (msg as any).subtype === "error_during_execution" && ((msg as any).num_turns ?? 0) === 0 && retryCount < MAX_RETRIES) {
|
|
482
629
|
retryCount++;
|
|
483
630
|
console.warn(`[sdk] transient error on first event — retrying (attempt ${retryCount}/${MAX_RETRIES})`);
|
|
484
|
-
//
|
|
631
|
+
// Close failed query and old channel, create new channel + query for retry
|
|
632
|
+
streamCtrl.done();
|
|
633
|
+
q.close();
|
|
634
|
+
const { generator: retryGen, controller: retryCtrl } = createMessageChannel();
|
|
635
|
+
retryCtrl.push(firstMsg);
|
|
485
636
|
const retryOpts = { ...queryOptions, sessionId: undefined, resume: undefined };
|
|
486
637
|
const rq = query({
|
|
487
|
-
prompt:
|
|
638
|
+
prompt: retryGen,
|
|
488
639
|
options: { ...retryOpts, ...(permissionHooks && { hooks: permissionHooks }), canUseTool } as any,
|
|
489
640
|
});
|
|
641
|
+
this.streamingSessions.set(sessionId, { meta, query: rq, controller: retryCtrl });
|
|
490
642
|
this.activeQueries.set(sessionId, rq);
|
|
491
643
|
eventSource = rq;
|
|
492
644
|
continue retryLoop;
|
|
@@ -632,11 +784,17 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
632
784
|
const refreshedAccount = accountService.getWithTokens(account.id);
|
|
633
785
|
if (refreshedAccount) {
|
|
634
786
|
const retryEnv = this.buildQueryEnv(meta.projectPath, refreshedAccount);
|
|
787
|
+
// Close failed query and old channel, create new channel + query with refreshed token
|
|
788
|
+
streamCtrl.done();
|
|
789
|
+
q.close();
|
|
790
|
+
const { generator: authRetryGen, controller: authRetryCtrl } = createMessageChannel();
|
|
791
|
+
authRetryCtrl.push(firstMsg);
|
|
635
792
|
const retryOpts = { ...queryOptions, sessionId: undefined, resume: undefined, env: retryEnv };
|
|
636
793
|
const rq = query({
|
|
637
|
-
prompt:
|
|
794
|
+
prompt: authRetryGen,
|
|
638
795
|
options: { ...retryOpts, ...(permissionHooks && { hooks: permissionHooks }), canUseTool } as any,
|
|
639
796
|
});
|
|
797
|
+
this.streamingSessions.set(sessionId, { meta, query: rq, controller: authRetryCtrl });
|
|
640
798
|
this.activeQueries.set(sessionId, rq);
|
|
641
799
|
eventSource = rq;
|
|
642
800
|
continue retryLoop;
|
|
@@ -708,9 +866,9 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
708
866
|
const errCode = this.detectResultErrorCode(msg);
|
|
709
867
|
if (errCode === 429) {
|
|
710
868
|
accountSelector.onRateLimit(account.id);
|
|
711
|
-
// Post-stream 429
|
|
869
|
+
// Post-stream 429 — surface error, continue waiting for next turn
|
|
712
870
|
yield { type: "error", message: "Rate limited. This account is now on cooldown. Please retry." };
|
|
713
|
-
|
|
871
|
+
continue;
|
|
714
872
|
} else if (errCode === 401) {
|
|
715
873
|
// Try refresh once
|
|
716
874
|
try {
|
|
@@ -818,7 +976,26 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
818
976
|
}
|
|
819
977
|
}
|
|
820
978
|
}
|
|
821
|
-
|
|
979
|
+
|
|
980
|
+
// Streaming input: yield done for this turn, then continue for next turn
|
|
981
|
+
yieldedDone = true;
|
|
982
|
+
yield {
|
|
983
|
+
type: "done",
|
|
984
|
+
sessionId,
|
|
985
|
+
resultSubtype: resultSubtype as any,
|
|
986
|
+
numTurns: resultNumTurns,
|
|
987
|
+
contextWindowPct: resultContextWindowPct,
|
|
988
|
+
};
|
|
989
|
+
|
|
990
|
+
// Reset per-turn state for next turn
|
|
991
|
+
lastPartialText = "";
|
|
992
|
+
pendingToolCount = 0;
|
|
993
|
+
assistantContent = "";
|
|
994
|
+
resultSubtype = undefined;
|
|
995
|
+
resultNumTurns = undefined;
|
|
996
|
+
resultContextWindowPct = undefined;
|
|
997
|
+
sdkEventCount = 0;
|
|
998
|
+
continue; // Wait for next turn from generator
|
|
822
999
|
}
|
|
823
1000
|
}
|
|
824
1001
|
|
|
@@ -827,7 +1004,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
827
1004
|
yield approvalEvents.shift()!;
|
|
828
1005
|
}
|
|
829
1006
|
|
|
830
|
-
if (
|
|
1007
|
+
if (!hadAnyEvents) {
|
|
831
1008
|
yield { type: "error", message: "Claude did not respond. Check that 'claude' CLI works in your terminal." };
|
|
832
1009
|
}
|
|
833
1010
|
break; // Exit retryLoop — normal completion
|
|
@@ -837,88 +1014,47 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
837
1014
|
console.error(`[sdk] session=${sessionId} cwd=${meta.projectPath} error: ${msg}`);
|
|
838
1015
|
if (msg.includes("abort") || msg.includes("closed")) {
|
|
839
1016
|
// User-initiated abort or WS closed — nothing to report
|
|
840
|
-
} else if (
|
|
841
|
-
//
|
|
842
|
-
console.warn(`[sdk] session
|
|
843
|
-
|
|
844
|
-
const providerConfig = this.getProviderConfig();
|
|
845
|
-
const effectiveCwd = meta.projectPath || homedir();
|
|
846
|
-
const retryAccount = accountSelector.isEnabled() ? accountSelector.next() : null;
|
|
847
|
-
const queryEnv = this.buildQueryEnv(meta.projectPath, retryAccount);
|
|
848
|
-
const retryOptions = {
|
|
849
|
-
...(process.platform === "win32" && { executable: "node" }),
|
|
850
|
-
cwd: effectiveCwd,
|
|
851
|
-
systemPrompt: systemPromptOpt,
|
|
852
|
-
settingSources: ["user", "project"],
|
|
853
|
-
env: queryEnv,
|
|
854
|
-
settings: { permissions: { allow: [], deny: [] } },
|
|
855
|
-
allowedTools,
|
|
856
|
-
permissionMode,
|
|
857
|
-
allowDangerouslySkipPermissions: isBypass,
|
|
858
|
-
...(providerConfig.model && { model: providerConfig.model }),
|
|
859
|
-
maxTurns: providerConfig.max_turns ?? 100,
|
|
860
|
-
includePartialMessages: true,
|
|
861
|
-
};
|
|
862
|
-
const retryQuery = query({
|
|
863
|
-
prompt: message,
|
|
864
|
-
options: {
|
|
865
|
-
...retryOptions,
|
|
866
|
-
...(permissionHooks && { hooks: permissionHooks }),
|
|
867
|
-
canUseTool,
|
|
868
|
-
} as any,
|
|
869
|
-
});
|
|
870
|
-
this.activeQueries.set(sessionId, retryQuery);
|
|
871
|
-
for await (const retryMsg of retryQuery) {
|
|
872
|
-
if (retryMsg.type === "system") continue;
|
|
873
|
-
if (retryMsg.type === "result") {
|
|
874
|
-
const r = retryMsg as any;
|
|
875
|
-
if (r.subtype && r.subtype !== "success") {
|
|
876
|
-
const retryErrors = Array.isArray(r.errors) ? r.errors.join("\n") : "";
|
|
877
|
-
yield { type: "error", message: retryErrors || `Agent stopped: ${r.subtype}` };
|
|
878
|
-
}
|
|
879
|
-
resultSubtype = r.subtype;
|
|
880
|
-
resultNumTurns = r.num_turns;
|
|
881
|
-
break;
|
|
882
|
-
}
|
|
883
|
-
if ((retryMsg as any).type === "assistant") {
|
|
884
|
-
const content = (retryMsg as any).message?.content;
|
|
885
|
-
if (Array.isArray(content)) {
|
|
886
|
-
for (const block of content) {
|
|
887
|
-
if (block.type === "text" && typeof block.text === "string") {
|
|
888
|
-
yield { type: "text", content: block.text };
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
} catch (retryErr) {
|
|
895
|
-
const retryMsg = (retryErr as Error).message ?? String(retryErr);
|
|
896
|
-
console.error(`[sdk] retry also failed: ${retryMsg}`);
|
|
897
|
-
yield { type: "error", message: `SDK error: ${msg}` };
|
|
898
|
-
}
|
|
1017
|
+
} else if (msg.includes("exited with code")) {
|
|
1018
|
+
// Subprocess crashed — session will auto-recover on next message
|
|
1019
|
+
console.warn(`[sdk] session=${sessionId} subprocess crashed: ${msg}`);
|
|
1020
|
+
yield { type: "error", message: `SDK subprocess crashed. Send another message to auto-recover.` };
|
|
899
1021
|
} else {
|
|
900
1022
|
yield { type: "error", message: `SDK error: ${msg}` };
|
|
901
1023
|
}
|
|
902
1024
|
} finally {
|
|
903
1025
|
this.activeQueries.delete(sessionId);
|
|
1026
|
+
this.streamingSessions.delete(sessionId);
|
|
1027
|
+
console.log(`[sdk] session=${sessionId} streaming session ended`);
|
|
904
1028
|
}
|
|
905
1029
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
1030
|
+
// Final done event when query ends (crash, close, generator done)
|
|
1031
|
+
// Skip if we already yielded done from the result handler (avoid duplicate)
|
|
1032
|
+
if (!yieldedDone) {
|
|
1033
|
+
yield {
|
|
1034
|
+
type: "done",
|
|
1035
|
+
sessionId,
|
|
1036
|
+
resultSubtype: resultSubtype as any,
|
|
1037
|
+
numTurns: resultNumTurns,
|
|
1038
|
+
contextWindowPct: resultContextWindowPct,
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
913
1041
|
}
|
|
914
1042
|
|
|
915
1043
|
|
|
916
|
-
/**
|
|
1044
|
+
/** Interrupt the current turn — session stays alive for the next message */
|
|
917
1045
|
abortQuery(sessionId: string): void {
|
|
1046
|
+
const ss = this.streamingSessions.get(sessionId);
|
|
1047
|
+
if (ss && typeof ss.query.interrupt === "function") {
|
|
1048
|
+
ss.query.interrupt().catch(() => {});
|
|
1049
|
+
console.log(`[sdk] abortQuery: interrupted session=${sessionId}`);
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
// Fallback: close query entirely and clean up streaming session
|
|
918
1053
|
const q = this.activeQueries.get(sessionId);
|
|
919
1054
|
if (q) {
|
|
920
1055
|
q.close();
|
|
921
1056
|
this.activeQueries.delete(sessionId);
|
|
1057
|
+
this.streamingSessions.delete(sessionId);
|
|
922
1058
|
}
|
|
923
1059
|
}
|
|
924
1060
|
|