@hellcoder/companion 0.118.0 → 0.119.0
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/dist/assets/{AgentsPage-DkcwIsY1.js → AgentsPage-TD9AO1Er.js} +1 -1
- package/dist/assets/{CronManager-BrGSjzJz.js → CronManager-DQXJXJO2.js} +1 -1
- package/dist/assets/{DashboardPage-B2q0O3yD.js → DashboardPage-CQc0PLwb.js} +1 -1
- package/dist/assets/{IntegrationsPage-CRfvSp68.js → IntegrationsPage-ChVMH0yi.js} +1 -1
- package/dist/assets/{LinearOAuthSettingsPage-DgzYg2kb.js → LinearOAuthSettingsPage-Bb7Tu4o3.js} +1 -1
- package/dist/assets/{LinearSettingsPage-BTQJFAj4.js → LinearSettingsPage-BxKEO7CY.js} +1 -1
- package/dist/assets/{MagicUIDashboard-BegKqU3e.js → MagicUIDashboard-j4axrj9-.js} +1 -1
- package/dist/assets/{MagicUIView-D23itGQ5.js → MagicUIView-D6jNdxHM.js} +1 -1
- package/dist/assets/{Playground-BJAQWThl.js → Playground-DlNnNZL_.js} +1 -1
- package/dist/assets/{PromptsPage-BKEK_e8P.js → PromptsPage-C-VOgj-R.js} +1 -1
- package/dist/assets/{RunsPage-Biakia-J.js → RunsPage-Ce99iVIk.js} +1 -1
- package/dist/assets/{SandboxManager-BZfEkHsb.js → SandboxManager-ZtcsgPxE.js} +1 -1
- package/dist/assets/{SettingsPage-BwZoML1s.js → SettingsPage-QEkLsk5w.js} +1 -1
- package/dist/assets/{TailscalePage-B6eauJ__.js → TailscalePage-C61E10pR.js} +1 -1
- package/dist/assets/index-CnVoJw43.js +140 -0
- package/dist/assets/{sw-register-fN5inCkx.js → sw-register-NM2AysKf.js} +1 -1
- package/dist/index.html +1 -1
- package/dist/sw.js +1 -1
- package/package.json +1 -1
- package/server/codex-adapter.test.ts +40 -1
- package/server/codex-adapter.ts +26 -2
- package/server/ws-bridge.test.ts +30 -0
- package/server/ws-bridge.ts +16 -0
- package/dist/assets/index-n6Tt3UFW.js +0 -140
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as u}from"./index-
|
|
1
|
+
import{_ as u}from"./index-CnVoJw43.js";function w(r={}){const{immediate:i=!1,onNeedReload:d,onNeedRefresh:_,onOfflineReady:s,onRegistered:n,onRegisteredSW:o,onRegisterError:t}=r;let a,c;const l=async(e=!0)=>{await c};async function f(){if("serviceWorker"in navigator){if(a=await u(async()=>{const{Workbox:e}=await import("./workbox-window.prod.es5-BBnX5xw4.js");return{Workbox:e}},[]).then(({Workbox:e})=>new e("/sw.js",{scope:"/",type:"classic"})).catch(e=>{t==null||t(e)}),!a)return;a.addEventListener("activated",e=>{(e.isUpdate||e.isExternal)&&(d?d():window.location.reload())}),a.addEventListener("installed",e=>{e.isUpdate||s==null||s()}),a.register({immediate:i}).then(e=>{o?o("/sw.js",e):n==null||n(e)}).catch(e=>{t==null||t(e)})}}return c=f(),l}w({onRegisteredSW(r,i){i&&setInterval(()=>{i.update()},3600*1e3)},onOfflineReady(){console.log("[SW] Offline-ready: all assets precached")}});
|
package/dist/index.html
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<meta name="apple-mobile-web-app-title" content="Companion ME" />
|
|
12
12
|
<meta name="theme-color" content="#d97757" />
|
|
13
13
|
<title>The Companion — Moritz Edition</title>
|
|
14
|
-
<script type="module" crossorigin src="/assets/index-
|
|
14
|
+
<script type="module" crossorigin src="/assets/index-CnVoJw43.js"></script>
|
|
15
15
|
<link rel="stylesheet" crossorigin href="/assets/index-DB85gIpd.css">
|
|
16
16
|
</head>
|
|
17
17
|
<body class="bg-cc-bg text-cc-fg">
|
package/dist/sw.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
try{self["workbox:core:7.4.0"]&&_()}catch{}const x=(a,...e)=>{let t=a;return e.length>0&&(t+=` :: ${JSON.stringify(e)}`),t},N=x;class l extends Error{constructor(e,t){const s=N(e,t);super(s),this.name=e,this.details=t}}const E=new Set,f={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:typeof registration<"u"?registration.scope:""},b=a=>[f.prefix,a,f.suffix].filter(e=>e&&e.length>0).join("-"),O=a=>{for(const e of Object.keys(f))a(e)},C={updateDetails:a=>{O(e=>{typeof a[e]=="string"&&(f[e]=a[e])})},getGoogleAnalyticsName:a=>a||b(f.googleAnalytics),getPrecacheName:a=>a||b(f.precache),getPrefix:()=>f.prefix,getRuntimeName:a=>a||b(f.runtime),getSuffix:()=>f.suffix};function P(a,e){const t=new URL(a);for(const s of e)t.searchParams.delete(s);return t.href}async function I(a,e,t,s){const n=P(e.url,t);if(e.url===n)return a.match(e,s);const r=Object.assign(Object.assign({},s),{ignoreSearch:!0}),c=await a.keys(e,r);for(const i of c){const o=P(i.url,t);if(n===o)return a.match(i,s)}}let y;function M(){if(y===void 0){const a=new Response("");if("body"in a)try{new Response(a.body),y=!0}catch{y=!1}y=!1}return y}class D{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}}async function S(){for(const a of E)await a()}const W=a=>new URL(String(a),location.href).href.replace(new RegExp(`^${location.origin}`),"");function A(a){return new Promise(e=>setTimeout(e,a))}function K(a,e){const t=e();return a.waitUntil(t),t}async function q(a,e){let t=null;if(a.url&&(t=new URL(a.url).origin),t!==self.location.origin)throw new l("cross-origin-copy-response",{origin:t});const s=a.clone(),r={headers:new Headers(s.headers),status:s.status,statusText:s.statusText},c=M()?s.body:await s.blob();return new Response(c,r)}function j(){self.addEventListener("activate",()=>self.clients.claim())}try{self["workbox:precaching:7.4.0"]&&_()}catch{}const H="__WB_REVISION__";function F(a){if(!a)throw new l("add-to-cache-list-unexpected-type",{entry:a});if(typeof a=="string"){const r=new URL(a,location.href);return{cacheKey:r.href,url:r.href}}const{revision:e,url:t}=a;if(!t)throw new l("add-to-cache-list-unexpected-type",{entry:a});if(!e){const r=new URL(t,location.href);return{cacheKey:r.href,url:r.href}}const s=new URL(t,location.href),n=new URL(t,location.href);return s.searchParams.set(H,e),{cacheKey:s.href,url:n.href}}class B{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:s})=>{if(e.type==="install"&&t&&t.originalRequest&&t.originalRequest instanceof Request){const n=t.originalRequest.url;s?this.notUpdatedURLs.push(n):this.updatedURLs.push(n)}return s}}}class ${constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:t,params:s})=>{const n=(s==null?void 0:s.cacheKey)||this._precacheController.getCacheKeyForURL(t.url);return n?new Request(n,{headers:t.headers}):t},this._precacheController=e}}try{self["workbox:strategies:7.4.0"]&&_()}catch{}function m(a){return typeof a=="string"?new Request(a):a}class G{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new D,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(const s of this._plugins)this._pluginStateMap.set(s,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){const{event:t}=this;let s=m(e);if(s.mode==="navigate"&&t instanceof FetchEvent&&t.preloadResponse){const c=await t.preloadResponse;if(c)return c}const n=this.hasCallback("fetchDidFail")?s.clone():null;try{for(const c of this.iterateCallbacks("requestWillFetch"))s=await c({request:s.clone(),event:t})}catch(c){if(c instanceof Error)throw new l("plugin-error-request-will-fetch",{thrownErrorMessage:c.message})}const r=s.clone();try{let c;c=await fetch(s,s.mode==="navigate"?void 0:this._strategy.fetchOptions);for(const i of this.iterateCallbacks("fetchDidSucceed"))c=await i({event:t,request:r,response:c});return c}catch(c){throw n&&await this.runCallbacks("fetchDidFail",{error:c,event:t,originalRequest:n.clone(),request:r.clone()}),c}}async fetchAndCachePut(e){const t=await this.fetch(e),s=t.clone();return this.waitUntil(this.cachePut(e,s)),t}async cacheMatch(e){const t=m(e);let s;const{cacheName:n,matchOptions:r}=this._strategy,c=await this.getCacheKey(t,"read"),i=Object.assign(Object.assign({},r),{cacheName:n});s=await caches.match(c,i);for(const o of this.iterateCallbacks("cachedResponseWillBeUsed"))s=await o({cacheName:n,matchOptions:r,cachedResponse:s,request:c,event:this.event})||void 0;return s}async cachePut(e,t){const s=m(e);await A(0);const n=await this.getCacheKey(s,"write");if(!t)throw new l("cache-put-with-no-response",{url:W(n.url)});const r=await this._ensureResponseSafeToCache(t);if(!r)return!1;const{cacheName:c,matchOptions:i}=this._strategy,o=await self.caches.open(c),h=this.hasCallback("cacheDidUpdate"),p=h?await I(o,n.clone(),["__WB_REVISION__"],i):null;try{await o.put(n,h?r.clone():r)}catch(u){if(u instanceof Error)throw u.name==="QuotaExceededError"&&await S(),u}for(const u of this.iterateCallbacks("cacheDidUpdate"))await u({cacheName:c,oldResponse:p,newResponse:r.clone(),request:n,event:this.event});return!0}async getCacheKey(e,t){const s=`${e.url} | ${t}`;if(!this._cacheKeys[s]){let n=e;for(const r of this.iterateCallbacks("cacheKeyWillBeUsed"))n=m(await r({mode:t,request:n,event:this.event,params:this.params}));this._cacheKeys[s]=n}return this._cacheKeys[s]}hasCallback(e){for(const t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(const s of this.iterateCallbacks(e))await s(t)}*iterateCallbacks(e){for(const t of this._strategy.plugins)if(typeof t[e]=="function"){const s=this._pluginStateMap.get(t);yield r=>{const c=Object.assign(Object.assign({},r),{state:s});return t[e](c)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){const e=this._extendLifetimePromises.splice(0),s=(await Promise.allSettled(e)).find(n=>n.status==="rejected");if(s)throw s.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,s=!1;for(const n of this.iterateCallbacks("cacheWillUpdate"))if(t=await n({request:this.request,response:t,event:this.event})||void 0,s=!0,!t)break;return s||t&&t.status!==200&&(t=void 0),t}}class V{constructor(e={}){this.cacheName=C.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){const[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});const t=e.event,s=typeof e.request=="string"?new Request(e.request):e.request,n="params"in e?e.params:void 0,r=new G(this,{event:t,request:s,params:n}),c=this._getResponse(r,s,t),i=this._awaitComplete(c,r,s,t);return[c,i]}async _getResponse(e,t,s){await e.runCallbacks("handlerWillStart",{event:s,request:t});let n;try{if(n=await this._handle(t,e),!n||n.type==="error")throw new l("no-response",{url:t.url})}catch(r){if(r instanceof Error){for(const c of e.iterateCallbacks("handlerDidError"))if(n=await c({error:r,event:s,request:t}),n)break}if(!n)throw r}for(const r of e.iterateCallbacks("handlerWillRespond"))n=await r({event:s,request:t,response:n});return n}async _awaitComplete(e,t,s,n){let r,c;try{r=await e}catch{}try{await t.runCallbacks("handlerDidRespond",{event:n,request:s,response:r}),await t.doneWaiting()}catch(i){i instanceof Error&&(c=i)}if(await t.runCallbacks("handlerDidComplete",{event:n,request:s,response:r,error:c}),t.destroy(),c)throw c}}class d extends V{constructor(e={}){e.cacheName=C.getPrecacheName(e.cacheName),super(e),this._fallbackToNetwork=e.fallbackToNetwork!==!1,this.plugins.push(d.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){const s=await t.cacheMatch(e);return s||(t.event&&t.event.type==="install"?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,t){let s;const n=t.params||{};if(this._fallbackToNetwork){const r=n.integrity,c=e.integrity,i=!c||c===r;s=await t.fetch(new Request(e,{integrity:e.mode!=="no-cors"?c||r:void 0})),r&&i&&e.mode!=="no-cors"&&(this._useDefaultCacheabilityPluginIfNeeded(),await t.cachePut(e,s.clone()))}else throw new l("missing-precache-entry",{cacheName:this.cacheName,url:e.url});return s}async _handleInstall(e,t){this._useDefaultCacheabilityPluginIfNeeded();const s=await t.fetch(e);if(!await t.cachePut(e,s.clone()))throw new l("bad-precaching-response",{url:e.url,status:s.status});return s}_useDefaultCacheabilityPluginIfNeeded(){let e=null,t=0;for(const[s,n]of this.plugins.entries())n!==d.copyRedirectedCacheableResponsesPlugin&&(n===d.defaultPrecacheCacheabilityPlugin&&(e=s),n.cacheWillUpdate&&t++);t===0?this.plugins.push(d.defaultPrecacheCacheabilityPlugin):t>1&&e!==null&&this.plugins.splice(e,1)}}d.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:a}){return!a||a.status>=400?null:a}};d.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:a}){return a.redirected?await q(a):a}};class Q{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:s=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new d({cacheName:C.getPrecacheName(e),plugins:[...t,new $({precacheController:this})],fallbackToNetwork:s}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this._installAndActiveListenersAdded=!0)}addToCacheList(e){const t=[];for(const s of e){typeof s=="string"?t.push(s):s&&s.revision===void 0&&t.push(s.url);const{cacheKey:n,url:r}=F(s),c=typeof s!="string"&&s.revision?"reload":"default";if(this._urlsToCacheKeys.has(r)&&this._urlsToCacheKeys.get(r)!==n)throw new l("add-to-cache-list-conflicting-entries",{firstEntry:this._urlsToCacheKeys.get(r),secondEntry:n});if(typeof s!="string"&&s.integrity){if(this._cacheKeysToIntegrities.has(n)&&this._cacheKeysToIntegrities.get(n)!==s.integrity)throw new l("add-to-cache-list-conflicting-integrities",{url:r});this._cacheKeysToIntegrities.set(n,s.integrity)}if(this._urlsToCacheKeys.set(r,n),this._urlsToCacheModes.set(r,c),t.length>0){const i=`Workbox is precaching URLs without revision info: ${t.join(", ")}
|
|
2
|
-
This is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(i)}}}install(e){return K(e,async()=>{const t=new B;this.strategy.plugins.push(t);for(const[r,c]of this._urlsToCacheKeys){const i=this._cacheKeysToIntegrities.get(c),o=this._urlsToCacheModes.get(r),h=new Request(r,{integrity:i,cache:o,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:c},request:h,event:e}))}const{updatedURLs:s,notUpdatedURLs:n}=t;return{updatedURLs:s,notUpdatedURLs:n}})}activate(e){return K(e,async()=>{const t=await self.caches.open(this.strategy.cacheName),s=await t.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(const c of s)n.has(c.url)||(await t.delete(c),r.push(c.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){const t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){const t=e instanceof Request?e.url:e,s=this.getCacheKeyForURL(t);if(s)return(await self.caches.open(this.strategy.cacheName)).match(s)}createHandlerBoundToURL(e){const t=this.getCacheKeyForURL(e);if(!t)throw new l("non-precached-url",{url:e});return s=>(s.request=new Request(e),s.params=Object.assign({cacheKey:t},s.params),this.strategy.handle(s))}}let U;const L=()=>(U||(U=new Q),U);try{self["workbox:routing:7.4.0"]&&_()}catch{}const v="GET",R=a=>a&&typeof a=="object"?a:{handle:a};class g{constructor(e,t,s=v){this.handler=R(t),this.match=e,this.method=s}setCatchHandler(e){this.catchHandler=R(e)}}class z extends g{constructor(e,t,s){const n=({url:r})=>{const c=e.exec(r.href);if(c&&!(r.origin!==location.origin&&c.index!==0))return c.slice(1)};super(n,t,s)}}class J{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener("fetch",(e=>{const{request:t}=e,s=this.handleRequest({request:t,event:e});s&&e.respondWith(s)}))}addCacheListener(){self.addEventListener("message",(e=>{if(e.data&&e.data.type==="CACHE_URLS"){const{payload:t}=e.data,s=Promise.all(t.urlsToCache.map(n=>{typeof n=="string"&&(n=[n]);const r=new Request(...n);return this.handleRequest({request:r,event:e})}));e.waitUntil(s),e.ports&&e.ports[0]&&s.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){const s=new URL(e.url,location.href);if(!s.protocol.startsWith("http"))return;const n=s.origin===location.origin,{params:r,route:c}=this.findMatchingRoute({event:t,request:e,sameOrigin:n,url:s});let i=c&&c.handler;const o=e.method;if(!i&&this._defaultHandlerMap.has(o)&&(i=this._defaultHandlerMap.get(o)),!i)return;let h;try{h=i.handle({url:s,request:e,event:t,params:r})}catch(u){h=Promise.reject(u)}const p=c&&c.catchHandler;return h instanceof Promise&&(this._catchHandler||p)&&(h=h.catch(async u=>{if(p)try{return await p.handle({url:s,request:e,event:t,params:r})}catch(k){k instanceof Error&&(u=k)}if(this._catchHandler)return this._catchHandler.handle({url:s,request:e,event:t});throw u})),h}findMatchingRoute({url:e,sameOrigin:t,request:s,event:n}){const r=this._routes.get(s.method)||[];for(const c of r){let i;const o=c.match({url:e,sameOrigin:t,request:s,event:n});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:c,params:i}}return{}}setDefaultHandler(e,t=v){this._defaultHandlerMap.set(t,R(e))}setCatchHandler(e){this._catchHandler=R(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 l("unregister-route-but-not-found-with-method",{method:e.method});const t=this._routes.get(e.method).indexOf(e);if(t>-1)this._routes.get(e.method).splice(t,1);else throw new l("unregister-route-route-not-registered")}}let w;const X=()=>(w||(w=new J,w.addFetchListener(),w.addCacheListener()),w);function T(a,e,t){let s;if(typeof a=="string"){const r=new URL(a,location.href),c=({url:i})=>i.href===r.href;s=new g(c,e,t)}else if(a instanceof RegExp)s=new z(a,e,t);else if(typeof a=="function")s=new g(a,e,t);else if(a instanceof g)s=a;else throw new l("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});return X().registerRoute(s),s}function Y(a,e=[]){for(const t of[...a.searchParams.keys()])e.some(s=>s.test(t))&&a.searchParams.delete(t);return a}function*Z(a,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:t="index.html",cleanURLs:s=!0,urlManipulation:n}={}){const r=new URL(a,location.href);r.hash="",yield r.href;const c=Y(r,e);if(yield c.href,t&&c.pathname.endsWith("/")){const i=new URL(c.href);i.pathname+=t,yield i.href}if(s){const i=new URL(c.href);i.pathname+=".html",yield i.href}if(n){const i=n({url:r});for(const o of i)yield o.href}}class ee extends g{constructor(e,t){const s=({request:n})=>{const r=e.getURLsToCacheKeys();for(const c of Z(n.url,t)){const i=r.get(c);if(i){const o=e.getIntegrityForCacheKey(i);return{cacheKey:i,integrity:o}}}};super(s,e.strategy)}}function te(a){const e=L(),t=new ee(e,a);T(t)}const se="-precache-",ae=async(a,e=se)=>{const s=(await self.caches.keys()).filter(n=>n.includes(e)&&n.includes(self.registration.scope)&&n!==a);return await Promise.all(s.map(n=>self.caches.delete(n))),s};function ne(){self.addEventListener("activate",(a=>{const e=C.getPrecacheName();a.waitUntil(ae(e).then(t=>{}))}))}function re(a){return L().createHandlerBoundToURL(a)}function ce(a){L().precache(a)}function ie(a,e){ce(a),te(e)}class oe extends g{constructor(e,{allowlist:t=[/./],denylist:s=[]}={}){super(n=>this._match(n),e),this._allowlist=t,this._denylist=s}_match({url:e,request:t}){if(t&&t.mode!=="navigate")return!1;const s=e.pathname+e.search;for(const n of this._denylist)if(n.test(s))return!1;return!!this._allowlist.some(n=>n.test(s))}}self.skipWaiting();j();ie([{"revision":"fab346dacb0b9b9af12554e9a59f004d","url":"logo.svg"},{"revision":"623840baec64a3438663496bb1050d30","url":"logo-docker.svg"},{"revision":"c5c8611b432190ec28522f1a2dfcbb7f","url":"logo-codex.svg"},{"revision":"
|
|
2
|
+
This is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(i)}}}install(e){return K(e,async()=>{const t=new B;this.strategy.plugins.push(t);for(const[r,c]of this._urlsToCacheKeys){const i=this._cacheKeysToIntegrities.get(c),o=this._urlsToCacheModes.get(r),h=new Request(r,{integrity:i,cache:o,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:c},request:h,event:e}))}const{updatedURLs:s,notUpdatedURLs:n}=t;return{updatedURLs:s,notUpdatedURLs:n}})}activate(e){return K(e,async()=>{const t=await self.caches.open(this.strategy.cacheName),s=await t.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(const c of s)n.has(c.url)||(await t.delete(c),r.push(c.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){const t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){const t=e instanceof Request?e.url:e,s=this.getCacheKeyForURL(t);if(s)return(await self.caches.open(this.strategy.cacheName)).match(s)}createHandlerBoundToURL(e){const t=this.getCacheKeyForURL(e);if(!t)throw new l("non-precached-url",{url:e});return s=>(s.request=new Request(e),s.params=Object.assign({cacheKey:t},s.params),this.strategy.handle(s))}}let U;const L=()=>(U||(U=new Q),U);try{self["workbox:routing:7.4.0"]&&_()}catch{}const v="GET",R=a=>a&&typeof a=="object"?a:{handle:a};class g{constructor(e,t,s=v){this.handler=R(t),this.match=e,this.method=s}setCatchHandler(e){this.catchHandler=R(e)}}class z extends g{constructor(e,t,s){const n=({url:r})=>{const c=e.exec(r.href);if(c&&!(r.origin!==location.origin&&c.index!==0))return c.slice(1)};super(n,t,s)}}class J{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener("fetch",(e=>{const{request:t}=e,s=this.handleRequest({request:t,event:e});s&&e.respondWith(s)}))}addCacheListener(){self.addEventListener("message",(e=>{if(e.data&&e.data.type==="CACHE_URLS"){const{payload:t}=e.data,s=Promise.all(t.urlsToCache.map(n=>{typeof n=="string"&&(n=[n]);const r=new Request(...n);return this.handleRequest({request:r,event:e})}));e.waitUntil(s),e.ports&&e.ports[0]&&s.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){const s=new URL(e.url,location.href);if(!s.protocol.startsWith("http"))return;const n=s.origin===location.origin,{params:r,route:c}=this.findMatchingRoute({event:t,request:e,sameOrigin:n,url:s});let i=c&&c.handler;const o=e.method;if(!i&&this._defaultHandlerMap.has(o)&&(i=this._defaultHandlerMap.get(o)),!i)return;let h;try{h=i.handle({url:s,request:e,event:t,params:r})}catch(u){h=Promise.reject(u)}const p=c&&c.catchHandler;return h instanceof Promise&&(this._catchHandler||p)&&(h=h.catch(async u=>{if(p)try{return await p.handle({url:s,request:e,event:t,params:r})}catch(k){k instanceof Error&&(u=k)}if(this._catchHandler)return this._catchHandler.handle({url:s,request:e,event:t});throw u})),h}findMatchingRoute({url:e,sameOrigin:t,request:s,event:n}){const r=this._routes.get(s.method)||[];for(const c of r){let i;const o=c.match({url:e,sameOrigin:t,request:s,event:n});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:c,params:i}}return{}}setDefaultHandler(e,t=v){this._defaultHandlerMap.set(t,R(e))}setCatchHandler(e){this._catchHandler=R(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 l("unregister-route-but-not-found-with-method",{method:e.method});const t=this._routes.get(e.method).indexOf(e);if(t>-1)this._routes.get(e.method).splice(t,1);else throw new l("unregister-route-route-not-registered")}}let w;const X=()=>(w||(w=new J,w.addFetchListener(),w.addCacheListener()),w);function T(a,e,t){let s;if(typeof a=="string"){const r=new URL(a,location.href),c=({url:i})=>i.href===r.href;s=new g(c,e,t)}else if(a instanceof RegExp)s=new z(a,e,t);else if(typeof a=="function")s=new g(a,e,t);else if(a instanceof g)s=a;else throw new l("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});return X().registerRoute(s),s}function Y(a,e=[]){for(const t of[...a.searchParams.keys()])e.some(s=>s.test(t))&&a.searchParams.delete(t);return a}function*Z(a,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:t="index.html",cleanURLs:s=!0,urlManipulation:n}={}){const r=new URL(a,location.href);r.hash="",yield r.href;const c=Y(r,e);if(yield c.href,t&&c.pathname.endsWith("/")){const i=new URL(c.href);i.pathname+=t,yield i.href}if(s){const i=new URL(c.href);i.pathname+=".html",yield i.href}if(n){const i=n({url:r});for(const o of i)yield o.href}}class ee extends g{constructor(e,t){const s=({request:n})=>{const r=e.getURLsToCacheKeys();for(const c of Z(n.url,t)){const i=r.get(c);if(i){const o=e.getIntegrityForCacheKey(i);return{cacheKey:i,integrity:o}}}};super(s,e.strategy)}}function te(a){const e=L(),t=new ee(e,a);T(t)}const se="-precache-",ae=async(a,e=se)=>{const s=(await self.caches.keys()).filter(n=>n.includes(e)&&n.includes(self.registration.scope)&&n!==a);return await Promise.all(s.map(n=>self.caches.delete(n))),s};function ne(){self.addEventListener("activate",(a=>{const e=C.getPrecacheName();a.waitUntil(ae(e).then(t=>{}))}))}function re(a){return L().createHandlerBoundToURL(a)}function ce(a){L().precache(a)}function ie(a,e){ce(a),te(e)}class oe extends g{constructor(e,{allowlist:t=[/./],denylist:s=[]}={}){super(n=>this._match(n),e),this._allowlist=t,this._denylist=s}_match({url:e,request:t}){if(t&&t.mode!=="navigate")return!1;const s=e.pathname+e.search;for(const n of this._denylist)if(n.test(s))return!1;return!!this._allowlist.some(n=>n.test(s))}}self.skipWaiting();j();ie([{"revision":"fab346dacb0b9b9af12554e9a59f004d","url":"logo.svg"},{"revision":"623840baec64a3438663496bb1050d30","url":"logo-docker.svg"},{"revision":"c5c8611b432190ec28522f1a2dfcbb7f","url":"logo-codex.svg"},{"revision":"994cea7692bfcf835f5044594e7c5dbf","url":"index.html"},{"revision":"1421e9c6cad8218ef5689b85034d3a95","url":"icon-512.png"},{"revision":"b96da5a0b6636012517f54b0e69c304d","url":"icon-192.png"},{"revision":"c64ca8ae8596d4ffe13d0f591beb2274","url":"favicon.svg"},{"revision":"6481face04bd08e6f0bfc2a633840b57","url":"apple-touch-icon.png"},{"revision":"83304194a3c8be2b5b61242eeb1c1046","url":"fonts/MesloLGSNerdFontMono-Regular.woff2"},{"revision":"60fafe18cbcb717c51cdabf87f9490f0","url":"fonts/MesloLGSNerdFontMono-Bold.woff2"},{"revision":null,"url":"assets/workbox-window.prod.es5-BBnX5xw4.js"},{"revision":null,"url":"assets/sw-register-NM2AysKf.js"},{"revision":null,"url":"assets/index-DB85gIpd.css"},{"revision":null,"url":"assets/index-CnVoJw43.js"},{"revision":null,"url":"assets/TailscalePage-C61E10pR.js"},{"revision":null,"url":"assets/SettingsPage-QEkLsk5w.js"},{"revision":null,"url":"assets/SandboxManager-ZtcsgPxE.js"},{"revision":null,"url":"assets/RunsPage-Ce99iVIk.js"},{"revision":null,"url":"assets/PromptsPage-C-VOgj-R.js"},{"revision":null,"url":"assets/Playground-DlNnNZL_.js"},{"revision":null,"url":"assets/MagicUIView-D6jNdxHM.js"},{"revision":null,"url":"assets/MagicUIDashboard-j4axrj9-.js"},{"revision":null,"url":"assets/LinearSettingsPage-BxKEO7CY.js"},{"revision":null,"url":"assets/LinearOAuthSettingsPage-Bb7Tu4o3.js"},{"revision":null,"url":"assets/IntegrationsPage-ChVMH0yi.js"},{"revision":null,"url":"assets/DashboardPage-CQc0PLwb.js"},{"revision":null,"url":"assets/CronManager-DQXJXJO2.js"},{"revision":null,"url":"assets/AgentsPage-TD9AO1Er.js"}]);ne();T(new oe(re("index.html"),{denylist:[/^\/api/,/^\/ws/]}));
|
package/package.json
CHANGED
|
@@ -971,11 +971,50 @@ describe("CodexAdapter", () => {
|
|
|
971
971
|
stdout.push(JSON.stringify({ id: 2, result: { thread: { id: "thr_123" } } }) + "\n");
|
|
972
972
|
await new Promise((r) => setTimeout(r, 50));
|
|
973
973
|
|
|
974
|
-
expect(adapter.sendBrowserMessage({ type: "set_model", model: "gpt-5.3-codex" })).toBe(false);
|
|
975
974
|
// set_permission_mode IS supported for Codex (runtime Auto↔Plan toggle)
|
|
976
975
|
expect(adapter.sendBrowserMessage({ type: "set_permission_mode", mode: "plan" })).toBe(true);
|
|
977
976
|
});
|
|
978
977
|
|
|
978
|
+
it("accepts set_model and applies the new model on the next turn", async () => {
|
|
979
|
+
// Codex has no dedicated "set model" RPC; the model rides on
|
|
980
|
+
// collaborationMode.settings.model, which is only sent when the
|
|
981
|
+
// collaboration-mode kind changes. set_model must reset that gate so the new
|
|
982
|
+
// model is re-sent on the next turn/start.
|
|
983
|
+
const calls: { method: string; params: Record<string, unknown> }[] = [];
|
|
984
|
+
const adapter = new CodexAdapter(proc as never, "test-session", { model: "gpt-5.3-codex" });
|
|
985
|
+
// Intercept outgoing turn/start params by spying on the transport call.
|
|
986
|
+
const transport = (adapter as unknown as {
|
|
987
|
+
transport: { call: (m: string, p: Record<string, unknown>) => Promise<unknown> };
|
|
988
|
+
}).transport;
|
|
989
|
+
const origCall = transport.call.bind(transport);
|
|
990
|
+
transport.call = (method: string, params: Record<string, unknown>) => {
|
|
991
|
+
calls.push({ method, params });
|
|
992
|
+
if (method === "turn/start") return Promise.resolve({ turn: { id: "turn_1" } });
|
|
993
|
+
return origCall(method, params);
|
|
994
|
+
};
|
|
995
|
+
|
|
996
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
997
|
+
stdout.push(JSON.stringify({ id: 1, result: { userAgent: "codex" } }) + "\n");
|
|
998
|
+
await new Promise((r) => setTimeout(r, 20));
|
|
999
|
+
stdout.push(JSON.stringify({ id: 2, result: { thread: { id: "thr_123" } } }) + "\n");
|
|
1000
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
1001
|
+
|
|
1002
|
+
// Switching to a new model is accepted…
|
|
1003
|
+
expect(adapter.sendBrowserMessage({ type: "set_model", model: "gpt-5.5" })).toBe(true);
|
|
1004
|
+
// …and re-selecting the current model is a no-op (still accepted).
|
|
1005
|
+
expect(adapter.sendBrowserMessage({ type: "set_model", model: "gpt-5.5" })).toBe(true);
|
|
1006
|
+
|
|
1007
|
+
// The next user turn must carry the new model via collaborationMode.settings.
|
|
1008
|
+
adapter.sendBrowserMessage({ type: "user_message", content: "hi" });
|
|
1009
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
1010
|
+
|
|
1011
|
+
const turnStart = calls.find((c) => c.method === "turn/start");
|
|
1012
|
+
expect(turnStart).toBeDefined();
|
|
1013
|
+
const collab = turnStart!.params.collaborationMode as { settings: { model: string } };
|
|
1014
|
+
expect(collab).toBeDefined();
|
|
1015
|
+
expect(collab.settings.model).toBe("gpt-5.5");
|
|
1016
|
+
});
|
|
1017
|
+
|
|
979
1018
|
it("translates webSearch item to WebSearch tool_use", async () => {
|
|
980
1019
|
const messages: BrowserIncomingMessage[] = [];
|
|
981
1020
|
const adapter = new CodexAdapter(proc as never, "test-session", { model: "o4-mini" });
|
package/server/codex-adapter.ts
CHANGED
|
@@ -917,8 +917,7 @@ export class CodexAdapter implements IBackendAdapter {
|
|
|
917
917
|
this.handleOutgoingInterrupt();
|
|
918
918
|
return true;
|
|
919
919
|
case "set_model":
|
|
920
|
-
|
|
921
|
-
return false;
|
|
920
|
+
return this.handleOutgoingSetModel(msg.model);
|
|
922
921
|
case "set_permission_mode":
|
|
923
922
|
this.handleOutgoingSetPermissionMode(msg.mode);
|
|
924
923
|
return true;
|
|
@@ -1459,6 +1458,31 @@ export class CodexAdapter implements IBackendAdapter {
|
|
|
1459
1458
|
});
|
|
1460
1459
|
}
|
|
1461
1460
|
|
|
1461
|
+
/**
|
|
1462
|
+
* Switch the model mid-session.
|
|
1463
|
+
*
|
|
1464
|
+
* Codex has no dedicated "set model" RPC. The active model rides on
|
|
1465
|
+
* `collaborationMode.settings.model`, which `handleOutgoingUserMessage` only
|
|
1466
|
+
* attaches to `turn/start` when the collaboration-mode *kind* changes (to
|
|
1467
|
+
* avoid re-enabling permission prompts every turn). To force the new model to
|
|
1468
|
+
* be sent, we update the stored model and reset `lastSentCollaborationModeKind`
|
|
1469
|
+
* so the next `turn/start` re-sends `collaborationMode` carrying it. The switch
|
|
1470
|
+
* therefore takes effect on the next turn — the same semantics as Claude's
|
|
1471
|
+
* `set_model`. Bridge-level persistence + broadcast of the model is handled in
|
|
1472
|
+
* ws-bridge (backend-agnostic), so we don't emit a session_update here.
|
|
1473
|
+
*/
|
|
1474
|
+
private handleOutgoingSetModel(model: string): boolean {
|
|
1475
|
+
if (!model || model === this.options.model) return true;
|
|
1476
|
+
this.options.model = model;
|
|
1477
|
+
// Force collaborationMode (which carries settings.model) to be re-sent on
|
|
1478
|
+
// the next turn/start so Codex picks up the new model.
|
|
1479
|
+
this.lastSentCollaborationModeKind = null;
|
|
1480
|
+
console.log(
|
|
1481
|
+
`[codex-adapter] Session ${this.sessionId}: model switched to ${model} (applies on next turn)`,
|
|
1482
|
+
);
|
|
1483
|
+
return true;
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1462
1486
|
private async handleOutgoingMcpGetStatus(): Promise<void> {
|
|
1463
1487
|
try {
|
|
1464
1488
|
const statusEntries = await this.listAllMcpServerStatuses();
|
package/server/ws-bridge.test.ts
CHANGED
|
@@ -2845,6 +2845,36 @@ describe("Browser message routing", () => {
|
|
|
2845
2845
|
expect(sent.request.model).toBe("claude-opus-4-5-20250929");
|
|
2846
2846
|
});
|
|
2847
2847
|
|
|
2848
|
+
it("set_model: persists the new model so it survives relaunch", () => {
|
|
2849
|
+
// Regression: previously set_model only reached the live CLI; the persisted
|
|
2850
|
+
// session.state.model was never updated, so any relaunch (--resume, wedge
|
|
2851
|
+
// recovery, server restart) rebuilt argv with the OLD model and reverted the
|
|
2852
|
+
// switch. The bridge must write the new model into session state.
|
|
2853
|
+
bridge.handleBrowserMessage(browser, JSON.stringify({
|
|
2854
|
+
type: "set_model",
|
|
2855
|
+
model: "claude-opus-4-5-20250929",
|
|
2856
|
+
}));
|
|
2857
|
+
|
|
2858
|
+
const session = bridge.getSession("s1")!;
|
|
2859
|
+
expect(session.state.model).toBe("claude-opus-4-5-20250929");
|
|
2860
|
+
});
|
|
2861
|
+
|
|
2862
|
+
it("set_model: broadcasts a session_update carrying the new model", () => {
|
|
2863
|
+
// Other browser clients (and the ModelSwitcher's runtime view) rely on a
|
|
2864
|
+
// session_update to reflect the switch authoritatively.
|
|
2865
|
+
bridge.handleBrowserMessage(browser, JSON.stringify({
|
|
2866
|
+
type: "set_model",
|
|
2867
|
+
model: "claude-opus-4-5-20250929",
|
|
2868
|
+
}));
|
|
2869
|
+
|
|
2870
|
+
const updates = browser.send.mock.calls
|
|
2871
|
+
.map((c: unknown[]) => JSON.parse(c[0] as string))
|
|
2872
|
+
.filter((m: { type: string; session?: { model?: string } }) =>
|
|
2873
|
+
m.type === "session_update" && m.session?.model);
|
|
2874
|
+
expect(updates.length).toBeGreaterThanOrEqual(1);
|
|
2875
|
+
expect(updates.at(-1).session.model).toBe("claude-opus-4-5-20250929");
|
|
2876
|
+
});
|
|
2877
|
+
|
|
2848
2878
|
it("set_permission_mode: sends control_request with set_permission_mode subtype to CLI", () => {
|
|
2849
2879
|
bridge.handleBrowserMessage(browser, JSON.stringify({
|
|
2850
2880
|
type: "set_permission_mode",
|
package/server/ws-bridge.ts
CHANGED
|
@@ -1472,6 +1472,22 @@ export class WsBridge {
|
|
|
1472
1472
|
});
|
|
1473
1473
|
}
|
|
1474
1474
|
|
|
1475
|
+
// -- set_model: persist the new model so it survives relaunch, then fall
|
|
1476
|
+
// through to forward it to the adapter (switches the live process). ------
|
|
1477
|
+
// Without persisting here, a switch takes effect on the running CLI but
|
|
1478
|
+
// reverts on the next relaunch (wedge recovery, --resume, server restart),
|
|
1479
|
+
// because cli-launcher rebuilds argv from the persisted session.state.model.
|
|
1480
|
+
// This is backend-agnostic: it fixes Claude and is required for Codex too.
|
|
1481
|
+
// We deliberately do NOT return — the message must still reach the adapter.
|
|
1482
|
+
if (msg.type === "set_model" && msg.model) {
|
|
1483
|
+
session.state.model = msg.model;
|
|
1484
|
+
this.persistSession(session);
|
|
1485
|
+
this.broadcastToBrowsers(session, {
|
|
1486
|
+
type: "session_update",
|
|
1487
|
+
session: { model: msg.model },
|
|
1488
|
+
});
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1475
1491
|
// Delegate to the backend adapter if connected; otherwise queue for later flush.
|
|
1476
1492
|
// For Claude: adapter may exist but WS is disconnected (CLI cycling). Queue at
|
|
1477
1493
|
// bridge level so handleCLIOpen flushes via adapter.send() after reconnect.
|