@seqyuan/annodex 0.1.97 → 0.1.98
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/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +7 -7
- package/.next/build-manifest.json +2 -2
- package/.next/prerender-manifest.json +3 -3
- package/.next/required-server-files.js +1 -1
- package/.next/required-server-files.json +1 -1
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +1 -1
- package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/api/internal/runtime/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/route.js +1 -1
- package/.next/server/app/api/version/route.js +1 -1
- package/.next/server/app/docs/changelog.html +2 -2
- package/.next/server/app/docs/changelog.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/_full.segment.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/_head.segment.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/_index.segment.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/docs/changelog/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/docs/changelog.segment.rsc +1 -1
- package/.next/server/app/docs/changelog.segments/docs.segment.rsc +1 -1
- package/.next/server/app/index.html +1 -1
- package/.next/server/app/index.rsc +1 -1
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/login.html +1 -1
- package/.next/server/app/login.rsc +1 -1
- package/.next/server/app/login.segments/_full.segment.rsc +1 -1
- package/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/.next/server/app/login.segments/_index.segment.rsc +1 -1
- package/.next/server/app/login.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/.next/server/app/workspace/page.js +12 -12
- package/.next/server/app/workspace/page_client-reference-manifest.js +1 -1
- package/.next/server/app/workspace.html +1 -1
- package/.next/server/app/workspace.rsc +2 -2
- package/.next/server/app/workspace.segments/_full.segment.rsc +2 -2
- package/.next/server/app/workspace.segments/_head.segment.rsc +1 -1
- package/.next/server/app/workspace.segments/_index.segment.rsc +1 -1
- package/.next/server/app/workspace.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/workspace.segments/workspace/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/workspace.segments/workspace.segment.rsc +1 -1
- package/.next/server/app-paths-manifest.json +7 -7
- package/.next/server/chunks/6429.js +1 -1
- package/.next/server/chunks/6983.js +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/app/workspace/page-5aae36c4d724b11d.js +265 -0
- package/package.json +1 -1
- package/.next/static/chunks/app/workspace/page-da42eab640e2c887.js +0 -265
- /package/.next/static/{SVHmVqHgsyh7rLM_BP4l1 → AGWDEHkSDNIvOTAQZ2_6O}/_buildManifest.js +0 -0
- /package/.next/static/{SVHmVqHgsyh7rLM_BP4l1 → AGWDEHkSDNIvOTAQZ2_6O}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(()=>{var a={};a.id=6849,a.ids=[6849],a.modules={261:a=>{a.exports=require("next/dist/shared/lib/router/utils/app-paths")},1932:a=>{a.exports=require("url")},3295:a=>{a.exports=require("next/dist/server/app-render/after-task-async-storage.external.js")},4984:a=>{a.exports=require("readline")},10846:a=>{a.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},21820:a=>{a.exports=require("os")},29021:a=>{a.exports=require("fs")},29250:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.r(b),c.d(b,{handler:()=>y,patchFetch:()=>x,routeModule:()=>z,serverHooks:()=>C,workAsyncStorage:()=>A,workUnitAsyncStorage:()=>B});var e=c(19225),f=c(84006),g=c(8317),h=c(99373),i=c(34775),j=c(24235),k=c(261),l=c(54365),m=c(90771),n=c(73461),o=c(67798),p=c(92280),q=c(62018),r=c(45696),s=c(47929),t=c(86439),u=c(37527),v=c(98192),w=a([v]);v=(w.then?(await w)():w)[0];let z=new e.AppRouteRouteModule({definition:{kind:f.RouteKind.APP_ROUTE,page:"/api/sessions/[id]/route",pathname:"/api/sessions/[id]",filename:"route",bundlePath:"app/api/sessions/[id]/route"},distDir:".next",relativeProjectDir:"",resolvedPagePath:"/home/runner/work/annodex/annodex/app/api/sessions/[id]/route.ts",nextConfigOutput:"",userland:v}),{workAsyncStorage:A,workUnitAsyncStorage:B,serverHooks:C}=z;function x(){return(0,g.patchFetch)({workAsyncStorage:A,workUnitAsyncStorage:B})}async function y(a,b,c){c.requestMeta&&(0,h.setRequestMeta)(a,c.requestMeta),z.isDev&&(0,h.addRequestMeta)(a,"devRequestTimingInternalsEnd",process.hrtime.bigint());let d="/api/sessions/[id]/route";"/index"===d&&(d="/");let e=await z.prepare(a,b,{srcPage:d,multiZoneDraftMode:!1});if(!e)return b.statusCode=400,b.end("Bad Request"),null==c.waitUntil||c.waitUntil.call(c,Promise.resolve()),null;let{buildId:g,params:v,nextConfig:w,parsedUrl:x,isDraftMode:y,prerenderManifest:A,routerServerContext:B,isOnDemandRevalidate:C,revalidateOnlyGenerated:D,resolvedPathname:E,clientReferenceManifest:F,serverActionsManifest:G}=e,H=(0,k.normalizeAppPath)(d),I=!!(A.dynamicRoutes[H]||A.routes[E]),J=async()=>((null==B?void 0:B.render404)?await B.render404(a,b,x,!1):b.end("This page could not be found"),null);if(I&&!y){let a=!!A.routes[E],b=A.dynamicRoutes[H];if(b&&!1===b.fallback&&!a){if(w.adapterPath)return await J();throw new t.NoFallbackError}}let K=null;!I||z.isDev||y||(K=E,K="/index"===K?"/":K);let L=!0===z.isDev||!I,M=I&&!L;G&&F&&(0,j.setManifestsSingleton)({page:d,clientReferenceManifest:F,serverActionsManifest:G});let N=a.method||"GET",O=(0,i.getTracer)(),P=O.getActiveScopeSpan(),Q=!!(null==B?void 0:B.isWrappedByNextServer),R=!!(0,h.getRequestMeta)(a,"minimalMode"),S=(0,h.getRequestMeta)(a,"incrementalCache")||await z.getIncrementalCache(a,w,A,R);null==S||S.resetRequestCache(),globalThis.__incrementalCache=S;let T={params:v,previewProps:A.preview,renderOpts:{experimental:{authInterrupts:!!w.experimental.authInterrupts},cacheComponents:!!w.cacheComponents,supportsDynamicResponse:L,incrementalCache:S,cacheLifeProfiles:w.cacheLife,waitUntil:c.waitUntil,onClose:a=>{b.on("close",a)},onAfterTaskError:void 0,onInstrumentationRequestError:(b,c,d,e)=>z.onRequestError(a,b,d,e,B)},sharedContext:{buildId:g}},U=new l.NodeNextRequest(a),V=new l.NodeNextResponse(b),W=m.NextRequestAdapter.fromNodeNextRequest(U,(0,m.signalFromNodeResponse)(b));try{let e,g=async a=>z.handle(W,T).finally(()=>{if(!a)return;a.setAttributes({"http.status_code":b.statusCode,"next.rsc":!1});let c=O.getRootSpanAttributes();if(!c)return;if(c.get("next.span_type")!==n.BaseServerSpan.handleRequest)return void console.warn(`Unexpected root span type '${c.get("next.span_type")}'. Please report this Next.js issue https://github.com/vercel/next.js`);let f=c.get("next.route");if(f){let b=`${N} ${f}`;a.setAttributes({"next.route":f,"http.route":f,"next.span_name":b}),a.updateName(b),e&&e!==a&&(e.setAttribute("http.route",f),e.updateName(b))}else a.updateName(`${N} ${d}`)}),h=async e=>{var h,i;let j=async({previousCacheEntry:f})=>{try{if(!R&&C&&D&&!f)return b.statusCode=404,b.setHeader("x-nextjs-cache","REVALIDATED"),b.end("This page could not be found"),null;let d=await g(e);a.fetchMetrics=T.renderOpts.fetchMetrics;let h=T.renderOpts.pendingWaitUntil;h&&c.waitUntil&&(c.waitUntil(h),h=void 0);let i=T.renderOpts.collectedTags;if(!I)return await (0,p.I)(U,V,d,T.renderOpts.pendingWaitUntil),null;{let a=await d.blob(),b=(0,q.toNodeOutgoingHttpHeaders)(d.headers);i&&(b[s.NEXT_CACHE_TAGS_HEADER]=i),!b["content-type"]&&a.type&&(b["content-type"]=a.type);let c=void 0!==T.renderOpts.collectedRevalidate&&!(T.renderOpts.collectedRevalidate>=s.INFINITE_CACHE)&&T.renderOpts.collectedRevalidate,e=void 0===T.renderOpts.collectedExpire||T.renderOpts.collectedExpire>=s.INFINITE_CACHE?void 0:T.renderOpts.collectedExpire;return{value:{kind:u.CachedRouteKind.APP_ROUTE,status:d.status,body:Buffer.from(await a.arrayBuffer()),headers:b},cacheControl:{revalidate:c,expire:e}}}}catch(b){throw(null==f?void 0:f.isStale)&&await z.onRequestError(a,b,{routerKind:"App Router",routePath:d,routeType:"route",revalidateReason:(0,o.c)({isStaticGeneration:M,isOnDemandRevalidate:C})},!1,B),b}},k=await z.handleResponse({req:a,nextConfig:w,cacheKey:K,routeKind:f.RouteKind.APP_ROUTE,isFallback:!1,prerenderManifest:A,isRoutePPREnabled:!1,isOnDemandRevalidate:C,revalidateOnlyGenerated:D,responseGenerator:j,waitUntil:c.waitUntil,isMinimalMode:R});if(!I)return null;if((null==k||null==(h=k.value)?void 0:h.kind)!==u.CachedRouteKind.APP_ROUTE)throw Object.defineProperty(Error(`Invariant: app-route received invalid cache entry ${null==k||null==(i=k.value)?void 0:i.kind}`),"__NEXT_ERROR_CODE",{value:"E701",enumerable:!1,configurable:!0});R||b.setHeader("x-nextjs-cache",C?"REVALIDATED":k.isMiss?"MISS":k.isStale?"STALE":"HIT"),y&&b.setHeader("Cache-Control","private, no-cache, no-store, max-age=0, must-revalidate");let l=(0,q.fromNodeOutgoingHttpHeaders)(k.value.headers);return R&&I||l.delete(s.NEXT_CACHE_TAGS_HEADER),!k.cacheControl||b.getHeader("Cache-Control")||l.get("Cache-Control")||l.set("Cache-Control",(0,r.getCacheControlHeader)(k.cacheControl)),await (0,p.I)(U,V,new Response(k.value.body,{headers:l,status:k.value.status||200})),null};Q&&P?await h(P):(e=O.getActiveScopeSpan(),await O.withPropagatedContext(a.headers,()=>O.trace(n.BaseServerSpan.handleRequest,{spanName:`${N} ${d}`,kind:i.SpanKind.SERVER,attributes:{"http.method":N,"http.target":a.url}},h),void 0,!Q))}catch(b){if(b instanceof t.NoFallbackError||await z.onRequestError(a,b,{routerKind:"App Router",routePath:H,routeType:"route",revalidateReason:(0,o.c)({isStaticGeneration:M,isOnDemandRevalidate:C})},!1,B),I)throw b;return await (0,p.I)(U,V,new Response(null,{status:500})),null}}d()}catch(a){d(a)}})},29294:a=>{a.exports=require("next/dist/server/app-render/work-async-storage.external.js")},33873:a=>{a.exports=require("path")},44870:a=>{a.exports=require("next/dist/compiled/next-server/app-route.runtime.prod.js")},55511:a=>{a.exports=require("crypto")},55591:a=>{a.exports=require("https")},56220:a=>{a.exports=import("ws")},63033:a=>{a.exports=require("next/dist/server/app-render/work-unit-async-storage.external.js")},79646:a=>{a.exports=require("child_process")},81630:a=>{a.exports=require("http")},86439:a=>{a.exports=require("next/dist/shared/lib/no-fallback-error.external")},91645:a=>{a.exports=require("net")},98192:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.r(b),c.d(b,{DELETE:()=>o,GET:()=>m,PATCH:()=>n});var e=c(23211),f=c(29021),g=c(40402),h=c(56429),i=c(46983),j=c(26257),k=c(55132),l=a([g,h,i]);async function m(a,{params:b}){let{id:c}=await b;try{let b,d=(0,g.r1)(c);if(!d)return e.NextResponse.json({error:"Session not found"},{status:404});let k=new URL(a.url);if(k.searchParams.has("infoOnly"))return e.NextResponse.json({info:{...d,cwdExists:!!d.cwd&&(0,f.existsSync)(d.cwd)}});let l=await (0,g.T0)(c,d.cwd).catch(()=>null),m=l?.context??{messages:[],entryIds:[],thinkingLevel:"off",model:null,subagentRuns:[]},n=l?.tree??[],o=l?.leafId??null;if(k.searchParams.has("includeState")){let a=(0,j.zZ)(c),d="danger-full-access",e=(0,h.A4)(c);if(e?.isAlive()){let a=await e.send({type:"get_state"});b={running:e.isBusy(),state:a}}else b=(0,i.nt)(l?.thread)?{running:!0,state:{isStreaming:!0,isCompacting:!1,contextUsage:m.contextUsage,thinkingLevel:m.thinkingLevel,sandboxMode:d,enabledExtensions:a?.extensions??[]}}:{running:!1,state:{sandboxMode:d,enabledExtensions:a?.extensions??[]}}}return e.NextResponse.json({sessionId:c,filePath:"",info:{...d,cwdExists:!!d.cwd&&(0,f.existsSync)(d.cwd)},tree:n,leafId:o,context:m,...void 0!==b?{agentState:b}:{}})}catch(a){return console.error(`[sessions/${c}] GET error:`,a),e.NextResponse.json({error:String(a)},{status:500})}}async function n(a,{params:b}){let{id:c}=await b;try{let{name:b}=await a.json();if("string"!=typeof b)return e.NextResponse.json({error:"name is required"},{status:400});let d=b.trim(),f=(0,h.A4)(c);if(f?.isAlive())try{return await f.send({type:"rename",name:d}),(0,j.yJ)(c,{name:d}),e.NextResponse.json({ok:!0})}catch(b){let a;if(a=b instanceof Error?b.message:String(b),!/not connected|disconnected|timeout|closed|ECONNRESET|ECONNREFUSED|WebSocket/i.test(a))throw b}let l=await (0,g.os)(c);if(!l)return e.NextResponse.json({error:"Session cwd not found"},{status:404});let m=await (0,i.gu)(l,(0,i.H3)((0,k.Dw)().providers));try{await m.request("thread/name/set",{threadId:c,name:d})}finally{(0,i.sM)(m)}return(0,j.yJ)(c,{name:d}),e.NextResponse.json({ok:!0})}catch(a){return console.error(`[sessions/${c}] PATCH error:`,a),e.NextResponse.json({error:String(a)},{status:500})}}async function o(a,{params:b}){let{id:c}=await b;try{(0,h.A4)(c)?.destroy();let a=await (0,g.os)(c);if(a){let b=await (0,i.gu)(a,(0,i.H3)((0,k.Dw)().providers));try{await b.request("thread/archive",{threadId:c}).catch(()=>{})}finally{(0,i.sM)(b)}}return(0,g.BR)(c),(0,j.s)(c),e.NextResponse.json({ok:!0})}catch(a){return console.error(`[sessions/${c}] DELETE error:`,a),e.NextResponse.json({error:String(a)},{status:500})}}[g,h,i]=l.then?(await l)():l,d()}catch(a){d(a)}})}};var b=require("../../../../webpack-runtime.js");b.C(a);var c=b.X(0,[4741,1813,8477,4768,5399,6983,402,6429],()=>b(b.s=29250));module.exports=c})();
|
|
1
|
+
"use strict";(()=>{var a={};a.id=6849,a.ids=[6849],a.modules={261:a=>{a.exports=require("next/dist/shared/lib/router/utils/app-paths")},1932:a=>{a.exports=require("url")},3295:a=>{a.exports=require("next/dist/server/app-render/after-task-async-storage.external.js")},4984:a=>{a.exports=require("readline")},10846:a=>{a.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},21820:a=>{a.exports=require("os")},29021:a=>{a.exports=require("fs")},29250:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.r(b),c.d(b,{handler:()=>y,patchFetch:()=>x,routeModule:()=>z,serverHooks:()=>C,workAsyncStorage:()=>A,workUnitAsyncStorage:()=>B});var e=c(19225),f=c(84006),g=c(8317),h=c(99373),i=c(34775),j=c(24235),k=c(261),l=c(54365),m=c(90771),n=c(73461),o=c(67798),p=c(92280),q=c(62018),r=c(45696),s=c(47929),t=c(86439),u=c(37527),v=c(98192),w=a([v]);v=(w.then?(await w)():w)[0];let z=new e.AppRouteRouteModule({definition:{kind:f.RouteKind.APP_ROUTE,page:"/api/sessions/[id]/route",pathname:"/api/sessions/[id]",filename:"route",bundlePath:"app/api/sessions/[id]/route"},distDir:".next",relativeProjectDir:"",resolvedPagePath:"/home/runner/work/annodex/annodex/app/api/sessions/[id]/route.ts",nextConfigOutput:"",userland:v}),{workAsyncStorage:A,workUnitAsyncStorage:B,serverHooks:C}=z;function x(){return(0,g.patchFetch)({workAsyncStorage:A,workUnitAsyncStorage:B})}async function y(a,b,c){c.requestMeta&&(0,h.setRequestMeta)(a,c.requestMeta),z.isDev&&(0,h.addRequestMeta)(a,"devRequestTimingInternalsEnd",process.hrtime.bigint());let d="/api/sessions/[id]/route";"/index"===d&&(d="/");let e=await z.prepare(a,b,{srcPage:d,multiZoneDraftMode:!1});if(!e)return b.statusCode=400,b.end("Bad Request"),null==c.waitUntil||c.waitUntil.call(c,Promise.resolve()),null;let{buildId:g,params:v,nextConfig:w,parsedUrl:x,isDraftMode:y,prerenderManifest:A,routerServerContext:B,isOnDemandRevalidate:C,revalidateOnlyGenerated:D,resolvedPathname:E,clientReferenceManifest:F,serverActionsManifest:G}=e,H=(0,k.normalizeAppPath)(d),I=!!(A.dynamicRoutes[H]||A.routes[E]),J=async()=>((null==B?void 0:B.render404)?await B.render404(a,b,x,!1):b.end("This page could not be found"),null);if(I&&!y){let a=!!A.routes[E],b=A.dynamicRoutes[H];if(b&&!1===b.fallback&&!a){if(w.adapterPath)return await J();throw new t.NoFallbackError}}let K=null;!I||z.isDev||y||(K=E,K="/index"===K?"/":K);let L=!0===z.isDev||!I,M=I&&!L;G&&F&&(0,j.setManifestsSingleton)({page:d,clientReferenceManifest:F,serverActionsManifest:G});let N=a.method||"GET",O=(0,i.getTracer)(),P=O.getActiveScopeSpan(),Q=!!(null==B?void 0:B.isWrappedByNextServer),R=!!(0,h.getRequestMeta)(a,"minimalMode"),S=(0,h.getRequestMeta)(a,"incrementalCache")||await z.getIncrementalCache(a,w,A,R);null==S||S.resetRequestCache(),globalThis.__incrementalCache=S;let T={params:v,previewProps:A.preview,renderOpts:{experimental:{authInterrupts:!!w.experimental.authInterrupts},cacheComponents:!!w.cacheComponents,supportsDynamicResponse:L,incrementalCache:S,cacheLifeProfiles:w.cacheLife,waitUntil:c.waitUntil,onClose:a=>{b.on("close",a)},onAfterTaskError:void 0,onInstrumentationRequestError:(b,c,d,e)=>z.onRequestError(a,b,d,e,B)},sharedContext:{buildId:g}},U=new l.NodeNextRequest(a),V=new l.NodeNextResponse(b),W=m.NextRequestAdapter.fromNodeNextRequest(U,(0,m.signalFromNodeResponse)(b));try{let e,g=async a=>z.handle(W,T).finally(()=>{if(!a)return;a.setAttributes({"http.status_code":b.statusCode,"next.rsc":!1});let c=O.getRootSpanAttributes();if(!c)return;if(c.get("next.span_type")!==n.BaseServerSpan.handleRequest)return void console.warn(`Unexpected root span type '${c.get("next.span_type")}'. Please report this Next.js issue https://github.com/vercel/next.js`);let f=c.get("next.route");if(f){let b=`${N} ${f}`;a.setAttributes({"next.route":f,"http.route":f,"next.span_name":b}),a.updateName(b),e&&e!==a&&(e.setAttribute("http.route",f),e.updateName(b))}else a.updateName(`${N} ${d}`)}),h=async e=>{var h,i;let j=async({previousCacheEntry:f})=>{try{if(!R&&C&&D&&!f)return b.statusCode=404,b.setHeader("x-nextjs-cache","REVALIDATED"),b.end("This page could not be found"),null;let d=await g(e);a.fetchMetrics=T.renderOpts.fetchMetrics;let h=T.renderOpts.pendingWaitUntil;h&&c.waitUntil&&(c.waitUntil(h),h=void 0);let i=T.renderOpts.collectedTags;if(!I)return await (0,p.I)(U,V,d,T.renderOpts.pendingWaitUntil),null;{let a=await d.blob(),b=(0,q.toNodeOutgoingHttpHeaders)(d.headers);i&&(b[s.NEXT_CACHE_TAGS_HEADER]=i),!b["content-type"]&&a.type&&(b["content-type"]=a.type);let c=void 0!==T.renderOpts.collectedRevalidate&&!(T.renderOpts.collectedRevalidate>=s.INFINITE_CACHE)&&T.renderOpts.collectedRevalidate,e=void 0===T.renderOpts.collectedExpire||T.renderOpts.collectedExpire>=s.INFINITE_CACHE?void 0:T.renderOpts.collectedExpire;return{value:{kind:u.CachedRouteKind.APP_ROUTE,status:d.status,body:Buffer.from(await a.arrayBuffer()),headers:b},cacheControl:{revalidate:c,expire:e}}}}catch(b){throw(null==f?void 0:f.isStale)&&await z.onRequestError(a,b,{routerKind:"App Router",routePath:d,routeType:"route",revalidateReason:(0,o.c)({isStaticGeneration:M,isOnDemandRevalidate:C})},!1,B),b}},k=await z.handleResponse({req:a,nextConfig:w,cacheKey:K,routeKind:f.RouteKind.APP_ROUTE,isFallback:!1,prerenderManifest:A,isRoutePPREnabled:!1,isOnDemandRevalidate:C,revalidateOnlyGenerated:D,responseGenerator:j,waitUntil:c.waitUntil,isMinimalMode:R});if(!I)return null;if((null==k||null==(h=k.value)?void 0:h.kind)!==u.CachedRouteKind.APP_ROUTE)throw Object.defineProperty(Error(`Invariant: app-route received invalid cache entry ${null==k||null==(i=k.value)?void 0:i.kind}`),"__NEXT_ERROR_CODE",{value:"E701",enumerable:!1,configurable:!0});R||b.setHeader("x-nextjs-cache",C?"REVALIDATED":k.isMiss?"MISS":k.isStale?"STALE":"HIT"),y&&b.setHeader("Cache-Control","private, no-cache, no-store, max-age=0, must-revalidate");let l=(0,q.fromNodeOutgoingHttpHeaders)(k.value.headers);return R&&I||l.delete(s.NEXT_CACHE_TAGS_HEADER),!k.cacheControl||b.getHeader("Cache-Control")||l.get("Cache-Control")||l.set("Cache-Control",(0,r.getCacheControlHeader)(k.cacheControl)),await (0,p.I)(U,V,new Response(k.value.body,{headers:l,status:k.value.status||200})),null};Q&&P?await h(P):(e=O.getActiveScopeSpan(),await O.withPropagatedContext(a.headers,()=>O.trace(n.BaseServerSpan.handleRequest,{spanName:`${N} ${d}`,kind:i.SpanKind.SERVER,attributes:{"http.method":N,"http.target":a.url}},h),void 0,!Q))}catch(b){if(b instanceof t.NoFallbackError||await z.onRequestError(a,b,{routerKind:"App Router",routePath:H,routeType:"route",revalidateReason:(0,o.c)({isStaticGeneration:M,isOnDemandRevalidate:C})},!1,B),I)throw b;return await (0,p.I)(U,V,new Response(null,{status:500})),null}}d()}catch(a){d(a)}})},29294:a=>{a.exports=require("next/dist/server/app-render/work-async-storage.external.js")},33873:a=>{a.exports=require("path")},44870:a=>{a.exports=require("next/dist/compiled/next-server/app-route.runtime.prod.js")},55511:a=>{a.exports=require("crypto")},55591:a=>{a.exports=require("https")},56220:a=>{a.exports=import("ws")},63033:a=>{a.exports=require("next/dist/server/app-render/work-unit-async-storage.external.js")},79646:a=>{a.exports=require("child_process")},81630:a=>{a.exports=require("http")},86439:a=>{a.exports=require("next/dist/shared/lib/no-fallback-error.external")},91645:a=>{a.exports=require("net")},98192:(a,b,c)=>{c.a(a,async(a,d)=>{try{c.r(b),c.d(b,{DELETE:()=>o,GET:()=>m,PATCH:()=>n});var e=c(23211),f=c(29021),g=c(40402),h=c(56429),i=c(46983),j=c(26257),k=c(55132),l=a([g,h,i]);async function m(a,{params:b}){let{id:c}=await b;try{let b,d=(0,g.r1)(c);if(!d)return e.NextResponse.json({error:"Session not found"},{status:404});let k=new URL(a.url);if(k.searchParams.has("infoOnly"))return e.NextResponse.json({info:{...d,cwdExists:!!d.cwd&&(0,f.existsSync)(d.cwd)}});let l=await (0,g.T0)(c,d.cwd).catch(()=>null),m=l?.context??{messages:[],entryIds:[],thinkingLevel:"off",model:null,subagentRuns:[]},n=l?.tree??[],o=l?.leafId??null;if(k.searchParams.has("includeState")){let a=(0,j.zZ)(c),d="danger-full-access",e=(0,h.A4)(c);if(e?.isAlive()){let a=await e.send({type:"get_state"});b={running:e.isBusy(),state:a}}else b=(0,i.nt)(l?.thread)?{running:!0,state:{isStreaming:!0,isCompacting:!1,contextUsage:m.contextUsage,thinkingLevel:m.thinkingLevel,sandboxMode:d,enabledExtensions:a?.extensions??[]}}:{running:!1,state:{sandboxMode:d,enabledExtensions:a?.extensions??[]}}}return e.NextResponse.json({sessionId:c,filePath:"",info:{...d,cwdExists:!!d.cwd&&(0,f.existsSync)(d.cwd)},tree:n,leafId:o,context:m,...void 0!==b?{agentState:b}:{}})}catch(a){return console.error(`[sessions/${c}] GET error:`,a),e.NextResponse.json({error:String(a)},{status:500})}}async function n(a,{params:b}){let{id:c}=await b;try{let{name:b}=await a.json();if("string"!=typeof b)return e.NextResponse.json({error:"name is required"},{status:400});let d=b.trim();if(!d)return e.NextResponse.json({error:"Name cannot be empty"},{status:400});let f=(0,h.A4)(c);if(f?.isAlive())try{return await f.send({type:"rename",name:d}),(0,j.yJ)(c,{name:d}),e.NextResponse.json({ok:!0})}catch(b){let a;if(a=b instanceof Error?b.message:String(b),!/not connected|disconnected|timeout|closed|ECONNRESET|ECONNREFUSED|WebSocket/i.test(a))throw b;try{f.destroy()}catch{}}let l=await (0,g.os)(c);if(!l)return e.NextResponse.json({error:"Session cwd not found"},{status:404});let m=await (0,i.gu)(l,(0,i.H3)((0,k.Dw)().providers));try{await m.request("thread/name/set",{threadId:c,name:d})}finally{(0,i.sM)(m)}return(0,j.yJ)(c,{name:d}),e.NextResponse.json({ok:!0})}catch(a){return console.error(`[sessions/${c}] PATCH error:`,a),e.NextResponse.json({error:String(a)},{status:500})}}async function o(a,{params:b}){let{id:c}=await b;try{(0,h.A4)(c)?.destroy();let a=await (0,g.os)(c);if(a){let b=await (0,i.gu)(a,(0,i.H3)((0,k.Dw)().providers));try{await b.request("thread/archive",{threadId:c}).catch(()=>{})}finally{(0,i.sM)(b)}}return(0,g.BR)(c),(0,j.s)(c),e.NextResponse.json({ok:!0})}catch(a){return console.error(`[sessions/${c}] DELETE error:`,a),e.NextResponse.json({error:String(a)},{status:500})}}[g,h,i]=l.then?(await l)():l,d()}catch(a){d(a)}})}};var b=require("../../../../webpack-runtime.js");b.C(a);var c=b.X(0,[4741,1813,8477,4768,5399,6983,402,6429],()=>b(b.s=29250));module.exports=c})();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var a={};a.id=2922,a.ids=[2922],a.modules={261:a=>{"use strict";a.exports=require("next/dist/shared/lib/router/utils/app-paths")},3295:a=>{"use strict";a.exports=require("next/dist/server/app-render/after-task-async-storage.external.js")},10846:a=>{"use strict";a.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},14158:(a,b,c)=>{"use strict";c.r(b),c.d(b,{handler:()=>N,patchFetch:()=>M,routeModule:()=>I,serverHooks:()=>L,workAsyncStorage:()=>J,workUnitAsyncStorage:()=>K});var d={};c.r(d),c.d(d,{GET:()=>H,dynamic:()=>D});var e=c(19225),f=c(84006),g=c(8317),h=c(99373),i=c(34775),j=c(24235),k=c(261),l=c(54365),m=c(90771),n=c(73461),o=c(67798),p=c(92280),q=c(62018),r=c(45696),s=c(47929),t=c(86439),u=c(37527),v=c(23211),w=c(65833),x=c(29021),y=c(33873),z=c(21820);function A(a){return"string"==typeof a&&a.length>0?a:null}function B(a){return Number.isInteger(a)&&Number(a)>0?Number(a):null}function C(a){if(!a)return!1;try{return process.kill(a,0),!0}catch{return!1}}let D="force-dynamic",E="0.1.
|
|
1
|
+
(()=>{var a={};a.id=2922,a.ids=[2922],a.modules={261:a=>{"use strict";a.exports=require("next/dist/shared/lib/router/utils/app-paths")},3295:a=>{"use strict";a.exports=require("next/dist/server/app-render/after-task-async-storage.external.js")},10846:a=>{"use strict";a.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},14158:(a,b,c)=>{"use strict";c.r(b),c.d(b,{handler:()=>N,patchFetch:()=>M,routeModule:()=>I,serverHooks:()=>L,workAsyncStorage:()=>J,workUnitAsyncStorage:()=>K});var d={};c.r(d),c.d(d,{GET:()=>H,dynamic:()=>D});var e=c(19225),f=c(84006),g=c(8317),h=c(99373),i=c(34775),j=c(24235),k=c(261),l=c(54365),m=c(90771),n=c(73461),o=c(67798),p=c(92280),q=c(62018),r=c(45696),s=c(47929),t=c(86439),u=c(37527),v=c(23211),w=c(65833),x=c(29021),y=c(33873),z=c(21820);function A(a){return"string"==typeof a&&a.length>0?a:null}function B(a){return Number.isInteger(a)&&Number(a)>0?Number(a):null}function C(a){if(!a)return!1;try{return process.kill(a,0),!0}catch{return!1}}let D="force-dynamic",E="0.1.98",F=null;async function G(){if(F&&F.expiresAt>Date.now())return F.value;let a=new AbortController,b=setTimeout(()=>a.abort(),3500);try{let b=await fetch(`https://registry.npmjs.org/${encodeURIComponent(w.JD)}/latest`,{cache:"no-store",signal:a.signal});if(!b.ok)return F={value:null,expiresAt:Date.now()+3e5},null;let c=await b.json(),d="string"==typeof c.version?c.version:null;return F={value:d,expiresAt:Date.now()+3e5},d}catch{return F={value:null,expiresAt:Date.now()+6e4},null}finally{clearTimeout(b)}}async function H(){let a=await G(),b={current:E,latest:a,updateAvailable:!!(a&&a!==E),updateCommand:w.AQ,runtime:function(){let a=function(){let a,b=(a=function(...a){for(let b of a){let a=process.env[b];if(void 0!==a)return a}}("ANNODEX_CONFIG_DIR","ANNOVIBE_CONFIG_DIR")??(0,y.join)((0,z.homedir)(),".config","annodex"),[(0,y.join)(a,"annodex.json"),(0,y.join)(a,"annovibe.json"),(0,y.join)(a,"pidex.json")]).find(a=>(0,x.existsSync)(a));if(!b)return null;try{return JSON.parse((0,x.readFileSync)(b,"utf8"))}catch{return null}}();if(!a)return null;let b=B(a.supervisorPid),c=B(a.nextPid),d=C(b),e=C(c),f=d||e;return{running:f,status:d?"running":e?"orphaned":"stopped",version:A(a.version),url:A(a.url),port:A(a.port),hostname:A(a.hostname),supervisorPid:d?b:null,nextPid:e?c:null,startedAt:f?A(a.startedAt):null,readyAt:f?A(a.readyAt):null,restartPending:f&&!!a.restartPending,installedVersion:f?A(a.installedVersion):null,restartDetectedAt:f?A(a.restartDetectedAt):null,restartStartedAt:f?A(a.restartStartedAt):null,updatedAt:A(a.updatedAt)}}()};return v.NextResponse.json(b)}let I=new e.AppRouteRouteModule({definition:{kind:f.RouteKind.APP_ROUTE,page:"/api/version/route",pathname:"/api/version",filename:"route",bundlePath:"app/api/version/route"},distDir:".next",relativeProjectDir:"",resolvedPagePath:"/home/runner/work/annodex/annodex/app/api/version/route.ts",nextConfigOutput:"",userland:d}),{workAsyncStorage:J,workUnitAsyncStorage:K,serverHooks:L}=I;function M(){return(0,g.patchFetch)({workAsyncStorage:J,workUnitAsyncStorage:K})}async function N(a,b,c){c.requestMeta&&(0,h.setRequestMeta)(a,c.requestMeta),I.isDev&&(0,h.addRequestMeta)(a,"devRequestTimingInternalsEnd",process.hrtime.bigint());let d="/api/version/route";"/index"===d&&(d="/");let e=await I.prepare(a,b,{srcPage:d,multiZoneDraftMode:!1});if(!e)return b.statusCode=400,b.end("Bad Request"),null==c.waitUntil||c.waitUntil.call(c,Promise.resolve()),null;let{buildId:g,params:v,nextConfig:w,parsedUrl:x,isDraftMode:y,prerenderManifest:z,routerServerContext:A,isOnDemandRevalidate:B,revalidateOnlyGenerated:C,resolvedPathname:D,clientReferenceManifest:E,serverActionsManifest:F}=e,G=(0,k.normalizeAppPath)(d),H=!!(z.dynamicRoutes[G]||z.routes[D]),J=async()=>((null==A?void 0:A.render404)?await A.render404(a,b,x,!1):b.end("This page could not be found"),null);if(H&&!y){let a=!!z.routes[D],b=z.dynamicRoutes[G];if(b&&!1===b.fallback&&!a){if(w.adapterPath)return await J();throw new t.NoFallbackError}}let K=null;!H||I.isDev||y||(K="/index"===(K=D)?"/":K);let L=!0===I.isDev||!H,M=H&&!L;F&&E&&(0,j.setManifestsSingleton)({page:d,clientReferenceManifest:E,serverActionsManifest:F});let N=a.method||"GET",O=(0,i.getTracer)(),P=O.getActiveScopeSpan(),Q=!!(null==A?void 0:A.isWrappedByNextServer),R=!!(0,h.getRequestMeta)(a,"minimalMode"),S=(0,h.getRequestMeta)(a,"incrementalCache")||await I.getIncrementalCache(a,w,z,R);null==S||S.resetRequestCache(),globalThis.__incrementalCache=S;let T={params:v,previewProps:z.preview,renderOpts:{experimental:{authInterrupts:!!w.experimental.authInterrupts},cacheComponents:!!w.cacheComponents,supportsDynamicResponse:L,incrementalCache:S,cacheLifeProfiles:w.cacheLife,waitUntil:c.waitUntil,onClose:a=>{b.on("close",a)},onAfterTaskError:void 0,onInstrumentationRequestError:(b,c,d,e)=>I.onRequestError(a,b,d,e,A)},sharedContext:{buildId:g}},U=new l.NodeNextRequest(a),V=new l.NodeNextResponse(b),W=m.NextRequestAdapter.fromNodeNextRequest(U,(0,m.signalFromNodeResponse)(b));try{let e,g=async a=>I.handle(W,T).finally(()=>{if(!a)return;a.setAttributes({"http.status_code":b.statusCode,"next.rsc":!1});let c=O.getRootSpanAttributes();if(!c)return;if(c.get("next.span_type")!==n.BaseServerSpan.handleRequest)return void console.warn(`Unexpected root span type '${c.get("next.span_type")}'. Please report this Next.js issue https://github.com/vercel/next.js`);let f=c.get("next.route");if(f){let b=`${N} ${f}`;a.setAttributes({"next.route":f,"http.route":f,"next.span_name":b}),a.updateName(b),e&&e!==a&&(e.setAttribute("http.route",f),e.updateName(b))}else a.updateName(`${N} ${d}`)}),h=async e=>{var h,i;let j=async({previousCacheEntry:f})=>{try{if(!R&&B&&C&&!f)return b.statusCode=404,b.setHeader("x-nextjs-cache","REVALIDATED"),b.end("This page could not be found"),null;let d=await g(e);a.fetchMetrics=T.renderOpts.fetchMetrics;let h=T.renderOpts.pendingWaitUntil;h&&c.waitUntil&&(c.waitUntil(h),h=void 0);let i=T.renderOpts.collectedTags;if(!H)return await (0,p.I)(U,V,d,T.renderOpts.pendingWaitUntil),null;{let a=await d.blob(),b=(0,q.toNodeOutgoingHttpHeaders)(d.headers);i&&(b[s.NEXT_CACHE_TAGS_HEADER]=i),!b["content-type"]&&a.type&&(b["content-type"]=a.type);let c=void 0!==T.renderOpts.collectedRevalidate&&!(T.renderOpts.collectedRevalidate>=s.INFINITE_CACHE)&&T.renderOpts.collectedRevalidate,e=void 0===T.renderOpts.collectedExpire||T.renderOpts.collectedExpire>=s.INFINITE_CACHE?void 0:T.renderOpts.collectedExpire;return{value:{kind:u.CachedRouteKind.APP_ROUTE,status:d.status,body:Buffer.from(await a.arrayBuffer()),headers:b},cacheControl:{revalidate:c,expire:e}}}}catch(b){throw(null==f?void 0:f.isStale)&&await I.onRequestError(a,b,{routerKind:"App Router",routePath:d,routeType:"route",revalidateReason:(0,o.c)({isStaticGeneration:M,isOnDemandRevalidate:B})},!1,A),b}},k=await I.handleResponse({req:a,nextConfig:w,cacheKey:K,routeKind:f.RouteKind.APP_ROUTE,isFallback:!1,prerenderManifest:z,isRoutePPREnabled:!1,isOnDemandRevalidate:B,revalidateOnlyGenerated:C,responseGenerator:j,waitUntil:c.waitUntil,isMinimalMode:R});if(!H)return null;if((null==k||null==(h=k.value)?void 0:h.kind)!==u.CachedRouteKind.APP_ROUTE)throw Object.defineProperty(Error(`Invariant: app-route received invalid cache entry ${null==k||null==(i=k.value)?void 0:i.kind}`),"__NEXT_ERROR_CODE",{value:"E701",enumerable:!1,configurable:!0});R||b.setHeader("x-nextjs-cache",B?"REVALIDATED":k.isMiss?"MISS":k.isStale?"STALE":"HIT"),y&&b.setHeader("Cache-Control","private, no-cache, no-store, max-age=0, must-revalidate");let l=(0,q.fromNodeOutgoingHttpHeaders)(k.value.headers);return R&&H||l.delete(s.NEXT_CACHE_TAGS_HEADER),!k.cacheControl||b.getHeader("Cache-Control")||l.get("Cache-Control")||l.set("Cache-Control",(0,r.getCacheControlHeader)(k.cacheControl)),await (0,p.I)(U,V,new Response(k.value.body,{headers:l,status:k.value.status||200})),null};Q&&P?await h(P):(e=O.getActiveScopeSpan(),await O.withPropagatedContext(a.headers,()=>O.trace(n.BaseServerSpan.handleRequest,{spanName:`${N} ${d}`,kind:i.SpanKind.SERVER,attributes:{"http.method":N,"http.target":a.url}},h),void 0,!Q))}catch(b){if(b instanceof t.NoFallbackError||await I.onRequestError(a,b,{routerKind:"App Router",routePath:G,routeType:"route",revalidateReason:(0,o.c)({isStaticGeneration:M,isOnDemandRevalidate:B})},!1,A),H)throw b;return await (0,p.I)(U,V,new Response(null,{status:500})),null}}},21820:a=>{"use strict";a.exports=require("os")},29021:a=>{"use strict";a.exports=require("fs")},29294:a=>{"use strict";a.exports=require("next/dist/server/app-render/work-async-storage.external.js")},33873:a=>{"use strict";a.exports=require("path")},44870:a=>{"use strict";a.exports=require("next/dist/compiled/next-server/app-route.runtime.prod.js")},63033:a=>{"use strict";a.exports=require("next/dist/server/app-render/work-unit-async-storage.external.js")},65833:(a,b,c)=>{"use strict";c.d(b,{AQ:()=>f,C3:()=>d,JD:()=>e});let d="annodex",e="@seqyuan/annodex",f="annodex update"},78335:()=>{},86439:a=>{"use strict";a.exports=require("next/dist/shared/lib/no-fallback-error.external")},96487:()=>{}};var b=require("../../../webpack-runtime.js");b.C(a);var c=b.X(0,[4741,1813],()=>b(b.s=14158));module.exports=c})();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="en" class="__variable_66b8ca"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/7deddc85b7ffd1dc-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/ec14413c594b3356-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/6b00dcf032cca328.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/fddca953485158e4.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-0b1e0af2488fca8f.js"/><script src="/_next/static/chunks/4bd1b696-e356ca5ba0218e27.js" async=""></script><script src="/_next/static/chunks/3794-123fdf632563f469.js" async=""></script><script src="/_next/static/chunks/main-app-45a0f19af99d61b6.js" async=""></script><script src="/_next/static/chunks/8500-f62a38ff68ab7f42.js" async=""></script><script src="/_next/static/chunks/4550-eff0bf233a5b0aec.js" async=""></script><script src="/_next/static/chunks/app/layout-2e8a047b671c8731.js" async=""></script><script src="/_next/static/chunks/app/docs/changelog/page-7f8ff3ce79d21000.js" async=""></script><meta name="next-size-adjust" content=""/><title>Changelog</title><meta name="description" content="Release history and changes"/><link rel="shortcut icon" href="/favicon.svg" type="image/svg+xml"/><link rel="icon" href="/favicon.svg" type="image/svg+xml"/><script>(function(){try{var t=localStorage.getItem("annodex-theme");if(t==="dark")document.documentElement.classList.add("dark")}catch(e){}})();</script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body style="min-height:100dvh;display:flex;flex-direction:column"><div hidden=""><!--$--><!--/$--></div><script>((a,b,c,d,e,f,g,h)=>{let i=document.documentElement,j=["light","dark"];function k(b){var c;(Array.isArray(a)?a:[a]).forEach(a=>{let c="class"===a,d=c&&f?e.map(a=>f[a]||a):e;c?(i.classList.remove(...d),i.classList.add(f&&f[b]?f[b]:b)):i.setAttribute(a,b)}),c=b,h&&j.includes(c)&&(i.style.colorScheme=c)}if(d)k(d);else try{let a=localStorage.getItem(b)||c,d=g&&"system"===a?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":a;k(d)}catch(a){}})("class","theme","system",null,["light","dark"],null,true,true)</script><!--$--><div class="bg-fd-secondary/50 p-3 empty:hidden"></div><!--/$--><div style="max-width:800px;margin:0 auto;padding:40px 24px 80px"><a style="display:inline-flex;align-items:center;gap:6px;color:var(--color-accent, #3b82f6);text-decoration:none;font-size:14px;margin-bottom:24px" href="/workspace">←<!-- --> Back to <!-- -->annodex</a><div class="changelog-content"><p class="cl-p"><h2 class="cl-h2">0.1.97</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename process cleanup</strong> — session rename now first uses the live session connection and only falls back to a managed codex server when needed, avoiding unnecessary codex app-server/router process churn. Codex app-server shutdown now includes a SIGKILL fallback for detached Linux processes, reducing orphaned background processes after idle cleanup or dev reloads.</li><br/></ul><br/><h2 class="cl-h2">0.1.96</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename not working</strong> — three root causes fixed: (1) frontend <code class="cl-code">commitRename</code> didn't check HTTP response status, silently proceeding after server errors; (2) session name had no local persistence, so it was lost when <code class="cl-code">thread/list</code> didn't return the <code class="cl-code">name</code> field or when falling back to local cache; (3) top bar and sidebar rename were completely independent — renaming from the sidebar never updated the top bar's <code class="cl-code">selectedSession</code>. Fixes: <code class="cl-code">commitRename</code> now checks <code class="cl-code">res.ok</code> and shows error toasts; PATCH endpoint persists name to <code class="cl-code">session-runtime.json</code> via <code class="cl-code">upsertSessionRuntime</code>; <code class="cl-code">sessionInfoFromThreadSummary</code> and <code class="cl-code">summarizeCodexSessionFile</code> recover name from runtime store; new <code class="cl-code">onSessionRenamed</code> callback syncs sidebar rename to AppShell's top bar.</li><br/></ul><br/><h2 class="cl-h2">0.1.95</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stop button triggers HTTP 500 during streaming</strong> — clicking Stop while the AI was responding could cause a 500 error due to a race condition between SSE cleanup and the abort POST handler. The abort case in <code class="cl-code">CodexSessionWrapper.send()</code> and the <code class="cl-code">POST /api/agent/[id]</code> route now both wrap their logic in try/catch, ensuring any exception is safely caught and a clean <code class="cl-code">{ running: false }</code> response is always returned.</li><br/><li><strong>"Stream idle timeout" after AI finishes</strong> — when the SSE connection closed after turn completion and the client auto-reconnected, the new SSE stream would receive no events (turn already done), causing the idle watchdog to fire after 3 minutes. The SSE <code class="cl-code">events/route.ts</code> now checks <code class="cl-code">session.isBusy()</code> after subscribing; if the session has no active turn, it immediately sends <code class="cl-code">agent_end</code> so the watchdog never starts.</li><br/></ul><br/><h2 class="cl-h2">0.1.93</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stuck chat after agent completion</strong> — when the SSE <code class="cl-code">agent_end</code> event was missed (due to network disconnect or timing), the UI would stay stuck showing "Stop" button and appear to be streaming, even though the agent had actually finished. Root cause: the <code class="cl-code">reconcileSession</code> polling loop fetched the session state every 10s but never updated <code class="cl-code">agentRunning</code> based on the server response. Now <code class="cl-code">reconcileSession</code> checks <code class="cl-code">agentState.running</code> after each reconcile and self-heals the UI if the agent has actually stopped, preventing the stuck state without requiring a page refresh.</li><br/><li><strong>Reduce left sidebar polling interval</strong> — changed from 10 seconds to 1.5 minutes (90s) to reduce unnecessary network traffic.</li><br/></ul><br/><h2 class="cl-h2">0.1.92</h2></p><p class="cl-p"><h3 class="cl-h3">Changes</h3><br/><ul class="cl-ul"><li><strong>Rename right-panel tab "Tools" → "Status"</strong> — the right-panel tab previously labeled "Tools" primarily shows agent runtime status (phase, uptime, active tools, model info) and working memory, not tool presets. The rename aligns the tab label with its actual content. A new pulse/activity SVG icon is used for the Status tab.</li><br/></ul><br/><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Defensive error handling in runtime status</strong> — <code class="cl-code">getRuntimeStatus()</code> now wraps each session's <code class="cl-code">isAlive()</code> and <code class="cl-code">getRuntimeStatus()</code> calls in try/catch blocks. Previously, a partially destroyed session wrapper could cause the entire status query to throw, resulting in an empty Tools panel.</li><br/><li><strong>Runtime API route hardening</strong> — <code class="cl-code">GET /api/agent/runtime</code> now catches errors from <code class="cl-code">getRuntimeStatus()</code> and <code class="cl-code">getMemoryStatus()</code> independently, falling back to an empty status instead of returning a 500 error. This prevents transient state issues from breaking the frontend Status panel.</li><br/></ul><br/><h2 class="cl-h2">0.1.91</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Sidebar refresh delay</strong> — new chat sessions now appear in the sidebar within seconds. Two changes: (1) <code class="cl-code">AppShell.handleSessionCreated</code> dispatches a <code class="cl-code">session-created</code> DOM event, and (2) <code class="cl-code">SessionSidebar</code> listens for that event and polls every 10s as a fallback (pattern adopted from CodePilot). Previously the sidebar relied solely on <code class="cl-code">refreshKey</code> prop propagation, which could lag behind the Codex app-server thread index.</li><br/><li><strong>Scroll-to-bottom on session open (v2)</strong> — the settle loop now uses a <code class="cl-code">lastSettledSessionIdRef</code> to reliably detect session switches, preventing the settle from being skipped when messages arrive in batches across renders. Also aborts the animation if the session changes mid-settle.</li><br/></ul><br/><h2 class="cl-h2">0.1.90</h2><br/></p></div><style>
|
|
1
|
+
<!DOCTYPE html><html lang="en" class="__variable_66b8ca"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/7deddc85b7ffd1dc-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="preload" href="/_next/static/media/ec14413c594b3356-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/6b00dcf032cca328.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/fddca953485158e4.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-0b1e0af2488fca8f.js"/><script src="/_next/static/chunks/4bd1b696-e356ca5ba0218e27.js" async=""></script><script src="/_next/static/chunks/3794-123fdf632563f469.js" async=""></script><script src="/_next/static/chunks/main-app-45a0f19af99d61b6.js" async=""></script><script src="/_next/static/chunks/8500-f62a38ff68ab7f42.js" async=""></script><script src="/_next/static/chunks/4550-eff0bf233a5b0aec.js" async=""></script><script src="/_next/static/chunks/app/layout-2e8a047b671c8731.js" async=""></script><script src="/_next/static/chunks/app/docs/changelog/page-7f8ff3ce79d21000.js" async=""></script><meta name="next-size-adjust" content=""/><title>Changelog</title><meta name="description" content="Release history and changes"/><link rel="shortcut icon" href="/favicon.svg" type="image/svg+xml"/><link rel="icon" href="/favicon.svg" type="image/svg+xml"/><script>(function(){try{var t=localStorage.getItem("annodex-theme");if(t==="dark")document.documentElement.classList.add("dark")}catch(e){}})();</script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body style="min-height:100dvh;display:flex;flex-direction:column"><div hidden=""><!--$--><!--/$--></div><script>((a,b,c,d,e,f,g,h)=>{let i=document.documentElement,j=["light","dark"];function k(b){var c;(Array.isArray(a)?a:[a]).forEach(a=>{let c="class"===a,d=c&&f?e.map(a=>f[a]||a):e;c?(i.classList.remove(...d),i.classList.add(f&&f[b]?f[b]:b)):i.setAttribute(a,b)}),c=b,h&&j.includes(c)&&(i.style.colorScheme=c)}if(d)k(d);else try{let a=localStorage.getItem(b)||c,d=g&&"system"===a?window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light":a;k(d)}catch(a){}})("class","theme","system",null,["light","dark"],null,true,true)</script><!--$--><div class="bg-fd-secondary/50 p-3 empty:hidden"></div><!--/$--><div style="max-width:800px;margin:0 auto;padding:40px 24px 80px"><a style="display:inline-flex;align-items:center;gap:6px;color:var(--color-accent, #3b82f6);text-decoration:none;font-size:14px;margin-bottom:24px" href="/workspace">←<!-- --> Back to <!-- -->annodex</a><div class="changelog-content"><p class="cl-p"><h2 class="cl-h2">0.1.98</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename robustness</strong> — five improvements: (1) wasted wrapper cleaned up after connection errors so follow-up operations don't fail on a dead connection; (2) empty name now rejected with 400 instead of sent to codex; (3) <code class="cl-code">CodexSessionWrapper.send("rename")</code> now syncs to <code class="cl-code">session-runtime.json</code> so direct calls (not through HTTP PATCH) also persist; (4) AppShell and SessionSidebar now share a single <code class="cl-code">renameSession()</code> helper in <code class="cl-code">agent-client.ts</code> eliminating duplicated fetch/error-handling logic.</li><br/></ul><br/><h2 class="cl-h2">0.1.97</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename process cleanup</strong> — session rename now first uses the live session connection and only falls back to a managed codex server when needed, avoiding unnecessary codex app-server/router process churn. Codex app-server shutdown now includes a SIGKILL fallback for detached Linux processes, reducing orphaned background processes after idle cleanup or dev reloads.</li><br/></ul><br/><h2 class="cl-h2">0.1.96</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename not working</strong> — three root causes fixed: (1) frontend <code class="cl-code">commitRename</code> didn't check HTTP response status, silently proceeding after server errors; (2) session name had no local persistence, so it was lost when <code class="cl-code">thread/list</code> didn't return the <code class="cl-code">name</code> field or when falling back to local cache; (3) top bar and sidebar rename were completely independent — renaming from the sidebar never updated the top bar's <code class="cl-code">selectedSession</code>. Fixes: <code class="cl-code">commitRename</code> now checks <code class="cl-code">res.ok</code> and shows error toasts; PATCH endpoint persists name to <code class="cl-code">session-runtime.json</code> via <code class="cl-code">upsertSessionRuntime</code>; <code class="cl-code">sessionInfoFromThreadSummary</code> and <code class="cl-code">summarizeCodexSessionFile</code> recover name from runtime store; new <code class="cl-code">onSessionRenamed</code> callback syncs sidebar rename to AppShell's top bar.</li><br/></ul><br/><h2 class="cl-h2">0.1.95</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stop button triggers HTTP 500 during streaming</strong> — clicking Stop while the AI was responding could cause a 500 error due to a race condition between SSE cleanup and the abort POST handler. The abort case in <code class="cl-code">CodexSessionWrapper.send()</code> and the <code class="cl-code">POST /api/agent/[id]</code> route now both wrap their logic in try/catch, ensuring any exception is safely caught and a clean <code class="cl-code">{ running: false }</code> response is always returned.</li><br/><li><strong>"Stream idle timeout" after AI finishes</strong> — when the SSE connection closed after turn completion and the client auto-reconnected, the new SSE stream would receive no events (turn already done), causing the idle watchdog to fire after 3 minutes. The SSE <code class="cl-code">events/route.ts</code> now checks <code class="cl-code">session.isBusy()</code> after subscribing; if the session has no active turn, it immediately sends <code class="cl-code">agent_end</code> so the watchdog never starts.</li><br/></ul><br/><h2 class="cl-h2">0.1.93</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stuck chat after agent completion</strong> — when the SSE <code class="cl-code">agent_end</code> event was missed (due to network disconnect or timing), the UI would stay stuck showing "Stop" button and appear to be streaming, even though the agent had actually finished. Root cause: the <code class="cl-code">reconcileSession</code> polling loop fetched the session state every 10s but never updated <code class="cl-code">agentRunning</code> based on the server response. Now <code class="cl-code">reconcileSession</code> checks <code class="cl-code">agentState.running</code> after each reconcile and self-heals the UI if the agent has actually stopped, preventing the stuck state without requiring a page refresh.</li><br/><li><strong>Reduce left sidebar polling interval</strong> — changed from 10 seconds to 1.5 minutes (90s) to reduce unnecessary network traffic.</li><br/></ul><br/><h2 class="cl-h2">0.1.92</h2></p><p class="cl-p"><h3 class="cl-h3">Changes</h3><br/><ul class="cl-ul"><li><strong>Rename right-panel tab "Tools" → "Status"</strong> — the right-panel tab previously labeled "Tools" primarily shows agent runtime status (phase, uptime, active tools, model info) and working memory, not tool presets. The rename aligns the tab label with its actual content. A new pulse/activity SVG icon is used for the Status tab.</li><br/></ul><br/><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Defensive error handling in runtime status</strong> — <code class="cl-code">getRuntimeStatus()</code> now wraps each session's <code class="cl-code">isAlive()</code> and <code class="cl-code">getRuntimeStatus()</code> calls in try/catch blocks. Previously, a partially destroyed session wrapper could cause the entire status query to throw, resulting in an empty Tools panel.</li><br/><li><strong>Runtime API route hardening</strong> — <code class="cl-code">GET /api/agent/runtime</code> now catches errors from <code class="cl-code">getRuntimeStatus()</code> and <code class="cl-code">getMemoryStatus()</code> independently, falling back to an empty status instead of returning a 500 error. This prevents transient state issues from breaking the frontend Status panel.</li><br/></ul><br/><h2 class="cl-h2">0.1.91</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Sidebar refresh delay</strong> — new chat sessions now appear in the sidebar within seconds. Two changes: (1) <code class="cl-code">AppShell.handleSessionCreated</code> dispatches a <code class="cl-code">session-created</code> DOM event, and (2) <code class="cl-code">SessionSidebar</code> listens for that event and polls every 10s as a fallback (pattern adopted from CodePilot). Previously the sidebar relied solely on <code class="cl-code">refreshKey</code> prop propagation, which could lag behind the Codex app-server thread index.</li><br/><li><strong>Scroll-to-bottom on session open (v2)</strong> — the settle loop now uses a <code class="cl-code">lastSettledSessionIdRef</code> to reliably detect session switches, preventing the settle from being skipped when messages arrive in batches across renders. Also aborts the animation if the session changes mid-settle.</li><br/></ul><br/><h2 class="cl-h2">0.1.90</h2><br/></p></div><style>
|
|
2
2
|
.changelog-content { font-family: var(--font-noto-mono, monospace); line-height: 1.7; color: var(--color-fg, #e5e7eb); }
|
|
3
3
|
.cl-h1 { font-size: 28px; font-weight: 700; margin: 40px 0 16px; color: var(--color-fg, #f9fafb); border-bottom: 1px solid var(--color-border, #374151); padding-bottom: 8px; }
|
|
4
4
|
.cl-h2 { font-size: 22px; font-weight: 600; margin: 32px 0 12px; color: var(--color-accent, #60a5fa); }
|
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
.cl-ul { margin: 8px 0 16px 20px; padding: 0; }
|
|
8
8
|
.cl-ul li { margin: 4px 0; }
|
|
9
9
|
.cl-code { background: var(--color-bg-code, #1f2937); padding: 2px 6px; border-radius: 4px; font-size: 13px; }
|
|
10
|
-
</style></div><!--$--><!--/$--><div aria-live="polite" style="position:fixed;right:16px;bottom:16px;z-index:10050;display:flex;flex-direction:column;gap:8px;max-width:min(420px, calc(100vw - 32px));pointer-events:none"></div><script src="/_next/static/chunks/webpack-0b1e0af2488fca8f.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[11056,[\"8500\",\"static/chunks/8500-f62a38ff68ab7f42.js\",\"4550\",\"static/chunks/4550-eff0bf233a5b0aec.js\",\"7177\",\"static/chunks/app/layout-2e8a047b671c8731.js\"],\"RootProvider\"]\n3:I[58132,[\"8500\",\"static/chunks/8500-f62a38ff68ab7f42.js\",\"4550\",\"static/chunks/4550-eff0bf233a5b0aec.js\",\"7177\",\"static/chunks/app/layout-2e8a047b671c8731.js\"],\"AppProviders\"]\n4:I[57121,[],\"\"]\n5:I[74581,[],\"\"]\n6:I[98500,[\"8500\",\"static/chunks/8500-f62a38ff68ab7f42.js\",\"9089\",\"static/chunks/app/docs/changelog/page-7f8ff3ce79d21000.js\"],\"\"]\nc:I[27123,[],\"default\",1]\n:HL[\"/_next/static/media/7deddc85b7ffd1dc-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/ec14413c594b3356-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/css/6b00dcf032cca328.css\",\"style\"]\n:HL[\"/_next/static/css/fddca953485158e4.css\",\"style\"]\n7:T187f,"])</script><script>self.__next_f.push([1,"\u003cp class=\"cl-p\"\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.97\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eSession rename process cleanup\u003c/strong\u003e — session rename now first uses the live session connection and only falls back to a managed codex server when needed, avoiding unnecessary codex app-server/router process churn. Codex app-server shutdown now includes a SIGKILL fallback for detached Linux processes, reducing orphaned background processes after idle cleanup or dev reloads.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.96\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eSession rename not working\u003c/strong\u003e — three root causes fixed: (1) frontend \u003ccode class=\"cl-code\"\u003ecommitRename\u003c/code\u003e didn't check HTTP response status, silently proceeding after server errors; (2) session name had no local persistence, so it was lost when \u003ccode class=\"cl-code\"\u003ethread/list\u003c/code\u003e didn't return the \u003ccode class=\"cl-code\"\u003ename\u003c/code\u003e field or when falling back to local cache; (3) top bar and sidebar rename were completely independent — renaming from the sidebar never updated the top bar's \u003ccode class=\"cl-code\"\u003eselectedSession\u003c/code\u003e. Fixes: \u003ccode class=\"cl-code\"\u003ecommitRename\u003c/code\u003e now checks \u003ccode class=\"cl-code\"\u003eres.ok\u003c/code\u003e and shows error toasts; PATCH endpoint persists name to \u003ccode class=\"cl-code\"\u003esession-runtime.json\u003c/code\u003e via \u003ccode class=\"cl-code\"\u003eupsertSessionRuntime\u003c/code\u003e; \u003ccode class=\"cl-code\"\u003esessionInfoFromThreadSummary\u003c/code\u003e and \u003ccode class=\"cl-code\"\u003esummarizeCodexSessionFile\u003c/code\u003e recover name from runtime store; new \u003ccode class=\"cl-code\"\u003eonSessionRenamed\u003c/code\u003e callback syncs sidebar rename to AppShell's top bar.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.95\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eStop button triggers HTTP 500 during streaming\u003c/strong\u003e — clicking Stop while the AI was responding could cause a 500 error due to a race condition between SSE cleanup and the abort POST handler. The abort case in \u003ccode class=\"cl-code\"\u003eCodexSessionWrapper.send()\u003c/code\u003e and the \u003ccode class=\"cl-code\"\u003ePOST /api/agent/[id]\u003c/code\u003e route now both wrap their logic in try/catch, ensuring any exception is safely caught and a clean \u003ccode class=\"cl-code\"\u003e{ running: false }\u003c/code\u003e response is always returned.\u003c/li\u003e\u003cbr/\u003e\u003cli\u003e\u003cstrong\u003e\"Stream idle timeout\" after AI finishes\u003c/strong\u003e — when the SSE connection closed after turn completion and the client auto-reconnected, the new SSE stream would receive no events (turn already done), causing the idle watchdog to fire after 3 minutes. The SSE \u003ccode class=\"cl-code\"\u003eevents/route.ts\u003c/code\u003e now checks \u003ccode class=\"cl-code\"\u003esession.isBusy()\u003c/code\u003e after subscribing; if the session has no active turn, it immediately sends \u003ccode class=\"cl-code\"\u003eagent_end\u003c/code\u003e so the watchdog never starts.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.93\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eStuck chat after agent completion\u003c/strong\u003e — when the SSE \u003ccode class=\"cl-code\"\u003eagent_end\u003c/code\u003e event was missed (due to network disconnect or timing), the UI would stay stuck showing \"Stop\" button and appear to be streaming, even though the agent had actually finished. Root cause: the \u003ccode class=\"cl-code\"\u003ereconcileSession\u003c/code\u003e polling loop fetched the session state every 10s but never updated \u003ccode class=\"cl-code\"\u003eagentRunning\u003c/code\u003e based on the server response. Now \u003ccode class=\"cl-code\"\u003ereconcileSession\u003c/code\u003e checks \u003ccode class=\"cl-code\"\u003eagentState.running\u003c/code\u003e after each reconcile and self-heals the UI if the agent has actually stopped, preventing the stuck state without requiring a page refresh.\u003c/li\u003e\u003cbr/\u003e\u003cli\u003e\u003cstrong\u003eReduce left sidebar polling interval\u003c/strong\u003e — changed from 10 seconds to 1.5 minutes (90s) to reduce unnecessary network traffic.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.92\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eChanges\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eRename right-panel tab \"Tools\" → \"Status\"\u003c/strong\u003e — the right-panel tab previously labeled \"Tools\" primarily shows agent runtime status (phase, uptime, active tools, model info) and working memory, not tool presets. The rename aligns the tab label with its actual content. A new pulse/activity SVG icon is used for the Status tab.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eDefensive error handling in runtime status\u003c/strong\u003e — \u003ccode class=\"cl-code\"\u003egetRuntimeStatus()\u003c/code\u003e now wraps each session's \u003ccode class=\"cl-code\"\u003eisAlive()\u003c/code\u003e and \u003ccode class=\"cl-code\"\u003egetRuntimeStatus()\u003c/code\u003e calls in try/catch blocks. Previously, a partially destroyed session wrapper could cause the entire status query to throw, resulting in an empty Tools panel.\u003c/li\u003e\u003cbr/\u003e\u003cli\u003e\u003cstrong\u003eRuntime API route hardening\u003c/strong\u003e — \u003ccode class=\"cl-code\"\u003eGET /api/agent/runtime\u003c/code\u003e now catches errors from \u003ccode class=\"cl-code\"\u003egetRuntimeStatus()\u003c/code\u003e and \u003ccode class=\"cl-code\"\u003egetMemoryStatus()\u003c/code\u003e independently, falling back to an empty status instead of returning a 500 error. This prevents transient state issues from breaking the frontend Status panel.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.91\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eSidebar refresh delay\u003c/strong\u003e — new chat sessions now appear in the sidebar within seconds. Two changes: (1) \u003ccode class=\"cl-code\"\u003eAppShell.handleSessionCreated\u003c/code\u003e dispatches a \u003ccode class=\"cl-code\"\u003esession-created\u003c/code\u003e DOM event, and (2) \u003ccode class=\"cl-code\"\u003eSessionSidebar\u003c/code\u003e listens for that event and polls every 10s as a fallback (pattern adopted from CodePilot). Previously the sidebar relied solely on \u003ccode class=\"cl-code\"\u003erefreshKey\u003c/code\u003e prop propagation, which could lag behind the Codex app-server thread index.\u003c/li\u003e\u003cbr/\u003e\u003cli\u003e\u003cstrong\u003eScroll-to-bottom on session open (v2)\u003c/strong\u003e — the settle loop now uses a \u003ccode class=\"cl-code\"\u003elastSettledSessionIdRef\u003c/code\u003e to reliably detect session switches, preventing the settle from being skipped when messages arrive in batches across renders. Also aborts the animation if the session changes mid-settle.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.90\u003c/h2\u003e\u003cbr/\u003e\u003c/p\u003e"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"docs\",\"changelog\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"docs\",{\"children\":[\"changelog\",{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/6b00dcf032cca328.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/fddca953485158e4.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"__variable_66b8ca\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"(function(){try{var t=localStorage.getItem(\\\"annodex-theme\\\");if(t===\\\"dark\\\")document.documentElement.classList.add(\\\"dark\\\")}catch(e){}})();\"}}]}],[\"$\",\"body\",null,{\"style\":{\"minHeight\":\"100dvh\",\"display\":\"flex\",\"flexDirection\":\"column\"},\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]}]]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"div\",null,{\"style\":{\"maxWidth\":800,\"margin\":\"0 auto\",\"padding\":\"40px 24px 80px\"},\"children\":[[\"$\",\"$L6\",null,{\"href\":\"/workspace\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"gap\":6,\"color\":\"var(--color-accent, #3b82f6)\",\"textDecoration\":\"none\",\"fontSize\":14,\"marginBottom\":24},\"children\":[\"←\",\" Back to \",\"annodex\"]}],[\"$\",\"div\",null,{\"className\":\"changelog-content\",\"dangerouslySetInnerHTML\":{\"__html\":\"$7\"}}],\"$L8\"]}],null,\"$L9\"]}],{},null,false,null]},null,false,\"$@a\"]},null,false,\"$@a\"]},null,false,null],\"$Lb\",false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"SVHmVqHgsyh7rLM_BP4l1\"}\n"])</script><script>self.__next_f.push([1,"d:I[90484,[],\"OutletBoundary\"]\ne:\"$Sreact.suspense\"\n11:I[90484,[],\"ViewportBoundary\"]\n13:I[90484,[],\"MetadataBoundary\"]\n8:[\"$\",\"style\",null,{\"children\":\"\\n .changelog-content { font-family: var(--font-noto-mono, monospace); line-height: 1.7; color: var(--color-fg, #e5e7eb); }\\n .cl-h1 { font-size: 28px; font-weight: 700; margin: 40px 0 16px; color: var(--color-fg, #f9fafb); border-bottom: 1px solid var(--color-border, #374151); padding-bottom: 8px; }\\n .cl-h2 { font-size: 22px; font-weight: 600; margin: 32px 0 12px; color: var(--color-accent, #60a5fa); }\\n .cl-h3 { font-size: 16px; font-weight: 600; margin: 20px 0 8px; color: var(--color-fg-secondary, #9ca3af); }\\n .cl-p { margin: 0 0 12px; }\\n .cl-ul { margin: 8px 0 16px 20px; padding: 0; }\\n .cl-ul li { margin: 4px 0; }\\n .cl-code { background: var(--color-bg-code, #1f2937); padding: 2px 6px; border-radius: 4px; font-size: 13px; }\\n \"}]\n9:[\"$\",\"$Ld\",null,{\"children\":[\"$\",\"$e\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@f\"}]}]\n10:[]\na:\"$W10\"\nb:[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L11\",null,{\"children\":\"$L12\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L13\",null,{\"children\":[\"$\",\"$e\",null,{\"name\":\"Next.Metadata\",\"children\":\"$L14\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}]\n"])</script><script>self.__next_f.push([1,"12:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"15:I[86869,[],\"IconMark\"]\nf:null\n14:[[\"$\",\"title\",\"0\",{\"children\":\"Changelog\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Release history and changes\"}],[\"$\",\"link\",\"2\",{\"rel\":\"shortcut icon\",\"href\":\"/favicon.svg\",\"type\":\"image/svg+xml\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/favicon.svg\",\"type\":\"image/svg+xml\"}],[\"$\",\"$L15\",\"4\",{}]]\n"])</script></body></html>
|
|
10
|
+
</style></div><!--$--><!--/$--><div aria-live="polite" style="position:fixed;right:16px;bottom:16px;z-index:10050;display:flex;flex-direction:column;gap:8px;max-width:min(420px, calc(100vw - 32px));pointer-events:none"></div><script src="/_next/static/chunks/webpack-0b1e0af2488fca8f.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[11056,[\"8500\",\"static/chunks/8500-f62a38ff68ab7f42.js\",\"4550\",\"static/chunks/4550-eff0bf233a5b0aec.js\",\"7177\",\"static/chunks/app/layout-2e8a047b671c8731.js\"],\"RootProvider\"]\n3:I[58132,[\"8500\",\"static/chunks/8500-f62a38ff68ab7f42.js\",\"4550\",\"static/chunks/4550-eff0bf233a5b0aec.js\",\"7177\",\"static/chunks/app/layout-2e8a047b671c8731.js\"],\"AppProviders\"]\n4:I[57121,[],\"\"]\n5:I[74581,[],\"\"]\n6:I[98500,[\"8500\",\"static/chunks/8500-f62a38ff68ab7f42.js\",\"9089\",\"static/chunks/app/docs/changelog/page-7f8ff3ce79d21000.js\"],\"\"]\nc:I[27123,[],\"default\",1]\n:HL[\"/_next/static/media/7deddc85b7ffd1dc-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/media/ec14413c594b3356-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n:HL[\"/_next/static/css/6b00dcf032cca328.css\",\"style\"]\n:HL[\"/_next/static/css/fddca953485158e4.css\",\"style\"]\n7:T1b6e,"])</script><script>self.__next_f.push([1,"\u003cp class=\"cl-p\"\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.98\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eSession rename robustness\u003c/strong\u003e — five improvements: (1) wasted wrapper cleaned up after connection errors so follow-up operations don't fail on a dead connection; (2) empty name now rejected with 400 instead of sent to codex; (3) \u003ccode class=\"cl-code\"\u003eCodexSessionWrapper.send(\"rename\")\u003c/code\u003e now syncs to \u003ccode class=\"cl-code\"\u003esession-runtime.json\u003c/code\u003e so direct calls (not through HTTP PATCH) also persist; (4) AppShell and SessionSidebar now share a single \u003ccode class=\"cl-code\"\u003erenameSession()\u003c/code\u003e helper in \u003ccode class=\"cl-code\"\u003eagent-client.ts\u003c/code\u003e eliminating duplicated fetch/error-handling logic.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.97\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eSession rename process cleanup\u003c/strong\u003e — session rename now first uses the live session connection and only falls back to a managed codex server when needed, avoiding unnecessary codex app-server/router process churn. Codex app-server shutdown now includes a SIGKILL fallback for detached Linux processes, reducing orphaned background processes after idle cleanup or dev reloads.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.96\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eSession rename not working\u003c/strong\u003e — three root causes fixed: (1) frontend \u003ccode class=\"cl-code\"\u003ecommitRename\u003c/code\u003e didn't check HTTP response status, silently proceeding after server errors; (2) session name had no local persistence, so it was lost when \u003ccode class=\"cl-code\"\u003ethread/list\u003c/code\u003e didn't return the \u003ccode class=\"cl-code\"\u003ename\u003c/code\u003e field or when falling back to local cache; (3) top bar and sidebar rename were completely independent — renaming from the sidebar never updated the top bar's \u003ccode class=\"cl-code\"\u003eselectedSession\u003c/code\u003e. Fixes: \u003ccode class=\"cl-code\"\u003ecommitRename\u003c/code\u003e now checks \u003ccode class=\"cl-code\"\u003eres.ok\u003c/code\u003e and shows error toasts; PATCH endpoint persists name to \u003ccode class=\"cl-code\"\u003esession-runtime.json\u003c/code\u003e via \u003ccode class=\"cl-code\"\u003eupsertSessionRuntime\u003c/code\u003e; \u003ccode class=\"cl-code\"\u003esessionInfoFromThreadSummary\u003c/code\u003e and \u003ccode class=\"cl-code\"\u003esummarizeCodexSessionFile\u003c/code\u003e recover name from runtime store; new \u003ccode class=\"cl-code\"\u003eonSessionRenamed\u003c/code\u003e callback syncs sidebar rename to AppShell's top bar.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.95\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eStop button triggers HTTP 500 during streaming\u003c/strong\u003e — clicking Stop while the AI was responding could cause a 500 error due to a race condition between SSE cleanup and the abort POST handler. The abort case in \u003ccode class=\"cl-code\"\u003eCodexSessionWrapper.send()\u003c/code\u003e and the \u003ccode class=\"cl-code\"\u003ePOST /api/agent/[id]\u003c/code\u003e route now both wrap their logic in try/catch, ensuring any exception is safely caught and a clean \u003ccode class=\"cl-code\"\u003e{ running: false }\u003c/code\u003e response is always returned.\u003c/li\u003e\u003cbr/\u003e\u003cli\u003e\u003cstrong\u003e\"Stream idle timeout\" after AI finishes\u003c/strong\u003e — when the SSE connection closed after turn completion and the client auto-reconnected, the new SSE stream would receive no events (turn already done), causing the idle watchdog to fire after 3 minutes. The SSE \u003ccode class=\"cl-code\"\u003eevents/route.ts\u003c/code\u003e now checks \u003ccode class=\"cl-code\"\u003esession.isBusy()\u003c/code\u003e after subscribing; if the session has no active turn, it immediately sends \u003ccode class=\"cl-code\"\u003eagent_end\u003c/code\u003e so the watchdog never starts.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.93\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eStuck chat after agent completion\u003c/strong\u003e — when the SSE \u003ccode class=\"cl-code\"\u003eagent_end\u003c/code\u003e event was missed (due to network disconnect or timing), the UI would stay stuck showing \"Stop\" button and appear to be streaming, even though the agent had actually finished. Root cause: the \u003ccode class=\"cl-code\"\u003ereconcileSession\u003c/code\u003e polling loop fetched the session state every 10s but never updated \u003ccode class=\"cl-code\"\u003eagentRunning\u003c/code\u003e based on the server response. Now \u003ccode class=\"cl-code\"\u003ereconcileSession\u003c/code\u003e checks \u003ccode class=\"cl-code\"\u003eagentState.running\u003c/code\u003e after each reconcile and self-heals the UI if the agent has actually stopped, preventing the stuck state without requiring a page refresh.\u003c/li\u003e\u003cbr/\u003e\u003cli\u003e\u003cstrong\u003eReduce left sidebar polling interval\u003c/strong\u003e — changed from 10 seconds to 1.5 minutes (90s) to reduce unnecessary network traffic.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.92\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eChanges\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eRename right-panel tab \"Tools\" → \"Status\"\u003c/strong\u003e — the right-panel tab previously labeled \"Tools\" primarily shows agent runtime status (phase, uptime, active tools, model info) and working memory, not tool presets. The rename aligns the tab label with its actual content. A new pulse/activity SVG icon is used for the Status tab.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eDefensive error handling in runtime status\u003c/strong\u003e — \u003ccode class=\"cl-code\"\u003egetRuntimeStatus()\u003c/code\u003e now wraps each session's \u003ccode class=\"cl-code\"\u003eisAlive()\u003c/code\u003e and \u003ccode class=\"cl-code\"\u003egetRuntimeStatus()\u003c/code\u003e calls in try/catch blocks. Previously, a partially destroyed session wrapper could cause the entire status query to throw, resulting in an empty Tools panel.\u003c/li\u003e\u003cbr/\u003e\u003cli\u003e\u003cstrong\u003eRuntime API route hardening\u003c/strong\u003e — \u003ccode class=\"cl-code\"\u003eGET /api/agent/runtime\u003c/code\u003e now catches errors from \u003ccode class=\"cl-code\"\u003egetRuntimeStatus()\u003c/code\u003e and \u003ccode class=\"cl-code\"\u003egetMemoryStatus()\u003c/code\u003e independently, falling back to an empty status instead of returning a 500 error. This prevents transient state issues from breaking the frontend Status panel.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.91\u003c/h2\u003e\u003c/p\u003e\u003cp class=\"cl-p\"\u003e\u003ch3 class=\"cl-h3\"\u003eFixes\u003c/h3\u003e\u003cbr/\u003e\u003cul class=\"cl-ul\"\u003e\u003cli\u003e\u003cstrong\u003eSidebar refresh delay\u003c/strong\u003e — new chat sessions now appear in the sidebar within seconds. Two changes: (1) \u003ccode class=\"cl-code\"\u003eAppShell.handleSessionCreated\u003c/code\u003e dispatches a \u003ccode class=\"cl-code\"\u003esession-created\u003c/code\u003e DOM event, and (2) \u003ccode class=\"cl-code\"\u003eSessionSidebar\u003c/code\u003e listens for that event and polls every 10s as a fallback (pattern adopted from CodePilot). Previously the sidebar relied solely on \u003ccode class=\"cl-code\"\u003erefreshKey\u003c/code\u003e prop propagation, which could lag behind the Codex app-server thread index.\u003c/li\u003e\u003cbr/\u003e\u003cli\u003e\u003cstrong\u003eScroll-to-bottom on session open (v2)\u003c/strong\u003e — the settle loop now uses a \u003ccode class=\"cl-code\"\u003elastSettledSessionIdRef\u003c/code\u003e to reliably detect session switches, preventing the settle from being skipped when messages arrive in batches across renders. Also aborts the animation if the session changes mid-settle.\u003c/li\u003e\u003cbr/\u003e\u003c/ul\u003e\u003cbr/\u003e\u003ch2 class=\"cl-h2\"\u003e0.1.90\u003c/h2\u003e\u003cbr/\u003e\u003c/p\u003e"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"docs\",\"changelog\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"docs\",{\"children\":[\"changelog\",{\"children\":[\"__PAGE__\",{}]}]}]},\"$undefined\",\"$undefined\",16],[[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/6b00dcf032cca328.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/fddca953485158e4.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"className\":\"__variable_66b8ca\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"(function(){try{var t=localStorage.getItem(\\\"annodex-theme\\\");if(t===\\\"dark\\\")document.documentElement.classList.add(\\\"dark\\\")}catch(e){}})();\"}}]}],[\"$\",\"body\",null,{\"style\":{\"minHeight\":\"100dvh\",\"display\":\"flex\",\"flexDirection\":\"column\"},\"children\":[\"$\",\"$L2\",null,{\"children\":[\"$\",\"$L3\",null,{\"children\":[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],[]],\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]}]}]]}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L4\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L5\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"div\",null,{\"style\":{\"maxWidth\":800,\"margin\":\"0 auto\",\"padding\":\"40px 24px 80px\"},\"children\":[[\"$\",\"$L6\",null,{\"href\":\"/workspace\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"gap\":6,\"color\":\"var(--color-accent, #3b82f6)\",\"textDecoration\":\"none\",\"fontSize\":14,\"marginBottom\":24},\"children\":[\"←\",\" Back to \",\"annodex\"]}],[\"$\",\"div\",null,{\"className\":\"changelog-content\",\"dangerouslySetInnerHTML\":{\"__html\":\"$7\"}}],\"$L8\"]}],null,\"$L9\"]}],{},null,false,null]},null,false,\"$@a\"]},null,false,\"$@a\"]},null,false,null],\"$Lb\",false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"AGWDEHkSDNIvOTAQZ2_6O\"}\n"])</script><script>self.__next_f.push([1,"d:I[90484,[],\"OutletBoundary\"]\ne:\"$Sreact.suspense\"\n11:I[90484,[],\"ViewportBoundary\"]\n13:I[90484,[],\"MetadataBoundary\"]\n8:[\"$\",\"style\",null,{\"children\":\"\\n .changelog-content { font-family: var(--font-noto-mono, monospace); line-height: 1.7; color: var(--color-fg, #e5e7eb); }\\n .cl-h1 { font-size: 28px; font-weight: 700; margin: 40px 0 16px; color: var(--color-fg, #f9fafb); border-bottom: 1px solid var(--color-border, #374151); padding-bottom: 8px; }\\n .cl-h2 { font-size: 22px; font-weight: 600; margin: 32px 0 12px; color: var(--color-accent, #60a5fa); }\\n .cl-h3 { font-size: 16px; font-weight: 600; margin: 20px 0 8px; color: var(--color-fg-secondary, #9ca3af); }\\n .cl-p { margin: 0 0 12px; }\\n .cl-ul { margin: 8px 0 16px 20px; padding: 0; }\\n .cl-ul li { margin: 4px 0; }\\n .cl-code { background: var(--color-bg-code, #1f2937); padding: 2px 6px; border-radius: 4px; font-size: 13px; }\\n \"}]\n9:[\"$\",\"$Ld\",null,{\"children\":[\"$\",\"$e\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@f\"}]}]\n10:[]\na:\"$W10\"\nb:[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L11\",null,{\"children\":\"$L12\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$L13\",null,{\"children\":[\"$\",\"$e\",null,{\"name\":\"Next.Metadata\",\"children\":\"$L14\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}]\n"])</script><script>self.__next_f.push([1,"12:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"15:I[86869,[],\"IconMark\"]\nf:null\n14:[[\"$\",\"title\",\"0\",{\"children\":\"Changelog\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Release history and changes\"}],[\"$\",\"link\",\"2\",{\"rel\":\"shortcut icon\",\"href\":\"/favicon.svg\",\"type\":\"image/svg+xml\"}],[\"$\",\"link\",\"3\",{\"rel\":\"icon\",\"href\":\"/favicon.svg\",\"type\":\"image/svg+xml\"}],[\"$\",\"$L15\",\"4\",{}]]\n"])</script></body></html>
|
|
@@ -9,7 +9,7 @@ c:I[27123,[],"default",1]
|
|
|
9
9
|
:HL["/_next/static/media/ec14413c594b3356-s.p.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
|
|
10
10
|
:HL["/_next/static/css/6b00dcf032cca328.css","style"]
|
|
11
11
|
:HL["/_next/static/css/fddca953485158e4.css","style"]
|
|
12
|
-
7:T187f,<p class="cl-p"><h2 class="cl-h2">0.1.97</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename process cleanup</strong> — session rename now first uses the live session connection and only falls back to a managed codex server when needed, avoiding unnecessary codex app-server/router process churn. Codex app-server shutdown now includes a SIGKILL fallback for detached Linux processes, reducing orphaned background processes after idle cleanup or dev reloads.</li><br/></ul><br/><h2 class="cl-h2">0.1.96</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename not working</strong> — three root causes fixed: (1) frontend <code class="cl-code">commitRename</code> didn't check HTTP response status, silently proceeding after server errors; (2) session name had no local persistence, so it was lost when <code class="cl-code">thread/list</code> didn't return the <code class="cl-code">name</code> field or when falling back to local cache; (3) top bar and sidebar rename were completely independent — renaming from the sidebar never updated the top bar's <code class="cl-code">selectedSession</code>. Fixes: <code class="cl-code">commitRename</code> now checks <code class="cl-code">res.ok</code> and shows error toasts; PATCH endpoint persists name to <code class="cl-code">session-runtime.json</code> via <code class="cl-code">upsertSessionRuntime</code>; <code class="cl-code">sessionInfoFromThreadSummary</code> and <code class="cl-code">summarizeCodexSessionFile</code> recover name from runtime store; new <code class="cl-code">onSessionRenamed</code> callback syncs sidebar rename to AppShell's top bar.</li><br/></ul><br/><h2 class="cl-h2">0.1.95</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stop button triggers HTTP 500 during streaming</strong> — clicking Stop while the AI was responding could cause a 500 error due to a race condition between SSE cleanup and the abort POST handler. The abort case in <code class="cl-code">CodexSessionWrapper.send()</code> and the <code class="cl-code">POST /api/agent/[id]</code> route now both wrap their logic in try/catch, ensuring any exception is safely caught and a clean <code class="cl-code">{ running: false }</code> response is always returned.</li><br/><li><strong>"Stream idle timeout" after AI finishes</strong> — when the SSE connection closed after turn completion and the client auto-reconnected, the new SSE stream would receive no events (turn already done), causing the idle watchdog to fire after 3 minutes. The SSE <code class="cl-code">events/route.ts</code> now checks <code class="cl-code">session.isBusy()</code> after subscribing; if the session has no active turn, it immediately sends <code class="cl-code">agent_end</code> so the watchdog never starts.</li><br/></ul><br/><h2 class="cl-h2">0.1.93</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stuck chat after agent completion</strong> — when the SSE <code class="cl-code">agent_end</code> event was missed (due to network disconnect or timing), the UI would stay stuck showing "Stop" button and appear to be streaming, even though the agent had actually finished. Root cause: the <code class="cl-code">reconcileSession</code> polling loop fetched the session state every 10s but never updated <code class="cl-code">agentRunning</code> based on the server response. Now <code class="cl-code">reconcileSession</code> checks <code class="cl-code">agentState.running</code> after each reconcile and self-heals the UI if the agent has actually stopped, preventing the stuck state without requiring a page refresh.</li><br/><li><strong>Reduce left sidebar polling interval</strong> — changed from 10 seconds to 1.5 minutes (90s) to reduce unnecessary network traffic.</li><br/></ul><br/><h2 class="cl-h2">0.1.92</h2></p><p class="cl-p"><h3 class="cl-h3">Changes</h3><br/><ul class="cl-ul"><li><strong>Rename right-panel tab "Tools" → "Status"</strong> — the right-panel tab previously labeled "Tools" primarily shows agent runtime status (phase, uptime, active tools, model info) and working memory, not tool presets. The rename aligns the tab label with its actual content. A new pulse/activity SVG icon is used for the Status tab.</li><br/></ul><br/><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Defensive error handling in runtime status</strong> — <code class="cl-code">getRuntimeStatus()</code> now wraps each session's <code class="cl-code">isAlive()</code> and <code class="cl-code">getRuntimeStatus()</code> calls in try/catch blocks. Previously, a partially destroyed session wrapper could cause the entire status query to throw, resulting in an empty Tools panel.</li><br/><li><strong>Runtime API route hardening</strong> — <code class="cl-code">GET /api/agent/runtime</code> now catches errors from <code class="cl-code">getRuntimeStatus()</code> and <code class="cl-code">getMemoryStatus()</code> independently, falling back to an empty status instead of returning a 500 error. This prevents transient state issues from breaking the frontend Status panel.</li><br/></ul><br/><h2 class="cl-h2">0.1.91</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Sidebar refresh delay</strong> — new chat sessions now appear in the sidebar within seconds. Two changes: (1) <code class="cl-code">AppShell.handleSessionCreated</code> dispatches a <code class="cl-code">session-created</code> DOM event, and (2) <code class="cl-code">SessionSidebar</code> listens for that event and polls every 10s as a fallback (pattern adopted from CodePilot). Previously the sidebar relied solely on <code class="cl-code">refreshKey</code> prop propagation, which could lag behind the Codex app-server thread index.</li><br/><li><strong>Scroll-to-bottom on session open (v2)</strong> — the settle loop now uses a <code class="cl-code">lastSettledSessionIdRef</code> to reliably detect session switches, preventing the settle from being skipped when messages arrive in batches across renders. Also aborts the animation if the session changes mid-settle.</li><br/></ul><br/><h2 class="cl-h2">0.1.90</h2><br/></p>0:{"P":null,"c":["","docs","changelog"],"q":"","i":false,"f":[[["",{"children":["docs",{"children":["changelog",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/6b00dcf032cca328.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/fddca953485158e4.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"__variable_66b8ca","suppressHydrationWarning":true,"children":[["$","head",null,{"children":["$","script",null,{"dangerouslySetInnerHTML":{"__html":"(function(){try{var t=localStorage.getItem(\"annodex-theme\");if(t===\"dark\")document.documentElement.classList.add(\"dark\")}catch(e){}})();"}}]}],["$","body",null,{"style":{"minHeight":"100dvh","display":"flex","flexDirection":"column"},"children":["$","$L2",null,{"children":["$","$L3",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","div",null,{"style":{"maxWidth":800,"margin":"0 auto","padding":"40px 24px 80px"},"children":[["$","$L6",null,{"href":"/workspace","style":{"display":"inline-flex","alignItems":"center","gap":6,"color":"var(--color-accent, #3b82f6)","textDecoration":"none","fontSize":14,"marginBottom":24},"children":["←"," Back to ","annodex"]}],["$","div",null,{"className":"changelog-content","dangerouslySetInnerHTML":{"__html":"$7"}}],"$L8"]}],null,"$L9"]}],{},null,false,null]},null,false,"$@a"]},null,false,"$@a"]},null,false,null],"$Lb",false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"SVHmVqHgsyh7rLM_BP4l1"}
|
|
12
|
+
7:T1b6e,<p class="cl-p"><h2 class="cl-h2">0.1.98</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename robustness</strong> — five improvements: (1) wasted wrapper cleaned up after connection errors so follow-up operations don't fail on a dead connection; (2) empty name now rejected with 400 instead of sent to codex; (3) <code class="cl-code">CodexSessionWrapper.send("rename")</code> now syncs to <code class="cl-code">session-runtime.json</code> so direct calls (not through HTTP PATCH) also persist; (4) AppShell and SessionSidebar now share a single <code class="cl-code">renameSession()</code> helper in <code class="cl-code">agent-client.ts</code> eliminating duplicated fetch/error-handling logic.</li><br/></ul><br/><h2 class="cl-h2">0.1.97</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename process cleanup</strong> — session rename now first uses the live session connection and only falls back to a managed codex server when needed, avoiding unnecessary codex app-server/router process churn. Codex app-server shutdown now includes a SIGKILL fallback for detached Linux processes, reducing orphaned background processes after idle cleanup or dev reloads.</li><br/></ul><br/><h2 class="cl-h2">0.1.96</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename not working</strong> — three root causes fixed: (1) frontend <code class="cl-code">commitRename</code> didn't check HTTP response status, silently proceeding after server errors; (2) session name had no local persistence, so it was lost when <code class="cl-code">thread/list</code> didn't return the <code class="cl-code">name</code> field or when falling back to local cache; (3) top bar and sidebar rename were completely independent — renaming from the sidebar never updated the top bar's <code class="cl-code">selectedSession</code>. Fixes: <code class="cl-code">commitRename</code> now checks <code class="cl-code">res.ok</code> and shows error toasts; PATCH endpoint persists name to <code class="cl-code">session-runtime.json</code> via <code class="cl-code">upsertSessionRuntime</code>; <code class="cl-code">sessionInfoFromThreadSummary</code> and <code class="cl-code">summarizeCodexSessionFile</code> recover name from runtime store; new <code class="cl-code">onSessionRenamed</code> callback syncs sidebar rename to AppShell's top bar.</li><br/></ul><br/><h2 class="cl-h2">0.1.95</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stop button triggers HTTP 500 during streaming</strong> — clicking Stop while the AI was responding could cause a 500 error due to a race condition between SSE cleanup and the abort POST handler. The abort case in <code class="cl-code">CodexSessionWrapper.send()</code> and the <code class="cl-code">POST /api/agent/[id]</code> route now both wrap their logic in try/catch, ensuring any exception is safely caught and a clean <code class="cl-code">{ running: false }</code> response is always returned.</li><br/><li><strong>"Stream idle timeout" after AI finishes</strong> — when the SSE connection closed after turn completion and the client auto-reconnected, the new SSE stream would receive no events (turn already done), causing the idle watchdog to fire after 3 minutes. The SSE <code class="cl-code">events/route.ts</code> now checks <code class="cl-code">session.isBusy()</code> after subscribing; if the session has no active turn, it immediately sends <code class="cl-code">agent_end</code> so the watchdog never starts.</li><br/></ul><br/><h2 class="cl-h2">0.1.93</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stuck chat after agent completion</strong> — when the SSE <code class="cl-code">agent_end</code> event was missed (due to network disconnect or timing), the UI would stay stuck showing "Stop" button and appear to be streaming, even though the agent had actually finished. Root cause: the <code class="cl-code">reconcileSession</code> polling loop fetched the session state every 10s but never updated <code class="cl-code">agentRunning</code> based on the server response. Now <code class="cl-code">reconcileSession</code> checks <code class="cl-code">agentState.running</code> after each reconcile and self-heals the UI if the agent has actually stopped, preventing the stuck state without requiring a page refresh.</li><br/><li><strong>Reduce left sidebar polling interval</strong> — changed from 10 seconds to 1.5 minutes (90s) to reduce unnecessary network traffic.</li><br/></ul><br/><h2 class="cl-h2">0.1.92</h2></p><p class="cl-p"><h3 class="cl-h3">Changes</h3><br/><ul class="cl-ul"><li><strong>Rename right-panel tab "Tools" → "Status"</strong> — the right-panel tab previously labeled "Tools" primarily shows agent runtime status (phase, uptime, active tools, model info) and working memory, not tool presets. The rename aligns the tab label with its actual content. A new pulse/activity SVG icon is used for the Status tab.</li><br/></ul><br/><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Defensive error handling in runtime status</strong> — <code class="cl-code">getRuntimeStatus()</code> now wraps each session's <code class="cl-code">isAlive()</code> and <code class="cl-code">getRuntimeStatus()</code> calls in try/catch blocks. Previously, a partially destroyed session wrapper could cause the entire status query to throw, resulting in an empty Tools panel.</li><br/><li><strong>Runtime API route hardening</strong> — <code class="cl-code">GET /api/agent/runtime</code> now catches errors from <code class="cl-code">getRuntimeStatus()</code> and <code class="cl-code">getMemoryStatus()</code> independently, falling back to an empty status instead of returning a 500 error. This prevents transient state issues from breaking the frontend Status panel.</li><br/></ul><br/><h2 class="cl-h2">0.1.91</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Sidebar refresh delay</strong> — new chat sessions now appear in the sidebar within seconds. Two changes: (1) <code class="cl-code">AppShell.handleSessionCreated</code> dispatches a <code class="cl-code">session-created</code> DOM event, and (2) <code class="cl-code">SessionSidebar</code> listens for that event and polls every 10s as a fallback (pattern adopted from CodePilot). Previously the sidebar relied solely on <code class="cl-code">refreshKey</code> prop propagation, which could lag behind the Codex app-server thread index.</li><br/><li><strong>Scroll-to-bottom on session open (v2)</strong> — the settle loop now uses a <code class="cl-code">lastSettledSessionIdRef</code> to reliably detect session switches, preventing the settle from being skipped when messages arrive in batches across renders. Also aborts the animation if the session changes mid-settle.</li><br/></ul><br/><h2 class="cl-h2">0.1.90</h2><br/></p>0:{"P":null,"c":["","docs","changelog"],"q":"","i":false,"f":[[["",{"children":["docs",{"children":["changelog",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/6b00dcf032cca328.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/fddca953485158e4.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"__variable_66b8ca","suppressHydrationWarning":true,"children":[["$","head",null,{"children":["$","script",null,{"dangerouslySetInnerHTML":{"__html":"(function(){try{var t=localStorage.getItem(\"annodex-theme\");if(t===\"dark\")document.documentElement.classList.add(\"dark\")}catch(e){}})();"}}]}],["$","body",null,{"style":{"minHeight":"100dvh","display":"flex","flexDirection":"column"},"children":["$","$L2",null,{"children":["$","$L3",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","div",null,{"style":{"maxWidth":800,"margin":"0 auto","padding":"40px 24px 80px"},"children":[["$","$L6",null,{"href":"/workspace","style":{"display":"inline-flex","alignItems":"center","gap":6,"color":"var(--color-accent, #3b82f6)","textDecoration":"none","fontSize":14,"marginBottom":24},"children":["←"," Back to ","annodex"]}],["$","div",null,{"className":"changelog-content","dangerouslySetInnerHTML":{"__html":"$7"}}],"$L8"]}],null,"$L9"]}],{},null,false,null]},null,false,"$@a"]},null,false,"$@a"]},null,false,null],"$Lb",false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"AGWDEHkSDNIvOTAQZ2_6O"}
|
|
13
13
|
d:I[90484,[],"OutletBoundary"]
|
|
14
14
|
e:"$Sreact.suspense"
|
|
15
15
|
11:I[90484,[],"ViewportBoundary"]
|
|
@@ -9,7 +9,7 @@ c:I[27123,[],"default",1]
|
|
|
9
9
|
:HL["/_next/static/media/ec14413c594b3356-s.p.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
|
|
10
10
|
:HL["/_next/static/css/6b00dcf032cca328.css","style"]
|
|
11
11
|
:HL["/_next/static/css/fddca953485158e4.css","style"]
|
|
12
|
-
7:T187f,<p class="cl-p"><h2 class="cl-h2">0.1.97</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename process cleanup</strong> — session rename now first uses the live session connection and only falls back to a managed codex server when needed, avoiding unnecessary codex app-server/router process churn. Codex app-server shutdown now includes a SIGKILL fallback for detached Linux processes, reducing orphaned background processes after idle cleanup or dev reloads.</li><br/></ul><br/><h2 class="cl-h2">0.1.96</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename not working</strong> — three root causes fixed: (1) frontend <code class="cl-code">commitRename</code> didn't check HTTP response status, silently proceeding after server errors; (2) session name had no local persistence, so it was lost when <code class="cl-code">thread/list</code> didn't return the <code class="cl-code">name</code> field or when falling back to local cache; (3) top bar and sidebar rename were completely independent — renaming from the sidebar never updated the top bar's <code class="cl-code">selectedSession</code>. Fixes: <code class="cl-code">commitRename</code> now checks <code class="cl-code">res.ok</code> and shows error toasts; PATCH endpoint persists name to <code class="cl-code">session-runtime.json</code> via <code class="cl-code">upsertSessionRuntime</code>; <code class="cl-code">sessionInfoFromThreadSummary</code> and <code class="cl-code">summarizeCodexSessionFile</code> recover name from runtime store; new <code class="cl-code">onSessionRenamed</code> callback syncs sidebar rename to AppShell's top bar.</li><br/></ul><br/><h2 class="cl-h2">0.1.95</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stop button triggers HTTP 500 during streaming</strong> — clicking Stop while the AI was responding could cause a 500 error due to a race condition between SSE cleanup and the abort POST handler. The abort case in <code class="cl-code">CodexSessionWrapper.send()</code> and the <code class="cl-code">POST /api/agent/[id]</code> route now both wrap their logic in try/catch, ensuring any exception is safely caught and a clean <code class="cl-code">{ running: false }</code> response is always returned.</li><br/><li><strong>"Stream idle timeout" after AI finishes</strong> — when the SSE connection closed after turn completion and the client auto-reconnected, the new SSE stream would receive no events (turn already done), causing the idle watchdog to fire after 3 minutes. The SSE <code class="cl-code">events/route.ts</code> now checks <code class="cl-code">session.isBusy()</code> after subscribing; if the session has no active turn, it immediately sends <code class="cl-code">agent_end</code> so the watchdog never starts.</li><br/></ul><br/><h2 class="cl-h2">0.1.93</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stuck chat after agent completion</strong> — when the SSE <code class="cl-code">agent_end</code> event was missed (due to network disconnect or timing), the UI would stay stuck showing "Stop" button and appear to be streaming, even though the agent had actually finished. Root cause: the <code class="cl-code">reconcileSession</code> polling loop fetched the session state every 10s but never updated <code class="cl-code">agentRunning</code> based on the server response. Now <code class="cl-code">reconcileSession</code> checks <code class="cl-code">agentState.running</code> after each reconcile and self-heals the UI if the agent has actually stopped, preventing the stuck state without requiring a page refresh.</li><br/><li><strong>Reduce left sidebar polling interval</strong> — changed from 10 seconds to 1.5 minutes (90s) to reduce unnecessary network traffic.</li><br/></ul><br/><h2 class="cl-h2">0.1.92</h2></p><p class="cl-p"><h3 class="cl-h3">Changes</h3><br/><ul class="cl-ul"><li><strong>Rename right-panel tab "Tools" → "Status"</strong> — the right-panel tab previously labeled "Tools" primarily shows agent runtime status (phase, uptime, active tools, model info) and working memory, not tool presets. The rename aligns the tab label with its actual content. A new pulse/activity SVG icon is used for the Status tab.</li><br/></ul><br/><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Defensive error handling in runtime status</strong> — <code class="cl-code">getRuntimeStatus()</code> now wraps each session's <code class="cl-code">isAlive()</code> and <code class="cl-code">getRuntimeStatus()</code> calls in try/catch blocks. Previously, a partially destroyed session wrapper could cause the entire status query to throw, resulting in an empty Tools panel.</li><br/><li><strong>Runtime API route hardening</strong> — <code class="cl-code">GET /api/agent/runtime</code> now catches errors from <code class="cl-code">getRuntimeStatus()</code> and <code class="cl-code">getMemoryStatus()</code> independently, falling back to an empty status instead of returning a 500 error. This prevents transient state issues from breaking the frontend Status panel.</li><br/></ul><br/><h2 class="cl-h2">0.1.91</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Sidebar refresh delay</strong> — new chat sessions now appear in the sidebar within seconds. Two changes: (1) <code class="cl-code">AppShell.handleSessionCreated</code> dispatches a <code class="cl-code">session-created</code> DOM event, and (2) <code class="cl-code">SessionSidebar</code> listens for that event and polls every 10s as a fallback (pattern adopted from CodePilot). Previously the sidebar relied solely on <code class="cl-code">refreshKey</code> prop propagation, which could lag behind the Codex app-server thread index.</li><br/><li><strong>Scroll-to-bottom on session open (v2)</strong> — the settle loop now uses a <code class="cl-code">lastSettledSessionIdRef</code> to reliably detect session switches, preventing the settle from being skipped when messages arrive in batches across renders. Also aborts the animation if the session changes mid-settle.</li><br/></ul><br/><h2 class="cl-h2">0.1.90</h2><br/></p>0:{"P":null,"c":["","docs","changelog"],"q":"","i":false,"f":[[["",{"children":["docs",{"children":["changelog",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/6b00dcf032cca328.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/fddca953485158e4.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"__variable_66b8ca","suppressHydrationWarning":true,"children":[["$","head",null,{"children":["$","script",null,{"dangerouslySetInnerHTML":{"__html":"(function(){try{var t=localStorage.getItem(\"annodex-theme\");if(t===\"dark\")document.documentElement.classList.add(\"dark\")}catch(e){}})();"}}]}],["$","body",null,{"style":{"minHeight":"100dvh","display":"flex","flexDirection":"column"},"children":["$","$L2",null,{"children":["$","$L3",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","div",null,{"style":{"maxWidth":800,"margin":"0 auto","padding":"40px 24px 80px"},"children":[["$","$L6",null,{"href":"/workspace","style":{"display":"inline-flex","alignItems":"center","gap":6,"color":"var(--color-accent, #3b82f6)","textDecoration":"none","fontSize":14,"marginBottom":24},"children":["←"," Back to ","annodex"]}],["$","div",null,{"className":"changelog-content","dangerouslySetInnerHTML":{"__html":"$7"}}],"$L8"]}],null,"$L9"]}],{},null,false,null]},null,false,"$@a"]},null,false,"$@a"]},null,false,null],"$Lb",false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"SVHmVqHgsyh7rLM_BP4l1"}
|
|
12
|
+
7:T1b6e,<p class="cl-p"><h2 class="cl-h2">0.1.98</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename robustness</strong> — five improvements: (1) wasted wrapper cleaned up after connection errors so follow-up operations don't fail on a dead connection; (2) empty name now rejected with 400 instead of sent to codex; (3) <code class="cl-code">CodexSessionWrapper.send("rename")</code> now syncs to <code class="cl-code">session-runtime.json</code> so direct calls (not through HTTP PATCH) also persist; (4) AppShell and SessionSidebar now share a single <code class="cl-code">renameSession()</code> helper in <code class="cl-code">agent-client.ts</code> eliminating duplicated fetch/error-handling logic.</li><br/></ul><br/><h2 class="cl-h2">0.1.97</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename process cleanup</strong> — session rename now first uses the live session connection and only falls back to a managed codex server when needed, avoiding unnecessary codex app-server/router process churn. Codex app-server shutdown now includes a SIGKILL fallback for detached Linux processes, reducing orphaned background processes after idle cleanup or dev reloads.</li><br/></ul><br/><h2 class="cl-h2">0.1.96</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename not working</strong> — three root causes fixed: (1) frontend <code class="cl-code">commitRename</code> didn't check HTTP response status, silently proceeding after server errors; (2) session name had no local persistence, so it was lost when <code class="cl-code">thread/list</code> didn't return the <code class="cl-code">name</code> field or when falling back to local cache; (3) top bar and sidebar rename were completely independent — renaming from the sidebar never updated the top bar's <code class="cl-code">selectedSession</code>. Fixes: <code class="cl-code">commitRename</code> now checks <code class="cl-code">res.ok</code> and shows error toasts; PATCH endpoint persists name to <code class="cl-code">session-runtime.json</code> via <code class="cl-code">upsertSessionRuntime</code>; <code class="cl-code">sessionInfoFromThreadSummary</code> and <code class="cl-code">summarizeCodexSessionFile</code> recover name from runtime store; new <code class="cl-code">onSessionRenamed</code> callback syncs sidebar rename to AppShell's top bar.</li><br/></ul><br/><h2 class="cl-h2">0.1.95</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stop button triggers HTTP 500 during streaming</strong> — clicking Stop while the AI was responding could cause a 500 error due to a race condition between SSE cleanup and the abort POST handler. The abort case in <code class="cl-code">CodexSessionWrapper.send()</code> and the <code class="cl-code">POST /api/agent/[id]</code> route now both wrap their logic in try/catch, ensuring any exception is safely caught and a clean <code class="cl-code">{ running: false }</code> response is always returned.</li><br/><li><strong>"Stream idle timeout" after AI finishes</strong> — when the SSE connection closed after turn completion and the client auto-reconnected, the new SSE stream would receive no events (turn already done), causing the idle watchdog to fire after 3 minutes. The SSE <code class="cl-code">events/route.ts</code> now checks <code class="cl-code">session.isBusy()</code> after subscribing; if the session has no active turn, it immediately sends <code class="cl-code">agent_end</code> so the watchdog never starts.</li><br/></ul><br/><h2 class="cl-h2">0.1.93</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stuck chat after agent completion</strong> — when the SSE <code class="cl-code">agent_end</code> event was missed (due to network disconnect or timing), the UI would stay stuck showing "Stop" button and appear to be streaming, even though the agent had actually finished. Root cause: the <code class="cl-code">reconcileSession</code> polling loop fetched the session state every 10s but never updated <code class="cl-code">agentRunning</code> based on the server response. Now <code class="cl-code">reconcileSession</code> checks <code class="cl-code">agentState.running</code> after each reconcile and self-heals the UI if the agent has actually stopped, preventing the stuck state without requiring a page refresh.</li><br/><li><strong>Reduce left sidebar polling interval</strong> — changed from 10 seconds to 1.5 minutes (90s) to reduce unnecessary network traffic.</li><br/></ul><br/><h2 class="cl-h2">0.1.92</h2></p><p class="cl-p"><h3 class="cl-h3">Changes</h3><br/><ul class="cl-ul"><li><strong>Rename right-panel tab "Tools" → "Status"</strong> — the right-panel tab previously labeled "Tools" primarily shows agent runtime status (phase, uptime, active tools, model info) and working memory, not tool presets. The rename aligns the tab label with its actual content. A new pulse/activity SVG icon is used for the Status tab.</li><br/></ul><br/><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Defensive error handling in runtime status</strong> — <code class="cl-code">getRuntimeStatus()</code> now wraps each session's <code class="cl-code">isAlive()</code> and <code class="cl-code">getRuntimeStatus()</code> calls in try/catch blocks. Previously, a partially destroyed session wrapper could cause the entire status query to throw, resulting in an empty Tools panel.</li><br/><li><strong>Runtime API route hardening</strong> — <code class="cl-code">GET /api/agent/runtime</code> now catches errors from <code class="cl-code">getRuntimeStatus()</code> and <code class="cl-code">getMemoryStatus()</code> independently, falling back to an empty status instead of returning a 500 error. This prevents transient state issues from breaking the frontend Status panel.</li><br/></ul><br/><h2 class="cl-h2">0.1.91</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Sidebar refresh delay</strong> — new chat sessions now appear in the sidebar within seconds. Two changes: (1) <code class="cl-code">AppShell.handleSessionCreated</code> dispatches a <code class="cl-code">session-created</code> DOM event, and (2) <code class="cl-code">SessionSidebar</code> listens for that event and polls every 10s as a fallback (pattern adopted from CodePilot). Previously the sidebar relied solely on <code class="cl-code">refreshKey</code> prop propagation, which could lag behind the Codex app-server thread index.</li><br/><li><strong>Scroll-to-bottom on session open (v2)</strong> — the settle loop now uses a <code class="cl-code">lastSettledSessionIdRef</code> to reliably detect session switches, preventing the settle from being skipped when messages arrive in batches across renders. Also aborts the animation if the session changes mid-settle.</li><br/></ul><br/><h2 class="cl-h2">0.1.90</h2><br/></p>0:{"P":null,"c":["","docs","changelog"],"q":"","i":false,"f":[[["",{"children":["docs",{"children":["changelog",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",16],[["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/6b00dcf032cca328.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/fddca953485158e4.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","className":"__variable_66b8ca","suppressHydrationWarning":true,"children":[["$","head",null,{"children":["$","script",null,{"dangerouslySetInnerHTML":{"__html":"(function(){try{var t=localStorage.getItem(\"annodex-theme\");if(t===\"dark\")document.documentElement.classList.add(\"dark\")}catch(e){}})();"}}]}],["$","body",null,{"style":{"minHeight":"100dvh","display":"flex","flexDirection":"column"},"children":["$","$L2",null,{"children":["$","$L3",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]}]}]]}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[null,["$","$L4",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","div",null,{"style":{"maxWidth":800,"margin":"0 auto","padding":"40px 24px 80px"},"children":[["$","$L6",null,{"href":"/workspace","style":{"display":"inline-flex","alignItems":"center","gap":6,"color":"var(--color-accent, #3b82f6)","textDecoration":"none","fontSize":14,"marginBottom":24},"children":["←"," Back to ","annodex"]}],["$","div",null,{"className":"changelog-content","dangerouslySetInnerHTML":{"__html":"$7"}}],"$L8"]}],null,"$L9"]}],{},null,false,null]},null,false,"$@a"]},null,false,"$@a"]},null,false,null],"$Lb",false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"AGWDEHkSDNIvOTAQZ2_6O"}
|
|
13
13
|
d:I[90484,[],"OutletBoundary"]
|
|
14
14
|
e:"$Sreact.suspense"
|
|
15
15
|
11:I[90484,[],"ViewportBoundary"]
|
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
3:I[90484,[],"MetadataBoundary"]
|
|
4
4
|
4:"$Sreact.suspense"
|
|
5
5
|
5:I[86869,[],"IconMark"]
|
|
6
|
-
0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"Changelog"}],["$","meta","1",{"name":"description","content":"Release history and changes"}],["$","link","2",{"rel":"shortcut icon","href":"/favicon.svg","type":"image/svg+xml"}],["$","link","3",{"rel":"icon","href":"/favicon.svg","type":"image/svg+xml"}],["$","$L5","4",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"
|
|
6
|
+
0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[["$","title","0",{"children":"Changelog"}],["$","meta","1",{"name":"description","content":"Release history and changes"}],["$","link","2",{"rel":"shortcut icon","href":"/favicon.svg","type":"image/svg+xml"}],["$","link","3",{"rel":"icon","href":"/favicon.svg","type":"image/svg+xml"}],["$","$L5","4",{}]]}]}]}],["$","meta",null,{"name":"next-size-adjust","content":""}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"AGWDEHkSDNIvOTAQZ2_6O"}
|
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
5:I[74581,[],""]
|
|
6
6
|
:HL["/_next/static/css/6b00dcf032cca328.css","style"]
|
|
7
7
|
:HL["/_next/static/css/fddca953485158e4.css","style"]
|
|
8
|
-
0:{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/6b00dcf032cca328.css","precedence":"next"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/fddca953485158e4.css","precedence":"next"}]],["$","html",null,{"lang":"en","className":"__variable_66b8ca","suppressHydrationWarning":true,"children":[["$","head",null,{"children":["$","script",null,{"dangerouslySetInnerHTML":{"__html":"(function(){try{var t=localStorage.getItem(\"annodex-theme\");if(t===\"dark\")document.documentElement.classList.add(\"dark\")}catch(e){}})();"}}]}],["$","body",null,{"style":{"minHeight":"100dvh","display":"flex","flexDirection":"column"},"children":["$","$L2",null,{"children":["$","$L3",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","template":["$","$L5",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]}]}]]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"
|
|
8
|
+
0:{"rsc":["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/6b00dcf032cca328.css","precedence":"next"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/fddca953485158e4.css","precedence":"next"}]],["$","html",null,{"lang":"en","className":"__variable_66b8ca","suppressHydrationWarning":true,"children":[["$","head",null,{"children":["$","script",null,{"dangerouslySetInnerHTML":{"__html":"(function(){try{var t=localStorage.getItem(\"annodex-theme\");if(t===\"dark\")document.documentElement.classList.add(\"dark\")}catch(e){}})();"}}]}],["$","body",null,{"style":{"minHeight":"100dvh","display":"flex","flexDirection":"column"},"children":["$","$L2",null,{"children":["$","$L3",null,{"children":["$","$L4",null,{"parallelRouterKey":"children","template":["$","$L5",null,{}],"notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]]}]}]}]}]]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"AGWDEHkSDNIvOTAQZ2_6O"}
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
:HL["/_next/static/media/ec14413c594b3356-s.p.woff2","font",{"crossOrigin":"","type":"font/woff2"}]
|
|
3
3
|
:HL["/_next/static/css/6b00dcf032cca328.css","style"]
|
|
4
4
|
:HL["/_next/static/css/fddca953485158e4.css","style"]
|
|
5
|
-
0:{"tree":{"name":"","param":null,"prefetchHints":16,"slots":{"children":{"name":"docs","param":null,"prefetchHints":0,"slots":{"children":{"name":"changelog","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}}}}}},"staleTime":300,"buildId":"
|
|
5
|
+
0:{"tree":{"name":"","param":null,"prefetchHints":16,"slots":{"children":{"name":"docs","param":null,"prefetchHints":0,"slots":{"children":{"name":"changelog","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}}}}}},"staleTime":300,"buildId":"AGWDEHkSDNIvOTAQZ2_6O"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
2:I[98500,["8500","static/chunks/8500-f62a38ff68ab7f42.js","9089","static/chunks/app/docs/changelog/page-7f8ff3ce79d21000.js"],""]
|
|
3
3
|
6:I[90484,[],"OutletBoundary"]
|
|
4
4
|
7:"$Sreact.suspense"
|
|
5
|
-
3:
|
|
5
|
+
3:T1b6e,<p class="cl-p"><h2 class="cl-h2">0.1.98</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename robustness</strong> — five improvements: (1) wasted wrapper cleaned up after connection errors so follow-up operations don't fail on a dead connection; (2) empty name now rejected with 400 instead of sent to codex; (3) <code class="cl-code">CodexSessionWrapper.send("rename")</code> now syncs to <code class="cl-code">session-runtime.json</code> so direct calls (not through HTTP PATCH) also persist; (4) AppShell and SessionSidebar now share a single <code class="cl-code">renameSession()</code> helper in <code class="cl-code">agent-client.ts</code> eliminating duplicated fetch/error-handling logic.</li><br/></ul><br/><h2 class="cl-h2">0.1.97</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename process cleanup</strong> — session rename now first uses the live session connection and only falls back to a managed codex server when needed, avoiding unnecessary codex app-server/router process churn. Codex app-server shutdown now includes a SIGKILL fallback for detached Linux processes, reducing orphaned background processes after idle cleanup or dev reloads.</li><br/></ul><br/><h2 class="cl-h2">0.1.96</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Session rename not working</strong> — three root causes fixed: (1) frontend <code class="cl-code">commitRename</code> didn't check HTTP response status, silently proceeding after server errors; (2) session name had no local persistence, so it was lost when <code class="cl-code">thread/list</code> didn't return the <code class="cl-code">name</code> field or when falling back to local cache; (3) top bar and sidebar rename were completely independent — renaming from the sidebar never updated the top bar's <code class="cl-code">selectedSession</code>. Fixes: <code class="cl-code">commitRename</code> now checks <code class="cl-code">res.ok</code> and shows error toasts; PATCH endpoint persists name to <code class="cl-code">session-runtime.json</code> via <code class="cl-code">upsertSessionRuntime</code>; <code class="cl-code">sessionInfoFromThreadSummary</code> and <code class="cl-code">summarizeCodexSessionFile</code> recover name from runtime store; new <code class="cl-code">onSessionRenamed</code> callback syncs sidebar rename to AppShell's top bar.</li><br/></ul><br/><h2 class="cl-h2">0.1.95</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stop button triggers HTTP 500 during streaming</strong> — clicking Stop while the AI was responding could cause a 500 error due to a race condition between SSE cleanup and the abort POST handler. The abort case in <code class="cl-code">CodexSessionWrapper.send()</code> and the <code class="cl-code">POST /api/agent/[id]</code> route now both wrap their logic in try/catch, ensuring any exception is safely caught and a clean <code class="cl-code">{ running: false }</code> response is always returned.</li><br/><li><strong>"Stream idle timeout" after AI finishes</strong> — when the SSE connection closed after turn completion and the client auto-reconnected, the new SSE stream would receive no events (turn already done), causing the idle watchdog to fire after 3 minutes. The SSE <code class="cl-code">events/route.ts</code> now checks <code class="cl-code">session.isBusy()</code> after subscribing; if the session has no active turn, it immediately sends <code class="cl-code">agent_end</code> so the watchdog never starts.</li><br/></ul><br/><h2 class="cl-h2">0.1.93</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Stuck chat after agent completion</strong> — when the SSE <code class="cl-code">agent_end</code> event was missed (due to network disconnect or timing), the UI would stay stuck showing "Stop" button and appear to be streaming, even though the agent had actually finished. Root cause: the <code class="cl-code">reconcileSession</code> polling loop fetched the session state every 10s but never updated <code class="cl-code">agentRunning</code> based on the server response. Now <code class="cl-code">reconcileSession</code> checks <code class="cl-code">agentState.running</code> after each reconcile and self-heals the UI if the agent has actually stopped, preventing the stuck state without requiring a page refresh.</li><br/><li><strong>Reduce left sidebar polling interval</strong> — changed from 10 seconds to 1.5 minutes (90s) to reduce unnecessary network traffic.</li><br/></ul><br/><h2 class="cl-h2">0.1.92</h2></p><p class="cl-p"><h3 class="cl-h3">Changes</h3><br/><ul class="cl-ul"><li><strong>Rename right-panel tab "Tools" → "Status"</strong> — the right-panel tab previously labeled "Tools" primarily shows agent runtime status (phase, uptime, active tools, model info) and working memory, not tool presets. The rename aligns the tab label with its actual content. A new pulse/activity SVG icon is used for the Status tab.</li><br/></ul><br/><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Defensive error handling in runtime status</strong> — <code class="cl-code">getRuntimeStatus()</code> now wraps each session's <code class="cl-code">isAlive()</code> and <code class="cl-code">getRuntimeStatus()</code> calls in try/catch blocks. Previously, a partially destroyed session wrapper could cause the entire status query to throw, resulting in an empty Tools panel.</li><br/><li><strong>Runtime API route hardening</strong> — <code class="cl-code">GET /api/agent/runtime</code> now catches errors from <code class="cl-code">getRuntimeStatus()</code> and <code class="cl-code">getMemoryStatus()</code> independently, falling back to an empty status instead of returning a 500 error. This prevents transient state issues from breaking the frontend Status panel.</li><br/></ul><br/><h2 class="cl-h2">0.1.91</h2></p><p class="cl-p"><h3 class="cl-h3">Fixes</h3><br/><ul class="cl-ul"><li><strong>Sidebar refresh delay</strong> — new chat sessions now appear in the sidebar within seconds. Two changes: (1) <code class="cl-code">AppShell.handleSessionCreated</code> dispatches a <code class="cl-code">session-created</code> DOM event, and (2) <code class="cl-code">SessionSidebar</code> listens for that event and polls every 10s as a fallback (pattern adopted from CodePilot). Previously the sidebar relied solely on <code class="cl-code">refreshKey</code> prop propagation, which could lag behind the Codex app-server thread index.</li><br/><li><strong>Scroll-to-bottom on session open (v2)</strong> — the settle loop now uses a <code class="cl-code">lastSettledSessionIdRef</code> to reliably detect session switches, preventing the settle from being skipped when messages arrive in batches across renders. Also aborts the animation if the session changes mid-settle.</li><br/></ul><br/><h2 class="cl-h2">0.1.90</h2><br/></p>0:{"rsc":["$","$1","c",{"children":[["$","div",null,{"style":{"maxWidth":800,"margin":"0 auto","padding":"40px 24px 80px"},"children":[["$","$L2",null,{"href":"/workspace","style":{"display":"inline-flex","alignItems":"center","gap":6,"color":"var(--color-accent, #3b82f6)","textDecoration":"none","fontSize":14,"marginBottom":24},"children":["←"," Back to ","annodex"]}],["$","div",null,{"className":"changelog-content","dangerouslySetInnerHTML":{"__html":"$3"}}],"$L4"]}],null,"$L5"]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"AGWDEHkSDNIvOTAQZ2_6O"}
|
|
6
6
|
4:["$","style",null,{"children":"\n .changelog-content { font-family: var(--font-noto-mono, monospace); line-height: 1.7; color: var(--color-fg, #e5e7eb); }\n .cl-h1 { font-size: 28px; font-weight: 700; margin: 40px 0 16px; color: var(--color-fg, #f9fafb); border-bottom: 1px solid var(--color-border, #374151); padding-bottom: 8px; }\n .cl-h2 { font-size: 22px; font-weight: 600; margin: 32px 0 12px; color: var(--color-accent, #60a5fa); }\n .cl-h3 { font-size: 16px; font-weight: 600; margin: 20px 0 8px; color: var(--color-fg-secondary, #9ca3af); }\n .cl-p { margin: 0 0 12px; }\n .cl-ul { margin: 8px 0 16px 20px; padding: 0; }\n .cl-ul li { margin: 4px 0; }\n .cl-code { background: var(--color-bg-code, #1f2937); padding: 2px 6px; border-radius: 4px; font-size: 13px; }\n "}]
|
|
7
7
|
5:["$","$L6",null,{"children":["$","$7",null,{"name":"Next.MetadataOutlet","children":"$@8"}]}]
|
|
8
8
|
8:null
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
2:I[57121,[],""]
|
|
3
3
|
3:I[74581,[],""]
|
|
4
4
|
4:[]
|
|
5
|
-
0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"
|
|
5
|
+
0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"AGWDEHkSDNIvOTAQZ2_6O"}
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
2:I[57121,[],""]
|
|
3
3
|
3:I[74581,[],""]
|
|
4
4
|
4:[]
|
|
5
|
-
0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"
|
|
5
|
+
0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"AGWDEHkSDNIvOTAQZ2_6O"}
|