@aoagents/ao-web 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-build-manifest.json +160 -94
- package/.next/app-path-routes-manifest.json +17 -10
- package/.next/build-manifest.json +5 -5
- package/.next/prerender-manifest.json +26 -26
- package/.next/react-loadable-manifest.json +12 -12
- package/.next/required-server-files.json +5 -3
- package/.next/routes-manifest.json +33 -0
- package/.next/server/app/_not-found/page.js +2 -2
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +1 -1
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/api/backlog/route.js +1 -1
- package/.next/server/app/api/backlog/route.js.nft.json +1 -1
- package/.next/server/app/api/backlog/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/browse-directory/route.js +1 -0
- package/.next/server/app/api/browse-directory/route.js.nft.json +1 -0
- package/.next/server/app/api/browse-directory/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/events/route.js +3 -3
- package/.next/server/app/api/events/route.js.nft.json +1 -1
- package/.next/server/app/api/events/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/filesystem/browse/route.js +1 -0
- package/.next/server/app/api/filesystem/browse/route.js.nft.json +1 -0
- package/.next/server/app/api/filesystem/browse/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/issues/route.js +1 -1
- package/.next/server/app/api/issues/route.js.nft.json +1 -1
- package/.next/server/app/api/issues/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/observability/route.js +1 -1
- package/.next/server/app/api/observability/route.js.nft.json +1 -1
- package/.next/server/app/api/observability/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/orchestrators/route.js +1 -1
- package/.next/server/app/api/orchestrators/route.js.nft.json +1 -1
- package/.next/server/app/api/orchestrators/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/projects/[id]/route.js +1 -0
- package/.next/server/app/api/projects/[id]/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/[id]/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/reload/route.js +1 -0
- package/.next/server/app/api/projects/reload/route.js.nft.json +1 -0
- package/.next/server/app/api/projects/reload/route_client-reference-manifest.js +1 -0
- package/.next/server/app/api/projects/route.js +1 -1
- package/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/prs/[id]/merge/route.js +1 -1
- package/.next/server/app/api/prs/[id]/merge/route.js.nft.json +1 -1
- package/.next/server/app/api/prs/[id]/merge/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/runtime/terminal/route.js +1 -1
- package/.next/server/app/api/runtime/terminal/route.js.nft.json +1 -1
- package/.next/server/app/api/runtime/terminal/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sessions/[id]/kill/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/kill/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/kill/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sessions/[id]/message/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/message/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/message/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sessions/[id]/remap/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/remap/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/remap/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sessions/[id]/restore/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/restore/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/restore/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sessions/[id]/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sessions/[id]/send/route.js +1 -1
- package/.next/server/app/api/sessions/[id]/send/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/[id]/send/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sessions/patches/route.js +1 -1
- package/.next/server/app/api/sessions/patches/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/patches/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/sessions/route.js +1 -1
- package/.next/server/app/api/sessions/route.js.nft.json +1 -1
- package/.next/server/app/api/sessions/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/setup-labels/route.js +1 -1
- package/.next/server/app/api/setup-labels/route.js.nft.json +1 -1
- package/.next/server/app/api/setup-labels/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/spawn/route.js +1 -1
- package/.next/server/app/api/spawn/route.js.nft.json +1 -1
- package/.next/server/app/api/spawn/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/verify/route.js +1 -1
- package/.next/server/app/api/verify/route.js.nft.json +1 -1
- package/.next/server/app/api/verify/route_client-reference-manifest.js +1 -1
- package/.next/server/app/api/webhooks/[...slug]/route.js +1 -1
- package/.next/server/app/api/webhooks/[...slug]/route.js.nft.json +1 -1
- package/.next/server/app/api/webhooks/[...slug]/route_client-reference-manifest.js +1 -1
- package/.next/server/app/apple-icon/route.js +1 -1
- package/.next/server/app/apple-icon/route.js.nft.json +1 -1
- package/.next/server/app/apple-icon/route_client-reference-manifest.js +1 -1
- package/.next/server/app/dev/terminal-test/page.js +2 -2
- package/.next/server/app/dev/terminal-test/page.js.nft.json +1 -1
- package/.next/server/app/dev/terminal-test/page_client-reference-manifest.js +1 -1
- package/.next/server/app/dev/terminal-test.html +1 -1
- package/.next/server/app/dev/terminal-test.rsc +3 -3
- package/.next/server/app/icon/route.js +1 -1
- package/.next/server/app/icon/route.js.nft.json +1 -1
- package/.next/server/app/icon/route_client-reference-manifest.js +1 -1
- package/.next/server/app/icon-192/route.js +1 -1
- package/.next/server/app/icon-192/route.js.nft.json +1 -1
- package/.next/server/app/icon-192/route_client-reference-manifest.js +1 -1
- package/.next/server/app/icon-512/route.js +1 -1
- package/.next/server/app/icon-512/route.js.nft.json +1 -1
- package/.next/server/app/icon-512/route_client-reference-manifest.js +1 -1
- package/.next/server/app/manifest.webmanifest/route.js +2 -2
- package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -1
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +1 -1
- package/.next/server/app/orchestrators/page.js +2 -2
- package/.next/server/app/orchestrators/page.js.nft.json +1 -1
- package/.next/server/app/orchestrators/page_client-reference-manifest.js +1 -1
- package/.next/server/app/page.js +2 -2
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/projects/[projectId]/page.js +2 -0
- package/.next/server/app/projects/[projectId]/page.js.nft.json +1 -0
- package/.next/server/app/projects/[projectId]/page_client-reference-manifest.js +1 -0
- package/.next/server/app/projects/[projectId]/sessions/[id]/page.js +2 -0
- package/.next/server/app/projects/[projectId]/sessions/[id]/page.js.nft.json +1 -0
- package/.next/server/app/projects/[projectId]/sessions/[id]/page_client-reference-manifest.js +1 -0
- package/.next/server/app/projects/[projectId]/settings/page.js +2 -0
- package/.next/server/app/projects/[projectId]/settings/page.js.nft.json +1 -0
- package/.next/server/app/projects/[projectId]/settings/page_client-reference-manifest.js +1 -0
- package/.next/server/app/prs/page.js +2 -2
- package/.next/server/app/prs/page.js.nft.json +1 -1
- package/.next/server/app/prs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/sessions/[id]/page.js +2 -12
- package/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
- package/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/test-direct/page.js +2 -2
- package/.next/server/app/test-direct/page.js.nft.json +1 -1
- package/.next/server/app/test-direct/page_client-reference-manifest.js +1 -1
- package/.next/server/app/test-direct.html +1 -1
- package/.next/server/app/test-direct.rsc +3 -3
- package/.next/server/app-paths-manifest.json +17 -10
- package/.next/server/chunks/1172.js +1 -0
- package/.next/server/chunks/1271.js +1 -0
- package/.next/server/chunks/2106.js +1 -0
- package/.next/server/chunks/252.js +11 -0
- package/.next/server/chunks/2810.js +1 -0
- package/.next/server/chunks/3602.js +382 -0
- package/.next/server/chunks/3667.js +277 -0
- package/.next/server/chunks/3714.js +1 -0
- package/.next/server/chunks/4520.js +1 -0
- package/.next/server/chunks/6086.js +25 -0
- package/.next/server/chunks/6172.js +9 -0
- package/.next/server/chunks/8367.js +3 -0
- package/.next/server/chunks/8386.js +1 -0
- package/.next/server/chunks/{803.js → 8803.js} +1 -1
- package/.next/server/chunks/{561.js → 9561.js} +1 -1
- package/.next/server/middleware-build-manifest.js +1 -1
- package/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/.next/server/next-font-manifest.js +1 -1
- package/.next/server/next-font-manifest.json +1 -1
- package/.next/server/pages/404.html +1 -1
- package/.next/server/pages/500.html +1 -1
- package/.next/server/pages/_document.js +1 -1
- package/.next/server/pages/_document.js.nft.json +1 -1
- package/.next/server/pages/_error.js +2 -2
- package/.next/server/pages/_error.js.nft.json +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/server/webpack-runtime.js +1 -1
- package/.next/static/chunks/1d2d5650.1ef8611b5325bd83.js +18 -0
- package/.next/static/chunks/3697.4d6d86c5f0caf73e.js +1 -0
- package/.next/static/chunks/4465-aaba60a6355de914.js +1 -0
- package/.next/static/chunks/6078.47ce88bee96cfaee.js +1 -0
- package/.next/static/chunks/6607-405ce4d15e595f4a.js +1 -0
- package/.next/static/chunks/7008-71ebb186f0549f41.js +1 -0
- package/.next/static/chunks/9331-fcdd652218ac6f68.js +1 -0
- package/.next/static/chunks/app/_not-found/page-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/backlog/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/browse-directory/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/events/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/filesystem/browse/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/issues/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/observability/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/orchestrators/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/projects/[id]/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/projects/reload/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/projects/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/prs/[id]/merge/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/runtime/terminal/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/kill/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/message/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/remap/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/restore/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/sessions/[id]/send/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/sessions/patches/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/sessions/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/setup-labels/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/spawn/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/verify/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/api/webhooks/[...slug]/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/apple-icon/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/dev/terminal-test/{page-4912fa9e6459f124.js → page-5765f0465db56fed.js} +1 -1
- package/.next/static/chunks/app/icon/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/icon-192/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/icon-512/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/loading-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/manifest.webmanifest/route-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/orchestrators/page-4c190484788aaaa3.js +1 -0
- package/.next/static/chunks/app/page-d3b83ad5f09b6ec7.js +1 -0
- package/.next/static/chunks/app/projects/[projectId]/loading-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/projects/[projectId]/page-9f3dfbea006747cf.js +1 -0
- package/.next/static/chunks/app/projects/[projectId]/sessions/[id]/page-a7090a06948f9a6b.js +1 -0
- package/.next/static/chunks/app/projects/[projectId]/settings/page-219df6dcbc6d1107.js +1 -0
- package/.next/static/chunks/app/prs/page-a285e930235a23af.js +1 -0
- package/.next/static/chunks/app/sessions/[id]/loading-e2dea9178b4af8db.js +1 -0
- package/.next/static/chunks/app/sessions/[id]/page-98f398b822092218.js +1 -0
- package/.next/static/chunks/app/test-direct/{page-1fd63edb9a9ca8be.js → page-f9bff7d7b4dfe728.js} +1 -1
- package/.next/static/chunks/{webpack-ab6c08c78ffc8113.js → webpack-d4ff5ed5e153ca3e.js} +1 -1
- package/.next/static/css/577ea7f5ad4f0576.css +1 -0
- package/.next/static/css/659eccb5db697b76.css +1 -0
- package/.next/static/q6yh3n8jgvyI9JIbexzuH/_buildManifest.js +1 -0
- package/next.config.js +5 -1
- package/package.json +17 -14
- package/.next/server/chunks/100.js +0 -1
- package/.next/server/chunks/106.js +0 -1
- package/.next/server/chunks/172.js +0 -9
- package/.next/server/chunks/180.js +0 -25
- package/.next/server/chunks/333.js +0 -1
- package/.next/server/chunks/367.js +0 -3
- package/.next/server/chunks/627.js +0 -408
- package/.next/server/chunks/886.js +0 -384
- package/.next/server/chunks/907.js +0 -1
- package/.next/static/OyzSw2fQpoJHXyoBWoZ2X/_buildManifest.js +0 -1
- package/.next/static/chunks/6923-ef8434dfec6f2a3c.js +0 -1
- package/.next/static/chunks/7097.fc904e5f313c4994.js +0 -1
- package/.next/static/chunks/8785-6b4b3ff260617997.js +0 -1
- package/.next/static/chunks/9478.656c9c263bc55893.js +0 -1
- package/.next/static/chunks/app/_not-found/page-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/backlog/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/events/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/issues/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/observability/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/orchestrators/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/projects/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/prs/[id]/merge/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/runtime/terminal/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/kill/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/message/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/remap/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/restore/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/sessions/[id]/send/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/sessions/patches/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/sessions/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/setup-labels/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/spawn/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/verify/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/api/webhooks/[...slug]/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/apple-icon/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/icon/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/icon-192/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/icon-512/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/loading-019391920005654f.js +0 -1
- package/.next/static/chunks/app/manifest.webmanifest/route-019391920005654f.js +0 -1
- package/.next/static/chunks/app/orchestrators/page-4da04720a09483d2.js +0 -1
- package/.next/static/chunks/app/page-abf3e3c98cac072f.js +0 -1
- package/.next/static/chunks/app/prs/page-46455c406183ffbf.js +0 -1
- package/.next/static/chunks/app/sessions/[id]/loading-019391920005654f.js +0 -1
- package/.next/static/chunks/app/sessions/[id]/page-7eb67fd32f39b15f.js +0 -1
- package/.next/static/chunks/df4ed4d4.b6997d8b8ce9d79b.js +0 -3
- package/.next/static/css/6ef2fa08dd043252.css +0 -1
- package/.next/static/css/a5398483e6b75ad3.css +0 -1
- /package/.next/static/{OyzSw2fQpoJHXyoBWoZ2X → q6yh3n8jgvyI9JIbexzuH}/_ssgManifest.js +0 -0
|
@@ -1,384 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=886,exports.ids=[886],exports.modules={9886:(a,b,c)=>{c.d(b,{ix:()=>aP,wp:()=>aR,Z1:()=>aG,uj:()=>aQ,Az:()=>aK});var d=c(43851),e=c(31421),f=c(57975),g=c(58500),h=c(77598),i=c(73024),j=c(48161),k=c(76760);let l=(0,f.promisify)(e.execFile),m=/^[a-zA-Z0-9_-]+$/;async function n(...a){let{stdout:b}=await l("tmux",a,{timeout:5e3});return b.trimEnd()}let o={manifest:{name:"tmux",slot:"runtime",description:"Runtime plugin: tmux sessions",version:"0.1.0"},create:function(){return{name:"tmux",async create(a){var b=a.sessionId;if(!m.test(b))throw Error(`Invalid session ID "${b}": must match ${m}`);let c=a.sessionId,e=[];for(let[b,c]of Object.entries(a.environment??{}))e.push("-e",`${b}=${c}`);await n("new-session","-d","-s",c,"-c",a.workspacePath,...e);try{if(a.launchCommand.length>200){let b=function(a){let b=(0,k.join)((0,j.tmpdir)(),`ao-launch-${(0,h.randomUUID)()}.sh`),c=`#!/usr/bin/env bash
|
|
2
|
-
rm -- "$0" 2>/dev/null || true
|
|
3
|
-
${a}
|
|
4
|
-
`;return(0,i.writeFileSync)(b,c,{encoding:"utf-8",mode:448}),`bash ${(0,d.TQ)(b)}`}(a.launchCommand);await n("send-keys","-t",c,"-l",b),await (0,g.setTimeout)(300),await n("send-keys","-t",c,"Enter")}else await n("send-keys","-t",c,a.launchCommand,"Enter")}catch(b){try{await n("kill-session","-t",c)}catch{}let a=b instanceof Error?b.message:String(b);throw Error(`Failed to send launch command to session "${c}": ${a}`,{cause:b})}return{id:c,runtimeName:"tmux",data:{createdAt:Date.now(),workspacePath:a.workspacePath}}},async destroy(a){try{await n("kill-session","-t",a.id)}catch{}},async sendMessage(a,b){if(await n("send-keys","-t",a.id,"C-u"),b.includes("\n")||b.length>200){let c=`ao-${(0,h.randomUUID)()}`,d=(0,k.join)((0,j.tmpdir)(),`ao-send-${(0,h.randomUUID)()}.txt`);(0,i.writeFileSync)(d,b,{encoding:"utf-8",mode:384});try{await n("load-buffer","-b",c,d),await n("paste-buffer","-b",c,"-t",a.id,"-d")}finally{try{(0,i.unlinkSync)(d)}catch{}try{await n("delete-buffer","-b",c)}catch{}}}else await n("send-keys","-t",a.id,"-l",b);await (0,g.setTimeout)(300),await n("send-keys","-t",a.id,"Enter")},async getOutput(a,b=50){try{return await n("capture-pane","-t",a.id,"-p","-S",`-${b}`)}catch{return""}},async isAlive(a){try{return await n("has-session","-t",a.id),!0}catch{return!1}},async getMetrics(a){let b=a.data.createdAt??Date.now();return{uptimeMs:Date.now()-b}},getAttachInfo:async a=>({type:"tmux",target:a.id,command:`tmux attach -t ${a.id}`})}}};var p=c(51455);let q=(0,f.promisify)(e.execFile),r=`#!/usr/bin/env bash
|
|
5
|
-
# Metadata Updater Hook for Agent Orchestrator
|
|
6
|
-
#
|
|
7
|
-
# This PostToolUse hook automatically updates session metadata when:
|
|
8
|
-
# - gh pr create: extracts PR URL and writes to metadata
|
|
9
|
-
# - git checkout -b / git switch -c: extracts branch name and writes to metadata
|
|
10
|
-
# - gh pr merge: updates status to "merged"
|
|
11
|
-
|
|
12
|
-
set -euo pipefail
|
|
13
|
-
|
|
14
|
-
# Configuration
|
|
15
|
-
AO_DATA_DIR="\${AO_DATA_DIR:-$HOME/.ao-sessions}"
|
|
16
|
-
|
|
17
|
-
# Read hook input from stdin
|
|
18
|
-
input=$(cat)
|
|
19
|
-
|
|
20
|
-
# Extract fields from JSON (using jq if available, otherwise basic parsing)
|
|
21
|
-
if command -v jq &>/dev/null; then
|
|
22
|
-
tool_name=$(echo "$input" | jq -r '.tool_name // empty')
|
|
23
|
-
command=$(echo "$input" | jq -r '.tool_input.command // empty')
|
|
24
|
-
output=$(echo "$input" | jq -r '.tool_response // empty')
|
|
25
|
-
exit_code=$(echo "$input" | jq -r '.exit_code // 0')
|
|
26
|
-
else
|
|
27
|
-
# Fallback: basic JSON parsing without jq
|
|
28
|
-
tool_name=$(echo "$input" | grep -o '"tool_name"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4 || echo "")
|
|
29
|
-
command=$(echo "$input" | grep -o '"command"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4 || echo "")
|
|
30
|
-
output=$(echo "$input" | grep -o '"tool_response"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4 || echo "")
|
|
31
|
-
exit_code=$(echo "$input" | grep -o '"exit_code"[[:space:]]*:[[:space:]]*[0-9]*' | grep -o '[0-9]*$' || echo "0")
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
# Only process successful commands (exit code 0)
|
|
35
|
-
if [[ "$exit_code" -ne 0 ]]; then
|
|
36
|
-
echo '{}'
|
|
37
|
-
exit 0
|
|
38
|
-
fi
|
|
39
|
-
|
|
40
|
-
# Only process Bash tool calls
|
|
41
|
-
if [[ "$tool_name" != "Bash" ]]; then
|
|
42
|
-
echo '{}' # Empty JSON output
|
|
43
|
-
exit 0
|
|
44
|
-
fi
|
|
45
|
-
|
|
46
|
-
# Validate AO_SESSION is set
|
|
47
|
-
if [[ -z "\${AO_SESSION:-}" ]]; then
|
|
48
|
-
echo '{"systemMessage": "AO_SESSION environment variable not set, skipping metadata update"}'
|
|
49
|
-
exit 0
|
|
50
|
-
fi
|
|
51
|
-
|
|
52
|
-
# Construct metadata file path
|
|
53
|
-
# AO_DATA_DIR is already set to the project-specific sessions directory
|
|
54
|
-
metadata_file="$AO_DATA_DIR/$AO_SESSION"
|
|
55
|
-
|
|
56
|
-
# Ensure metadata file exists
|
|
57
|
-
if [[ ! -f "$metadata_file" ]]; then
|
|
58
|
-
echo '{"systemMessage": "Metadata file not found: '"$metadata_file"'"}'
|
|
59
|
-
exit 0
|
|
60
|
-
fi
|
|
61
|
-
|
|
62
|
-
# Update a single key in metadata
|
|
63
|
-
update_metadata_key() {
|
|
64
|
-
local key="$1"
|
|
65
|
-
local value="$2"
|
|
66
|
-
|
|
67
|
-
# Create temp file
|
|
68
|
-
local temp_file="\${metadata_file}.tmp"
|
|
69
|
-
|
|
70
|
-
# Escape special sed characters in value (& | / \\)
|
|
71
|
-
local escaped_value=$(echo "$value" | sed 's/[&|\\/]/\\\\&/g')
|
|
72
|
-
|
|
73
|
-
# Check if key already exists
|
|
74
|
-
if grep -q "^$key=" "$metadata_file" 2>/dev/null; then
|
|
75
|
-
# Update existing key
|
|
76
|
-
sed "s|^$key=.*|$key=$escaped_value|" "$metadata_file" > "$temp_file"
|
|
77
|
-
else
|
|
78
|
-
# Append new key
|
|
79
|
-
cp "$metadata_file" "$temp_file"
|
|
80
|
-
echo "$key=$value" >> "$temp_file"
|
|
81
|
-
fi
|
|
82
|
-
|
|
83
|
-
# Atomic replace
|
|
84
|
-
mv "$temp_file" "$metadata_file"
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
# ============================================================================
|
|
88
|
-
# Command Detection and Parsing
|
|
89
|
-
# ============================================================================
|
|
90
|
-
|
|
91
|
-
# Strip leading directory-change prefixes so that commands like
|
|
92
|
-
# cd ~/.worktrees/project && gh pr create ...
|
|
93
|
-
# are correctly detected. Agents frequently cd into a worktree first.
|
|
94
|
-
# Store the regex pattern in a variable for clarity (avoids shell quoting confusion).
|
|
95
|
-
# Uses space-padded (&&|;) to avoid breaking on paths containing & or ; chars.
|
|
96
|
-
cd_prefix_pattern='^[[:space:]]*cd[[:space:]]+.*[[:space:]]+(&&|;)[[:space:]]+(.*)'
|
|
97
|
-
clean_command="$command"
|
|
98
|
-
while [[ "$clean_command" =~ ^[[:space:]]*cd[[:space:]] ]]; do
|
|
99
|
-
if [[ "$clean_command" =~ $cd_prefix_pattern ]]; then
|
|
100
|
-
clean_command="\${BASH_REMATCH[2]}"
|
|
101
|
-
else
|
|
102
|
-
break
|
|
103
|
-
fi
|
|
104
|
-
done
|
|
105
|
-
|
|
106
|
-
# Detect: gh pr create
|
|
107
|
-
if [[ "$clean_command" =~ ^gh[[:space:]]+pr[[:space:]]+create ]]; then
|
|
108
|
-
# Extract PR URL from output
|
|
109
|
-
pr_url=$(echo "$output" | grep -Eo 'https://github[.]com/[^/]+/[^/]+/pull/[0-9]+' | head -1)
|
|
110
|
-
|
|
111
|
-
if [[ -n "$pr_url" ]]; then
|
|
112
|
-
update_metadata_key "pr" "$pr_url"
|
|
113
|
-
update_metadata_key "status" "pr_open"
|
|
114
|
-
echo '{"systemMessage": "Updated metadata: PR created at '"$pr_url"'"}'
|
|
115
|
-
exit 0
|
|
116
|
-
fi
|
|
117
|
-
fi
|
|
118
|
-
|
|
119
|
-
# Detect: git checkout -b <branch> or git switch -c <branch>
|
|
120
|
-
if [[ "$clean_command" =~ ^git[[:space:]]+checkout[[:space:]]+-b[[:space:]]+([^[:space:]]+) ]] || \\
|
|
121
|
-
[[ "$clean_command" =~ ^git[[:space:]]+switch[[:space:]]+-c[[:space:]]+([^[:space:]]+) ]]; then
|
|
122
|
-
branch="\${BASH_REMATCH[1]}"
|
|
123
|
-
|
|
124
|
-
if [[ -n "$branch" ]]; then
|
|
125
|
-
update_metadata_key "branch" "$branch"
|
|
126
|
-
echo '{"systemMessage": "Updated metadata: branch = '"$branch"'"}'
|
|
127
|
-
exit 0
|
|
128
|
-
fi
|
|
129
|
-
fi
|
|
130
|
-
|
|
131
|
-
# Detect: git checkout <branch> (without -b) or git switch <branch> (without -c)
|
|
132
|
-
# Only update if the branch name looks like a feature branch (contains / or -)
|
|
133
|
-
if [[ "$clean_command" =~ ^git[[:space:]]+checkout[[:space:]]+([^[:space:]-]+[/-][^[:space:]]+) ]] || \\
|
|
134
|
-
[[ "$clean_command" =~ ^git[[:space:]]+switch[[:space:]]+([^[:space:]-]+[/-][^[:space:]]+) ]]; then
|
|
135
|
-
branch="\${BASH_REMATCH[1]}"
|
|
136
|
-
|
|
137
|
-
# Avoid updating for checkout of commits/tags
|
|
138
|
-
if [[ -n "$branch" && "$branch" != "HEAD" ]]; then
|
|
139
|
-
update_metadata_key "branch" "$branch"
|
|
140
|
-
echo '{"systemMessage": "Updated metadata: branch = '"$branch"'"}'
|
|
141
|
-
exit 0
|
|
142
|
-
fi
|
|
143
|
-
fi
|
|
144
|
-
|
|
145
|
-
# Detect: gh pr merge
|
|
146
|
-
if [[ "$clean_command" =~ ^gh[[:space:]]+pr[[:space:]]+merge ]]; then
|
|
147
|
-
update_metadata_key "status" "merged"
|
|
148
|
-
echo '{"systemMessage": "Updated metadata: status = merged"}'
|
|
149
|
-
exit 0
|
|
150
|
-
fi
|
|
151
|
-
|
|
152
|
-
# No matching command, exit silently
|
|
153
|
-
echo '{}'
|
|
154
|
-
exit 0
|
|
155
|
-
`;function s(a){return a.replace(/\\/g,"/").replace(/:/g,"").replace(/[/.]/g,"-")}async function t(a){let b;try{b=await (0,p.readdir)(a)}catch{return null}let c=b.filter(a=>a.endsWith(".jsonl")&&!a.startsWith("agent-"));if(0===c.length)return null;let d=await Promise.all(c.map(async b=>{let c=(0,k.join)(a,b);try{let a=await (0,p.stat)(c);return{path:c,mtime:a.mtimeMs}}catch{return{path:c,mtime:0}}}));return d.sort((a,b)=>b.mtime-a.mtime),d[0]?.path??null}async function u(a,b=131072){let c,d;try{let{size:e=0}=await (0,p.stat)(a);if(d=Math.max(0,e-b),0===d)c=await (0,p.readFile)(a,"utf-8");else{let b=await (0,p.open)(a,"r");try{let a=e-d,f=Buffer.allocUnsafe(a);await b.read(f,0,a,d),c=f.toString("utf-8")}finally{await b.close()}}}catch{return[]}let e=c.indexOf("\n"),f=d>0&&e>=0?c.slice(e+1):c,g=[];for(let a of f.split("\n")){let b=a.trim();if(b)try{let a=JSON.parse(b);"object"!=typeof a||null===a||Array.isArray(a)||g.push(a)}catch{}}return g}let v=null;async function w(){let a=Date.now();if(v&&a-v.timestamp<5e3)return v.promise?v.promise:v.output;let b=q("ps",["-eo","pid,tty,args"],{timeout:5e3}).then(({stdout:a})=>(v?.promise===b&&(v={output:a,timestamp:Date.now()}),a));v={output:"",timestamp:a,promise:b};try{return await b}catch{return v?.promise===b&&(v=null),""}}async function x(a){try{if("tmux"===a.runtimeName&&a.id){let{stdout:b}=await q("tmux",["list-panes","-t",a.id,"-F","#{pane_tty}"],{timeout:5e3}),c=b.trim().split("\n").map(a=>a.trim()).filter(Boolean);if(0===c.length)return null;let d=await w();if(!d)return null;let e=new Set(c.map(a=>a.replace(/^\/dev\//,""))),f=/(?:^|\/)claude(?:\s|$)/;for(let a of d.split("\n")){let b=a.trimStart().split(/\s+/);if(b.length<3||!e.has(b[1]??""))continue;let c=b.slice(2).join(" ");if(f.test(c))return parseInt(b[0]??"0",10)}return null}let b=a.data.pid,c="number"==typeof b?b:Number(b);if(Number.isFinite(c)&&c>0)try{return process.kill(c,0),c}catch(a){if(a instanceof Error&&"code"in a&&"EPERM"===a.code)return c}return null}catch{return null}}async function y(a,b){let c=(0,k.join)(a,".claude"),d=(0,k.join)(c,"settings.json"),e=(0,k.join)(c,"metadata-updater.sh");try{await (0,p.mkdir)(c,{recursive:!0})}catch{}await (0,p.writeFile)(e,r,"utf-8"),await (0,p.chmod)(e,493);let f={};if((0,i.existsSync)(d))try{let a=await (0,p.readFile)(d,"utf-8");f=JSON.parse(a)}catch{}let g=f.hooks??{},h=g.PostToolUse??[],j=-1,l=-1;for(let a=0;a<h.length;a++){let b=h[a];if("object"!=typeof b||null===b||Array.isArray(b))continue;let c=b.hooks;if(Array.isArray(c)){for(let b=0;b<c.length;b++){let d=c[b];if(!("object"!=typeof d||null===d||Array.isArray(d))&&"string"==typeof d.command&&d.command.includes("metadata-updater.sh")){j=a,l=b;break}}if(j>=0)break}}-1===j?h.push({matcher:"Bash",hooks:[{type:"command",command:b,timeout:5e3}]}):h[j].hooks[l].command=b,g.PostToolUse=h,f.hooks=g,await (0,p.writeFile)(d,JSON.stringify(f,null,2)+"\n","utf-8")}let z={manifest:{name:"claude-code",slot:"agent",description:"Agent plugin: Claude Code CLI",version:"0.1.0",displayName:"Claude Code"},create:function(){return{name:"claude-code",processName:"claude",promptDelivery:"post-launch",getLaunchCommand(a){let b=["claude"],c=(0,d.DD)(a.permissions);return("permissionless"===c||"auto-edit"===c)&&b.push("--dangerously-skip-permissions"),a.model&&b.push("--model",(0,d.TQ)(a.model)),a.systemPromptFile?b.push("--append-system-prompt",`"$(cat ${(0,d.TQ)(a.systemPromptFile)})"`):a.systemPrompt&&b.push("--append-system-prompt",(0,d.TQ)(a.systemPrompt)),b.join(" ")},getEnvironment(a){let b={};return b.CLAUDECODE="",b.AO_SESSION_ID=a.sessionId,a.issueId&&(b.AO_ISSUE_ID=a.issueId),b},detectActivity:a=>(function(a){if(!a.trim())return"idle";let b=a.trim().split("\n"),c=b[b.length-1]?.trim()??"";if(/^[❯>$#]\s*$/.test(c))return"idle";let d=b.slice(-5).join("\n");return/Do you want to proceed\?/i.test(d)||/\(Y\)es.*\(N\)o/i.test(d)||/bypass.*permissions/i.test(d)?"waiting_input":"active"})(a),isProcessRunning:async a=>null!==await x(a),async getActivityState(a,b){let c=b??d.PE,e=new Date;if(!a.runtimeHandle)return{state:"exited",timestamp:e};if(!await this.isProcessRunning(a.runtimeHandle))return Date.now()-a.createdAt.getTime()<6e4?{state:"idle",timestamp:a.createdAt}:{state:"exited",timestamp:e};if(!a.workspacePath)return null;let f=s(a.workspacePath),g=(0,k.join)((0,j.homedir)(),".claude","projects",f),h=await t(g);if(!h)return{state:"idle",timestamp:a.createdAt};let i=await (0,d.XI)(h);if(!i)return null;let l=Date.now()-i.modifiedAt.getTime(),m=i.modifiedAt,n=Math.min(d.V1,c);switch(i.lastType){case"user":case"tool_use":case"progress":default:if(l<=n)return{state:"active",timestamp:m};return{state:l>c?"idle":"ready",timestamp:m};case"assistant":case"system":case"summary":case"result":return{state:l>c?"idle":"ready",timestamp:m};case"permission_request":return{state:"waiting_input",timestamp:m};case"error":return{state:"blocked",timestamp:m}}},async getSessionInfo(a){if(!a.workspacePath)return null;let b=s(a.workspacePath),c=(0,k.join)((0,j.homedir)(),".claude","projects",b),d=await t(c);if(!d)return null;let e=await u(d);if(0===e.length)return null;let f=(0,k.basename)(d,".jsonl"),g=function(a){for(let b=a.length-1;b>=0;b--){let c=a[b];if(c?.type==="summary"&&c.summary)return{summary:c.summary,isFallback:!1}}for(let b of a)if(b?.type==="user"&&b.message?.content&&"string"==typeof b.message.content){let a=b.message.content.trim();if(a.length>0)return{summary:a.length>120?a.substring(0,120)+"...":a,isFallback:!0}}return null}(e);return{summary:g?.summary??null,summaryIsFallback:g?.isFallback,agentSessionId:f,cost:function(a){let b=0,c=0,d=0;for(let e of a)"number"==typeof e.costUSD?d+=e.costUSD:"number"==typeof e.estimatedCostUsd&&(d+=e.estimatedCostUsd),e.usage?(b+=e.usage.input_tokens??0,b+=e.usage.cache_read_input_tokens??0,b+=e.usage.cache_creation_input_tokens??0,c+=e.usage.output_tokens??0):("number"==typeof e.inputTokens&&(b+=e.inputTokens),"number"==typeof e.outputTokens&&(c+=e.outputTokens));if(0!==b||0!==c||0!==d)return 0===d&&(b>0||c>0)&&(d=b/1e6*3+c/1e6*15),{inputTokens:b,outputTokens:c,estimatedCostUsd:d}}(e)}},async getRestoreCommand(a,b){if(!a.workspacePath)return null;let c=s(a.workspacePath),e=(0,k.join)((0,j.homedir)(),".claude","projects",c),f=await t(e);if(!f)return null;let g=(0,k.basename)(f,".jsonl");if(!g)return null;let h=["claude","--resume",(0,d.TQ)(g)],i=(0,d.DD)(b.agentConfig?.permissions);return("permissionless"===i||"auto-edit"===i)&&h.push("--dangerously-skip-permissions"),b.agentConfig?.model&&h.push("--model",(0,d.TQ)(b.agentConfig.model)),h.join(" ")},async setupWorkspaceHooks(a,b){await y(a,".claude/metadata-updater.sh")},async postLaunchSetup(a){a.workspacePath&&await y(a.workspacePath,".claude/metadata-updater.sh")}}},detect:function(){try{return(0,e.execFileSync)("claude",["--version"],{stdio:"ignore"}),!0}catch{return!1}}},A=(0,f.promisify)(e.execFile);async function B(a){try{let{stdout:b}=await A("git",["log","--since=60 seconds ago","--format=%H"],{cwd:a,timeout:5e3});return b.trim().length>0}catch{return!1}}async function C(a){try{let b=(0,k.join)(a,".cursor"),c=(0,k.join)(b,"chat.md");if((await (0,p.lstat)(b)).isSymbolicLink())return null;try{if((await (0,p.lstat)(c)).isSymbolicLink())return null;return(await (0,p.stat)(c)).mtime}catch{return await (0,p.access)(b,i.constants.R_OK),(await (0,p.stat)(b)).mtime}}catch{return null}}async function D(a){try{let b=(0,k.join)(a,".cursor"),c=(0,k.join)(b,"chat.md");try{if((await (0,p.lstat)(b)).isSymbolicLink()||(await (0,p.lstat)(c)).isSymbolicLink())return null;let d=(0,k.resolve)(c),e=(0,k.resolve)(a);if(!d.startsWith(e))return null;for(let a of(await (0,p.readFile)(c,"utf-8")).split("\n")){let b=a.trim();if(b.length>0&&!b.startsWith("#"))return b.length>120?b.substring(0,120)+"...":b}}catch{}}catch{}return null}let E={manifest:{name:"cursor",slot:"agent",description:"Agent plugin: Cursor Agent CLI",version:"0.1.0",displayName:"Cursor"},create:function(){return{name:"cursor",processName:"agent",getLaunchCommand(a){let b=["agent"],c=(0,d.DD)(a.permissions);if(("permissionless"===c||"auto-edit"===c)&&b.push("--force","--sandbox","disabled","--approve-mcps"),a.model&&b.push("--model",(0,d.TQ)(a.model)),a.systemPromptFile)try{if(!(0,i.lstatSync)(a.systemPromptFile).isSymbolicLink())return a.prompt?b.push("--",`"$(cat ${(0,d.TQ)(a.systemPromptFile)}; printf '\\n\\n'; printf %s ${(0,d.TQ)(a.prompt)})"`):b.push("--",`"$(cat ${(0,d.TQ)(a.systemPromptFile)})"`),b.join(" ")}catch{}let e="";return a.systemPrompt&&(e=a.systemPrompt.trim()),a.prompt&&(e=e?e+"\n\n"+a.prompt:a.prompt),e&&b.push("--",(0,d.TQ)(e)),b.join(" ")},getEnvironment(a){let b={};return b.AO_SESSION_ID=a.sessionId,a.issueId&&(b.AO_ISSUE_ID=a.issueId),b.PATH=(0,d.Te)(process.env.PATH),b.GH_PATH=d.C3,b},detectActivity(a){if(!a.trim())return"idle";let b=a.trim().split("\n"),c=b[b.length-1]?.trim()??"",d=b.slice(-5).join("\n");return/\(Y\)es.*\(N\)o/i.test(d)||/Approve.*changes\?/i.test(d)||/Continue\?/i.test(d)||/\[Yes\].*\[No\]/i.test(d)||/proceed\?/i.test(d)||/Press Enter to continue/i.test(d)?"waiting_input":/^[>$#]\s*$/.test(c)||/^agent>\s*$/.test(c)||/^\[agent\]\s*$/.test(c)?"idle":"active"},async getActivityState(a,b){let c=b??d.PE,e=new Date;if(!a.runtimeHandle||!await this.isProcessRunning(a.runtimeHandle))return{state:"exited",timestamp:e};if(!a.workspacePath)return null;let f=await (0,d.Ah)(a.workspacePath),g=(0,d.Bm)(f);if(g)return g;if(await B(a.workspacePath))return{state:"active"};let h=await C(a.workspacePath);if(h){let a=Date.now()-h.getTime();return a<=Math.min(d.V1,c)?{state:"active",timestamp:h}:a<=c?{state:"ready",timestamp:h}:{state:"idle",timestamp:h}}let i=Math.min(d.V1,c),j=(0,d.Vo)(f,i,c);return j||null},async recordActivity(a,b){a.workspacePath&&await (0,d.Jy)(a.workspacePath,b,a=>this.detectActivity(a))},async isProcessRunning(a){try{if("tmux"===a.runtimeName&&a.id){let{stdout:b}=await A("tmux",["list-panes","-t",a.id,"-F","#{pane_tty}"],{timeout:3e4}),c=b.trim().split("\n").map(a=>a.trim()).filter(Boolean);if(0===c.length)return!1;let{stdout:d}=await A("ps",["-eo","pid,tty,args"],{timeout:3e4}),e=new Set(c.map(a=>a.replace(/^\/dev\//,""))),f=/(?:^|\/)\.?agent\b(?:\s|$)/;for(let a of d.split("\n")){let b=a.trimStart().split(/\s+/);if(b.length<3||!e.has(b[1]??""))continue;let c=b.slice(2).join(" ");if(f.test(c))return!0}return!1}let b=a.data.pid,c="number"==typeof b?b:Number(b);if(Number.isFinite(c)&&c>0)try{return process.kill(c,0),!0}catch(a){if(a instanceof Error&&"code"in a&&"EPERM"===a.code)return!0}return!1}catch{return!1}},async getSessionInfo(a){if(!a.workspacePath)return null;let b=await D(a.workspacePath);return b?{summary:b,summaryIsFallback:!0,agentSessionId:null}:null},getRestoreCommand:async(a,b)=>null,async setupWorkspaceHooks(a,b){await (0,d.J0)(a)},async postLaunchSetup(a){a.workspacePath&&await (0,d.J0)(a.workspacePath)}}},detect:function(){try{let a=(0,e.execFileSync)("agent",["--help"],{encoding:"utf-8"}),b=a.includes("Cursor Agent"),c=a.includes("--approve-mcps")&&a.includes("--sandbox");return b||c}catch{return!1}}},F=(0,f.promisify)(e.execFile);function G(a){if("number"==typeof a){if(!Number.isFinite(a))return null;let b=new Date(a);return Number.isNaN(b.getTime())?null:b}if("string"!=typeof a)return null;let b=a.trim();if(0===b.length)return null;if(/^\d+$/.test(b)){let a=Number(b);if(!Number.isFinite(a))return null;let c=new Date(a);return Number.isNaN(c.getTime())?null:c}let c=Date.parse(b);return Number.isFinite(c)?new Date(c):null}async function H(a){try{let{stdout:b}=await F("opencode",["session","list","--format","json"],{timeout:3e4}),c=function(a){let b;try{b=JSON.parse(a)}catch{return[]}return Array.isArray(b)?b.filter(a=>!!a&&"object"==typeof a&&void 0!==(0,d.Hr)(a.id)):[]}(b);if(a.metadata?.opencodeSessionId){let b=c.find(b=>b.id===a.metadata.opencodeSessionId);if(b)return b}let e=c.filter(b=>b.title===`AO:${a.id}`);if(0===e.length)return null;if(1===e.length)return e[0];return e.reduce((a,b)=>{let c=G(a.updated)?.getTime()??0;return(G(b.updated)?.getTime()??0)>c?b:a})}catch{return null}}let I={manifest:{name:"opencode",slot:"agent",description:"Agent plugin: OpenCode",version:"0.1.0",displayName:"OpenCode"},create:function(){return{name:"opencode",processName:"opencode",getLaunchCommand(a){let b,c=[],e=[],f=(0,d.Hr)(a.projectConfig.agentConfig?.opencodeSessionId);if(f&&c.push("--session",(0,d.TQ)(f)),a.subagent&&e.push("--agent",(0,d.TQ)(a.subagent)),a.prompt?b=a.systemPromptFile?`"$(cat ${(0,d.TQ)(a.systemPromptFile)}; printf '\\n\\n'; printf %s ${(0,d.TQ)(a.prompt)})"`:a.systemPrompt?(0,d.TQ)(`${a.systemPrompt}
|
|
156
|
-
|
|
157
|
-
${a.prompt}`):(0,d.TQ)(a.prompt):a.systemPromptFile?b=`"$(cat ${(0,d.TQ)(a.systemPromptFile)})"`:a.systemPrompt&&(b=(0,d.TQ)(a.systemPrompt)),a.model&&e.push("--model",(0,d.TQ)(a.model)),!f){let c=["--format","json","--title",(0,d.TQ)(`AO:${a.sessionId}`),...e],f=`
|
|
158
|
-
let buffer = '';
|
|
159
|
-
let captured = null;
|
|
160
|
-
process.stdin.on('data', chunk => {
|
|
161
|
-
buffer += chunk;
|
|
162
|
-
const lines = buffer.split('\\n');
|
|
163
|
-
buffer = lines.pop() || '';
|
|
164
|
-
for (const line of lines) {
|
|
165
|
-
if (captured) continue;
|
|
166
|
-
const trimmed = line.trim();
|
|
167
|
-
if (!trimmed) continue;
|
|
168
|
-
try {
|
|
169
|
-
const obj = JSON.parse(trimmed);
|
|
170
|
-
const sid = (typeof obj.session_id === 'string' && obj.session_id) || (typeof obj.sessionID === 'string' && obj.sessionID);
|
|
171
|
-
if (sid && /^ses_[A-Za-z0-9_-]+$/.test(sid)) {
|
|
172
|
-
captured = sid;
|
|
173
|
-
}
|
|
174
|
-
} catch {}
|
|
175
|
-
}
|
|
176
|
-
}).on('end', () => {
|
|
177
|
-
if (buffer.trim()) {
|
|
178
|
-
try {
|
|
179
|
-
const obj = JSON.parse(buffer.trim());
|
|
180
|
-
const sid = (typeof obj.session_id === 'string' && obj.session_id) || (typeof obj.sessionID === 'string' && obj.sessionID);
|
|
181
|
-
if (sid && /^ses_[A-Za-z0-9_-]+$/.test(sid)) {
|
|
182
|
-
captured = sid;
|
|
183
|
-
}
|
|
184
|
-
} catch {}
|
|
185
|
-
}
|
|
186
|
-
if (captured) {
|
|
187
|
-
process.stdout.write(captured);
|
|
188
|
-
process.exit(0);
|
|
189
|
-
}
|
|
190
|
-
process.exit(1);
|
|
191
|
-
});
|
|
192
|
-
`.trim().replace(/\n/g," ").replace(/\s+/g," "),g=`
|
|
193
|
-
let input = '';
|
|
194
|
-
process.stdin.on('data', c => input += c).on('end', () => {
|
|
195
|
-
const title = process.argv[1];
|
|
196
|
-
let rows;
|
|
197
|
-
try { rows = JSON.parse(input); } catch { process.exit(1); }
|
|
198
|
-
if (!Array.isArray(rows)) process.exit(1);
|
|
199
|
-
const isValidId = id => /^ses_[A-Za-z0-9_-]+$/.test(id);
|
|
200
|
-
const timestamp = value => {
|
|
201
|
-
if (typeof value === 'number' && Number.isFinite(value)) return value;
|
|
202
|
-
if (typeof value === 'string') {
|
|
203
|
-
const parsed = Date.parse(value);
|
|
204
|
-
return Number.isNaN(parsed) ? Number.NEGATIVE_INFINITY : parsed;
|
|
205
|
-
}
|
|
206
|
-
return Number.NEGATIVE_INFINITY;
|
|
207
|
-
};
|
|
208
|
-
const matches = rows
|
|
209
|
-
.filter(r => r && r.title === title && typeof r.id === 'string' && isValidId(r.id))
|
|
210
|
-
.sort((a, b) => {
|
|
211
|
-
const ta = timestamp(a.updated);
|
|
212
|
-
const tb = timestamp(b.updated);
|
|
213
|
-
if (ta === tb) return 0;
|
|
214
|
-
return tb - ta;
|
|
215
|
-
});
|
|
216
|
-
if (matches.length === 0) process.exit(1);
|
|
217
|
-
process.stdout.write(matches[0].id);
|
|
218
|
-
});
|
|
219
|
-
`.trim().replace(/\n/g," ").replace(/\s+/g," "),h=["opencode","run",...c,"--command","true"].join(" "),i=[...b?["--prompt",b]:[],...e],j=i.length>0?` ${i.join(" ")}`:"",k=(0,d.TQ)(`failed to discover OpenCode session ID for AO:${a.sessionId}`);return`SES_ID=$(${h} | node -e ${(0,d.TQ)(f)}); if [ -z "$SES_ID" ]; then SES_ID=$(opencode session list --format json | node -e ${(0,d.TQ)(g)} ${(0,d.TQ)(`AO:${a.sessionId}`)}); fi; [ -n "$SES_ID" ] && exec opencode --session "$SES_ID"${j}; echo ${k} >&2; exit 1`}return b&&c.push("--prompt",b),c.push(...e),["opencode",...c].join(" ")},getEnvironment(a){let b={};return b.AO_SESSION_ID=a.sessionId,a.issueId&&(b.AO_ISSUE_ID=a.issueId),b.PATH=(0,d.Te)(process.env.PATH),b.GH_PATH=d.C3,b},detectActivity(a){if(!a.trim())return"idle";let b=a.trim().split("\n"),c=b[b.length-1]?.trim()??"";if(/^[>$#]\s*$/.test(c))return"idle";let d=b.slice(-5).join("\n");return/\(Y\)es.*\(N\)o/i.test(d)||/approval required/i.test(d)||/Do you want to proceed\?/i.test(d)||/Allow .+\?/i.test(d)?"waiting_input":"active"},async getActivityState(a,b){let c=b??d.PE,e=Math.min(d.V1,c),f=new Date;if(!a.runtimeHandle||!await this.isProcessRunning(a.runtimeHandle))return{state:"exited",timestamp:f};let g=null;if(a.workspacePath){g=await (0,d.Ah)(a.workspacePath);let b=(0,d.Bm)(g);if(b)return b}let h=await H(a);if(h){let a=G(h.updated);if(a){let b=Math.max(0,Date.now()-a.getTime());return b<=e?{state:"active",timestamp:a}:b<=c?{state:"ready",timestamp:a}:{state:"idle",timestamp:a}}}let i=(0,d.Vo)(g,e,c);return i||null},async recordActivity(a,b){a.workspacePath&&await (0,d.Jy)(a.workspacePath,b,a=>this.detectActivity(a))},async isProcessRunning(a){try{if("tmux"===a.runtimeName&&a.id){let{stdout:b}=await F("tmux",["list-panes","-t",a.id,"-F","#{pane_tty}"],{timeout:3e4}),c=b.trim().split("\n").map(a=>a.trim()).filter(Boolean);if(0===c.length)return!1;let{stdout:d}=await F("ps",["-eo","pid,tty,args"],{timeout:3e4}),e=new Set(c.map(a=>a.replace(/^\/dev\//,""))),f=/(?:^|\/)opencode(?:\s|$)/;for(let a of d.split("\n")){let b=a.trimStart().split(/\s+/);if(b.length<3||!e.has(b[1]??""))continue;let c=b.slice(2).join(" ");if(f.test(c))return!0}return!1}let b=a.data.pid,c="number"==typeof b?b:Number(b);if(Number.isFinite(c)&&c>0)try{return process.kill(c,0),!0}catch(a){if(a instanceof Error&&"code"in a&&"EPERM"===a.code)return!0}return!1}catch{return!1}},async getSessionInfo(a){let b=await H(a);return b?{summary:b.title??null,summaryIsFallback:!0,agentSessionId:b.id}:null},async getRestoreCommand(a,b){let c=(0,d.Hr)(a.metadata?.opencodeSessionId)??(await H(a))?.id??null;if(!c)return null;let e=["opencode","--session",(0,d.TQ)(c)],f=b.agentConfig;return f?.model&&e.push("--model",(0,d.TQ)(f.model)),e.join(" ")},async setupWorkspaceHooks(a,b){await (0,d.J0)(a)},async postLaunchSetup(a){a.workspacePath&&await (0,d.J0)(a.workspacePath)}}},detect:function(){try{return(0,e.execFileSync)("opencode",["version"],{stdio:"ignore"}),!0}catch{return!1}}},J=(0,f.promisify)(e.execFile);async function K(a,...b){let{stdout:c}=await J("git",b,{cwd:a});return c.trimEnd()}async function L(a){try{return await K(a,"remote","get-url","origin"),!0}catch{return!1}}async function M(a,b){try{return await K(a,"rev-parse","--verify","--quiet",b),!0}catch{return!1}}async function N(a,b,c){if(c?.hasOrigin??await L(a)){if(c?.branch){let b=`origin/${c.branch}`;if(await M(a,b))return b}let d=`origin/${b}`;if(await M(a,d))return d}let d=`refs/heads/${b}`;if(await M(a,d))return d;throw Error(`Unable to resolve base ref for default branch "${b}"`)}let O=/^[a-zA-Z0-9_-]+$/;function P(a,b){if(!O.test(a))throw Error(`Invalid ${b} "${a}": must match ${O}`)}function Q(a){return a.startsWith("~/")?(0,k.join)((0,j.homedir)(),a.slice(2)):a}let R={manifest:{name:"worktree",slot:"workspace",description:"Workspace plugin: git worktrees",version:"0.1.0"},create:function(a){let b=a?.worktreeDir?Q(a.worktreeDir):(0,k.join)((0,j.homedir)(),".worktrees");return{name:"worktree",async create(a){P(a.projectId,"projectId"),P(a.sessionId,"sessionId");let c=Q(a.project.path),d=(0,k.join)(b,a.projectId),e=(0,k.join)(d,a.sessionId);(0,i.mkdirSync)(d,{recursive:!0});let f=await L(c);if(f)try{await K(c,"fetch","origin","--quiet")}catch{}let g=await N(c,a.project.defaultBranch,{hasOrigin:f});try{await K(c,"worktree","add","-b",a.branch,e,g)}catch(d){let b=d instanceof Error?d.message:String(d);if(!b.includes("already exists"))throw Error(`Failed to create worktree for branch "${a.branch}": ${b}`,{cause:d});await K(c,"worktree","add",e,g);try{await K(e,"checkout",a.branch)}catch(d){try{await K(c,"worktree","remove","--force",e)}catch{}let b=d instanceof Error?d.message:String(d);throw Error(`Failed to checkout branch "${a.branch}" in worktree: ${b}`,{cause:d})}}return{path:e,branch:a.branch,sessionId:a.sessionId,projectId:a.projectId}},async destroy(a){try{let b=await K(a,"rev-parse","--path-format=absolute","--git-common-dir"),c=(0,k.resolve)(b,"..");await K(c,"worktree","remove","--force",a)}catch{(0,i.existsSync)(a)&&(0,i.rmSync)(a,{recursive:!0,force:!0})}},async list(a){P(a,"projectId");let c=(0,k.join)(b,a);if(!(0,i.existsSync)(c))return[];let d=(0,i.readdirSync)(c,{withFileTypes:!0}).filter(a=>a.isDirectory()).map(a=>(0,k.join)(c,a.name));if(0===d.length)return[];let e="";for(let a of d)try{e=await K(a,"worktree","list","--porcelain");break}catch{continue}if(!e)return[];let f=[];for(let b of e.split("\n\n")){let d=b.trim().split("\n"),e="",g="";for(let a of d)a.startsWith("worktree ")?e=a.slice(9):a.startsWith("branch ")&&(g=a.slice(7).replace("refs/heads/",""));if(e&&(e===c||e.startsWith(c+"/"))){let b=(0,k.basename)(e);f.push({path:e,branch:g||"detached",sessionId:b,projectId:a})}}return f},async exists(a){if(!(0,i.existsSync)(a))return!1;try{return await J("git",["rev-parse","--is-inside-work-tree"],{cwd:a,timeout:3e4}),!0}catch{return!1}},async restore(a,b){let c=Q(a.project.path);try{await K(c,"worktree","prune")}catch{}let d=await L(c);if(d)try{await K(c,"fetch","origin","--quiet")}catch{}try{await K(c,"worktree","add",b,a.branch)}catch{let e=await N(c,a.project.defaultBranch,{branch:a.branch,hasOrigin:d});if(e.startsWith("origin/"))try{await K(c,"worktree","add","-b",a.branch,b,e)}catch{await K(c,"worktree","add","-b",a.branch,b,`refs/heads/${a.project.defaultBranch}`)}else await K(c,"worktree","add","-b",a.branch,b,e)}return{path:b,branch:a.branch,sessionId:a.sessionId,projectId:a.projectId}},async postCreate(a,b){let c=Q(b.path);if(b.symlinks)for(let d of b.symlinks){if(d.startsWith("/")||d.includes(".."))throw Error(`Invalid symlink path "${d}": must be a relative path without ".." segments`);let b=(0,k.join)(c,d),e=(0,k.resolve)(a.path,d);if(!e.startsWith(a.path+"/")&&e!==a.path)throw Error(`Symlink target "${d}" resolves outside workspace: ${e}`);if((0,i.existsSync)(b)){try{let a=(0,i.lstatSync)(e);(a.isSymbolicLink()||a.isFile()||a.isDirectory())&&(0,i.rmSync)(e,{recursive:!0,force:!0})}catch{}(0,i.mkdirSync)((0,k.dirname)(e),{recursive:!0}),(0,i.symlinkSync)(b,e)}}if(b.postCreate)for(let c of b.postCreate)await J("sh",["-c",c],{cwd:a.path})}}}};class S{constructor(a){if(this.cache=new Map,this.accessOrder=[],this.maxSize=a,a<=0)throw Error("LRUCache maxSize must be greater than 0")}get(a){if(this.cache.has(a))return this.moveToEnd(a),this.cache.get(a)}set(a,b){if(this.cache.has(a)){this.moveToEnd(a),this.cache.set(a,b);return}if(this.cache.set(a,b),this.accessOrder.push(a),this.accessOrder.length>this.maxSize){let a=this.accessOrder.shift();void 0!==a&&this.cache.delete(a)}}delete(a){this.cache.delete(a);let b=this.accessOrder.indexOf(a);-1!==b&&this.accessOrder.splice(b,1)}clear(){this.cache.clear(),this.accessOrder=[]}get size(){return this.cache.size}has(a){return this.cache.has(a)}keys(){return[...this.accessOrder]}moveToEnd(a){let b=this.accessOrder.indexOf(a);-1!==b&&(this.accessOrder.splice(b,1),this.accessOrder.push(a))}toMap(){return new Map(this.cache)}}let T=(0,f.promisify)(e.execFile),U={prList:new S(100),commitStatus:new S(500)},V=new S(200),W=new S(200);async function X(a){let b=[],c=!1;if(0===a.length)return{shouldRefresh:!1,details:["No PRs to check"]};let d=new Map;for(let b of a){let a=`${b.owner}/${b.repo}`;d.has(a)||d.set(a,[]);let c=d.get(a);c&&c.push(b)}let e=!1;for(let[a]of d){let[d,f]=a.split("/");await Z(d,f)&&(e=!0,c=!0,b.push(`PR list changed for ${a} (Guard 1)`))}if(!e)for(let d of a){let a=`${d.owner}/${d.repo}#${d.number}`,e=V.get(a);if(e&&null===e.headSha){c=!0,b.push(`First time seeing PR #${d.number} (Guard 2: no cached head SHA)`);continue}e&&e.headSha&&await $(d.owner,d.repo,e.headSha)&&(c=!0,b.push(`CI status changed for ${d.owner}/${d.repo}#${d.number} (Guard 2)`))}return{shouldRefresh:c,details:b}}async function Y(){try{await T("gh",["--version"],{timeout:5e3})}catch{let a=Error("gh CLI not available or not authenticated. GraphQL batch enrichment requires gh CLI to be installed and configured.");throw a.cause="GH_CLI_UNAVAILABLE",a}}async function Z(a,b){let c=`${a}/${b}`,d=U.prList.get(c),e=["api","--method","GET",`repos/${c}/pulls?state=open&sort=updated&direction=desc&per_page=1`,"-i"];d&&e.push("-H",`If-None-Match: ${d}`);try{let{stdout:c}=await T("gh",e,{timeout:1e4}),d=c.trim();if(d.includes("HTTP/1.1 304")||d.includes("HTTP/2 304"))return!1;let f=d.match(/etag:\s*(.+)/i);if(f){let c=f[1].trim();U.prList.set(`${a}/${b}`,c)}return!0}catch(b){let a=b instanceof Error?b.message:String(b);return console.warn(`[ETag Guard 1] PR list check failed for ${c}: ${a}`),!0}}async function $(a,b,c){let d=`${a}/${b}#${c}`,e=U.commitStatus.get(d),f=["api","--method","GET",`repos/${a}/${b}/commits/${c}/status`,"-i"];e&&f.push("-H",`If-None-Match: ${e}`);try{let{stdout:d}=await T("gh",f,{timeout:1e4}),e=d.trim();if(e.includes("HTTP/1.1 304")||e.includes("HTTP/2 304"))return!1;let g=e.match(/etag:\s*(.+)/i);if(g){let d=g[1].trim();U.commitStatus.set(`${a}/${b}#${c}`,d)}return!0}catch(b){let a=b instanceof Error?b.message:String(b);return console.warn(`[ETag Guard 2] Commit status check failed for ${d}: ${a}`),!0}}let _=`
|
|
220
|
-
title
|
|
221
|
-
state
|
|
222
|
-
additions
|
|
223
|
-
deletions
|
|
224
|
-
isDraft
|
|
225
|
-
mergeable
|
|
226
|
-
mergeStateStatus
|
|
227
|
-
reviewDecision
|
|
228
|
-
headRefName
|
|
229
|
-
headRefOid
|
|
230
|
-
reviews(last: 5) {
|
|
231
|
-
nodes {
|
|
232
|
-
author { login }
|
|
233
|
-
state
|
|
234
|
-
submittedAt
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
commits(last: 1) {
|
|
238
|
-
nodes {
|
|
239
|
-
commit {
|
|
240
|
-
statusCheckRollup {
|
|
241
|
-
state
|
|
242
|
-
contexts(first: 20) {
|
|
243
|
-
nodes {
|
|
244
|
-
... on CheckRun {
|
|
245
|
-
name
|
|
246
|
-
status
|
|
247
|
-
conclusion
|
|
248
|
-
detailsUrl
|
|
249
|
-
}
|
|
250
|
-
... on StatusContext {
|
|
251
|
-
context
|
|
252
|
-
state
|
|
253
|
-
targetUrl
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
pageInfo {
|
|
257
|
-
hasNextPage
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
`;async function aa(a){let{query:b,variables:c}=function(a){if(0===a.length)return{query:"",variables:{}};let b=[],c={};a.forEach((a,d)=>{let e=`pr${d}`;b.push(`
|
|
265
|
-
${e}: repository(owner: $${e}Owner, name: $${e}Name) {
|
|
266
|
-
... on Repository {
|
|
267
|
-
pullRequest(number: $${e}Number) { ${_} }
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
`),c[`${e}Owner`]=a.owner,c[`${e}Name`]=a.repo,c[`${e}Number`]=a.number});let d=Object.entries(c).map(([a,b])=>`$${a}: ${"number"==typeof b?"Int!":"String!"}`).join(", ");return{query:`query BatchPRs(${d}) {
|
|
271
|
-
${b.join("\n")}
|
|
272
|
-
}`,variables:c}}(a);if(!b||0===a.length)return{};await Y();let d=[];for(let[a,b]of Object.entries(c))"string"==typeof b?d.push("-f",`${a}=${b}`):d.push("-F",`${a}=${b}`);let e=["api","graphql",...d,"-f",`query=${b}`],f=3e4+Math.max(0,(a.length-10)*2e3),{stdout:g}=await T("gh",e,{maxBuffer:0xa00000,timeout:f}),h=JSON.parse(g.trim());if(h.errors&&h.errors.length>0){let a=h.errors.map(a=>a.message).join("; ");throw Error(`GraphQL query errors: ${a}`)}return h.data??{}}async function ab(a,b){let c=new Map;if(0===a.length)return c;let d=await X(a);if(!d.shouldRefresh){let e=[];for(let b of a){let a=`${b.owner}/${b.repo}#${b.number}`,d=W.get(a);d?c.set(a,d):e.push(b)}if(0===e.length)return b?.log("info",`[ETag Guard] Skipping GraphQL batch - all ${c.size} PRs cached. Reasons: ${d.details.join(", ")}`),c;b?.log("info",`[ETag Guard] Partial cache: ${c.size} cached, ${e.length} missing. Fetching missing PRs via GraphQL.`),a=e}let e=[];for(let b=0;b<a.length;b+=25)e.push(a.slice(b,b+25));for(let a=0;a<e.length;a++){let d,f=e[a],g=c.size,h=Date.now();try{let i=await aa(f);d=Date.now()-h,f.forEach((a,b)=>{let d=`pr${b}`,e=`${a.owner}/${a.repo}#${a.number}`,f=i[d];if(f?.pullRequest){let a=function(a){if(!a||"object"!=typeof a||void 0===a.state&&void 0===a.title&&void 0===a.reviews&&void 0===a.commits)return null;let b=function(a){let b="string"==typeof a?a.toUpperCase():"";return"MERGED"===b?"merged":"CLOSED"===b?"closed":"open"}(a.state),c="string"==typeof a.title?a.title:void 0,d="number"==typeof a.additions?a.additions:0,e="number"==typeof a.deletions?a.deletions:0,f=!0===a.isDraft,g="string"==typeof a.headRefOid?a.headRefOid:"string"==typeof a.headSha?a.headSha:null,h=a.mergeable,i="string"==typeof a.mergeStateStatus?a.mergeStateStatus.toUpperCase():"",j="CONFLICTING"===h,k="BEHIND"===i,l=function(a){let b="string"==typeof a?a.toUpperCase():"";return"APPROVED"===b?"approved":"CHANGES_REQUESTED"===b?"changes_requested":"REVIEW_REQUIRED"===b?"pending":"none"}(a.reviewDecision),m=a.commits,n=m?.nodes?.[0]?.commit?.statusCheckRollup,o=n?function(a){if(!a||"object"!=typeof a)return"none";let b="string"==typeof a.state?a.state.toUpperCase():"";return"SUCCESS"===b?"passing":"FAILURE"===b||"ERROR"===b?"failing":"PENDING"===b||"EXPECTED"===b?"pending":"TIMED_OUT"===b||"CANCELLED"===b||"ACTION_REQUIRED"===b?"failing":"QUEUED"===b||"IN_PROGRESS"===b||"WAITING"===b?"pending":"none"}(n):"none",p=n?.contexts,q=p?.pageInfo,r=null!=q&&"object"==typeof q&&!0===q.hasNextPage,s=p&&!r?function(a){if(!a||"object"!=typeof a)return[];let b=a.nodes;if(!Array.isArray(b))return[];let c=[];for(let a of b)if(a&&"object"==typeof a){if("string"==typeof a.name&&"string"==typeof a.status){let b,d=a.status.toUpperCase(),e="string"==typeof a.conclusion?a.conclusion.toUpperCase():null;b="COMPLETED"===d?"SUCCESS"===e?"passed":"SKIPPED"===e||"NEUTRAL"===e||"STALE"===e||"NOT_REQUIRED"===e||"NONE"===e?"skipped":"FAILURE"===e||"TIMED_OUT"===e||"CANCELLED"===e||"ACTION_REQUIRED"===e||"ERROR"===e?"failed":"skipped":"IN_PROGRESS"===d?"running":"pending",c.push({name:a.name,status:b,conclusion:e??void 0,url:"string"==typeof a.detailsUrl?a.detailsUrl:void 0});continue}if("string"==typeof a.context&&"string"==typeof a.state){let b,d=a.state.toUpperCase();b="SUCCESS"===d?"passed":"FAILURE"===d||"ERROR"===d?"failed":"pending",c.push({name:a.context,status:b,conclusion:d,url:"string"==typeof a.targetUrl?a.targetUrl:void 0})}}return c}(p):void 0,t=[];"failing"===o&&t.push("CI is failing"),"changes_requested"===l&&t.push("Changes requested in review"),"pending"===l&&t.push("Review required"),j&&t.push("Merge conflicts"),k&&t.push("Branch is behind base branch"),f&&t.push("PR is still a draft");let u="open"===b&&("passing"===o||"none"===o)&&("approved"===l||"none"===l)&&!j&&!k&&!f;return{data:{state:b,ciStatus:o,reviewDecision:l,mergeable:u,title:c,additions:d,deletions:e,isDraft:f,hasConflicts:j,isBehind:k,blockers:t,...void 0!==s?{ciChecks:s}:{}},headSha:g}}(f.pullRequest);if(a){let{data:b,headSha:d}=a;c.set(e,b),V.set(e,{headSha:d,ciStatus:b.ciStatus}),W.set(e,b)}}});let j=c.size;if(j>g){let c={batchIndex:a,totalBatches:e.length,prCount:j-g,durationMs:d};b?.recordSuccess(c),b?.log("info",`[GraphQL Batch Success] Batch ${a+1}/${e.length} succeeded: added ${j-g} PRs to cache (${d}ms)`)}}catch(g){d=Date.now()-h;let c=g instanceof Error?g.message:String(g);b?.recordFailure({batchIndex:a,totalBatches:e.length,prCount:f.length,error:c,durationMs:d}),console.error(`[GraphQL Batch Warning] Batch enrichment partially failed: ${c}`)}}return c}function ac(a,b){let c=b.toLowerCase();for(let[b,d]of Object.entries(a))if(b.toLowerCase()===c){if(Array.isArray(d))return d[0];return d}}function ad(a){if("string"!=typeof a)return;let b=new Date(a);return Number.isNaN(b.getTime())?void 0:b}function ae(a){return"string"!=typeof a||0===a.length?void 0:a.startsWith("refs/heads/")?a.slice(11):a.startsWith("refs/")?void 0:a}let af=(0,f.promisify)(e.execFile),ag=new Set(["cursor[bot]","github-actions[bot]","codecov[bot]","sonarcloud[bot]","dependabot[bot]","renovate[bot]","codeclimate[bot]","deepsource-autofix[bot]","snyk-bot","lgtm-com[bot]"]);async function ah(a,b,c){try{let{stdout:d}=await af(a,b,{...c?{cwd:c}:{},maxBuffer:0xa00000,timeout:3e4});return d.trim()}catch(c){throw Error(`${a} ${b.slice(0,3).join(" ")} failed: ${c.message}`,{cause:c})}}async function ai(a){return ah("gh",a)}async function aj(a,b){return ah("gh",a,b)}async function ak(a,b){return ah("git",a,b)}function al(a){let b=a.split("/");if(2!==b.length||!b[0]||!b[1])throw Error(`Invalid repo format "${a}", expected "owner/repo"`);return[b[0],b[1]]}function am(a,b){let[c,d]=al(b);return{number:a.number,url:a.url,title:a.title,owner:c,repo:d,branch:a.headRefName,baseBranch:a.baseRefName,isDraft:a.isDraft}}function an(a){let b=(a??"").toUpperCase();return"IN_PROGRESS"===b?"running":"PENDING"===b||"QUEUED"===b||"REQUESTED"===b||"WAITING"===b||"EXPECTED"===b?"pending":"SUCCESS"===b?"passed":"FAILURE"===b||"TIMED_OUT"===b||"CANCELLED"===b||"ACTION_REQUIRED"===b||"ERROR"===b?"failed":("SKIPPED"===b||"NEUTRAL"===b||"STALE"===b||"NOT_REQUIRED"===b,"skipped")}async function ao(a){let b=JSON.parse(await ai(["pr","view",String(a.number),"--repo",aq(a),"--json","statusCheckRollup"]));return(Array.isArray(b.statusCheckRollup)?b.statusCheckRollup:[]).map(a=>{if(!a||"object"!=typeof a)return null;let b="string"==typeof a.name&&a.name||"string"==typeof a.context&&a.context;if(!b)return null;let c="string"==typeof a.conclusion?a.conclusion:"string"==typeof a.state?a.state:"string"==typeof a.status?a.status:void 0,d="string"==typeof a.link&&a.link||"string"==typeof a.detailsUrl&&a.detailsUrl||"string"==typeof a.targetUrl&&a.targetUrl||void 0,e="string"==typeof a.startedAt?a.startedAt:"string"==typeof a.createdAt?a.createdAt:void 0,f="string"==typeof a.completedAt?a.completedAt:void 0,g={name:b,status:an(c),conclusion:"string"==typeof c?c.toUpperCase():void 0,startedAt:e?new Date(e):void 0,completedAt:f?new Date(f):void 0};return d&&(g.url=d),g}).filter(a=>null!==a)}function ap(a){let b=a.scm?.webhook;return{enabled:b?.enabled!==!1,path:b?.path??"/api/webhooks/github",secretEnvVar:b?.secretEnvVar,signatureHeader:b?.signatureHeader??"x-hub-signature-256",eventHeader:b?.eventHeader??"x-github-event",deliveryHeader:b?.deliveryHeader??"x-github-delivery",maxBodyBytes:b?.maxBodyBytes}}function aq(a){return`${a.owner}/${a.repo}`}function ar(a){if(!a)return new Date(0);let b=new Date(a);return isNaN(b.getTime())?new Date(0):b}let as={manifest:{name:"github",slot:"scm",description:"SCM plugin: GitHub PRs, CI checks, reviews, merge readiness",version:"0.1.0"},create:function(){return{name:"github",async verifyWebhook(a,b){let c=ap(b);if(!c.enabled)return{ok:!1,reason:"Webhook is disabled for this project"};if("POST"!==a.method.toUpperCase())return{ok:!1,reason:"Webhook requests must use POST"};if(void 0!==c.maxBodyBytes&&Buffer.byteLength(a.body,"utf8")>c.maxBodyBytes)return{ok:!1,reason:"Webhook payload exceeds configured maxBodyBytes"};let d=ac(a.headers,c.eventHeader);if(!d)return{ok:!1,reason:`Missing ${c.eventHeader} header`};let e=ac(a.headers,c.deliveryHeader),f=c.secretEnvVar;if(!f)return{ok:!0,deliveryId:e,eventType:d};let g=process.env[f];if(!g)return{ok:!1,reason:`Webhook secret env var ${f} is not configured`};let i=ac(a.headers,c.signatureHeader);return i?!function(a,b,c){if(!c.startsWith("sha256="))return!1;let d=(0,h.createHmac)("sha256",b).update(a).digest("hex"),e=c.slice(7),f=Buffer.from(d,"hex"),g=Buffer.from(e,"hex");return f.length===g.length&&(0,h.timingSafeEqual)(f,g)}(a.rawBody??a.body,g,i)?{ok:!1,reason:"Webhook signature verification failed",deliveryId:e,eventType:d}:{ok:!0,deliveryId:e,eventType:d}:{ok:!1,reason:`Missing ${c.signatureHeader} header`}},async parseWebhook(a,b){let c=ap(b),d=function(a){let b=JSON.parse(a);if(!b||"object"!=typeof b||Array.isArray(b))throw Error("Webhook payload must be a JSON object");return b}(a.body);return function(a,b,c){let d=ac(a.headers,c.eventHeader);if(!d)return null;let e=ac(a.headers,c.deliveryHeader),f=function(a){let b=a.repository;if(!b||"object"!=typeof b)return;let c=b.owner,d=c&&"object"==typeof c?c.login:void 0,e="string"==typeof d?d:void 0,f="string"==typeof b.name?b.name:void 0;if(e&&f)return{owner:e,name:f}}(b),g="string"==typeof b.action?b.action:d;if("pull_request"===d){let a=b.pull_request;if(!a||"object"!=typeof a)return null;let c=a.head;return{provider:"github",kind:"pull_request",action:g,rawEventType:d,deliveryId:e,repository:f,prNumber:"number"==typeof b.number?b.number:"number"==typeof a.number?a.number:void 0,branch:"string"==typeof c?.ref?c.ref:void 0,sha:"string"==typeof c?.sha?c.sha:void 0,timestamp:ad(a.updated_at),data:b}}if("pull_request_review"===d||"pull_request_review_comment"===d){let a=b.pull_request;if(!a||"object"!=typeof a)return null;let c=a.head;return{provider:"github",kind:"pull_request_review"===d?"review":"comment",action:g,rawEventType:d,deliveryId:e,repository:f,prNumber:"number"==typeof b.number?b.number:"number"==typeof a.number?a.number:void 0,branch:"string"==typeof c?.ref?c.ref:void 0,sha:"string"==typeof c?.sha?c.sha:void 0,timestamp:"pull_request_review"===d?ad(b.review?.submitted_at):ad(b.comment?.updated_at??b.comment?.created_at),data:b}}if("issue_comment"===d){let a=b.issue;return a&&"object"==typeof a&&"pull_request"in a?{provider:"github",kind:"comment",action:g,rawEventType:d,deliveryId:e,repository:f,prNumber:"number"==typeof a.number?a.number:void 0,timestamp:ad(b.comment?.updated_at??b.comment?.created_at),data:b}:null}if("check_run"===d||"check_suite"===d){let a=b[d],c=(Array.isArray(a?.pull_requests)?a?.pull_requests:[])[0];return{provider:"github",kind:"ci",action:g,rawEventType:d,deliveryId:e,repository:f,prNumber:"number"==typeof c?.number?c.number:void 0,branch:"string"==typeof a?.head_branch?a.head_branch:"string"==typeof a?.check_suite?.head_branch?(a?.check_suite).head_branch:void 0,sha:"string"==typeof a?.head_sha?a.head_sha:void 0,timestamp:ad(a?.updated_at),data:b}}if("status"===d){let a=Array.isArray(b.branches)?b.branches:[];return{provider:"github",kind:"ci",action:"string"==typeof b.state?b.state:g,rawEventType:d,deliveryId:e,repository:f,branch:ae(a[0]?.name??b.ref),sha:"string"==typeof b.sha?b.sha:void 0,timestamp:ad(b.updated_at),data:b}}if("push"===d){let a=b.head_commit&&"object"==typeof b.head_commit?b.head_commit:void 0;return{provider:"github",kind:"push",action:g,rawEventType:d,deliveryId:e,repository:f,branch:ae(b.ref),sha:"string"==typeof b.after?b.after:void 0,timestamp:ad(a?.timestamp??b.updated_at),data:b}}return{provider:"github",kind:"unknown",action:g,rawEventType:d,deliveryId:e,repository:f,timestamp:ad(b.updated_at),data:b}}(a,d,c)},async detectPR(a,b){if(!a.branch)return null;al(b.repo);try{let c=await ai(["pr","list","--repo",b.repo,"--head",a.branch,"--json","number,url,title,headRefName,baseRefName,isDraft","--limit","1"]),d=JSON.parse(c);if(0===d.length)return null;return am(d[0],b.repo)}catch{return null}},resolvePR:async(a,b)=>am(JSON.parse(await ai(["pr","view",a,"--repo",b.repo,"--json","number,url,title,headRefName,baseRefName,isDraft"])),b.repo),async assignPRToCurrentUser(a){await ai(["pr","edit",String(a.number),"--repo",aq(a),"--add-assignee","@me"])},async checkoutPR(a,b){if(await ak(["branch","--show-current"],b)===a.branch)return!1;if(await ak(["status","--porcelain"],b))throw Error(`Workspace has uncommitted changes; cannot switch to PR branch "${a.branch}" safely`);return await aj(["pr","checkout",String(a.number),"--repo",aq(a)],b),!0},async getPRState(a){let b=JSON.parse(await ai(["pr","view",String(a.number),"--repo",aq(a),"--json","state"])).state.toUpperCase();return"MERGED"===b?"merged":"CLOSED"===b?"closed":"open"},async getPRSummary(a){let b=JSON.parse(await ai(["pr","view",String(a.number),"--repo",aq(a),"--json","state,title,additions,deletions"])),c=b.state.toUpperCase();return{state:"MERGED"===c?"merged":"CLOSED"===c?"closed":"open",title:b.title??"",additions:b.additions??0,deletions:b.deletions??0}},async mergePR(a,b="squash"){await ai(["pr","merge",String(a.number),"--repo",aq(a),"rebase"===b?"--rebase":"merge"===b?"--merge":"--squash","--delete-branch"])},async closePR(a){await ai(["pr","close",String(a.number),"--repo",aq(a)])},async getCIChecks(a){try{let b=await ai(["pr","checks",String(a.number),"--repo",aq(a),"--json","name,state,link,startedAt,completedAt"]);return JSON.parse(b).map(a=>{let b=a.state?.toUpperCase();return{name:a.name,status:an(b),url:a.link||void 0,conclusion:b||void 0,startedAt:a.startedAt?new Date(a.startedAt):void 0,completedAt:a.completedAt?new Date(a.completedAt):void 0}})}catch(b){if(b instanceof Error&&/pr checks/i.test(b.message)&&/unknown json field/i.test(b.message))return ao(a);throw Error("Failed to fetch CI checks",{cause:b})}},async getCISummary(a){let b;try{b=await this.getCIChecks(a)}catch{try{let b=await this.getPRState(a);if("merged"===b||"closed"===b)return"none"}catch{}return"failing"}return 0===b.length?"none":b.some(a=>"failed"===a.status)?"failing":b.some(a=>"pending"===a.status||"running"===a.status)?"pending":b.some(a=>"passed"===a.status)?"passing":"none"},getReviews:async a=>JSON.parse(await ai(["pr","view",String(a.number),"--repo",aq(a),"--json","reviews"])).reviews.map(a=>{let b,c=a.state?.toUpperCase();return b="APPROVED"===c?"approved":"CHANGES_REQUESTED"===c?"changes_requested":"DISMISSED"===c?"dismissed":"PENDING"===c?"pending":"commented",{author:a.author?.login??"unknown",state:b,body:a.body||void 0,submittedAt:ar(a.submittedAt)}}),async getReviewDecision(a){let b=(JSON.parse(await ai(["pr","view",String(a.number),"--repo",aq(a),"--json","reviewDecision"])).reviewDecision??"").toUpperCase();return"APPROVED"===b?"approved":"CHANGES_REQUESTED"===b?"changes_requested":"REVIEW_REQUIRED"===b?"pending":"none"},async getPendingComments(a){try{let b=await ai(["api","graphql","-f",`owner=${a.owner}`,"-f",`name=${a.repo}`,"-F",`number=${a.number}`,"-f",`query=query($owner: String!, $name: String!, $number: Int!) {
|
|
273
|
-
repository(owner: $owner, name: $name) {
|
|
274
|
-
pullRequest(number: $number) {
|
|
275
|
-
reviewThreads(first: 100) {
|
|
276
|
-
nodes {
|
|
277
|
-
isResolved
|
|
278
|
-
comments(first: 1) {
|
|
279
|
-
nodes {
|
|
280
|
-
id
|
|
281
|
-
author { login }
|
|
282
|
-
body
|
|
283
|
-
path
|
|
284
|
-
line
|
|
285
|
-
url
|
|
286
|
-
createdAt
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}`]);return JSON.parse(b).data.repository.pullRequest.reviewThreads.nodes.filter(a=>{if(a.isResolved)return!1;let b=a.comments.nodes[0];if(!b)return!1;let c=b.author?.login??"";return!ag.has(c)}).map(a=>{let b=a.comments.nodes[0];return{id:b.id,author:b.author?.login??"unknown",body:b.body,path:b.path||void 0,line:b.line??void 0,isResolved:a.isResolved,createdAt:ar(b.createdAt),url:b.url}})}catch(a){throw Error("Failed to fetch pending comments",{cause:a})}},async getAutomatedComments(a){try{let b=[];for(let c=1;;c++){let d=await ai(["api","--method","GET",`repos/${aq(a)}/pulls/${a.number}/comments?per_page=100&page=${c}`]),e=JSON.parse(d);if(0===e.length||(b.push(...e),e.length<100))break}return b.filter(a=>ag.has(a.user?.login??"")).map(a=>{let b="info",c=a.body.toLowerCase();return c.includes("error")||c.includes("bug")||c.includes("critical")||c.includes("potential issue")?b="error":(c.includes("warning")||c.includes("suggest")||c.includes("consider"))&&(b="warning"),{id:String(a.id),botName:a.user?.login??"unknown",body:a.body,path:a.path||void 0,line:a.line??a.original_line??void 0,severity:b,createdAt:ar(a.created_at),url:a.html_url}})}catch(a){throw Error("Failed to fetch automated comments",{cause:a})}},async getMergeability(a){let b=[];if("merged"===await this.getPRState(a))return{mergeable:!0,ciPassing:!0,approved:!0,noConflicts:!0,blockers:[]};let c=JSON.parse(await ai(["pr","view",String(a.number),"--repo",aq(a),"--json","mergeable,reviewDecision,mergeStateStatus,isDraft"])),e=await this.getCISummary(a),f=e===d.U1.PASSING||e===d.U1.NONE;f||b.push(`CI is ${e}`);let g=(c.reviewDecision??"").toUpperCase();"CHANGES_REQUESTED"===g?b.push("Changes requested in review"):"REVIEW_REQUIRED"===g&&b.push("Review required");let h=(c.mergeable??"").toUpperCase(),i=(c.mergeStateStatus??"").toUpperCase();return"CONFLICTING"===h?b.push("Merge conflicts"):("UNKNOWN"===h||""===h)&&b.push("Merge status unknown (GitHub is computing)"),"BEHIND"===i?b.push("Branch is behind base branch"):"BLOCKED"===i?b.push("Merge is blocked by branch protection"):"UNSTABLE"===i&&b.push("Required checks are failing"),c.isDraft&&b.push("PR is still a draft"),{mergeable:0===b.length,ciPassing:f,approved:"APPROVED"===g,noConflicts:"MERGEABLE"===h,blockers:b}},enrichSessionsPRBatch:async(a,b)=>ab(a,b)}}},at=(0,f.promisify)(e.execFile);async function au(a){try{let{stdout:b}=await at("gh",a,{maxBuffer:0xa00000,timeout:3e4});return b.trim()}catch(b){throw Error(`gh ${a.slice(0,3).join(" ")} failed: ${b.message}`,{cause:b})}}function av(a,b){let c=function a(b){if(!(b instanceof Error))return"";let c=[b.message];return"string"==typeof b.stderr&&c.push(b.stderr),"string"==typeof b.stdout&&c.push(b.stdout),b.cause instanceof Error&&c.push(a(b.cause)),c.join("\n").toLowerCase()}(a);return!!c&&(c.includes("unknown json field")||c.includes("unknown field")||c.includes("invalid field"))&&c.includes(b.toLowerCase())}async function aw(a,b){try{return await au(["issue","view",a,"--repo",b.repo,"--json","number,title,body,url,state,stateReason,labels,assignees"])}catch(c){if(!av(c,"stateReason"))throw c;return au(["issue","view",a,"--repo",b.repo,"--json","number,title,body,url,state,labels,assignees"])}}async function ax(a){let b=[...a,"--json","number,title,body,url,state,stateReason,labels,assignees"];try{return await au(b)}catch(b){if(!av(b,"stateReason"))throw b;return au([...a,"--json","number,title,body,url,state,labels,assignees"])}}function ay(a,b){return"CLOSED"===a.toUpperCase()?b?.toUpperCase()==="NOT_PLANNED"?"cancelled":"closed":"open"}let az={manifest:{name:"github",slot:"tracker",description:"Tracker plugin: GitHub Issues",version:"0.1.0"},create:function(){return{name:"github",async getIssue(a,b){let c=JSON.parse(await aw(a,b));return{id:String(c.number),title:c.title,description:c.body??"",url:c.url,state:ay(c.state,c.stateReason),labels:c.labels.map(a=>a.name),assignee:c.assignees[0]?.login}},isCompleted:async(a,b)=>"CLOSED"===JSON.parse(await au(["issue","view",a,"--repo",b.repo,"--json","state"])).state.toUpperCase(),issueUrl(a,b){let c=a.replace(/^#/,"");return`https://github.com/${b.repo}/issues/${c}`},issueLabel(a,b){let c=a.match(/\/issues\/(\d+)/);if(c)return`#${c[1]}`;let d=a.split("/"),e=d[d.length-1];return e?`#${e}`:a},branchName(a,b){let c=a.replace(/^#/,"");return`feat/issue-${c}`},async generatePrompt(a,b){let c=await this.getIssue(a,b),d=[`You are working on GitHub issue #${c.id}: ${c.title}`,`Issue URL: ${c.url}`,""];return c.labels.length>0&&d.push(`Labels: ${c.labels.join(", ")}`),c.description&&d.push("## Description","",c.description),d.push("","Please implement the changes described in this issue. When done, commit and push your changes."),d.join("\n")},async listIssues(a,b){let c=["issue","list","--repo",b.repo,"--limit",String(a.limit??30)];return"closed"===a.state?c.push("--state","closed"):"all"===a.state?c.push("--state","all"):c.push("--state","open"),a.labels&&a.labels.length>0&&c.push("--label",a.labels.join(",")),a.assignee&&c.push("--assignee",a.assignee),JSON.parse(await ax(c)).map(a=>({id:String(a.number),title:a.title,description:a.body??"",url:a.url,state:ay(a.state,a.stateReason),labels:a.labels.map(a=>a.name),assignee:a.assignees[0]?.login}))},async updateIssue(a,b,c){"closed"===b.state?await au(["issue","close",a,"--repo",c.repo]):"open"===b.state&&await au(["issue","reopen",a,"--repo",c.repo]),b.removeLabels&&b.removeLabels.length>0&&await au(["issue","edit",a,"--repo",c.repo,"--remove-label",b.removeLabels.join(",")]),b.labels&&b.labels.length>0&&await au(["issue","edit",a,"--repo",c.repo,"--add-label",b.labels.join(",")]),b.assignee&&await au(["issue","edit",a,"--repo",c.repo,"--add-assignee",b.assignee]),b.comment&&await au(["issue","comment",a,"--repo",c.repo,"--body",b.comment])},async createIssue(a,b){let c=["issue","create","--repo",b.repo,"--title",a.title,"--body",a.description??""];a.labels&&a.labels.length>0&&c.push("--label",a.labels.join(",")),a.assignee&&c.push("--assignee",a.assignee);let d=await au(c),e=d.match(/\/issues\/(\d+)/);if(!e)throw Error(`Failed to parse issue URL from gh output: ${d}`);let f=e[1];return this.getIssue(f,b)}}}};var aA=c(44708);function aB(a){switch(a){case"completed":return"closed";case"canceled":return"cancelled";case"started":return"in_progress";default:return"open"}}let aC=`
|
|
294
|
-
id
|
|
295
|
-
identifier
|
|
296
|
-
title
|
|
297
|
-
description
|
|
298
|
-
url
|
|
299
|
-
priority
|
|
300
|
-
branchName
|
|
301
|
-
state { name type }
|
|
302
|
-
labels { nodes { name } }
|
|
303
|
-
assignee { name displayName }
|
|
304
|
-
team { key }
|
|
305
|
-
`;function aD(a){return{name:"linear",async getIssue(b,c){let d=(await a(`query($id: String!) {
|
|
306
|
-
issue(id: $id) {
|
|
307
|
-
${aC}
|
|
308
|
-
}
|
|
309
|
-
}`,{id:b})).issue;return{id:d.identifier,title:d.title,description:d.description??"",url:d.url,state:aB(d.state.type),labels:d.labels.nodes.map(a=>a.name),assignee:d.assignee?.displayName??d.assignee?.name,priority:d.priority,branchName:d.branchName??void 0}},async isCompleted(b,c){let d=(await a(`query($id: String!) {
|
|
310
|
-
issue(id: $id) {
|
|
311
|
-
state { type }
|
|
312
|
-
}
|
|
313
|
-
}`,{id:b})).issue.state.type;return"completed"===d||"canceled"===d},issueUrl(a,b){let c=b.tracker?.workspaceSlug;return c?`https://linear.app/${c}/issue/${a}`:`https://linear.app/issue/${a}`},issueLabel(a,b){let c=a.match(/\/issue\/([A-Z]+-\d+)/);if(c)return c[1];let d=a.split("/");return d[d.length-1]||a},branchName:(a,b)=>`feat/${a}`,async generatePrompt(a,b){let c=await this.getIssue(a,b),d=[`You are working on Linear ticket ${c.id}: ${c.title}`,`Issue URL: ${c.url}`,""];return c.labels.length>0&&d.push(`Labels: ${c.labels.join(", ")}`),void 0!==c.priority&&d.push(`Priority: ${{0:"No priority",1:"Urgent",2:"High",3:"Normal",4:"Low"}[c.priority]??String(c.priority)}`),c.description&&d.push("## Description","",c.description),d.push("","Please implement the changes described in this ticket. When done, commit and push your changes."),d.join("\n")},async listIssues(b,c){let d={},e={};"closed"===b.state?d.state={type:{in:["completed","canceled"]}}:"all"!==b.state&&(d.state={type:{nin:["completed","canceled"]}}),b.assignee&&(d.assignee={displayName:{eq:b.assignee}}),b.labels&&b.labels.length>0&&(d.labels={name:{in:b.labels}});let f=c.tracker?.teamId;return f&&(d.team={id:{eq:f}}),e.filter=Object.keys(d).length>0?d:void 0,e.first=b.limit??30,(await a(`query($filter: IssueFilter, $first: Int!) {
|
|
314
|
-
issues(filter: $filter, first: $first) {
|
|
315
|
-
nodes {
|
|
316
|
-
${aC}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
}`,e)).issues.nodes.map(a=>({id:a.identifier,title:a.title,description:a.description??"",url:a.url,state:aB(a.state.type),labels:a.labels.nodes.map(a=>a.name),assignee:a.assignee?.displayName??a.assignee?.name,priority:a.priority,branchName:a.branchName??void 0}))},async updateIssue(b,c,d){let e=await a(`query($id: String!) {
|
|
320
|
-
issue(id: $id) {
|
|
321
|
-
id
|
|
322
|
-
team { id }
|
|
323
|
-
}
|
|
324
|
-
}`,{id:b}),f=e.issue.id,g=e.issue.team.id;if(c.state){let b=await a(`query($teamId: ID!) {
|
|
325
|
-
workflowStates(filter: { team: { id: { eq: $teamId } } }) {
|
|
326
|
-
nodes { id name type }
|
|
327
|
-
}
|
|
328
|
-
}`,{teamId:g}),d="closed"===c.state?"completed":"open"===c.state?"unstarted":"started",e=b.workflowStates.nodes.find(a=>a.type===d);if(!e)throw Error(`No workflow state of type "${d}" found for team ${g}`);await a(`mutation($id: String!, $stateId: String!) {
|
|
329
|
-
issueUpdate(id: $id, input: { stateId: $stateId }) {
|
|
330
|
-
success
|
|
331
|
-
}
|
|
332
|
-
}`,{id:f,stateId:e.id})}if(c.assignee){let b=(await a(`query($filter: UserFilter) {
|
|
333
|
-
users(filter: $filter) {
|
|
334
|
-
nodes { id displayName name }
|
|
335
|
-
}
|
|
336
|
-
}`,{filter:{displayName:{eq:c.assignee}}})).users.nodes[0];b&&await a(`mutation($id: String!, $assigneeId: String!) {
|
|
337
|
-
issueUpdate(id: $id, input: { assigneeId: $assigneeId }) {
|
|
338
|
-
success
|
|
339
|
-
}
|
|
340
|
-
}`,{id:f,assigneeId:b.id})}if(c.labels&&c.labels.length>0){let b=new Set((await a(`query($id: String!) {
|
|
341
|
-
issue(id: $id) {
|
|
342
|
-
labels { nodes { id } }
|
|
343
|
-
}
|
|
344
|
-
}`,{id:f})).issue.labels.nodes.map(a=>a.id)),d=new Map((await a(`query($teamId: ID) {
|
|
345
|
-
issueLabels(filter: { team: { id: { eq: $teamId } } }) {
|
|
346
|
-
nodes { id name }
|
|
347
|
-
}
|
|
348
|
-
}`,{teamId:g})).issueLabels.nodes.map(a=>[a.name,a.id]));for(let a of c.labels){let c=d.get(a);c&&b.add(c)}await a(`mutation($id: String!, $labelIds: [String!]!) {
|
|
349
|
-
issueUpdate(id: $id, input: { labelIds: $labelIds }) {
|
|
350
|
-
success
|
|
351
|
-
}
|
|
352
|
-
}`,{id:f,labelIds:[...b]})}c.comment&&await a(`mutation($issueId: String!, $body: String!) {
|
|
353
|
-
commentCreate(input: { issueId: $issueId, body: $body }) {
|
|
354
|
-
success
|
|
355
|
-
}
|
|
356
|
-
}`,{issueId:f,body:c.comment})},async createIssue(b,c){let d=c.tracker?.teamId;if(!d)throw Error("Linear tracker requires 'teamId' in project tracker config");let e={title:b.title,description:b.description??"",teamId:d};void 0!==b.priority&&(e.priority=b.priority);let f=(await a(`mutation($title: String!, $description: String!, $teamId: String!, $priority: Int) {
|
|
357
|
-
issueCreate(input: {
|
|
358
|
-
title: $title,
|
|
359
|
-
description: $description,
|
|
360
|
-
teamId: $teamId,
|
|
361
|
-
priority: $priority
|
|
362
|
-
}) {
|
|
363
|
-
success
|
|
364
|
-
issue {
|
|
365
|
-
${aC}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}`,e)).issueCreate.issue,g={id:f.identifier,title:f.title,description:f.description??"",url:f.url,state:aB(f.state.type),labels:f.labels.nodes.map(a=>a.name),assignee:f.assignee?.displayName??f.assignee?.name,priority:f.priority,branchName:f.branchName??void 0};if(b.assignee)try{let c=(await a(`query($filter: UserFilter) {
|
|
369
|
-
users(filter: $filter) {
|
|
370
|
-
nodes { id displayName name }
|
|
371
|
-
}
|
|
372
|
-
}`,{filter:{displayName:{eq:b.assignee}}})).users.nodes[0];c&&(await a(`mutation($id: String!, $assigneeId: String!) {
|
|
373
|
-
issueUpdate(id: $id, input: { assigneeId: $assigneeId }) {
|
|
374
|
-
success
|
|
375
|
-
}
|
|
376
|
-
}`,{id:f.id,assigneeId:c.id}),g.assignee=b.assignee)}catch{}if(b.labels&&b.labels.length>0)try{let c=await a(`query($teamId: ID) {
|
|
377
|
-
issueLabels(filter: { team: { id: { eq: $teamId } } }) {
|
|
378
|
-
nodes { id name }
|
|
379
|
-
}
|
|
380
|
-
}`,{teamId:d}),e=new Map(c.issueLabels.nodes.map(a=>[a.name,a.id])),h=[],i=[];for(let a of b.labels){let b=e.get(a);b&&(i.push(b),h.push(a))}i.length>0&&(await a(`mutation($id: String!, $labelIds: [String!]!) {
|
|
381
|
-
issueUpdate(id: $id, input: { labelIds: $labelIds }) {
|
|
382
|
-
success
|
|
383
|
-
}
|
|
384
|
-
}`,{id:f.id,labelIds:i}),g.labels=h)}catch{}return g}}}let aE={manifest:{name:"linear",slot:"tracker",description:"Tracker plugin: Linear issue tracker",version:"0.1.0"},create:function(){let a=process.env.COMPOSIO_API_KEY;if(a){let b,c=process.env.COMPOSIO_ENTITY_ID??"default";return aD(async(d,e)=>{let f,g=(await (!b&&(b=(async()=>{try{let{Composio:b}=await Promise.resolve().then(function(){var a=Error("Cannot find module '@composio/core'");throw a.code="MODULE_NOT_FOUND",a});return new b({apiKey:a}).tools}catch(b){let a=b instanceof Error?b.message:String(b);if(a.includes("Cannot find module")||a.includes("Cannot find package")||a.includes("ERR_MODULE_NOT_FOUND"))throw Error("Composio SDK (@composio/core) is not installed. Install it with: pnpm add @composio/core",{cause:b});throw b}})()),b)).execute("LINEAR_RUN_QUERY_OR_MUTATION",{entityId:c,arguments:{query_or_mutation:d,variables:e?JSON.stringify(e):"{}"}}),h=new Promise((a,b)=>{f=setTimeout(()=>{b(Error("Composio Linear API request timed out after 30s"))},3e4)});g.catch(()=>{}),h.catch(()=>{});try{let a=await Promise.race([g,h]);if(!a.successful)throw Error(`Composio Linear API error: ${a.error??"unknown error"}`);if(!a.data)throw Error("Composio Linear API returned no data");return a.data}finally{clearTimeout(f)}})}return aD((a,b)=>{let c=function(){let a=process.env.LINEAR_API_KEY;if(!a)throw Error("LINEAR_API_KEY environment variable is required for the Linear tracker plugin");return a}(),d=JSON.stringify({query:a,variables:b});return new Promise((a,b)=>{let e=new URL("https://api.linear.app/graphql"),f=!1,g=a=>{f||(f=!0,a())},h=(0,aA.request)({hostname:e.hostname,path:e.pathname,method:"POST",headers:{"Content-Type":"application/json",Authorization:c,"Content-Length":Buffer.byteLength(d)}},c=>{let d=[];c.on("error",a=>g(()=>b(a))),c.on("data",a=>d.push(a)),c.on("end",()=>{g(()=>{try{let e=Buffer.concat(d).toString("utf-8"),f=c.statusCode??0;if(f<200||f>=300)return void b(Error(`Linear API returned HTTP ${f}: ${e.slice(0,200)}`));let g=JSON.parse(e);if(g.errors&&g.errors.length>0)return void b(Error(`Linear API error: ${g.errors[0].message}`));if(!g.data)return void b(Error("Linear API returned no data"));a(g.data)}catch(a){b(a)}})})});h.setTimeout(3e4,()=>{g(()=>{h.destroy(),b(Error("Linear API request timed out after 30s"))})}),h.on("error",a=>g(()=>b(a))),h.write(d),h.end()})})}},aF=globalThis;function aG(){return aF._aoServices?Promise.resolve(aF._aoServices):(aF._aoServicesInit||(aF._aoServicesInit=aH().catch(a=>{throw aF._aoServicesInit=void 0,a})),aF._aoServicesInit)}async function aH(){let a=(0,d.Z9)(),b=(0,d.R)();b.register(o),b.register(z),b.register(E),b.register(I),b.register(R),b.register(as),b.register(az),b.register(aE);let c=(0,d.Qu)({config:a,registry:b}),e=(0,d.C1)({config:a,registry:b,sessionManager:c});e.start(3e4);let f={config:a,registry:b,sessionManager:c,lifecycleManager:e};return aF._aoServices=f,f}let aI="agent:backlog",aJ=globalThis;function aK(){aJ._aoBacklogStarted||(aJ._aoBacklogStarted=!0,aO(),aJ._aoBacklogTimer=setInterval(()=>void aO(),6e4))}let aL=new Set;async function aM(a,b,c){for(let d of a.filter(a=>"merged"===a.status&&a.issueId&&!aL.has(`${a.projectId}:${a.issueId}`))){let a=`${d.projectId}:${d.issueId}`,e=b.projects[d.projectId];if(!e?.tracker?.plugin){aL.add(a);continue}let f=c.get("tracker",e.tracker.plugin);if(!f?.updateIssue){aL.add(a);continue}let g=d.issueId;if(!g){aL.add(a);continue}try{await f.updateIssue(g,{labels:["merged-unverified"],removeLabels:["agent:backlog","agent:in-progress"],comment:"PR merged. Issue awaiting human verification on staging."},e)}catch(a){console.error(`[backlog] Failed to close issue ${d.issueId}:`,a)}aL.add(a)}}async function aN(a,b){for(let[,c]of Object.entries(a.projects)){let a;if(!c.tracker?.plugin)continue;let d=b.get("tracker",c.tracker.plugin);if(d?.listIssues&&d.updateIssue){try{a=await d.listIssues({state:"open",labels:["agent:done"],limit:20},c)}catch{continue}for(let b of a)try{await d.updateIssue(b.id,{labels:[aI],removeLabels:["agent:done"],comment:"Issue reopened — returning to agent backlog."},c),console.log(`[backlog] Relabeled reopened issue ${b.id} → ${aI}`)}catch(a){console.error(`[backlog] Failed to relabel reopened issue ${b.id}:`,a)}}}}async function aO(){try{let{config:a,registry:b,sessionManager:c}=await aG(),e=await c.list();await aM(e,a,b),await aN(a,b);let f=Object.entries(a.projects).map(([a,b])=>b.sessionPrefix??a),g=e.filter(b=>!(0,d.tT)(b,a.projects[b.projectId]?.sessionPrefix??b.projectId,f)&&!d.CM.has(b.status)),h=new Set(g.map(a=>a.issueId?.toLowerCase()).filter(a=>!!a)),i=5-g.length;if(i<=0)return;for(let[d,e]of Object.entries(a.projects)){let a;if(i<=0)break;if(!e.tracker?.plugin)continue;let f=b.get("tracker",e.tracker.plugin);if(f?.listIssues){try{a=await f.listIssues({state:"open",labels:[aI],limit:10},e)}catch{continue}for(let b of a){if(i<=0)break;if(!h.has(b.id.toLowerCase()))try{await c.spawn({projectId:d,issueId:b.id}),i--,h.add(b.id.toLowerCase()),f.updateIssue&&await f.updateIssue(b.id,{labels:["agent:in-progress"],removeLabels:["agent:backlog"],comment:"Claimed by agent orchestrator — session spawned."},e)}catch(a){console.error(`[backlog] Failed to spawn session for issue ${b.id}:`,a)}}}}}catch(a){console.error("[backlog] Poll failed:",a)}}async function aP(){let a=[];try{let{config:b,registry:c}=await aG();for(let[d,e]of Object.entries(b.projects)){if(!e.tracker?.plugin)continue;let b=c.get("tracker",e.tracker.plugin);if(b?.listIssues)try{for(let c of(await b.listIssues({state:"open",labels:[aI],limit:20},e)))a.push({...c,projectId:d})}catch{}}}catch{}return a}async function aQ(){let a=[];try{let{config:b,registry:c}=await aG();for(let[d,e]of Object.entries(b.projects)){if(!e.tracker?.plugin)continue;let b=c.get("tracker",e.tracker.plugin);if(b?.listIssues)try{for(let c of(await b.listIssues({state:"open",labels:["merged-unverified"],limit:20},e)))a.push({...c,projectId:d})}catch{}}}catch{}return a}function aR(a,b){return b?.scm?.plugin?a.get("scm",b.scm.plugin):null}}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=907,exports.ids=[907],exports.modules={21271:(a,b,c)=>{c.d(b,{bV:()=>q,Ik:()=>k,g$:()=>p,oc:()=>n,WQ:()=>j,KI:()=>h,cg:()=>i});var d=c(43851);class e{constructor(a=3e5){this.cache=new Map,this.ttlMs=a,this.cleanupInterval=setInterval(()=>this.evictExpired(),a),this.cleanupInterval.unref&&this.cleanupInterval.unref()}get(a){let b=this.cache.get(a);return b?Date.now()>b.expiresAt?(this.cache.delete(a),null):b.value:null}set(a,b,c){this.cache.set(a,{value:b,expiresAt:Date.now()+(c??this.ttlMs)})}evictExpired(){let a=Date.now();for(let[b,c]of this.cache.entries())a>c.expiresAt&&this.cache.delete(b)}clear(){this.cache.clear(),this.cleanupInterval&&(clearInterval(this.cleanupInterval),this.cleanupInterval=void 0)}size(){return this.cache.size}}let f=new e,g=new e(3e5);function h(a,b){let c=b[a.projectId];if(c)return c;let d=Object.entries(b).find(([,b])=>a.id.startsWith(b.sessionPrefix));if(d)return d[1];let e=Object.keys(b)[0];return e?b[e]:void 0}function i(a){var b;let c=a.agentInfo?.summary,d=c??a.metadata.summary??null;return{id:a.id,projectId:a.projectId,status:a.status,activity:a.activity,branch:a.branch,issueId:a.issueId,issueUrl:a.issueId,issueLabel:null,issueTitle:null,userPrompt:a.metadata.userPrompt??null,summary:d,summaryIsFallback:!!c&&(a.agentInfo?.summaryIsFallback??!1),createdAt:a.createdAt.toISOString(),lastActivityAt:a.lastActivityAt.toISOString(),pr:a.pr?{number:(b=a.pr).number,url:b.url,title:b.title,owner:b.owner,repo:b.repo,branch:b.branch,baseBranch:b.baseBranch,isDraft:b.isDraft,state:"open",additions:0,deletions:0,ciStatus:"none",ciChecks:[],reviewDecision:"none",mergeability:{mergeable:!1,ciPassing:!1,approved:!1,noConflicts:!0,blockers:[]},unresolvedThreads:0,unresolvedComments:[],enriched:!1}:null,metadata:a.metadata}}function j(a,b){let c=Object.entries(b).map(([a,b])=>b.sessionPrefix??a);return a.filter(a=>(0,d.tT)(a,b[a.projectId]?.sessionPrefix??a.projectId,c)).map(a=>({id:a.id,projectId:a.projectId,projectName:b[a.projectId]?.name??a.projectId})).sort((a,b)=>a.projectName.localeCompare(b.projectName)||a.id.localeCompare(b.id))}async function k(a,b,c,d){var e,g,h;if(!a.pr)return!1;let i=(e=c.owner,g=c.repo,h=c.number,`${e}/${g}#${h}`),j=f.get(i);if(j&&a.pr)return a.pr.state=j.state,a.pr.title=j.title,a.pr.additions=j.additions,a.pr.deletions=j.deletions,a.pr.ciStatus=j.ciStatus,a.pr.ciChecks=j.ciChecks,a.pr.reviewDecision=j.reviewDecision,a.pr.mergeability=j.mergeability,a.pr.unresolvedThreads=j.unresolvedThreads,a.pr.unresolvedComments=j.unresolvedComments,a.pr.enriched=!0,!0;if(d?.cacheOnly)return!1;let k=await Promise.allSettled([b.getPRSummary?b.getPRSummary(c):b.getPRState(c).then(a=>({state:a,title:"",additions:0,deletions:0})),b.getCIChecks(c),b.getCISummary(c),b.getReviewDecision(c),b.getMergeability(c),b.getPendingComments(c)]),[l,m,n,o,p,q]=k,r=k.filter(a=>"rejected"===a.status).length,s=r>=k.length/2;if(s){let a=k.filter(a=>"rejected"===a.status),b=a[0]?.reason;console.warn(`[enrichSessionPR] ${r}/${k.length} API calls failed for PR #${c.number} (rate limited or unavailable):`,String(b))}if("fulfilled"===l.status&&(a.pr.state=l.value.state,a.pr.additions=l.value.additions,a.pr.deletions=l.value.deletions,l.value.title&&(a.pr.title=l.value.title)),"fulfilled"===m.status&&(a.pr.ciChecks=m.value.map(a=>({name:a.name,status:a.status,url:a.url}))),"fulfilled"===n.status&&(a.pr.ciStatus=n.value),"fulfilled"===o.status&&(a.pr.reviewDecision=o.value),"fulfilled"===p.status?a.pr.mergeability=p.value:a.pr.mergeability.blockers=["Merge status unavailable"],"fulfilled"===q.status){let b=q.value;a.pr.unresolvedThreads=b.length,a.pr.unresolvedComments=b.map(a=>({url:a.url,path:a.path??"",author:a.author,body:a.body}))}if(a.pr.enriched=!0,s&&!a.pr.mergeability.blockers.includes("API rate limited or unavailable")&&a.pr.mergeability.blockers.push("API rate limited or unavailable"),s){let b={state:a.pr.state,title:a.pr.title,additions:a.pr.additions,deletions:a.pr.deletions,ciStatus:a.pr.ciStatus,ciChecks:a.pr.ciChecks,reviewDecision:a.pr.reviewDecision,mergeability:a.pr.mergeability,unresolvedThreads:a.pr.unresolvedThreads,unresolvedComments:a.pr.unresolvedComments};return f.set(i,b,36e5),!0}let t={state:a.pr.state,title:a.pr.title,additions:a.pr.additions,deletions:a.pr.deletions,ciStatus:a.pr.ciStatus,ciChecks:a.pr.ciChecks,reviewDecision:a.pr.reviewDecision,mergeability:a.pr.mergeability,unresolvedThreads:a.pr.unresolvedThreads,unresolvedComments:a.pr.unresolvedComments};return f.set(i,t),!0}async function l(a,b,c){if(!a.summary)try{let d=await c.getSessionInfo(b);d?.summary&&(a.summary=d.summary,a.summaryIsFallback=d.summaryIsFallback??!1)}catch{}}async function m(a,b,c){if(!a.issueUrl||!a.issueLabel)return;let d=g.get(a.issueUrl);if(d){a.issueTitle=d;return}try{let d=a.issueLabel.replace(/^#/,""),e=await b.getIssue(d,c);e.title&&(a.issueTitle=e.title,g.set(a.issueUrl,e.title))}catch{}}async function n(a,b,c,d){let{summaryPromises:e}=o(a,b,c,d);await Promise.allSettled(e)}function o(a,b,c,d){let e=a.map(a=>h(a,c.projects));e.forEach((a,c)=>{if(!b[c].issueUrl||!a?.tracker?.plugin)return;let e=d.get("tracker",a.tracker.plugin);if(e){var f=b[c];if(f.issueUrl)if(e.issueLabel)try{f.issueLabel=e.issueLabel(f.issueUrl,a)}catch{let a=f.issueUrl.split("/");f.issueLabel=a[a.length-1]||f.issueUrl}else{let a=f.issueUrl.split("/");f.issueLabel=a[a.length-1]||f.issueUrl}}});let f=a.map((a,f)=>{if(b[f].summary)return Promise.resolve();let g=e[f]?.agent??c.defaults.agent;if(!g)return Promise.resolve();let h=d.get("agent",g);return h?l(b[f],a,h):Promise.resolve()});return{projects:e,summaryPromises:f}}async function p(a,b,c,d){let{projects:e,summaryPromises:f}=o(a,b,c,d),g=e.map((a,c)=>{if(!b[c].issueUrl||!b[c].issueLabel||!a?.tracker?.plugin)return Promise.resolve();let e=d.get("tracker",a.tracker.plugin);return e?m(b[c],e,a):Promise.resolve()});await Promise.allSettled([...f,...g])}function q(a){return{totalSessions:a.length,workingSessions:a.filter(a=>null!==a.activity&&"exited"!==a.activity).length,openPRs:a.filter(a=>a.pr?.state==="open").length,needsReview:a.filter(a=>a.pr&&!a.pr.isDraft&&"pending"===a.pr.reviewDecision).length}}},36269:(a,b,c)=>{c.d(b,{CM:()=>d.CM,ng:()=>g});var d=c(15407);function e(a){return a.mergeability.blockers.includes("API rate limited or unavailable")}function f(a){return!1===a.enriched}function g(a){if("merged"===a.status||"killed"===a.status||"cleanup"===a.status||"done"===a.status||"terminated"===a.status||a.pr&&("merged"===a.pr.state||"closed"===a.pr.state))return"done";if("mergeable"===a.status||"approved"===a.status||a.pr&&!f(a.pr)&&a.pr.mergeability.mergeable)return"merge";if(a.status===d.SB.ERRORED||a.status===d.SB.NEEDS_INPUT||a.status===d.SB.STUCK||a.activity===d.u3.WAITING_INPUT||a.activity===d.u3.BLOCKED||a.activity===d.u3.EXITED)return"respond";if("ci_failed"===a.status||"changes_requested"===a.status)return"review";if(a.pr&&!e(a.pr)&&!f(a.pr)){let b=a.pr;if(b.ciStatus===d.U1.FAILING||"changes_requested"===b.reviewDecision||!b.mergeability.noConflicts)return"review"}if("review_pending"===a.status)return"pending";if(a.pr&&!e(a.pr)&&!f(a.pr)){let b=a.pr;if(!b.isDraft&&b.unresolvedThreads>0||!b.isDraft&&("pending"===b.reviewDecision||"none"===b.reviewDecision))return"pending"}return"working"}},52557:(a,b,c)=>{c.d(b,{KG:()=>f,PB:()=>e});var d=c(15407);function e(a,b,c){return b&&"all"!==b?a.filter(a=>(function(a,b,c){if(a.projectId===b)return!0;let d=c[b];return!!(d?.sessionPrefix&&a.id.startsWith(d.sessionPrefix))||c[a.projectId]?.sessionPrefix===b})(a,b,c)):a}function f(a,b,c){let f=Object.entries(c).map(([a,b])=>b.sessionPrefix??a);return e(a.filter(a=>!(0,d.tT)(a,c[a.projectId]?.sessionPrefix??a.projectId,f)),b,c)}}};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
self.__BUILD_MANIFEST=function(e,r,t,_){return{__rewrites:{afterFiles:[],beforeFiles:[],fallback:[]},__routerFilterStatic:{numItems:23,errorRate:1e-4,numBits:441,numHashes:14,bitArray:[1,1,0,0,r,e,e,e,r,r,e,r,e,e,e,r,e,e,e,e,e,e,r,r,e,r,r,r,r,e,r,r,e,r,e,e,r,r,e,r,r,r,e,r,r,r,r,r,e,r,e,r,r,e,e,e,e,e,e,r,e,e,r,r,r,e,e,r,r,e,e,e,r,e,r,r,r,r,e,r,r,e,r,e,e,r,e,r,e,r,e,r,r,e,r,e,r,e,r,r,e,e,e,e,e,r,r,e,e,e,r,e,e,e,e,e,r,e,r,e,e,r,e,e,r,r,e,e,e,e,r,e,e,e,r,e,r,e,e,r,r,e,e,r,r,r,r,e,e,r,r,e,r,e,r,e,e,e,r,r,r,e,e,e,e,e,e,e,r,r,r,e,r,r,r,r,e,e,e,r,r,r,r,r,r,e,r,e,e,e,r,r,r,e,r,e,r,e,e,e,r,r,r,e,e,e,e,r,r,e,r,r,e,r,e,r,r,e,e,r,r,r,e,r,e,r,r,e,e,e,r,r,r,e,e,e,e,e,e,r,r,e,e,r,r,r,r,r,e,r,e,e,r,e,e,r,e,r,r,e,r,r,r,e,e,e,r,r,e,r,e,e,e,e,e,r,e,r,r,r,e,r,e,r,e,r,e,e,r,e,r,r,r,e,e,e,e,r,e,r,e,e,r,e,r,r,r,e,r,e,r,e,e,e,e,e,e,e,e,r,r,e,e,e,r,r,r,e,e,e,r,e,r,r,e,r,e,e,e,e,e,r,e,e,r,r,e,e,r,r,r,e,e,r,e,r,r,r,r,e,r,r,e,e,r,e,r,r,r,e,r,e,r,r,e,r,r,r,r,r,r,r,e,e,r,e,r,e,e,r,e,e,r,e,r,e,e,e,e,r,e,r,r,e,e,e,e,r,r,r,r,r,e,r,r,e,r,r,r,e,e,e,r,r,r,e,e,e,e,e,e,e,e,e,e,e,e,r,e,r,r]},__routerFilterDynamic:{numItems:4,errorRate:1e-4,numBits:77,numHashes:14,bitArray:[r,r,e,r,r,e,r,e,e,r,e,r,e,e,r,e,e,e,r,e,r,e,e,e,r,e,r,r,e,r,e,e,e,e,e,e,e,r,r,r,e,e,e,e,e,e,e,e,e,e,e,r,r,r,r,r,e,e,e,e,r,r,r,r,e,e,r,e,e,r,e,e,r,r,r,r,e]},"/_error":["static/chunks/pages/_error-a7f6723f42093f29.js"],sortedPages:["/_app","/_error"]}}(1,0,1e-4,14),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6923],{1213:(e,t,r)=>{function n(e,t){return t?"".concat(e,"?project=").concat(encodeURIComponent(t)):"".concat(e,"?project=all")}r.d(t,{Jy:()=>n}),r(5425)},1237:(e,t,r)=>{r.d(t,{dG:()=>l,i_:()=>a,j6:()=>o});var n=r(3817),s=r(545),c=r(4906);function a(e,t){let r=e+t;return r>1e3?"XL":r>500?"L":r>200?"M":r>50?"S":"XS"}function o(e){let{pr:t,muted:r=!1}=e,o=a(t.additions,t.deletions),l=(0,s.fZ)(t),i=(0,s.sZ)(t),u=l||i,d=u?"—":"merged"===t.state?"merged":"closed"===t.state?"closed":t.isDraft?"draft":"approved"===t.reviewDecision?"approved":"changes_requested"===t.reviewDecision?"changes requested":"needs review",p=u?"text-[var(--color-text-tertiary)]":t.isDraft?"text-[var(--color-text-muted)]":"approved"===t.reviewDecision?"text-[var(--color-accent-green)]":"changes_requested"===t.reviewDecision?"text-[var(--color-accent-red)]":"text-[var(--color-accent-yellow)]",m=(0,n.jsx)("span",{className:"inline-block h-3 w-12 animate-pulse rounded bg-[var(--color-bg-subtle)]"});return(0,n.jsxs)("tr",{className:"border-b border-[var(--color-border-subtle)] transition-colors hover:bg-[var(--color-bg-subtle)]".concat(r?" opacity-60 hover:opacity-100":""),children:[(0,n.jsx)("td",{className:"px-3 py-2.5 text-sm",children:(0,n.jsxs)("a",{href:t.url,target:"_blank",rel:"noopener noreferrer",className:"hover:underline",children:["#",t.number]})}),(0,n.jsx)("td",{className:"max-w-[420px] truncate px-3 py-2.5 text-sm font-medium",children:(0,n.jsx)("a",{href:t.url,target:"_blank",rel:"noopener noreferrer",className:"hover:underline",children:t.title})}),(0,n.jsx)("td",{className:"px-3 py-2.5 text-sm",children:i?m:l?(0,n.jsx)("span",{className:"text-[var(--color-text-tertiary)]",children:"—"}):(0,n.jsxs)(n.Fragment,{children:[(0,n.jsxs)("span",{className:"text-[var(--color-accent-green)]",children:["+",t.additions]})," ",(0,n.jsxs)("span",{className:"text-[var(--color-accent-red)]",children:["-",t.deletions]})," ",(0,n.jsx)("span",{className:"text-[var(--color-text-muted)]",children:o})]})}),(0,n.jsx)("td",{className:"px-3 py-2.5",children:i?m:l?(0,n.jsx)("span",{className:"text-[var(--color-text-tertiary)]",children:"—"}):(0,n.jsx)(c.wX,{status:t.ciStatus,checks:t.ciChecks,compact:!0})}),(0,n.jsx)("td",{className:"px-3 py-2.5 text-xs font-semibold ".concat(p),children:i?m:d}),(0,n.jsx)("td",{className:"px-3 py-2.5 text-center text-sm font-bold ".concat(i?"":t.unresolvedThreads>0?"text-[var(--color-accent-red)]":"text-[var(--color-border-default)]"),children:i?m:t.unresolvedThreads})]})}function l(e){let{pr:t,muted:r=!1}=e,c=(0,s.fZ)(t),a=(0,s.sZ)(t),o=c||a,l=o?"—":"passing"===t.ciStatus?"passing":"failing"===t.ciStatus?"failed":"pending",i=o?"—":"merged"===t.state?"merged":"closed"===t.state?"closed":t.isDraft?"draft":"approved"===t.reviewDecision?"approved":"changes_requested"===t.reviewDecision?"changes":"needs review",u=(0,n.jsx)("span",{className:"inline-block h-3 w-10 animate-pulse rounded bg-[var(--color-bg-subtle)]"}),d=o?null:"+".concat(t.additions," -").concat(t.deletions),p="merged"===t.state?"mobile-pr-card__meta--merged":"closed"===t.state?"mobile-pr-card__meta--closed":"changes_requested"===t.reviewDecision?"mobile-pr-card__meta--changes":"approved"===t.reviewDecision?"mobile-pr-card__meta--approved":"mobile-pr-card__meta--open";return(0,n.jsxs)("a",{href:t.url,target:"_blank",rel:"noopener noreferrer",className:"mobile-pr-card".concat(r?" mobile-pr-card--muted":""),children:[(0,n.jsxs)("div",{className:"mobile-pr-card__line",children:[(0,n.jsxs)("span",{className:"mobile-pr-card__number",children:["#",t.number]}),(0,n.jsx)("span",{className:"mobile-pr-card__title",children:t.title})]}),(0,n.jsxs)("div",{className:"mobile-pr-card__meta ".concat(p),children:[a?u:(0,n.jsxs)("span",{className:"mobile-pr-card__metric-value",children:[(0,n.jsx)("span",{className:"mobile-pr-card__ci-dot",style:{background:o?"var(--color-text-tertiary)":"passing"===t.ciStatus?"var(--color-accent-green)":"failing"===t.ciStatus?"var(--color-accent-red)":"var(--color-status-attention)"}}),(0,n.jsx)("span",{style:{color:o?void 0:"passing"===t.ciStatus?"var(--color-accent-green)":"failing"===t.ciStatus?"var(--color-accent-red)":"var(--color-text-secondary)"},children:l})]}),(0,n.jsx)("span",{className:"mobile-pr-card__review",style:{color:o?void 0:"approved"===t.reviewDecision?"var(--color-accent-green)":"changes_requested"===t.reviewDecision?"var(--color-accent-red)":"var(--color-text-secondary)"},children:a?u:i}),(0,n.jsx)("span",{className:"mobile-pr-card__diff",children:o?u:d})]})]})}},4906:(e,t,r)=>{r.d(t,{wX:()=>c,zm:()=>l});var n=r(3817);let s={passing:{label:"CI passing",className:"bg-[rgba(63,185,80,0.1)] text-[var(--color-accent-green)]",icon:"✓"},failing:{label:"CI failing",className:"bg-[rgba(248,81,73,0.15)] text-[var(--color-accent-red)]",icon:"✗"},pending:{label:"CI pending",className:"bg-[rgba(210,153,34,0.1)] text-[var(--color-accent-yellow)]",icon:"●"},none:{label:"—",className:"text-[var(--color-text-muted)]",icon:""}};function c(e){var t;let{status:r,checks:c,compact:a}=e,o=s[r],l=null!=(t=null==c?void 0:c.filter(e=>"failed"===e.status).length)?t:0;if("none"===r)return(0,n.jsx)("span",{className:"text-xs text-[var(--color-text-muted)]",children:"—"});let i="failing"===r&&l>0?"".concat(l," check").concat(l>1?"s":""," failing"):o.label;return(0,n.jsxs)("span",{className:"inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-semibold tracking-wide ".concat(o.className),children:[!a&&(0,n.jsx)("span",{children:o.icon}),i]})}let a={passed:{icon:"✓",color:"var(--color-accent-green)"},failed:{icon:"✗",color:"var(--color-accent-red)"},running:{icon:"●",color:"var(--color-accent-yellow)"},pending:{icon:"○",color:"var(--color-text-muted)"},skipped:{icon:"○",color:"var(--color-text-muted)"}},o={failed:0,running:1,pending:2,passed:3,skipped:4};function l(e){let{checks:t,layout:r="vertical"}=e,s=[...t].sort((e,t)=>o[e.status]-o[t.status]);return"inline"===r?(0,n.jsx)("div",{className:"flex flex-wrap items-center gap-x-3 gap-y-1",children:s.map(e=>{let{icon:t,color:r}=a[e.status],s=(0,n.jsxs)("span",{className:"inline-flex items-center gap-1 text-xs",children:[(0,n.jsx)("span",{style:{color:r},children:t}),(0,n.jsx)("span",{className:"text-[var(--color-text-secondary)]",children:e.name})]});return e.url?(0,n.jsx)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",className:"hover:no-underline",children:s},e.name):(0,n.jsx)("span",{children:s},e.name)})}):"expanded"===r?(0,n.jsx)("div",{className:"space-y-1",children:s.map(e=>{let{icon:t,color:r}=a[e.status],s=(0,n.jsxs)("span",{className:"inline-flex items-center gap-1 text-xs",children:[(0,n.jsx)("span",{style:{color:r},children:t}),(0,n.jsx)("span",{className:"text-[var(--color-text-secondary)]",children:e.name})]});return(0,n.jsxs)("div",{className:"flex items-center gap-2",children:[e.url?(0,n.jsx)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",className:"hover:no-underline",children:s}):s,e.url&&(0,n.jsx)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",className:"text-[11px] text-[var(--color-accent-blue)] hover:underline",children:"view"})]},e.name)})}):(0,n.jsx)("div",{className:"space-y-1",children:s.map(e=>{let{icon:t,color:r}=a[e.status];return(0,n.jsxs)("div",{className:"flex items-center gap-2 text-xs",children:[(0,n.jsx)("span",{style:{color:r},className:"w-3.5 shrink-0 text-center",children:t}),(0,n.jsx)("span",{className:"min-w-0 flex-1 truncate text-[var(--color-text-secondary)]",children:e.name}),e.url&&(0,n.jsx)("a",{href:e.url,target:"_blank",rel:"noopener noreferrer",className:"shrink-0 text-[11px] text-[var(--color-accent-blue)] hover:underline",children:"view"})]},e.name)})})}},5184:(e,t,r)=>{r.d(t,{Ug:()=>o,eT:()=>l,i2:()=>i});var n=r(3817),s=r(6749),c=r(1806);let a=s.createContext(void 0);function o(){let e=s.useContext(a);if(!e)throw Error("useMux() must be used within <MuxProvider>");return e}function l(){return s.useContext(a)}function i(e){let{children:t}=e,r=(0,s.useRef)(null),o=(0,s.useRef)(new Map),l=(0,s.useRef)(new Set),[i,u]=(0,s.useState)("connecting"),[d,p]=(0,s.useState)([]),m=(0,s.useRef)(0),f=(0,s.useRef)(null),v=(0,s.useRef)({}),x=(0,s.useRef)(!1),h=(0,s.useCallback)(()=>{if(!r.current){u("connecting");try{let e=function(e){var t,r,n;let s=window.location,a="https:"===s.protocol?"wss:":"ws:",o=null!=(t=e.proxyWsPath)?t:c.env.NEXT_PUBLIC_TERMINAL_WS_PATH;if(o){let e=o.replace(/\/ws\/?$/,"");return"".concat(a,"//").concat(s.host).concat(e,"/mux")}if(""===s.port||"443"===s.port||"80"===s.port)return"".concat(a,"//").concat(s.hostname,"/ao-terminal-mux");let l=null!=(n=null!=(r=e.directTerminalPort)?r:c.env.NEXT_PUBLIC_DIRECT_TERMINAL_PORT)?n:"14801";return"".concat(a,"//").concat(s.hostname,":").concat(l,"/mux")}(v.current);console.log("[MuxProvider] Connecting to",e);let t=new WebSocket(e);r.current=t,t.addEventListener("open",()=>{if(x.current)return void t.close();for(let e of(console.log("[MuxProvider] Connected"),u("connected"),m.current=0,l.current)){let r={ch:"terminal",id:e,type:"open"};t.send(JSON.stringify(r))}t.send(JSON.stringify({ch:"subscribe",topics:["sessions"]}))}),t.addEventListener("message",e=>{try{let t=JSON.parse(e.data);if("terminal"===t.ch)if("data"===t.type){let e=o.current.get(t.id);if(e)for(let r of e)r(t.data)}else if("opened"===t.type)l.current.add(t.id);else if("exited"===t.type){l.current.delete(t.id);let e=o.current.get(t.id);if(e){let r="\r\n\x1b[31m[Terminal exited with code ".concat(t.code,"]\x1b[0m\r\n");for(let t of e)t(r)}}else"error"===t.type&&console.error("[MuxProvider] Terminal error for ".concat(t.id,":"),t.message);else"sessions"===t.ch&&"snapshot"===t.type&&p(t.sessions)}catch(e){console.error("[MuxProvider] Error processing message:",e)}}),t.addEventListener("error",e=>{console.error("[MuxProvider] WebSocket error:",e)}),t.addEventListener("close",()=>{if(console.log("[MuxProvider] Disconnected"),r.current===t&&(r.current=null),x.current)return;let e=Math.min(1e3*Math.pow(2,m.current),3e4);m.current+=1,u("reconnecting"),f.current=setTimeout(()=>{console.log("[MuxProvider] Reconnecting (attempt ".concat(m.current,")...")),h()},e)})}catch(e){console.error("[MuxProvider] Failed to create WebSocket:",e),u("disconnected")}}},[]);(0,s.useEffect)(()=>{x.current=!1;let e=!1;return(async()=>{try{let e=await fetch("/api/runtime/terminal");if(e.ok){let t=await e.json();v.current={directTerminalPort:function(e){if("string"!=typeof e&&"number"!=typeof e)return;let t=Number.parseInt(String(e),10);if(Number.isInteger(t)&&!(t<=0)&&!(t>65535))return String(t)}(t.directTerminalPort),proxyWsPath:function(e){if("string"!=typeof e)return;let t=e.trim();if(t.startsWith("/"))return t}(t.proxyWsPath)}}}catch(e){}e||h()})(),()=>{var t;e=!0,x.current=!0,f.current&&clearTimeout(f.current),null==(t=r.current)||t.close()}},[h]);let g=(0,s.useCallback)((e,t)=>{var n;let s=o.current.get(e);return s||(s=new Set,o.current.set(e,s)),s.add(t),l.current.has(e)||(null==(n=r.current)?void 0:n.readyState)!==WebSocket.OPEN||r.current.send(JSON.stringify({ch:"terminal",id:e,type:"open"})),()=>{let r=o.current.get(e);r&&(r.delete(t),0===r.size&&o.current.delete(e))}},[]),b=(0,s.useCallback)((e,t)=>{var n;(null==(n=r.current)?void 0:n.readyState)===WebSocket.OPEN&&r.current.send(JSON.stringify({ch:"terminal",id:e,type:"data",data:t}))},[]),y=(0,s.useCallback)(e=>{var t;l.current.add(e),(null==(t=r.current)?void 0:t.readyState)===WebSocket.OPEN&&r.current.send(JSON.stringify({ch:"terminal",id:e,type:"open"}))},[]),N=(0,s.useCallback)(e=>{var t;l.current.delete(e),(null==(t=r.current)?void 0:t.readyState)===WebSocket.OPEN&&r.current.send(JSON.stringify({ch:"terminal",id:e,type:"close"}))},[]),w=(0,s.useCallback)((e,t,n)=>{var s;(null==(s=r.current)?void 0:s.readyState)===WebSocket.OPEN&&r.current.send(JSON.stringify({ch:"terminal",id:e,type:"resize",cols:t,rows:n}))},[]),j=(0,s.useMemo)(()=>({subscribeTerminal:g,writeTerminal:b,openTerminal:y,closeTerminal:N,resizeTerminal:w,status:i,sessions:d}),[g,b,y,N,w,i,d]);return(0,n.jsx)(a.Provider,{value:j,children:t})}},5309:(e,t,r)=>{r.d(t,{D:()=>o});var n=r(6749),s=r(545);function c(e,t){switch(t.type){case"reset":return{...e,sessions:t.sessions,...void 0!==t.sseAttentionLevels?{sseAttentionLevels:t.sseAttentionLevels}:{}};case"setConnection":return{...e,connectionStatus:t.status};case"snapshot":{let r=new Map(t.patches.map(e=>[e.id,e])),n=!1,s=e.sessions.map(e=>{let t=r.get(e.id);return t&&(e.status!==t.status||e.activity!==t.activity||e.lastActivityAt!==t.lastActivityAt)?(n=!0,{...e,status:t.status,activity:t.activity,lastActivityAt:t.lastActivityAt}):e}),c={};for(let e of t.patches)c[e.id]=e.attentionLevel;let a=n,o=Object.keys(c).length!==Object.keys(e.sseAttentionLevels).length||t.patches.some(t=>e.sseAttentionLevels[t.id]!==t.attentionLevel);if(!a&&!o)return e;return{...e,sessions:a?s:e.sessions,sseAttentionLevels:o?c:e.sseAttentionLevels}}}}function a(e){return e.map(e=>e.id).sort().join("\0")}function o(e,t,r,o){let l=arguments.length>4&&void 0!==arguments[4]&&arguments[4],[i,u]=(0,n.useReducer)(c,{sessions:e,connectionStatus:"connected",sseAttentionLevels:null!=o?o:{}}),d=(0,n.useRef)(i.sessions),p=(0,n.useRef)(o);p.current=o;let m=(0,n.useRef)(!1),f=(0,n.useRef)(null),v=(0,n.useRef)(null),x=(0,n.useRef)(0),h=(0,n.useRef)(null),g=(0,n.useRef)(null);(0,n.useEffect)(()=>{d.current=i.sessions},[i.sessions]),(0,n.useEffect)(()=>{var t;u({type:"reset",sessions:e,sseAttentionLevels:null!=(t=p.current)?t:{}})},[e]);let b=void 0!==r,y=(0,n.useCallback)(()=>{m.current||f.current||(f.current=setTimeout(()=>{f.current=null,m.current=!0;let e=v.current,r=new AbortController;g.current=r,fetch(t?"/api/sessions?project=".concat(encodeURIComponent(t)):"/api/sessions",{signal:r.signal}).then(e=>e.ok?e.json():null).then(e=>{if(r.signal.aborted||!(null==e?void 0:e.sessions)){r.signal.aborted||(x.current=Date.now());return}x.current=Date.now();let t=Object.fromEntries(e.sessions.map(e=>[e.id,(0,s.ng)(e)]));u({type:"reset",sessions:e.sessions,sseAttentionLevels:t})}).catch(e=>{e instanceof DOMException&&"AbortError"===e.name||(console.warn("[useSessionEvents] refresh failed:",e),x.current=Date.now())}).finally(()=>{if(g.current===r&&(g.current=null),r.signal.aborted){m.current=!1,null!==v.current&&y();return}if(m.current=!1,null!==v.current&&v.current!==e)return void y();v.current=null})},120))},[t]);return(0,n.useEffect)(()=>{if(l||!r)return;let e=new Set(d.current.map(e=>e.id)),t=r.filter(t=>e.has(t.id)),n=r.some(t=>!e.has(t.id));u({type:"snapshot",patches:t});let s=a(d.current),c=a(t);return n||s!==c?(v.current=c,y()):Date.now()-x.current>=15e3&&y(),()=>{var e;null==(e=g.current)||e.abort(),g.current=null}},[l,r,y]),(0,n.useEffect)(()=>{if(l)return;if(b)return u({type:"setConnection",status:"connected"}),()=>{var e;f.current&&(clearTimeout(f.current),f.current=null),v.current=null,m.current=!1,null==(e=g.current)||e.abort(),g.current=null};x.current=0;let e=new EventSource(t?"/api/events?project=".concat(encodeURIComponent(t)):"/api/events"),r=!1,n=()=>{h.current&&(clearTimeout(h.current),h.current=null)};return e.onmessage=e=>{try{let t=JSON.parse(e.data);if("snapshot"===t.type){u({type:"snapshot",patches:t.sessions});let e=a(d.current),r=a(t.sessions);if(e!==r){v.current=r,y();return}Date.now()-x.current>=15e3&&y()}}catch(e){return}},e.onopen=()=>{n(),r||u({type:"setConnection",status:"connected"})},e.onerror=()=>{if(!r){if(e.readyState===EventSource.CLOSED){n(),u({type:"setConnection",status:"disconnected"});return}u({type:"setConnection",status:"reconnecting"}),null===h.current&&(h.current=setTimeout(()=>{h.current=null,r||e.readyState===EventSource.OPEN||u({type:"setConnection",status:"disconnected"})},4e3))}},()=>{var t;r=!0,null==(t=g.current)||t.abort(),g.current=null,m.current=!1,v.current=null,f.current&&(clearTimeout(f.current),f.current=null),n(),e.close()}},[l,t,b,y]),i}},7848:(e,t,r)=>{r.d(t,{S:()=>c,u:()=>a});var n=r(6749);let s={green:"#22c55e",yellow:"#eab308",red:"#ef4444"};function c(e){let t=0;for(let r of Object.values(e))("respond"===r||"review"===r||"merge"===r)&&t++;return t}function a(e){let{sseAttentionLevels:t,projectName:r="A"}=e,c=r.charAt(0).toUpperCase();return(0,n.useEffect)(()=>{let e=function(e,t){let r='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">\n <rect width="32" height="32" rx="6" fill="'.concat(t,'"/>\n <text x="16" y="23" text-anchor="middle" fill="white" font-family="sans-serif" font-weight="700" font-size="20">').concat(e,"</text>\n </svg>");return"data:image/svg+xml,".concat(encodeURIComponent(r))}(c,s[function(e){let t=Object.values(e);if(0===t.length)return"green";let r=!1;for(let e of t){if("respond"===e)return"red";("review"===e||"merge"===e)&&(r=!0)}return r?"yellow":"green"}(t)]),r=document.querySelector('link[rel="icon"]');r||((r=document.createElement("link")).rel="icon",document.head.appendChild(r)),r.type="image/svg+xml",r.href=e},[t,c]),null}}}]);
|