af360 0.1.13 → 0.1.14
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/bin/af360.mjs +38 -5
- package/dist/.next/BUILD_ID +1 -1
- package/dist/.next/app-build-manifest.json +69 -69
- package/dist/.next/app-path-routes-manifest.json +18 -18
- package/dist/.next/build-manifest.json +2 -2
- package/dist/.next/prerender-manifest.json +39 -39
- package/dist/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/_not-found.html +1 -1
- package/dist/.next/server/app/_not-found.rsc +1 -1
- package/dist/.next/server/app/ahead/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/ahead.html +1 -1
- package/dist/.next/server/app/ahead.rsc +1 -1
- package/dist/.next/server/app/api/browse/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/card/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/check/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/config/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/connections/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/connectors/github/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/consent/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/context/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/discover/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/expiry/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/first-light/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/handoff/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/health/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/incidents/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/insights/route.js +1 -1
- package/dist/.next/server/app/api/insights/route.js.nft.json +1 -1
- package/dist/.next/server/app/api/insights/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/log/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/pulse/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/radar/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/report/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/services/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/api/status/route.js +1 -1
- package/dist/.next/server/app/api/status/route_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/connections/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/connections.html +1 -1
- package/dist/.next/server/app/connections.rsc +1 -1
- package/dist/.next/server/app/dashboard/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/dashboard.html +1 -1
- package/dist/.next/server/app/dashboard.rsc +1 -1
- package/dist/.next/server/app/discoveries/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/discoveries.html +1 -1
- package/dist/.next/server/app/discoveries.rsc +1 -1
- package/dist/.next/server/app/expiry/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/expiry.html +1 -1
- package/dist/.next/server/app/expiry.rsc +1 -1
- package/dist/.next/server/app/fleet/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/fleet.html +1 -1
- package/dist/.next/server/app/fleet.rsc +1 -1
- package/dist/.next/server/app/home/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/home.html +1 -1
- package/dist/.next/server/app/home.rsc +1 -1
- package/dist/.next/server/app/legal/privacy/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/legal/terms/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/log/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/log.html +1 -1
- package/dist/.next/server/app/log.rsc +1 -1
- package/dist/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/projects.html +1 -1
- package/dist/.next/server/app/projects.rsc +1 -1
- package/dist/.next/server/app/radar/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/radar.html +1 -1
- package/dist/.next/server/app/radar.rsc +1 -1
- package/dist/.next/server/app/report/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/report.html +1 -1
- package/dist/.next/server/app/report.rsc +1 -1
- package/dist/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/settings.html +1 -1
- package/dist/.next/server/app/settings.rsc +1 -1
- package/dist/.next/server/app/sites/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/sites.html +1 -1
- package/dist/.next/server/app/sites.rsc +1 -1
- package/dist/.next/server/app/welcome/page_client-reference-manifest.js +1 -1
- package/dist/.next/server/app/welcome.html +1 -1
- package/dist/.next/server/app/welcome.rsc +1 -1
- package/dist/.next/server/app-paths-manifest.json +18 -18
- package/dist/.next/server/chunks/2817.js +1 -1
- package/dist/.next/server/chunks/8150.js +1 -1
- package/dist/.next/server/chunks/9170.js +1 -1
- package/dist/.next/server/middleware-manifest.json +5 -5
- package/dist/.next/server/pages/404.html +1 -1
- package/dist/.next/server/pages/500.html +1 -1
- package/dist/.next/server/server-reference-manifest.json +1 -1
- package/dist/build-id.json +96 -96
- package/dist/package.json +1 -1
- package/dist/shell/bin/af360-bridge.exe +0 -0
- package/lib/mcpActivity.mjs +1 -0
- package/package.json +1 -1
- package/scripts/mcp-server.mjs +174 -2
- package/shell/bin/af360-bridge.exe +0 -0
- /package/dist/.next/static/{da1c2e66999c334d135d9 → 0b943e6aa8d5ffe860588}/_buildManifest.js +0 -0
- /package/dist/.next/static/{da1c2e66999c334d135d9 → 0b943e6aa8d5ffe860588}/_ssgManifest.js +0 -0
|
@@ -12,7 +12,7 @@ f:I[4431,[],"MetadataBoundary"]
|
|
|
12
12
|
12:I[7150,[],""]
|
|
13
13
|
:HL["/_next/static/css/94d302c686de7e23.css","style"]
|
|
14
14
|
:HL["/_next/static/css/9b639a814d15c5ff.css","style"]
|
|
15
|
-
0:{"P":null,"b":"
|
|
15
|
+
0:{"P":null,"b":"0b943e6aa8d5ffe860588","p":"","c":["","welcome"],"i":false,"f":[[["",{"children":["welcome",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",["$","$1","c",{"children":[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/94d302c686de7e23.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}],["$","link","1",{"rel":"stylesheet","href":"/_next/static/css/9b639a814d15c5ff.css","precedence":"next","crossOrigin":"$undefined","nonce":"$undefined"}]],["$","html",null,{"lang":"en","dir":"ltr","suppressHydrationWarning":true,"className":"__variable_01ae00 __variable_f367f3 __variable_46fe82 __variable_c5564f","children":[["$","head",null,{"children":["$","script",null,{"src":"/boot.js"}]}],["$","body",null,{"children":["$","$L2",null,{"parallelRouterKey":"children","error":"$3","errorStyles":[],"errorScripts":[],"template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":404}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],[]],"forbidden":"$undefined","unauthorized":"$undefined"}]}]]}]]}],{"children":["welcome",["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":["__PAGE__",["$","$1","c",{"children":[["$","$L5",null,{"Component":"$6","searchParams":{},"params":{},"promises":["$@7","$@8"]}],null,["$","$L9",null,{"children":["$La",["$","$Lb",null,{"promise":"$@c"}]]}]]}],{},null,false]},null,false]},null,false],["$","$1","h",{"children":[null,[["$","$Ld",null,{"children":"$Le"}],null],["$","$Lf",null,{"children":["$","div",null,{"hidden":true,"children":["$","$10",null,{"fallback":null,"children":"$L11"}]}]}]]}],false]],"m":"$undefined","G":["$12",[]],"s":false,"S":true}
|
|
16
16
|
7:{}
|
|
17
17
|
8:"$0:f:0:1:2:children:2:children:1:props:children:0:props:params"
|
|
18
18
|
e:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
|
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"/_not-found/page": "app/_not-found/page.js",
|
|
3
|
+
"/api/connections/route": "app/api/connections/route.js",
|
|
3
4
|
"/api/card/route": "app/api/card/route.js",
|
|
5
|
+
"/api/browse/route": "app/api/browse/route.js",
|
|
4
6
|
"/api/check/route": "app/api/check/route.js",
|
|
7
|
+
"/api/consent/route": "app/api/consent/route.js",
|
|
5
8
|
"/api/discover/route": "app/api/discover/route.js",
|
|
6
|
-
"/api/browse/route": "app/api/browse/route.js",
|
|
7
|
-
"/api/context/route": "app/api/context/route.js",
|
|
8
|
-
"/api/insights/route": "app/api/insights/route.js",
|
|
9
|
-
"/api/connections/route": "app/api/connections/route.js",
|
|
10
|
-
"/api/handoff/route": "app/api/handoff/route.js",
|
|
11
|
-
"/api/incidents/route": "app/api/incidents/route.js",
|
|
12
|
-
"/api/first-light/route": "app/api/first-light/route.js",
|
|
13
9
|
"/api/expiry/route": "app/api/expiry/route.js",
|
|
10
|
+
"/api/handoff/route": "app/api/handoff/route.js",
|
|
14
11
|
"/api/health/route": "app/api/health/route.js",
|
|
15
|
-
"/api/consent/route": "app/api/consent/route.js",
|
|
16
|
-
"/api/services/route": "app/api/services/route.js",
|
|
17
12
|
"/api/connectors/github/route": "app/api/connectors/github/route.js",
|
|
18
|
-
"/api/
|
|
13
|
+
"/api/incidents/route": "app/api/incidents/route.js",
|
|
14
|
+
"/api/insights/route": "app/api/insights/route.js",
|
|
19
15
|
"/api/pulse/route": "app/api/pulse/route.js",
|
|
16
|
+
"/api/status/route": "app/api/status/route.js",
|
|
17
|
+
"/api/log/route": "app/api/log/route.js",
|
|
18
|
+
"/api/context/route": "app/api/context/route.js",
|
|
19
|
+
"/api/services/route": "app/api/services/route.js",
|
|
20
20
|
"/api/report/route": "app/api/report/route.js",
|
|
21
|
-
"/api/
|
|
21
|
+
"/api/first-light/route": "app/api/first-light/route.js",
|
|
22
22
|
"/api/radar/route": "app/api/radar/route.js",
|
|
23
|
-
"/api/
|
|
23
|
+
"/api/config/route": "app/api/config/route.js",
|
|
24
24
|
"/ahead/page": "app/ahead/page.js",
|
|
25
|
-
"/connections/page": "app/connections/page.js",
|
|
26
|
-
"/fleet/page": "app/fleet/page.js",
|
|
27
25
|
"/dashboard/page": "app/dashboard/page.js",
|
|
26
|
+
"/connections/page": "app/connections/page.js",
|
|
28
27
|
"/discoveries/page": "app/discoveries/page.js",
|
|
28
|
+
"/home/page": "app/home/page.js",
|
|
29
|
+
"/fleet/page": "app/fleet/page.js",
|
|
29
30
|
"/expiry/page": "app/expiry/page.js",
|
|
30
31
|
"/log/page": "app/log/page.js",
|
|
31
32
|
"/projects/page": "app/projects/page.js",
|
|
33
|
+
"/report/page": "app/report/page.js",
|
|
32
34
|
"/sites/page": "app/sites/page.js",
|
|
33
35
|
"/welcome/page": "app/welcome/page.js",
|
|
34
|
-
"/home/page": "app/home/page.js",
|
|
35
|
-
"/report/page": "app/report/page.js",
|
|
36
36
|
"/legal/privacy/page": "app/legal/privacy/page.js",
|
|
37
37
|
"/page": "app/page.js",
|
|
38
38
|
"/legal/terms/page": "app/legal/terms/page.js",
|
|
39
|
-
"/
|
|
40
|
-
"/
|
|
39
|
+
"/settings/page": "app/settings/page.js",
|
|
40
|
+
"/radar/page": "app/radar/page.js"
|
|
41
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";exports.id=2817,exports.ids=[2817],exports.modules={52817:(a,b,c)=>{c.d(b,{GG:()=>o,_d:()=>p,xF:()=>q});var d=c(29021),e=c(33873),f=c.n(e),g=c(71011),h=c(1232),i=c(86587);function j(a){return"unsaved"===a.losable?0:a.losable?1:"expiry"===a.kind?a.entrusted&&!a.cost?1:2:"site"===a.kind?2:3}function k(a){return a?a.items.map((a,b)=>({it:a,i:b})).sort((a,b)=>Number(!!a.it.handled)-Number(!!b.it.handled)||j(a.it)-j(b.it)||Number("red"===b.it.tone)-Number("red"===a.it.tone)||(a.it.since??1/0)-(b.it.since??1/0)||a.i-b.i).map(a=>a.it):[]}var l=c(88804);function m(a){return`${a} project${1===a?"":"s"}`}function n(a=(0,g.yF)()){return f().join(a,"last-look.json")}function o(a){let b=a.now??Date.now(),c=a.attention,d=function(a,b){if(!a)return null;let c=(0,i.yy)(a);if(c)return{commits:0,files:0,projects:0,components:{unpushed:{commits:0,projects:0},unsaved:{files:0,projects:0},unbacked:{projects:0,commits:0}},unmeasured:[],empty:c,zero:!c};let d=new Map(b.map(a=>[a.path.toLowerCase(),a])),e=0,f=0,g=0,h=0,j=0,m=0,n=0,o=0,p=0,q=[];for(let b of a?k(a).filter(a=>!a.handled&&a.losable):[]){let a="project"===b.kind?d.get(b.id):void 0;if(!a)continue;let c=!1;a.statusKnown?a.uncommitted>0&&(m+=a.uncommitted,n++,f+=a.uncommitted,c=!0):q.push({name:a.name,why:`af360 could not read ${a.name}'s working tree, so its unsaved changes are not in this number`,whyP:(0,l.ph)("radius.unmeasured.status","af360 could not read {0}'s working tree, so its unsaved changes are not in this number",a.name)}),(0,i.ze)(a)?(o++,null!==a.commitCount?(p+=a.commitCount,e+=a.commitCount,c=!0):q.push({name:a.name,why:`af360 could not count ${a.name}'s commits, so its history is not in this number`,whyP:(0,l.ph)("radius.unmeasured.commits","af360 could not count {0}'s commits, so its history is not in this number",a.name)})):null!==a.ahead?a.ahead>0&&(h+=a.ahead,j++,e+=a.ahead,c=!0):a.isGit&&a.hasRemote&&q.push({name:a.name,why:`${a.name} has no upstream branch set, so af360 cannot tell which of its commits are only here`,whyP:(0,l.ph)("radius.unmeasured.upstream","{0} has no upstream branch set, so af360 cannot tell which of its commits are only here",a.name)}),c&&g++}for(let a of b)a.isGit||a.looksDownloaded||q.some(b=>b.name===a.name)||q.push({name:a.name,why:`${a.name} is not in git, so af360 has no way to tell whether a copy of it exists anywhere else`,whyP:(0,l.ph)("radius.unmeasured.noGit","{0} is not in git, so af360 has no way to tell whether a copy of it exists anywhere else",a.name)});return{commits:e,files:f,projects:g,components:{unpushed:{commits:h,projects:j},unsaved:{files:m,projects:n},unbacked:{projects:o,commits:p}},unmeasured:q,empty:!1,zero:0===e&&0===f}}(c,a.projects)??{commits:0,files:0,projects:0,components:{unpushed:{commits:0,projects:0},unsaved:{files:0,projects:0},unbacked:{projects:0,commits:0}},unmeasured:[],empty:!0,zero:!1},e=function(a){var b,c;if(a.empty)return{tone:"clean",headline:(0,l.pl)("radius.empty.head","Nothing to lose yet"),under:(0,l.pl)("radius.empty.under","Point af360 at a folder and it will tell you what only exists here.")};if(a.zero){let b=a.unmeasured.length;return{tone:"clean",headline:0===b?(0,l.pl)("radius.zero.head","If this laptop died right now: nothing would be lost."):(0,l.pl)("radius.zero.headPartial","Everything af360 could check has a copy elsewhere"),under:0===b?(0,l.pl)("radius.zero.under","Every project af360 watches also exists somewhere off this machine."):(0,l.ph)("radius.zero.underPartial","Nothing af360 could measure is only on this machine - and it could not measure {0}, so this does not speak for that work.",m(b))}}let d=[];a.commits>0&&d.push((b=a.commits,`${b} commit${1===b?"":"s"}`)),a.files>0&&d.push((c=a.files,`${c} file${1===c?"":"s"}`));let e=d.join(", ");return{tone:"amber",headline:(0,l.ph)("radius.head","If this laptop died right now: {0} across {1} - gone forever.",e,m(a.projects)),under:(0,l.pl)("radius.under","That work exists nowhere but this machine.")}}(d),f=function(a){if(0===a.unmeasured.length)return null;let b=a.unmeasured.length;return(0,l.ph)("radius.excluded","{0} not included: af360 could not measure {1}.",m(b),1===b?a.unmeasured[0].name:"them this time")}(d),g=c?(0,i.Pl)(c):null,h=k(c).map(a=>({id:a.id,kind:a.kind,tone:a.tone,label:a.label,what:a.what,why:a.why,consequence:function(a){let b=j(a);return b<=1?"losable":2===b?"money":"hygiene"}(a),losable:a.losable,handled:a.handled,since:a.since,steps:a.steps,devSteps:a.devSteps,path:"project"===a.kind?a.id:void 0})),n=c?.tones??{},o=a.projects.map(a=>({name:a.name,path:a.path,isGit:a.isGit,branch:a.branch,hasRemote:a.hasRemote,remoteKnown:a.remoteKnown,statusKnown:a.statusKnown,uncommitted:a.uncommitted,deleted:a.deleted,ahead:a.ahead,behind:a.behind,commitCount:a.commitCount,lastCommit:a.lastCommit,lastActivity:a.lastActivity,tone:n[a.path.toLowerCase()]??null})),p=a.sites.map(a=>({label:a.entry.label??a.entry.url,url:a.entry.url,ok:a.current?a.current.ok:null,status:a.current?.status,checkedAt:a.current?.ts??null,since:a.sinceText,tone:n[a.entry.id]??null})),q=a.expiry.map(a=>({id:a.id,name:a.name,date:a.date,daysLeft:a.daysLeft,source:a.manual?"entrusted":"observed",kind:a.kind,cost:a.cost,done:a.done,note:a.note})),r={scannedAt:a.scannedAt,projects:a.projects.slice(0,250).map(a=>({path:a.path,name:a.name,uncommitted:a.uncommitted,statusKnown:a.statusKnown,ahead:a.ahead,commitCount:a.commitCount,hasRemote:a.hasRemote,lastCommit:a.lastCommit})),capped:a.projects.length>250||void 0,sites:a.sites.map(a=>({url:a.entry.url,ok:a.current?a.current.ok:null})),radius:{commits:d.commits,files:d.files,projects:d.projects}},s=a.previous.filter(b=>b.scannedAt!==a.scannedAt);return s.push(r),s.sort((a,b)=>a.scannedAt-b.scannedAt),{v:2,scannedAt:a.scannedAt,ts:b,configFault:a.configFault,empty:!c||(0,i.yy)(c),estate:{state:c?.state??"QUIET",open:c?.open??0,line:g?.line??"",under:g?.under??"",notChecked:a.notChecked,counts:{projects:a.projects.length,sites:a.sites.length,findings:h.length},findings:h},projects:o,sites:p,ahead:q,radius:{...d,headline:e.headline.en,under:e.under.en,tone:e.tone,excluded:f?f.en:null},looks:s.slice(-40)}}async function p(a=(0,g.yF)()){try{let b=JSON.parse(await d.promises.readFile(n(a),"utf8"));if(!b||"object"!=typeof b||"number"!=typeof b.scannedAt)return null;return b}catch{return null}}async function q(a,b=(0,g.yF)()){try{await d.promises.mkdir(b,{recursive:!0});let c=(0,h.fI)(a),e=f().join(b,`.last-look.${process.pid}.tmp`);await d.promises.writeFile(e,JSON.stringify(c)+"\n","utf8"),await d.promises.rename(e,n(b))}catch{}}},86587:(a,b,c)=>{c.d(b,{Pl:()=>n,W8:()=>k,yy:()=>m,ze:()=>l});var d=c(72346),e=c(88804),f=c(87078),g=c(83720);function h(a){return{what:a.what.en,whatP:a.what,why:a.why.en,whyP:a.why,evidence:a.evidence.map(a=>a.en),evidenceP:a.evidence,steps:a.steps.map(a=>a.en),stepsP:a.steps}}function i(a){return{action:a.en,actionP:a}}function j(a){return a?{handledNote:a.en,handledNoteP:a}:{}}function k(a){let b=a=>Array.isArray(a)?a:[],c=b(a.projects),k=b(a.urls),m=b(a.expiryItems),n=b(a.incidents),r=b(a.missingRoots),s=b(a.ignored),{snoozes:t,isAcked:u,isDupe:v,offline:w}=a,x=Date.now(),y=a=>{let b=t?.[a];return!!b&&new Date(b).getTime()>x},z=[],A={};for(let a of c){let b=a.path.toLowerCase(),h=function(a,b,c){var h,i;let j=[],k=[],m=[],n=[];a.changedTotal>0&&(j.push((0,e.ph)("attn.reason.unsaved",`{0} unsaved change${1===a.changedTotal?"":"s"}`,a.changedTotal)),k.push((0,e.ph)("attn.ev.changed",`changed: {0}${a.changedTotal>a.dirtyFiles.length?" and {1} more":""}`,a.dirtyFiles.join(", "),a.changedTotal-a.dirtyFiles.length))),a.deleted>0&&(j.push((0,e.ph)("attn.reason.deleted",`{0} file${1===a.deleted?"":"s"} deleted`,a.deleted)),k.push((0,e.ph)("attn.ev.deleted",`deleted: {0}${a.deleted>a.deletedFiles.length?" and {1} more":""}`,a.deletedFiles.join(", "),a.deleted-a.deletedFiles.length))),a.uncommitted>0&&(m.push((0,e.pl)("attn.step.commit","Commit the work - a commit makes it permanent history.")),n.push('git add -A && git commit -m "wip"')),a.deleted>0&&(m.push((0,e.pl)("attn.step.deleted","If a deletion was not meant, git still holds the file - restore it before committing.")),n.push("git restore --")),(a.ahead??0)>0&&(j.push((0,e.ph)("attn.reason.unpushed",`{0} commit${1===a.ahead?"":"s"} not pushed`,a.ahead??0)),k.push((0,e.ph)("attn.ev.onlyHere",`{0} commit${1===a.ahead?"":"s"} exist only on this machine`,a.ahead??0)),m.push((0,e.pl)("attn.step.push","Push once - the remote gets a full copy and the risk is gone.")),n.push("git push")),l(a)&&(j.push((0,e.pl)("attn.reason.noBackup","no backup anywhere")),k.push((0,e.pl)("attn.ev.noRemote","no remote is configured - this disk holds the only copy")),m.push((0,e.pl)("attn.step.createRepo","Create an empty repository on your code host, connect it, and push.")),n.push("git remote add origin <url>","git push -u origin main"));let o=a.isGit&&!a.statusKnown;o&&(j.push((0,e.pl)("unread.reason",d.UI.unread.reason)),k.push((0,e.pl)("unread.evidence",d.UI.unread.evidence)),m.push((0,e.pl)("unread.step",d.UI.unread.step)));let p=b?function(a,b){let c=b.filter(b=>b.name===a.name&&b.path!==a.path);if(0===c.length)return null;let d=a.remoteKnown?(0,f.p8)(a.remoteUrl):null,e=a=>a.remoteKnown?(0,f.p8)(a.remoteUrl):null;if(d){let a=c.filter(a=>e(a)===d);if(a.length>0)return{kind:"duplicate",others:a}}return!d||c.some(a=>null===e(a))?{kind:"unproven",others:c}:{kind:"sharesName",others:c}}(a,c):null,q=p?.kind==="duplicate"?p:null,r=!!q&&("dormant"===a.staleness||"forgotten"===a.staleness);if(0===j.length&&r&&q){for(let a of(j.push((0,e.pl)("attn.reason.dupe","a dormant duplicate")),q.others))k.push((0,e.ph)("attn.ev.livingCopy","the living copy: {0}",a.path));let b=(0,f.p8)(a.remoteUrl);b&&k.push((0,e.ph)("attn.ev.sameRemote","both point at the same repository: {0}",b)),a.lastActivity&&(0,g.nW)(a.lastActivity)?k.push((0,e.pl)("attn.ev.untouchedSkew",`this copy untouched ${g.lt.since}`)):k.push((0,e.ph)("attn.ev.untouched","this copy untouched {0}",a.lastActivity?(h=a.lastActivity,(0,g.I)(h)):"for a long time")),m.push((0,e.pl)("attn.step.keepOne","Keep one copy - archive or delete the other so future-you isn't guessing."))}if(0===j.length)return{tone:"clean",what:"",why:"",evidence:[],steps:[]};let s=l(a),t=a.uncommitted>0?"unsaved":(a.ahead??0)>0?"unpushed":s?"unbacked":void 0,u=o&&1===j.length,v="unsaved"===t?(0,e.ph)("act.save","Save {0}",a.name):"unpushed"===t?(0,e.ph)("act.push","Push {0}",a.name):"unbacked"===t?(0,e.ph)("act.backUp","Back up {0}",a.name):u?(0,e.ph)("unread.what","af360 could not finish reading {0}.",a.name):(0,e.ph)("act.duplicate","Decide on {0}'s duplicate",a.name),w=(i=j.map(a=>a.en),(0,e.nn)(i,e.v1.and,e.v1.comma)),x=u?(0,e.ph)("unread.what","af360 could not finish reading {0}.",a.name):{...(0,e.ph)("attn.project.what","{0} has {1}.",a.name,w),list:{slot:1,items:j}},y=u?(0,e.pl)("unread.why",d.UI.unread.why):s?(0,e.pl)("attn.why.noBackup","One disk failure and it's gone - a remote copy fixes that in a minute."):(a.ahead??0)>0&&0===a.uncommitted?(0,e.pl)("attn.why.unpushed","A push costs a minute; losing them costs the work."):r&&0===a.uncommitted?(0,e.pl)("attn.why.dupe","Two copies of one project drift apart quietly."):(0,e.pl)("attn.why.unsaved","Unsaved work survives nowhere - one bad day and it's gone.");return k.push((0,e.ph)("attn.ev.path","{0}",`path: ${a.path}`)),{tone:"amber",what:x.en,why:y.en,whatP:x,whyP:y,since:a.lastActivity?new Date(a.lastActivity).getTime():void 0,evidence:k.map(a=>a.en),evidenceP:k,steps:m.map(a=>a.en),stepsP:m,devSteps:n.length>0?n:void 0,losable:t,action:v.en,actionP:v}}(a,v(a.name),c);A[b]=h.tone,"clean"!==h.tone&&z.push({...h,id:b,kind:"project",label:a.name,handled:y(b)||void 0,handledNote:y(b)?"quiet until tomorrow":void 0,openPath:a.path,laterId:b,ignore:{id:b,kind:"project",label:a.name,atRisk:l(a)}})}let B=a.github;if(B)for(let a of c){let b=B.byPath[a.path.toLowerCase()];if(!b?.ok)continue;let c=b.value;if(c.ci.ok&&c.ci.value&&"failing"===c.ci.value.state){let b=c.ci.value,d=`ci:${a.path.toLowerCase()}`;z.push({id:d,kind:"project",tone:"amber",label:a.name,since:b.at,...h({what:(0,e.ph)("attn.gh.ci.what","{0}'s build failed on {1}.",a.name,b.branch),why:(0,e.pl)("attn.gh.ci.why","GitHub Actions went red - the last push didn't survive CI."),evidence:[(0,e.ph)("attn.gh.ci.ev1","the {0} workflow reported {1}",b.workflow,b.conclusion??"a failure"),(0,e.ph)("attn.gh.ci.ev2","on branch {0}",b.branch),(0,e.ph)("attn.gh.ci.ev3","GitHub last moved this run at {0}",new Date(b.at).toISOString())],steps:[(0,e.pl)("attn.gh.ci.step1","Open the run on GitHub and read the first failing step - the rest usually follow from it."),(0,e.pl)("attn.gh.ci.step2","Nothing here is lost: the commits are pushed. This is about the checks, not the work.")]}),handled:y(d)||void 0,...j(y(d)?(0,e.pl)("attn.handled.snoozed","quiet until tomorrow"):void 0),openPath:a.path,laterId:d,...i((0,e.ph)("act.gh.ci","Read {0}'s failing run on GitHub",a.name))})}if("refuted"===c.backup.verdict){let b=c.backup,d=`backup:${a.path.toLowerCase()}`;z.push({id:d,kind:"project",tone:"amber",label:a.name,losable:"unpushed",...h({what:(0,e.ph)("attn.gh.backup.what","{0} says everything is pushed, and GitHub doesn't have it.",a.name),why:(0,e.pl)("attn.gh.backup.why","Local git reports nothing to push and nothing to pull, so this machine and GitHub should be on the same commit. They aren't."),evidence:[(0,e.ph)("attn.gh.backup.ev1","this machine is on {0} at branch {1}",b.localSha.slice(0,12),b.branch),(0,e.ph)("attn.gh.backup.ev2","GitHub's {0} is at {1}",b.branch,b.remoteSha.slice(0,12)),(0,e.pl)("attn.gh.backup.ev3","af360 asked both ends this scan - this is not read from local git's own record of the remote")],steps:[(0,e.pl)("attn.gh.backup.step1","Fetch from the remote and look again - the usual cause is that this machine's record of the remote is out of date."),(0,e.pl)("attn.gh.backup.step2","If the commits really are only here, push them. Until then treat this project as not backed up.")]}),devSteps:["git fetch --all","git status -sb","git log --oneline -1 HEAD"],handled:y(d)||void 0,...j(y(d)?(0,e.pl)("attn.handled.snoozed","quiet until tomorrow"):void 0),openPath:a.path,laterId:d,...i((0,e.ph)("act.gh.backup","Check where {0}'s commits actually are",a.name))})}}if(w&&k.length>0){for(let a of k)A[a.entry.id]="clean";z.push({id:"offline",kind:"site",tone:"amber",label:"Internet connection",...h({what:(0,e.pl)("attn.offline.what","This computer seems to be offline."),why:(0,e.pl)("attn.offline.why","Your sites may be perfectly fine - af360 can't reach anything right now, so it won't guess."),evidence:[(0,e.ph)("attn.offline.ev1","none of the {0} watched sites answered",k.length),(0,e.pl)("attn.offline.ev2","the domain lookup didn't get through either"),(0,e.pl)("attn.offline.ev3","checks keep running while af360 is open; this clears itself the moment something answers")],steps:[(0,e.pl)("attn.offline.step1","Check this machine's internet connection - wifi, cable, or a VPN that dropped."),(0,e.pl)("attn.offline.step2","Nothing to do here once it's back: af360 rechecks every minute while it is open, and clears this on its own.")]}),devSteps:["ping 1.1.1.1","nslookup example.com"],...i((0,e.pl)("act.offline","Check this machine's connection"))})}for(let a of w?[]:k){let b=a.entry.id,c=a.current,d=a.entry.label||function(a){try{return new URL(a).hostname}catch{return a}}(a.entry.url);if(!c||c.ok){A[b]="clean";continue}A[b]="red";let f=n.find(a=>a.subjectId===b&&!a.endedTs),g=u(b),k=y(b);z.push({id:b,kind:"site",tone:"red",label:d,...h({what:c.status?(0,e.ph)("attn.down.whatStatus","{0} is down (HTTP {1}).",d,c.status):c.error?(0,e.ph)("attn.down.whatError","{0} is down - {1}.",d,c.error):(0,e.ph)("attn.down.what","{0} is down.",d),why:(0,e.pl)("attn.down.why","af360 asked for your site from this machine and got an error back instead of the page."),evidence:[(0,e.ph)("attn.down.evUrl","{0}",a.entry.url),c.status?(0,e.ph)("attn.down.evAnswer","last answer: HTTP {0}",c.status):c.error?(0,e.ph)("attn.down.evAnswerText","last answer: {0}",c.error):(0,e.pl)("attn.down.evNoAnswer","no answer"),f?(0,e.ph)("attn.down.evSince","down since {0}",new Date(f.startedTs).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})):(0,e.pl)("attn.down.evJust","just went quiet"),(0,e.pl)("attn.down.evCadence","checked every minute while af360 is open; recovery is logged automatically")],steps:[(0,e.pl)("attn.down.step1","Open your host's dashboard - most outages are a crashed service or a failed deploy."),(0,e.pl)("attn.down.step2","Press Check once you're on it; the row calms down and clears itself when the site answers again.")]}),since:f?.startedTs,handled:g||k||void 0,...j(g?(0,e.pl)("attn.handled.acked","being handled ✓"):k?(0,e.pl)("attn.handled.snoozed","quiet until tomorrow"):void 0),devSteps:[`curl -sI ${a.entry.url}`],...i((0,e.ph)("act.siteDown","{0} is down",d)),checkId:b,laterId:b,ignore:{id:b,kind:"url",label:d,atRisk:!0}})}for(let a of s){if(!a.resurface)continue;let b=`resurface:${a.id}`;A[b]="amber",z.push({id:b,kind:"resurface",tone:"amber",label:a.label,...h({what:(0,e.ph)("attn.resurface.what","{0}",a.resurface.text),why:(0,e.pl)("attn.resurface.why","You silenced this earlier - the situation moved, so it gets one more look."),evidence:[(0,e.ph)("attn.resurface.evThen","ignored at: {0}",o(a.snapshot)),(0,e.ph)("attn.resurface.evNow","now: {0}",o(a.resurface.current))],steps:[(0,e.pl)("attn.resurface.step","Watch again to bring it back, or Still ignore to re-silence it at today's numbers.")]}),...i((0,e.ph)("act.decide","Decide on {0}",a.label)),resurfaceId:a.id,ignore:{id:a.id,kind:a.kind,label:a.label,atRisk:!1}})}for(let a of m){if(a.manual){if(a.done||null===a.rung||void 0===a.rung){A[a.id]="clean";continue}A[a.id]="amber";let b=y(a.id);z.push({id:a.id,kind:"expiry",tone:"amber",label:a.name,entrusted:!0,cost:a.cost,passed:a.passed,entrustedId:a.id,...h({what:a.passed?(0,e.ph)("attn.entrusted.passed","{0} was due {1}.",a.name,q(a.daysLeft)):(0,e.ph)("attn.entrusted.what","{0} is due {1}.",a.name,q(a.daysLeft)),why:a.note?(0,e.ph)("attn.entrusted.userNote","{0}",a.note):(0,e.pl)("attn.entrusted.why","You asked af360 to tell you about this one."),evidence:[(0,e.pl)("attn.entrusted.evAdded","you added this date"),(0,e.ph)("attn.expiry.evDate","date: {0}",new Date(a.date).toLocaleDateString()),a.note?(0,e.ph)("attn.entrusted.evNote",'what you wrote: "{0}"',a.note):null].filter(a=>null!==a),steps:[(0,e.pl)("attn.entrusted.step","Deal with it, or open Ahead to change the date, mark it done or remove it.")]}),handled:b||void 0,...j(b?(0,e.pl)("attn.handled.snoozed","quiet until tomorrow"):void 0),...i((0,e.ph)("act.entrusted","Deal with {0}",a.name)),laterId:a.id});continue}let b="red"===a.chip||"amber"===a.chip&&"ssl"===a.kind&&a.managed;if(A[a.id]=b?"amber":"clean",!b)continue;let c=y(a.id);z.push({id:a.id,kind:"expiry",tone:"amber",label:a.name,...h({what:"ssl"===a.kind&&a.managed&&"red"!==a.chip?(0,e.ph)("attn.expiry.certLate","{0}'s certificate should have auto-renewed by now - it hasn't.",a.name):a.daysLeft<0?(0,e.ph)("attn.expiry.expired","{0} expired {1}.",a.name,q(a.daysLeft)):(0,e.ph)("attn.expiry.expires","{0} expires {1}.",a.name,q(a.daysLeft)),why:a.note?(0,e.ph)("attn.expiry.userNote","{0}",a.note):"ssl"===a.kind?(0,e.pl)("attn.expiry.whySsl","When it lapses, browsers show a scary warning instead of your site."):(0,e.pl)("attn.expiry.whyDomain","After the date it stops working - renewing early is painless."),evidence:[(0,e.ph)("attn.expiry.evDate","date: {0}",new Date(a.date).toLocaleDateString()),a.judgment?(0,e.ph)("attn.expiry.evJudgment","{0}",a.judgment):a.note?(0,e.ph)("attn.expiry.evNote",'your note: "{0}"',a.note):null,a.issuer?(0,e.ph)("attn.expiry.evIssuer","issuer: {0}",a.issuer):null].filter(a=>null!==a),steps:"ssl"===a.kind?[(0,e.pl)("attn.expiry.stepSsl","Ask your host why the renewal hasn't landed - managed certificates renew on their own, so a late one means something is stuck.")]:[(0,e.pl)("attn.expiry.stepDomain","Renew it (or let it lapse on purpose), then remove or update the entry on Ahead.")]}),handled:c||void 0,...j(c?(0,e.pl)("attn.handled.snoozed","quiet until tomorrow"):void 0),...i("ssl"===a.kind&&a.managed&&"red"!==a.chip?(0,e.ph)("act.certLate","Chase {0}'s certificate",a.name):(0,e.ph)("act.renew","Renew {0}",a.name)),laterId:a.id})}for(let a of r){let b=`missing:${a}`;A[b]="amber",z.push({id:b,kind:"missing",tone:"amber",label:p(a),...h({what:(0,e.ph)("attn.missing.what","The folder {0} can't be found",a),why:(0,e.pl)("attn.missing.why","It moved or was renamed - point me at its new home, or stop watching it."),evidence:[(0,e.ph)("attn.missing.evPath","watched path: {0}",a),(0,e.pl)("attn.missing.evScan","the folder stopped answering on the last scan")],steps:[(0,e.pl)("attn.missing.step1","Press Find it and click through to where the folder lives now - the old entry is replaced."),(0,e.pl)("attn.missing.step2","If it's gone on purpose, Stop watching removes it.")]}),...i((0,e.ph)("act.find","Find {0}",p(a))),findPath:a})}z.sort((a,b)=>Number(a.handled??!1)-Number(b.handled??!1)||Number("red"===b.tone)-Number("red"===a.tone));let C=z.filter(a=>!a.handled).length,D=z.some(a=>"red"===a.tone&&!a.handled),E=b(a.findings).filter(a=>a?.cat==="safety").length,F=0;if(B){for(let a of c){let b=B.byPath[a.path.toLowerCase()];b&&!b.ok&&F++}B.outage&&F++}return F+=b(a.unreachedChecks).length,{state:D?"INCIDENT":C>0?"NEEDS_YOU":E>0?"SAFETY":"QUIET",open:C,items:z,tones:A,unreached:F+=new Set(b(a.unscannedSubjects)).size,safety:E}}function l(a){return a.isGit&&a.remoteKnown&&!a.hasRemote&&!a.looksDownloaded}function m(a){return 0===a.items.length&&0===Object.keys(a.tones).length}function n(a){let b=(a,b)=>({line:a.en,under:b.en,lineP:a,underP:b});if(m(a))return b((0,e.pl)("head.emptyLine","Nothing watched yet"),(0,e.pl)("head.emptyUnder","Point me at a folder and I'll show you the projects inside it."));if("INCIDENT"===a.state){let c=a.items.filter(a=>"red"===a.tone&&!a.handled);return b(1===c.length?(0,e.ph)("head.downOne","{0} is down",c[0].label):(0,e.ph)("head.downMany","{0} down",c.length),1===c.length?(0,e.pl)("head.incidentUnder","everything else can wait - this is the one to look at"):(0,e.pl)("head.incidentUnderMany","everything else can wait - these are the ones to look at"))}if("NEEDS_YOU"===a.state)return a.safety>0?b((0,e.ph)("head.needsLine",`{0} need${1===a.open?"s":""} you`,a.open),(0,e.ph)("head.needsUnderSafety",`none of it is on fire - each has a reason, and {0} safety finding${1===a.safety?" is":"s are"} waiting in Discoveries`,a.safety)):b((0,e.ph)("head.needsLine",`{0} need${1===a.open?"s":""} you`,a.open),(0,e.pl)("head.needsUnder","none of it is on fire - each has a reason"));let c=a.items.filter(a=>a.handled).length,d=a.unreached??0,f=a=>`thing${1===a?"":"s"}`;if("SAFETY"===a.state){let c=a.safety;return b((0,e.ph)("head.safetyLine",`{0} safety finding${1===c?"":"s"}`,c),d>0?(0,e.ph)("head.safetyMissed",`${1===c?"it is":"they are"} waiting in Discoveries - and af360 couldn't check {0} ${f(d)} this time`,d):(0,e.pl)("head.safetyUnder",`${1===c?"it is":"they are"} waiting in Discoveries`))}return b((0,e.pl)("head.quietLine","All quiet"),c>0?d>0?(0,e.ph)("head.quietHandledMissed",`nothing new needs you - {0} item${1===c?" is":"s are"} being handled, and af360 couldn't check {1} ${f(d)} this time`,c,d):(0,e.ph)("head.quietHandled",`nothing new needs you - {0} item${1===c?" is":"s are"} being handled`,c):d>0?(0,e.ph)("head.quietMissed",`nothing needs you - and af360 couldn't check {0} ${f(d)} this time`,d):(0,e.pl)("head.quietUnder","nothing needs you - go build something"))}function o(a){if(!a)return"nothing recorded";let b=[];return"number"==typeof a.uncommitted&&b.push(`${a.uncommitted} unsaved`),!1===a.hasRemote&&b.push("no backup"),a.down&&b.push("down"),b.length>0?b.join(", "):"all fine"}function p(a){let b=a.split(/[\\/]/).filter(Boolean);return b[b.length-1]??a}function q(a){return a<0?`${-a} day${-1===a?"":"s"} ago`:0===a?"today":1===a?"tomorrow":`in ${a} days`}}};
|
|
1
|
+
"use strict";exports.id=2817,exports.ids=[2817],exports.modules={52817:(a,b,c)=>{c.d(b,{GG:()=>o,_d:()=>p,eN:()=>r,xF:()=>q});var d=c(29021),e=c(33873),f=c.n(e),g=c(71011),h=c(1232),i=c(86587);function j(a){return"unsaved"===a.losable?0:a.losable?1:"expiry"===a.kind?a.entrusted&&!a.cost?1:2:"site"===a.kind?2:3}function k(a){return a?a.items.map((a,b)=>({it:a,i:b})).sort((a,b)=>Number(!!a.it.handled)-Number(!!b.it.handled)||j(a.it)-j(b.it)||Number("red"===b.it.tone)-Number("red"===a.it.tone)||(a.it.since??1/0)-(b.it.since??1/0)||a.i-b.i).map(a=>a.it):[]}var l=c(88804);function m(a){return`${a} project${1===a?"":"s"}`}function n(a=(0,g.yF)()){return f().join(a,"last-look.json")}function o(a){let b=a.now??Date.now(),c=a.attention,d=function(a,b){if(!a)return null;let c=(0,i.yy)(a);if(c)return{commits:0,files:0,projects:0,components:{unpushed:{commits:0,projects:0},unsaved:{files:0,projects:0},unbacked:{projects:0,commits:0}},unmeasured:[],empty:c,zero:!c};let d=new Map(b.map(a=>[a.path.toLowerCase(),a])),e=0,f=0,g=0,h=0,j=0,m=0,n=0,o=0,p=0,q=[];for(let b of a?k(a).filter(a=>!a.handled&&a.losable):[]){let a="project"===b.kind?d.get(b.id):void 0;if(!a)continue;let c=!1;a.statusKnown?a.uncommitted>0&&(m+=a.uncommitted,n++,f+=a.uncommitted,c=!0):q.push({name:a.name,why:`af360 could not read ${a.name}'s working tree, so its unsaved changes are not in this number`,whyP:(0,l.ph)("radius.unmeasured.status","af360 could not read {0}'s working tree, so its unsaved changes are not in this number",a.name)}),(0,i.ze)(a)?(o++,null!==a.commitCount?(p+=a.commitCount,e+=a.commitCount,c=!0):q.push({name:a.name,why:`af360 could not count ${a.name}'s commits, so its history is not in this number`,whyP:(0,l.ph)("radius.unmeasured.commits","af360 could not count {0}'s commits, so its history is not in this number",a.name)})):null!==a.ahead?a.ahead>0&&(h+=a.ahead,j++,e+=a.ahead,c=!0):a.isGit&&a.hasRemote&&q.push({name:a.name,why:`${a.name} has no upstream branch set, so af360 cannot tell which of its commits are only here`,whyP:(0,l.ph)("radius.unmeasured.upstream","{0} has no upstream branch set, so af360 cannot tell which of its commits are only here",a.name)}),c&&g++}for(let a of b)a.isGit||a.looksDownloaded||q.some(b=>b.name===a.name)||q.push({name:a.name,why:`${a.name} is not in git, so af360 has no way to tell whether a copy of it exists anywhere else`,whyP:(0,l.ph)("radius.unmeasured.noGit","{0} is not in git, so af360 has no way to tell whether a copy of it exists anywhere else",a.name)});return{commits:e,files:f,projects:g,components:{unpushed:{commits:h,projects:j},unsaved:{files:m,projects:n},unbacked:{projects:o,commits:p}},unmeasured:q,empty:!1,zero:0===e&&0===f}}(c,a.projects)??{commits:0,files:0,projects:0,components:{unpushed:{commits:0,projects:0},unsaved:{files:0,projects:0},unbacked:{projects:0,commits:0}},unmeasured:[],empty:!0,zero:!1},e=function(a){var b,c;if(a.empty)return{tone:"clean",headline:(0,l.pl)("radius.empty.head","Nothing to lose yet"),under:(0,l.pl)("radius.empty.under","Point af360 at a folder and it will tell you what only exists here.")};if(a.zero){let b=a.unmeasured.length;return{tone:"clean",headline:0===b?(0,l.pl)("radius.zero.head","If this laptop died right now: nothing would be lost."):(0,l.pl)("radius.zero.headPartial","Everything af360 could check has a copy elsewhere"),under:0===b?(0,l.pl)("radius.zero.under","Every project af360 watches also exists somewhere off this machine."):(0,l.ph)("radius.zero.underPartial","Nothing af360 could measure is only on this machine - and it could not measure {0}, so this does not speak for that work.",m(b))}}let d=[];a.commits>0&&d.push((b=a.commits,`${b} commit${1===b?"":"s"}`)),a.files>0&&d.push((c=a.files,`${c} file${1===c?"":"s"}`));let e=d.join(", ");return{tone:"amber",headline:(0,l.ph)("radius.head","If this laptop died right now: {0} across {1} - gone forever.",e,m(a.projects)),under:(0,l.pl)("radius.under","That work exists nowhere but this machine.")}}(d),f=function(a){if(0===a.unmeasured.length)return null;let b=a.unmeasured.length;return(0,l.ph)("radius.excluded","{0} not included: af360 could not measure {1}.",m(b),1===b?a.unmeasured[0].name:"them this time")}(d),g=c?(0,i.Pl)(c):null,h=k(c).map(a=>({id:a.id,kind:a.kind,tone:a.tone,label:a.label,what:a.what,why:a.why,consequence:function(a){let b=j(a);return b<=1?"losable":2===b?"money":"hygiene"}(a),losable:a.losable,handled:a.handled,since:a.since,steps:a.steps,devSteps:a.devSteps,path:"project"===a.kind?a.id:void 0})),n=c?.tones??{},o=a.projects.map(a=>({name:a.name,path:a.path,isGit:a.isGit,branch:a.branch,hasRemote:a.hasRemote,remoteKnown:a.remoteKnown,statusKnown:a.statusKnown,uncommitted:a.uncommitted,deleted:a.deleted,ahead:a.ahead,behind:a.behind,commitCount:a.commitCount,lastCommit:a.lastCommit,lastActivity:a.lastActivity,tone:n[a.path.toLowerCase()]??null})),p=a.sites.map(a=>({label:a.entry.label??a.entry.url,url:a.entry.url,ok:a.current?a.current.ok:null,status:a.current?.status,checkedAt:a.current?.ts??null,since:a.sinceText,tone:n[a.entry.id]??null})),q=a.expiry.map(a=>({id:a.id,name:a.name,date:a.date,daysLeft:a.daysLeft,source:a.manual?"entrusted":"observed",kind:a.kind,cost:a.cost,done:a.done,note:a.note})),r={scannedAt:a.scannedAt,projects:a.projects.slice(0,250).map(a=>({path:a.path,name:a.name,uncommitted:a.uncommitted,statusKnown:a.statusKnown,ahead:a.ahead,commitCount:a.commitCount,hasRemote:a.hasRemote,lastCommit:a.lastCommit})),capped:a.projects.length>250||void 0,sites:a.sites.map(a=>({url:a.entry.url,ok:a.current?a.current.ok:null})),radius:{commits:d.commits,files:d.files,projects:d.projects}},s=a.previous.filter(b=>b.scannedAt!==a.scannedAt);return s.push(r),s.sort((a,b)=>a.scannedAt-b.scannedAt),{v:2,scannedAt:a.scannedAt,ts:b,configFault:a.configFault,empty:!c||(0,i.yy)(c),estate:{state:c?.state??"QUIET",open:c?.open??0,line:g?.line??"",under:g?.under??"",notChecked:a.notChecked,counts:{projects:a.projects.length,sites:a.sites.length,findings:h.length},findings:h},projects:o,sites:p,ahead:q,radius:{...d,headline:e.headline.en,under:e.under.en,tone:e.tone,excluded:f?f.en:null},looks:s.slice(-40),discoveries:a.discoveries}}async function p(a=(0,g.yF)()){try{let b=JSON.parse(await d.promises.readFile(n(a),"utf8"));if(!b||"object"!=typeof b||"number"!=typeof b.scannedAt)return null;return b}catch{return null}}async function q(a,b=(0,g.yF)()){try{await d.promises.mkdir(b,{recursive:!0});let c=(0,h.fI)(a),e=f().join(b,`.last-look.${process.pid}.tmp`);await d.promises.writeFile(e,JSON.stringify(c)+"\n","utf8"),await d.promises.rename(e,n(b))}catch{}}async function r(a,b=(0,g.yF)()){try{let c=await p(b);if(!c)return;let e={...c,discoveries:(0,h.fI)(a)};await d.promises.mkdir(b,{recursive:!0});let g=f().join(b,`.last-look.${process.pid}.tmp`);await d.promises.writeFile(g,JSON.stringify(e)+"\n","utf8"),await d.promises.rename(g,n(b))}catch{}}},86587:(a,b,c)=>{c.d(b,{Pl:()=>n,W8:()=>k,yy:()=>m,ze:()=>l});var d=c(72346),e=c(88804),f=c(87078),g=c(83720);function h(a){return{what:a.what.en,whatP:a.what,why:a.why.en,whyP:a.why,evidence:a.evidence.map(a=>a.en),evidenceP:a.evidence,steps:a.steps.map(a=>a.en),stepsP:a.steps}}function i(a){return{action:a.en,actionP:a}}function j(a){return a?{handledNote:a.en,handledNoteP:a}:{}}function k(a){let b=a=>Array.isArray(a)?a:[],c=b(a.projects),k=b(a.urls),m=b(a.expiryItems),n=b(a.incidents),r=b(a.missingRoots),s=b(a.ignored),{snoozes:t,isAcked:u,isDupe:v,offline:w}=a,x=Date.now(),y=a=>{let b=t?.[a];return!!b&&new Date(b).getTime()>x},z=[],A={};for(let a of c){let b=a.path.toLowerCase(),h=function(a,b,c){var h,i;let j=[],k=[],m=[],n=[];a.changedTotal>0&&(j.push((0,e.ph)("attn.reason.unsaved",`{0} unsaved change${1===a.changedTotal?"":"s"}`,a.changedTotal)),k.push((0,e.ph)("attn.ev.changed",`changed: {0}${a.changedTotal>a.dirtyFiles.length?" and {1} more":""}`,a.dirtyFiles.join(", "),a.changedTotal-a.dirtyFiles.length))),a.deleted>0&&(j.push((0,e.ph)("attn.reason.deleted",`{0} file${1===a.deleted?"":"s"} deleted`,a.deleted)),k.push((0,e.ph)("attn.ev.deleted",`deleted: {0}${a.deleted>a.deletedFiles.length?" and {1} more":""}`,a.deletedFiles.join(", "),a.deleted-a.deletedFiles.length))),a.uncommitted>0&&(m.push((0,e.pl)("attn.step.commit","Commit the work - a commit makes it permanent history.")),n.push('git add -A && git commit -m "wip"')),a.deleted>0&&(m.push((0,e.pl)("attn.step.deleted","If a deletion was not meant, git still holds the file - restore it before committing.")),n.push("git restore --")),(a.ahead??0)>0&&(j.push((0,e.ph)("attn.reason.unpushed",`{0} commit${1===a.ahead?"":"s"} not pushed`,a.ahead??0)),k.push((0,e.ph)("attn.ev.onlyHere",`{0} commit${1===a.ahead?"":"s"} exist only on this machine`,a.ahead??0)),m.push((0,e.pl)("attn.step.push","Push once - the remote gets a full copy and the risk is gone.")),n.push("git push")),l(a)&&(j.push((0,e.pl)("attn.reason.noBackup","no backup anywhere")),k.push((0,e.pl)("attn.ev.noRemote","no remote is configured - this disk holds the only copy")),m.push((0,e.pl)("attn.step.createRepo","Create an empty repository on your code host, connect it, and push.")),n.push("git remote add origin <url>","git push -u origin main"));let o=a.isGit&&!a.statusKnown;o&&(j.push((0,e.pl)("unread.reason",d.UI.unread.reason)),k.push((0,e.pl)("unread.evidence",d.UI.unread.evidence)),m.push((0,e.pl)("unread.step",d.UI.unread.step)));let p=b?function(a,b){let c=b.filter(b=>b.name===a.name&&b.path!==a.path);if(0===c.length)return null;let d=a.remoteKnown?(0,f.p8)(a.remoteUrl):null,e=a=>a.remoteKnown?(0,f.p8)(a.remoteUrl):null;if(d){let a=c.filter(a=>e(a)===d);if(a.length>0)return{kind:"duplicate",others:a}}return!d||c.some(a=>null===e(a))?{kind:"unproven",others:c}:{kind:"sharesName",others:c}}(a,c):null,q=p?.kind==="duplicate"?p:null,r=!!q&&("dormant"===a.staleness||"forgotten"===a.staleness);if(0===j.length&&r&&q){for(let a of(j.push((0,e.pl)("attn.reason.dupe","a dormant duplicate")),q.others))k.push((0,e.ph)("attn.ev.livingCopy","the living copy: {0}",a.path));let b=(0,f.p8)(a.remoteUrl);b&&k.push((0,e.ph)("attn.ev.sameRemote","both point at the same repository: {0}",b)),a.lastActivity&&(0,g.nW)(a.lastActivity)?k.push((0,e.pl)("attn.ev.untouchedSkew",`this copy untouched ${g.lt.since}`)):k.push((0,e.ph)("attn.ev.untouched","this copy untouched {0}",a.lastActivity?(h=a.lastActivity,(0,g.I)(h)):"for a long time")),m.push((0,e.pl)("attn.step.keepOne","Keep one copy - archive or delete the other so future-you isn't guessing."))}if(0===j.length)return{tone:"clean",what:"",why:"",evidence:[],steps:[]};let s=l(a),t=a.uncommitted>0?"unsaved":(a.ahead??0)>0?"unpushed":s?"unbacked":void 0,u=o&&1===j.length,v="unsaved"===t?(0,e.ph)("act.save","Save {0}",a.name):"unpushed"===t?(0,e.ph)("act.push","Push {0}",a.name):"unbacked"===t?(0,e.ph)("act.backUp","Back up {0}",a.name):u?(0,e.ph)("unread.what","af360 could not finish reading {0}.",a.name):(0,e.ph)("act.duplicate","Decide on {0}'s duplicate",a.name),w=(i=j.map(a=>a.en),(0,e.nn)(i,e.v1.and,e.v1.comma)),x=u?(0,e.ph)("unread.what","af360 could not finish reading {0}.",a.name):{...(0,e.ph)("attn.project.what","{0} has {1}.",a.name,w),list:{slot:1,items:j}},y=u?(0,e.pl)("unread.why",d.UI.unread.why):s?(0,e.pl)("attn.why.noBackup","One disk failure and it's gone - a remote copy fixes that in a minute."):(a.ahead??0)>0&&0===a.uncommitted?(0,e.pl)("attn.why.unpushed","A push costs a minute; losing them costs the work."):r&&0===a.uncommitted?(0,e.pl)("attn.why.dupe","Two copies of one project drift apart quietly."):(0,e.pl)("attn.why.unsaved","Unsaved work survives nowhere - one bad day and it's gone.");return k.push((0,e.ph)("attn.ev.path","{0}",`path: ${a.path}`)),{tone:"amber",what:x.en,why:y.en,whatP:x,whyP:y,since:a.lastActivity?new Date(a.lastActivity).getTime():void 0,evidence:k.map(a=>a.en),evidenceP:k,steps:m.map(a=>a.en),stepsP:m,devSteps:n.length>0?n:void 0,losable:t,action:v.en,actionP:v}}(a,v(a.name),c);A[b]=h.tone,"clean"!==h.tone&&z.push({...h,id:b,kind:"project",label:a.name,handled:y(b)||void 0,handledNote:y(b)?"quiet until tomorrow":void 0,openPath:a.path,laterId:b,ignore:{id:b,kind:"project",label:a.name,atRisk:l(a)}})}let B=a.github;if(B)for(let a of c){let b=B.byPath[a.path.toLowerCase()];if(!b?.ok)continue;let c=b.value;if(c.ci.ok&&c.ci.value&&"failing"===c.ci.value.state){let b=c.ci.value,d=`ci:${a.path.toLowerCase()}`;z.push({id:d,kind:"project",tone:"amber",label:a.name,since:b.at,...h({what:(0,e.ph)("attn.gh.ci.what","{0}'s build failed on {1}.",a.name,b.branch),why:(0,e.pl)("attn.gh.ci.why","GitHub Actions went red - the last push didn't survive CI."),evidence:[(0,e.ph)("attn.gh.ci.ev1","the {0} workflow reported {1}",b.workflow,b.conclusion??"a failure"),(0,e.ph)("attn.gh.ci.ev2","on branch {0}",b.branch),(0,e.ph)("attn.gh.ci.ev3","GitHub last moved this run at {0}",new Date(b.at).toISOString())],steps:[(0,e.pl)("attn.gh.ci.step1","Open the run on GitHub and read the first failing step - the rest usually follow from it."),(0,e.pl)("attn.gh.ci.step2","Nothing here is lost: the commits are pushed. This is about the checks, not the work.")]}),handled:y(d)||void 0,...j(y(d)?(0,e.pl)("attn.handled.snoozed","quiet until tomorrow"):void 0),openPath:a.path,laterId:d,...i((0,e.ph)("act.gh.ci","Read {0}'s failing run on GitHub",a.name))})}if("refuted"===c.backup.verdict){let b=c.backup,d=`backup:${a.path.toLowerCase()}`;z.push({id:d,kind:"project",tone:"amber",label:a.name,losable:"unpushed",...h({what:(0,e.ph)("attn.gh.backup.what","{0} says everything is pushed, and GitHub doesn't have it.",a.name),why:(0,e.pl)("attn.gh.backup.why","Local git reports nothing to push and nothing to pull, so this machine and GitHub should be on the same commit. They aren't."),evidence:[(0,e.ph)("attn.gh.backup.ev1","this machine is on {0} at branch {1}",b.localSha.slice(0,12),b.branch),(0,e.ph)("attn.gh.backup.ev2","GitHub's {0} is at {1}",b.branch,b.remoteSha.slice(0,12)),(0,e.pl)("attn.gh.backup.ev3","af360 asked both ends this scan - this is not read from local git's own record of the remote")],steps:[(0,e.pl)("attn.gh.backup.step1","Fetch from the remote and look again - the usual cause is that this machine's record of the remote is out of date."),(0,e.pl)("attn.gh.backup.step2","If the commits really are only here, push them. Until then treat this project as not backed up.")]}),devSteps:["git fetch --all","git status -sb","git log --oneline -1 HEAD"],handled:y(d)||void 0,...j(y(d)?(0,e.pl)("attn.handled.snoozed","quiet until tomorrow"):void 0),openPath:a.path,laterId:d,...i((0,e.ph)("act.gh.backup","Check where {0}'s commits actually are",a.name))})}}if(w&&k.length>0){for(let a of k)A[a.entry.id]="clean";z.push({id:"offline",kind:"site",tone:"amber",label:"Internet connection",...h({what:(0,e.pl)("attn.offline.what","This computer seems to be offline."),why:(0,e.pl)("attn.offline.why","Your sites may be perfectly fine - af360 can't reach anything right now, so it won't guess."),evidence:[(0,e.ph)("attn.offline.ev1","none of the {0} watched sites answered",k.length),(0,e.pl)("attn.offline.ev2","the domain lookup didn't get through either"),(0,e.pl)("attn.offline.ev3","checks keep running while af360 is open; this clears itself the moment something answers")],steps:[(0,e.pl)("attn.offline.step1","Check this machine's internet connection - wifi, cable, or a VPN that dropped."),(0,e.pl)("attn.offline.step2","Nothing to do here once it's back: af360 rechecks every minute while it is open, and clears this on its own.")]}),devSteps:["ping 1.1.1.1","nslookup example.com"],...i((0,e.pl)("act.offline","Check this machine's connection"))})}for(let a of w?[]:k){let b=a.entry.id,c=a.current,d=a.entry.label||function(a){try{return new URL(a).hostname}catch{return a}}(a.entry.url);if(!c||c.ok){A[b]="clean";continue}A[b]="red";let f=n.find(a=>a.subjectId===b&&!a.endedTs),g=u(b),k=y(b);z.push({id:b,kind:"site",tone:"red",label:d,...h({what:c.status?(0,e.ph)("attn.down.whatStatus","{0} is down (HTTP {1}).",d,c.status):c.error?(0,e.ph)("attn.down.whatError","{0} is down - {1}.",d,c.error):(0,e.ph)("attn.down.what","{0} is down.",d),why:(0,e.pl)("attn.down.why","af360 asked for your site from this machine and got an error back instead of the page."),evidence:[(0,e.ph)("attn.down.evUrl","{0}",a.entry.url),c.status?(0,e.ph)("attn.down.evAnswer","last answer: HTTP {0}",c.status):c.error?(0,e.ph)("attn.down.evAnswerText","last answer: {0}",c.error):(0,e.pl)("attn.down.evNoAnswer","no answer"),f?(0,e.ph)("attn.down.evSince","down since {0}",new Date(f.startedTs).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"})):(0,e.pl)("attn.down.evJust","just went quiet"),(0,e.pl)("attn.down.evCadence","checked every minute while af360 is open; recovery is logged automatically")],steps:[(0,e.pl)("attn.down.step1","Open your host's dashboard - most outages are a crashed service or a failed deploy."),(0,e.pl)("attn.down.step2","Press Check once you're on it; the row calms down and clears itself when the site answers again.")]}),since:f?.startedTs,handled:g||k||void 0,...j(g?(0,e.pl)("attn.handled.acked","being handled ✓"):k?(0,e.pl)("attn.handled.snoozed","quiet until tomorrow"):void 0),devSteps:[`curl -sI ${a.entry.url}`],...i((0,e.ph)("act.siteDown","{0} is down",d)),checkId:b,laterId:b,ignore:{id:b,kind:"url",label:d,atRisk:!0}})}for(let a of s){if(!a.resurface)continue;let b=`resurface:${a.id}`;A[b]="amber",z.push({id:b,kind:"resurface",tone:"amber",label:a.label,...h({what:(0,e.ph)("attn.resurface.what","{0}",a.resurface.text),why:(0,e.pl)("attn.resurface.why","You silenced this earlier - the situation moved, so it gets one more look."),evidence:[(0,e.ph)("attn.resurface.evThen","ignored at: {0}",o(a.snapshot)),(0,e.ph)("attn.resurface.evNow","now: {0}",o(a.resurface.current))],steps:[(0,e.pl)("attn.resurface.step","Watch again to bring it back, or Still ignore to re-silence it at today's numbers.")]}),...i((0,e.ph)("act.decide","Decide on {0}",a.label)),resurfaceId:a.id,ignore:{id:a.id,kind:a.kind,label:a.label,atRisk:!1}})}for(let a of m){if(a.manual){if(a.done||null===a.rung||void 0===a.rung){A[a.id]="clean";continue}A[a.id]="amber";let b=y(a.id);z.push({id:a.id,kind:"expiry",tone:"amber",label:a.name,entrusted:!0,cost:a.cost,passed:a.passed,entrustedId:a.id,...h({what:a.passed?(0,e.ph)("attn.entrusted.passed","{0} was due {1}.",a.name,q(a.daysLeft)):(0,e.ph)("attn.entrusted.what","{0} is due {1}.",a.name,q(a.daysLeft)),why:a.note?(0,e.ph)("attn.entrusted.userNote","{0}",a.note):(0,e.pl)("attn.entrusted.why","You asked af360 to tell you about this one."),evidence:[(0,e.pl)("attn.entrusted.evAdded","you added this date"),(0,e.ph)("attn.expiry.evDate","date: {0}",new Date(a.date).toLocaleDateString()),a.note?(0,e.ph)("attn.entrusted.evNote",'what you wrote: "{0}"',a.note):null].filter(a=>null!==a),steps:[(0,e.pl)("attn.entrusted.step","Deal with it, or open Ahead to change the date, mark it done or remove it.")]}),handled:b||void 0,...j(b?(0,e.pl)("attn.handled.snoozed","quiet until tomorrow"):void 0),...i((0,e.ph)("act.entrusted","Deal with {0}",a.name)),laterId:a.id});continue}let b="red"===a.chip||"amber"===a.chip&&"ssl"===a.kind&&a.managed;if(A[a.id]=b?"amber":"clean",!b)continue;let c=y(a.id);z.push({id:a.id,kind:"expiry",tone:"amber",label:a.name,...h({what:"ssl"===a.kind&&a.managed&&"red"!==a.chip?(0,e.ph)("attn.expiry.certLate","{0}'s certificate should have auto-renewed by now - it hasn't.",a.name):a.daysLeft<0?(0,e.ph)("attn.expiry.expired","{0} expired {1}.",a.name,q(a.daysLeft)):(0,e.ph)("attn.expiry.expires","{0} expires {1}.",a.name,q(a.daysLeft)),why:a.note?(0,e.ph)("attn.expiry.userNote","{0}",a.note):"ssl"===a.kind?(0,e.pl)("attn.expiry.whySsl","When it lapses, browsers show a scary warning instead of your site."):(0,e.pl)("attn.expiry.whyDomain","After the date it stops working - renewing early is painless."),evidence:[(0,e.ph)("attn.expiry.evDate","date: {0}",new Date(a.date).toLocaleDateString()),a.judgment?(0,e.ph)("attn.expiry.evJudgment","{0}",a.judgment):a.note?(0,e.ph)("attn.expiry.evNote",'your note: "{0}"',a.note):null,a.issuer?(0,e.ph)("attn.expiry.evIssuer","issuer: {0}",a.issuer):null].filter(a=>null!==a),steps:"ssl"===a.kind?[(0,e.pl)("attn.expiry.stepSsl","Ask your host why the renewal hasn't landed - managed certificates renew on their own, so a late one means something is stuck.")]:[(0,e.pl)("attn.expiry.stepDomain","Renew it (or let it lapse on purpose), then remove or update the entry on Ahead.")]}),handled:c||void 0,...j(c?(0,e.pl)("attn.handled.snoozed","quiet until tomorrow"):void 0),...i("ssl"===a.kind&&a.managed&&"red"!==a.chip?(0,e.ph)("act.certLate","Chase {0}'s certificate",a.name):(0,e.ph)("act.renew","Renew {0}",a.name)),laterId:a.id})}for(let a of r){let b=`missing:${a}`;A[b]="amber",z.push({id:b,kind:"missing",tone:"amber",label:p(a),...h({what:(0,e.ph)("attn.missing.what","The folder {0} can't be found",a),why:(0,e.pl)("attn.missing.why","It moved or was renamed - point me at its new home, or stop watching it."),evidence:[(0,e.ph)("attn.missing.evPath","watched path: {0}",a),(0,e.pl)("attn.missing.evScan","the folder stopped answering on the last scan")],steps:[(0,e.pl)("attn.missing.step1","Press Find it and click through to where the folder lives now - the old entry is replaced."),(0,e.pl)("attn.missing.step2","If it's gone on purpose, Stop watching removes it.")]}),...i((0,e.ph)("act.find","Find {0}",p(a))),findPath:a})}z.sort((a,b)=>Number(a.handled??!1)-Number(b.handled??!1)||Number("red"===b.tone)-Number("red"===a.tone));let C=z.filter(a=>!a.handled).length,D=z.some(a=>"red"===a.tone&&!a.handled),E=b(a.findings).filter(a=>a?.cat==="safety").length,F=0;if(B){for(let a of c){let b=B.byPath[a.path.toLowerCase()];b&&!b.ok&&F++}B.outage&&F++}return F+=b(a.unreachedChecks).length,{state:D?"INCIDENT":C>0?"NEEDS_YOU":E>0?"SAFETY":"QUIET",open:C,items:z,tones:A,unreached:F+=new Set(b(a.unscannedSubjects)).size,safety:E}}function l(a){return a.isGit&&a.remoteKnown&&!a.hasRemote&&!a.looksDownloaded}function m(a){return 0===a.items.length&&0===Object.keys(a.tones).length}function n(a){let b=(a,b)=>({line:a.en,under:b.en,lineP:a,underP:b});if(m(a))return b((0,e.pl)("head.emptyLine","Nothing watched yet"),(0,e.pl)("head.emptyUnder","Point me at a folder and I'll show you the projects inside it."));if("INCIDENT"===a.state){let c=a.items.filter(a=>"red"===a.tone&&!a.handled);return b(1===c.length?(0,e.ph)("head.downOne","{0} is down",c[0].label):(0,e.ph)("head.downMany","{0} down",c.length),1===c.length?(0,e.pl)("head.incidentUnder","everything else can wait - this is the one to look at"):(0,e.pl)("head.incidentUnderMany","everything else can wait - these are the ones to look at"))}if("NEEDS_YOU"===a.state)return a.safety>0?b((0,e.ph)("head.needsLine",`{0} need${1===a.open?"s":""} you`,a.open),(0,e.ph)("head.needsUnderSafety",`none of it is on fire - each has a reason, and {0} safety finding${1===a.safety?" is":"s are"} waiting in Discoveries`,a.safety)):b((0,e.ph)("head.needsLine",`{0} need${1===a.open?"s":""} you`,a.open),(0,e.pl)("head.needsUnder","none of it is on fire - each has a reason"));let c=a.items.filter(a=>a.handled).length,d=a.unreached??0,f=a=>`thing${1===a?"":"s"}`;if("SAFETY"===a.state){let c=a.safety;return b((0,e.ph)("head.safetyLine",`{0} safety finding${1===c?"":"s"}`,c),d>0?(0,e.ph)("head.safetyMissed",`${1===c?"it is":"they are"} waiting in Discoveries - and af360 couldn't check {0} ${f(d)} this time`,d):(0,e.pl)("head.safetyUnder",`${1===c?"it is":"they are"} waiting in Discoveries`))}return b((0,e.pl)("head.quietLine","All quiet"),c>0?d>0?(0,e.ph)("head.quietHandledMissed",`nothing new needs you - {0} item${1===c?" is":"s are"} being handled, and af360 couldn't check {1} ${f(d)} this time`,c,d):(0,e.ph)("head.quietHandled",`nothing new needs you - {0} item${1===c?" is":"s are"} being handled`,c):d>0?(0,e.ph)("head.quietMissed",`nothing needs you - and af360 couldn't check {0} ${f(d)} this time`,d):(0,e.pl)("head.quietUnder","nothing needs you - go build something"))}function o(a){if(!a)return"nothing recorded";let b=[];return"number"==typeof a.uncommitted&&b.push(`${a.uncommitted} unsaved`),!1===a.hasRemote&&b.push("no backup"),a.down&&b.push("down"),b.length>0?b.join(", "):"all fine"}function p(a){let b=a.split(/[\\/]/).filter(Boolean);return b[b.length-1]??a}function q(a){return a<0?`${-a} day${-1===a?"":"s"} ago`:0===a?"today":1===a?"tomorrow":`in ${a} days`}}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";exports.id=8150,exports.ids=[6995,8150],exports.modules={1232:(a,b,c)=>{c.d(b,{dK:()=>e,fI:()=>function a(b,c=0){if("string"==typeof b)return e(b);if(null===b||"object"!=typeof b)return b;if(c>=12)return"[too deeply nested for af360 to mask - not shown]";if(Array.isArray(b))return b.map(b=>a(b,c+1));let d={};for(let[f,g]of Object.entries(b))d[e(f)]=a(g,c+1);return d}});let d="[secret masked]";function e(a){let b=a;return(b=(b=(b=(b=(b=(b=(b=(b=(b=b.replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,d)).replace(/\b([A-Za-z0-9_.-]*(?:SECRET|TOKEN|PASSWORD|PASSWD|API[_-]?KEY|APIKEY|ACCESS[_-]?KEY|PRIVATE[_-]?KEY|CLIENT[_-]?SECRET|AUTH|CREDENTIAL|[A-Z0-9]_KEY|^KEY)[A-Za-z0-9_.-]*)(\s*[:=]\s*)(["'`]?)([^\s"'`,;]{4,})\3/gi,(a,b,c)=>`${b}${c}${d}`)).replace(/\b([A-Za-z0-9_.-]*(?:URL|URI|DSN|CONN)[A-Za-z0-9_.-]*)(\s*[:=]\s*)(["'`]?)([^\s"'`,;]{4,})\3/gi,(a,b,c)=>/[A-Za-z]/.test(b)&&(b.includes("_")||b===b.toUpperCase())?`${b}${c}${d}`:a)).replace(/\b([A-Za-z][A-Za-z0-9+.-]*):\/\/([^\s/:@]{1,128}):([^\s/@]{1,256})@/g,(a,b,c)=>`${b}://${c}:${d}@`).replace(/(^|[\s(<'"`=,])([A-Za-z0-9._%+-]{1,64}):([^\s:@/\\]{4,128})@((?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,}|\d{1,3}(?:\.\d{1,3}){3}|localhost)(?=[:/?\s'"`)>,]|$)/g,(a,b,c,e,f)=>`${b}${c}:${d}@${f}`)).replace(/gh[pousr]_[A-Za-z0-9]{16,}|github_pat_[A-Za-z0-9_]{20,}/g,d)).replace(/(?<![A-Za-z0-9])(AKIA[0-9A-Z]{12,}|ASIA[0-9A-Z]{12,}|sk_(?:live|test)_[0-9A-Za-z]{10,}|rk_(?:live|test)_[0-9A-Za-z]{10,}|pk_live_[0-9A-Za-z]{10,}|glpat-[A-Za-z0-9_-]{16,}|AIza[0-9A-Za-z_-]{30,}|ya29\.[0-9A-Za-z_-]{20,}|xox[baprs]-[0-9A-Za-z-]{8,}|npm_[A-Za-z0-9]{30,}|dop_v1_[a-f0-9]{40,}|SG\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}|hf_[A-Za-z0-9]{30,}|sk-ant-[A-Za-z0-9_-]{20,}|sk-[A-Za-z0-9]{32,})(?![A-Za-z0-9])/g,d)).replace(/\b(bearer|basic)\s+[A-Za-z0-9._~+/=-]{12,}/gi,(a,b)=>`${b} ${d}`)).replace(/(?<![A-Za-z0-9])eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}(?![A-Za-z0-9])/g,d)).replace(/(?<![A-Za-z0-9])[0-9a-f]{32,}(?![A-Za-z0-9])/gi,d)).replace(/(?<![A-Za-z0-9])[A-Za-z0-9+/]{40,}={0,2}(?![A-Za-z0-9+/=])/g,d)}},4683:(a,b,c)=>{c.d(b,{APP_CONFIGURED:()=>h,II:()=>k,f2:()=>l,Zd:()=>t,Re:()=>s});var d=c(73024),e=c(76760);let f=["githubClientId"],g=process.env.AF360_GITHUB_CLIENT_ID??function(){let a=function(){let a,b;try{a=(0,d.readFileSync)(function(){let a=process.env.AF360_APP_IDENTITY;return a||e.join(void 0,"app-identity.json")}(),"utf8")}catch{return{ok:!1,reason:"af360 could not read its own app identity file"}}try{b=JSON.parse(a)}catch{return{ok:!1,reason:"af360's app identity file is not readable JSON"}}if(!b||"object"!=typeof b||Array.isArray(b))return{ok:!1,reason:"af360's app identity file is not a JSON object"};let c=Object.keys(b).filter(a=>!f.includes(a));if(c.length>0)return{ok:!1,reason:`af360's app identity file carries a key that may not ship: ${c.join(", ")}`};let g=b.githubClientId;return"string"!=typeof g||0===g.length?{ok:!1,reason:"af360's app identity file carries no GitHub client id"}:{ok:!0,githubClientId:g}}();return a.ok&&a.githubClientId?a.githubClientId:"REPLACE_WITH_APP_CLIENT_ID"}(),h=!g.startsWith("REPLACE_WITH"),i="https://github.com",j=`${i}/login/device`,k=process.env.AF360_GITHUB_APP_SLUG??"af360-app",l=Object.freeze({arrived:"GitHub's answer arrived on this machine",declined:"you declined the authorization on GitHub - nothing was stored",refused:"GitHub refused the authorization - nothing was stored",expired:"the sign-in code expired before it was used, so af360 stopped asking - nothing was stored",cancelled:"you cancelled the authorization in af360 - nothing was stored",issued:"GitHub issued a sign-in code and af360 is waiting for you to enter it","slow-down":"GitHub asked af360 to check less often, and af360 slowed down"});Object.freeze(["issued","slow-down"]);let m=Object.freeze({expired_token:"that sign-in code had expired before it was used - press Connect to get a fresh one",access_denied:"the sign-in was declined on GitHub, so nothing was stored",incorrect_device_code:"GitHub did not recognise this sign-in attempt, so nothing was stored - press Connect to start a fresh one",unsupported_grant_type:"GitHub would not accept the way af360 asked, so nothing was stored - this is af360's own registration and not something to fix here",device_flow_disabled:"GitHub says device sign-in is turned off for af360, so nothing was stored - this is af360's own registration and not something to fix here",incorrect_client_credentials:"GitHub did not recognise af360 itself, so nothing was stored - this is af360's own registration and not something to fix here",unverified_user_email:"GitHub needs a verified email address on your account before it will complete this"});function n(a){return m[a]??"GitHub refused to complete the sign-in, so nothing was stored - press Connect to try again"}let o=Object.freeze({access_denied:"declined",expired_token:"expired"});async function p(a,b){let c=new AbortController,d=setTimeout(()=>c.abort(),15e3);try{return await q(a,b,c)}finally{clearTimeout(d)}}async function q(a,b,c){let d,e;try{d=await fetch(`${i}${a}`,{method:"POST",signal:c.signal,redirect:"error",headers:{accept:"application/json","content-type":"application/x-www-form-urlencoded","user-agent":"af360"},body:new URLSearchParams(b).toString()})}catch(a){return{ok:!1,reason:a?.name==="AbortError"?"GitHub did not answer in time":"this machine could not reach GitHub"}}if(!d.ok){var f;return{ok:!1,reason:404===(f=d.status)?"GitHub did not recognise af360's app registration":401===f||403===f?"GitHub would not accept af360's app credentials":`GitHub answered ${f}`}}try{e=await d.json()}catch(a){if(a?.name==="AbortError")return{ok:!1,reason:"GitHub did not answer in time"};return{ok:!1,reason:"GitHub's answer was not readable"}}return e&&"object"==typeof e?{ok:!0,json:e}:{ok:!1,reason:"GitHub's answer was not readable"}}let r=(a,b)=>"number"==typeof a&&Number.isFinite(a)&&a>0?a:b;async function s(){let a=await p("/login/device/code",{client_id:g});if(!a.ok)return a;let b=a.json;if("string"==typeof b.error)return{ok:!1,reason:n(b.error)};let c="string"==typeof b.device_code?b.device_code:"",d="string"==typeof b.user_code?b.user_code:"";return c&&d?{ok:!0,device:{deviceCode:c,userCode:d,verificationUri:"string"==typeof b.verification_uri&&b.verification_uri?b.verification_uri:j,expiresAt:Date.now()+1e3*r(b.expires_in,900),intervalMs:Math.max(5e3,1e3*r(b.interval,5))}}:{ok:!1,reason:"GitHub did not send a sign-in code"}}async function t(a,b={}){let c=b.cancelled??(()=>!1),d=b.sleep??(a=>new Promise(b=>setTimeout(b,a))),e=a.intervalMs;for(;;){if(c())return{ok:!1,ending:"cancelled",reason:l.cancelled};if(Date.now()>=a.expiresAt)return{ok:!1,ending:"expired",reason:l.expired};if(await d(e),c())return{ok:!1,ending:"cancelled",reason:l.cancelled};let f=await p("/login/oauth/access_token",{client_id:g,device_code:a.deviceCode,grant_type:"urn:ietf:params:oauth:grant-type:device_code"});if(!f.ok)continue;let h=f.json,i="string"==typeof h.error?h.error:"";if("authorization_pending"===i)continue;if("slow_down"===i){e=Math.max(5e3,("number"==typeof h.interval&&Number.isFinite(h.interval)&&h.interval>0?1e3*h.interval:0)||e+5e3),b.onEnding?.("slow-down");continue}if(i)return{ok:!1,ending:o[i]??"refused",reason:n(i)};let j="string"==typeof h.access_token?h.access_token:"";if(!j)return{ok:!1,ending:"refused",reason:"GitHub returned no access token"};let k=Date.now();return{ok:!0,ending:"arrived",tokens:{accessToken:j,accessExpiresAt:"number"==typeof h.expires_in&&Number.isFinite(h.expires_in)&&h.expires_in>0?k+1e3*h.expires_in:0,refreshToken:"",refreshExpiresAt:0}}}}},18150:(a,b,c)=>{c.d(b,{PC:()=>B,y6:()=>M,github:()=>y,state:()=>J,M_:()=>L,ZL:()=>F,fn:()=>I});var d=c(1232);let e=a=>({ok:!0,value:a}),f=(a,b)=>({ok:!1,kind:a,reason:(0,d.dK)(b)}),g="https://api.github.com";async function h(a,b){let c=new AbortController,d=setTimeout(()=>c.abort(),8e3);try{return await i(a,b,c)}finally{clearTimeout(d)}}async function i(a,b,c){let d,h,i;try{d=await fetch(g+a,{signal:c.signal,redirect:"manual",headers:{authorization:`Bearer ${b}`,accept:"application/vnd.github+json","x-github-api-version":"2022-11-28","user-agent":"af360"}})}catch(c){if(c?.name==="AbortError")return f("timeout","GitHub did not answer in time");let a=c?.code??c?.name,b="string"==typeof a&&/^[A-Z][A-Z0-9_]{2,31}$/.test(a)?a:null;return f("unreachable",b?`af360 could not open a connection to GitHub (${b})`:"af360 could not open a connection to GitHub")}if(301===d.status||308===d.status){let a=function(a){let b;if(!a)return null;try{b=new URL(a,g)}catch{return null}if(b.origin!==new URL(g).origin)return null;let c=b.pathname.replace(/^\/+/,"").split("/").filter(Boolean);if(3!==c.length||"repos"!==c[0])return null;let[,d,e]=c,f=a=>/^[A-Za-z0-9._-]{1,100}$/.test(a)&&"."!==a&&".."!==a;return f(d)&&f(e)?`${d}/${e}`:null}(d.headers.get("location"));return f("moved",a?`GitHub now calls this repository ${a}`:"GitHub says this repository has moved, and did not say where")}let k=d.headers.get("github-authentication-token-expiration"),l=d.headers.get("x-oauth-scopes"),m=d.headers.get("x-ratelimit-remaining"),n=null===m?null:Number.parseInt(m,10);if((403===d.status||429===d.status)&&0===n)return f("ratelimited","your GitHub rate limit is spent - it refills on its own");if(401===d.status)return f("unauthorized","GitHub did not accept the token - it may have been revoked or have expired");if(d.status>=500)return f("down",`GitHub answered ${d.status}`);try{h=await j(d)}catch(a){if(a?.name==="AbortError")return f("timeout","GitHub did not answer in time");throw a}if(null===h)return f("down","GitHub's answer was larger than af360 will read");if(!d.ok)return f(404===d.status||403===d.status?"forbidden":"down",404===d.status?"GitHub has no repository there that this token can see":"GitHub accepted the token but this is outside what it was granted");try{i=JSON.parse(h)}catch{return f("down","GitHub's answer was not readable")}return e({body:i,tokenExpiry:k,oauthScopes:l,rateRemaining:n})}async function j(a){let b=Number.parseInt(a.headers.get("content-length")??"",10);if(Number.isFinite(b)&&b>524288)return null;let c=a.body?.getReader();if(!c)return await a.text();let d=[],e=0;for(;;){let{done:a,value:b}=await c.read();if(a)break;if(b){if((e+=b.byteLength)>524288)return await c.cancel().catch(()=>{}),null;d.push(b)}}let f=new Uint8Array(e),g=0;for(let a of d)f.set(a,g),g+=a.byteLength;return new TextDecoder("utf-8").decode(f)}let k=a=>encodeURIComponent(a),l=(a,b)=>h(`/user/installations/${encodeURIComponent(String(a))}/repositories?per_page=100`,b);var m=c(71011),n=c(46995);let o="dpapi:v1:",p=new Map;async function q(a){if("string"!=typeof a||!a)return{stored:a,encrypted:!1};let b=await (0,n.bridge)("protect",a);if(!b.ok)return{stored:a,encrypted:!1,reason:b.reason};let c=o+b.out;return p.set(c,a),{stored:c,encrypted:!0}}async function r(a){if("string"!=typeof a||!a)return{ok:!1,reason:"empty"};if(!("string"==typeof a&&a.startsWith(o)))return{ok:!0,token:a,encrypted:!1};let b=p.get(a);if(void 0!==b)return{ok:!0,token:b,encrypted:!0};let c=await (0,n.bridge)("unprotect",a.slice(o.length));return c.ok?(p.set(a,c.out),{ok:!0,token:c.out,encrypted:!0}):{ok:!1,reason:c.reason,encrypted:!0}}let s={unreachable:"not checked this scan - af360 could not open a connection to GitHub",down:"not checked this scan - GitHub did not answer properly",expired:"not checked this scan - the GitHub token has expired",unauthorized:"not checked this scan - GitHub would not accept the token",forbidden:"not checked this scan - the token is fine, but this is outside what af360 was granted",ratelimited:"not checked this scan - your GitHub rate limit is spent",timeout:"not checked this scan - GitHub did not answer in time",moved:"not checked - your remote points at a name GitHub has moved, and it will stay unchecked until the remote is updated","past-ceiling":"not checked - af360 asks GitHub about a limited number of repositories each scan, and this one is past that"},t={unreachable:"no connection",down:"GitHub down",expired:"token expired",unauthorized:"token refused",forbidden:"not granted",ratelimited:"rate limit",timeout:"no answer",moved:"remote moved","past-ceiling":"past the scan limit"};Object.fromEntries(Object.keys(t).map(a=>[a,`GitHub not checked (${t[a]})`]));var u=c(4683);let v=new Set(["read:org","read:user","read:packages","read:discussion","read:project","read:audit_log","read:gpg_key","read:public_key","user:email","read:enterprise","read:network"]),w=new Set(["read"]);async function x(a,b,c,d){var g;let i,j=await h(`/repos/${k(b)}/${k(c)}`,d);if(!j.ok)return f(j.kind,j.reason);let l="string"==typeof j.value.body.default_branch?j.value.body.default_branch:null,m=a.branch||l;if(!m)return f("down","GitHub did not name a default branch and local git did not name one either");let[n,o,p]=await Promise.all([h(`/repos/${k(b)}/${k(c)}/actions/runs?branch=${k(m)}&per_page=1&exclude_pull_requests=true`,d),h(`/repos/${k(b)}/${k(c)}/pulls?state=open&per_page=100`,d),(g=a).statusKnown&&0===g.ahead&&0===g.behind&&g.headSha?h(`/repos/${k(b)}/${k(c)}/branches/${k(m)}`,d):Promise.resolve(null)]),q=n.ok?e(function(a,b){if(!a)return null;let c=Date.parse(a.updated_at??a.created_at??""),d=a.conclusion??null;return{state:"success"===d?"passing":"failure"===d||"timed_out"===d||"startup_failure"===d?"failing":null===d?"running":"other",conclusion:d,workflow:"string"==typeof a.name&&a.name?a.name:"a workflow",branch:a.head_branch||b,at:Number.isFinite(c)?c:Date.now(),runNumber:"number"==typeof a.run_number?a.run_number:null}}(n.value.body?.workflow_runs?.[0],m)):f(n.kind,n.reason),r=o.ok?o.value.body??[]:null,s=o.ok?e((o.value.body??[]).length):f(o.kind,o.reason),t=null!==r&&r.length>=100,u="number"==typeof j.value.body.open_issues_count?j.value.body.open_issues_count:null;return i=null===u?f("down","GitHub did not say how many issues are open"):o.ok?e(Math.max(0,u-(r?.length??0))):f(o.kind,"af360 could not separate issues from pull requests this scan"),e({owner:b,name:c,fullName:j.value.body.full_name??`${b}/${c}`,defaultBranch:l,branch:m,ci:q,prCount:s,prCapped:t,issueCount:i,backup:function(a,b,c){if(!a.statusKnown)return{verdict:"unmeasured",reason:"local git did not finish answering, so there was nothing to confirm against"};if(!a.headSha)return{verdict:"unmeasured",reason:"af360 could not read this project's current commit"};if(null===a.ahead||null===a.behind)return{verdict:"unmeasured",reason:"local git did not report this branch's position against its remote"};if(a.ahead>0)return{verdict:"unmeasured",reason:"local git already reports commits that are not pushed - there is no claim to confirm"};if(a.behind>0)return{verdict:"unmeasured",reason:"this machine is behind its remote, so the two tips are expected to differ"};if(!c)return{verdict:"unmeasured",reason:"af360 did not ask GitHub for this branch"};if(!c.ok)return{verdict:"unmeasured",reason:c.reason};let d=c.value.body.commit?.sha;return"string"==typeof d&&d?d===a.headSha?{verdict:"confirmed",sha:d,branch:b}:{verdict:"refuted",localSha:a.headSha,remoteSha:d,branch:b}:{verdict:"unmeasured",reason:"GitHub did not name a commit for that branch"}}(a,m,p)})}let y={id:"github",label:"GitHub",host:"api.github.com",verify:async function a(a){let b,c=await h("/user",a);if(!c.ok)return{kind:"unreached",unreached:c.kind,reason:c.reason};let d="string"==typeof c.value.body.login?c.value.body.login:"";if(!d)return{kind:"unreached",unreached:"down",reason:"GitHub did not say who this token belongs to"};if(c.value.oauthScopes){let b=function(a){let b=a.split(",").map(a=>a.trim()).filter(Boolean);if(0===b.length)return{readOnly:!0,detail:"a classic token with no scopes - it can read public repositories only"};let c=b.filter(a=>!v.has(a));return 0===c.length?{readOnly:!0,detail:`classic token, read-only scopes (${b.join(", ")})`}:{readOnly:!1,detail:`it carries the ${c.join(", ")} scope${1===c.length?"":"s"}, which can write`}}(c.value.oauthScopes);if(!b.readOnly)return{kind:"refused-write",detail:b.detail};let e=await h("/user/repos?per_page=100&sort=pushed",a);if(!e.ok)return{kind:"unreached",unreached:e.kind,reason:`${e.reason} - af360 could not check what this token can reach, so nothing was stored`};let f=function(a){let b=a.filter(a=>a.permissions?.push||a.permissions?.admin||a.permissions?.maintain);if(0===b.length)return{readOnly:!0,detail:`fine-grained token, read-only on all ${a.length} repositor${1===a.length?"y":"ies"} it can see`};let c=b.slice(0,3).map(a=>a.full_name??"a repository").join(", "),d=b.length>3?` and ${b.length-3} more`:"";return{readOnly:!1,detail:`it can push to ${c}${d}`}}(e.value.body??[]);return f.readOnly?{kind:"ok",login:d,scopesRead:!0,expiryKnown:!1,repoNames:(e.value.body??[]).map(a=>a.full_name??"").filter(Boolean)}:{kind:"refused-write",detail:f.detail}}let e=await h("/user/installations?per_page=100",a);if(!e.ok)return{kind:"unreached",unreached:e.kind,reason:`${e.reason} - af360 could not check what it was granted, so nothing was stored`};let f=e.value.body.installations??[],g=f.filter(a=>a.app_slug===u.II);if(f.length>0&&0===g.length)return{kind:"unreached",unreached:"down",reason:`GitHub returned ${f.length} installation${1===f.length?"":"s"}, none of them af360's own, so af360 could not confirm the grant it was reading was its own - nothing was stored`};let i=function(a){if(0===a.length)return{readOnly:!0,detail:"the App is authorized but not installed on any account yet"};let b=[];for(let c of a)for(let[a,d]of Object.entries(c.permissions??{}))w.has(String(d).toLowerCase())||b.push(`${a}: ${d}${c.account?.login?` on ${c.account.login}`:""}`);return 0===b.length?{readOnly:!0,detail:`the App is installed read-only on ${a.length} account${1===a.length?"":"s"}`}:{readOnly:!1,detail:`the installation grants ${b.slice(0,3).join(", ")}${b.length>3?` and ${b.length-3} more`:""}`}}(g);if(!i.readOnly)return{kind:"refused-write",detail:i.detail};let j=[],k=0;for(let c of g){if("number"!=typeof c.id)continue;b??=c.id;let d=await l(c.id,a);if(!d.ok){k++;continue}for(let a of d.value.body.repositories??[])a.full_name&&j.push(a.full_name)}return{kind:"ok",login:d,repoNames:j,scopesRead:!0,expiryKnown:!1,installationId:b,installationCount:g.length,reposUnread:k}},facts:async function a(a){let b,c=Date.now(),d=await I();if(!d)return{at:c,byPath:{},outage:{kind:"unauthorized",reason:"af360 holds no GitHub token"}};if(d.expiresAt&&Date.parse(d.expiresAt)<=c)return{at:c,byPath:{},outage:{kind:"expired",reason:"the GitHub token's expiry date has passed"}};let e=a.map(a=>({s:a,repo:function(a){if(!a)return null;let b=a.trim(),c=null,d=null,e=/^(?:[A-Za-z0-9._-]+@)?([A-Za-z0-9._-]+):(.+)$/.exec(b);if(e&&!/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(b))c=e[1].toLowerCase(),d=e[2];else try{let a=new URL(b);c=a.hostname.toLowerCase(),d=a.pathname}catch{return null}if("github.com"!==c&&"www.github.com"!==c)return null;let f=(d??"").replace(/^\/+/,"").replace(/\.git$/i,"").split("/").filter(Boolean);if(2!==f.length)return null;let[g,h]=f,i=a=>/^[A-Za-z0-9._-]{1,100}$/.test(a)&&"."!==a&&".."!==a;return i(g)&&i(h)?{owner:g,name:h}:null}(a.remoteUrl)})).filter(a=>null!==a.repo),g={},h=e.slice(0,25);for(let a of e.slice(25))g[a.s.path.toLowerCase()]=f("past-ceiling","af360 asks GitHub about at most 25 repositories in one scan, and this one was past that");let i=0,j=Array.from({length:Math.min(4,h.length)},async()=>{for(;;){if(b)return;let a=i++;if(a>=h.length)return;let{s:c,repo:e}=h[a],f=await x(c,e.owner,e.name,d.token);if(!f.ok&&("ratelimited"===f.kind||"expired"===f.kind)){b={kind:f.kind,reason:f.reason};return}g[c.path.toLowerCase()]=f}});return await Promise.all(j),{at:c,byPath:g,outage:b}},expiry:function(a){return a.connected&&a.expiryKnown&&a.expiresAt&&Number.isFinite(Date.parse(a.expiresAt))?{id:"connector:github",name:"GitHub token (af360 stops seeing CI, PRs and issues)",date:a.expiresAt}:null},unmeasuredLine:a=>s[a]},z=null,A=null,B="This build of af360 has no GitHub App registration, so it cannot renew access",C=0,D=6e4;function E(a,b){C=b+D,D=Math.min(2*D,18e5),A!==a&&(A=a,z={ok:!1,reason:a})}function F(){let a=z;return z=null,a}async function G(a){let b=await r(a.token);if(!b.ok)return null;let c=a.refreshToken;if(c){let a=await r(c);c=a.ok?a.token:void 0}return{...a,token:b.token,refreshToken:c}}async function H(a){let b={...a,token:(await q(a.token)).stored};return a.refreshToken&&(b.refreshToken=(await q(a.refreshToken)).stored),b}async function I(a=Date.now()){try{let b=await (0,m.G5)(),d=b.config?.connectors?.github;if(!d||"string"!=typeof d.token||!d.token)return null;let e=await G(d);if(!e)return null;let f=e.expiresAt?Date.parse(e.expiresAt):NaN;if(!Number.isFinite(f)||f-a>3e5)return A=null,C=0,D=6e4,e;if(!e.refreshToken)return e;let{APP_CONFIGURED:g}=await Promise.resolve().then(c.bind(c,4683));if(!g)return E(B,a),e;if(A&&a<C)return e;return E("af360 cannot renew this sign-in with GitHub - press Connect to sign in again",a),e}catch{return null}}async function J(){let a,b={id:y.id,label:y.label,connected:!1},d=null;try{let a=await (0,m.G5)();d=a.config?.connectors?.github??null}catch{return b}if(!d?.token)return b;if(!(await r(d.token)).ok)return{...b,connected:!0,unreadable:!0,login:d.login,repoNames:d.repoNames,repoCount:d.repoNames?.length,connectedAt:d.connectedAt};let e=!1;try{let{cachedGithubScan:b}=await c.e(6988).then(c.bind(c,26988)),d=await b(),f=d?.outage?.kind;if(!f){for(let a of Object.values(d?.byPath??{}))if(!a.ok&&("unauthorized"===a.kind||"expired"===a.kind)){f=a.kind;break}}("unauthorized"===f||"expired"===f)&&(a=f),d&&!d.outage&&(e=Object.values(d.byPath??{}).some(a=>a.ok))}catch{}return K&&(e=!0),{...b,connected:!0,refusal:a,verified:e,login:d.login,repoNames:d.repoNames,repoCount:d.repoNames?.length,reposKnown:d.reposKnown,installationCount:d.installationCount,expiryKnown:!1,connectedAt:d.connectedAt}}let K=!1;async function L(a,b,c){let d=await (0,m.G5)();if("unreadable"===d.status||!d.config)throw Error("af360 could not read its own settings, so it did not store anything");let e=d.config;e.connectors={...e.connectors,github:await H({token:a,login:b.login,repoNames:b.repoNames,reposKnown:(b.reposUnread??0)===0,installationId:b.installationId,installationCount:b.installationCount,connectedAt:Date.now(),...c?{expiresAt:new Date(c.expiresAt).toISOString(),refreshToken:c.refreshToken,refreshExpiresAt:new Date(c.refreshExpiresAt).toISOString()}:{}})},await (0,m.ql)(e),K=!0}async function M(){var a;let b=await (0,m.G5)();if("unreadable"===b.status||!b.config)throw Error("af360 could not read its own settings, so it changed nothing");let c=b.config;"string"==typeof(a=c.connectors?.github?.token)?p.delete(a):p.clear(),c.connectors&&delete c.connectors.github,await (0,m.ql)(c),K=!1}},46995:(a,b,c)=>{c.d(b,{$:()=>i,bridge:()=>k});var d=c(79646),e=c(29021),f=c(33873),g=c(79551);let h=f.resolve(f.dirname((0,g.fileURLToPath)("file:///C:/dev/af360/lib/bridge.mjs")),"..");function i(){let a=process.env.AF360_BRIDGE;return a?(0,e.existsSync)(a)?a:null:j()}function j(){for(let a of[f.join(h,"af360-bridge.exe"),f.join(h,"shell","bin","af360-bridge.exe")])if((0,e.existsSync)(a))return a;return null}function k(a,b="",{fixedPath:c=!1,timeout:e=15e3}={}){let f=c?j():i();return f?new Promise(c=>{let g=(0,d.execFile)(f,[a],{windowsHide:!0,timeout:e,maxBuffer:1e6},(a,b,d)=>{if(a)return void c({ok:!1,reason:String(d||"").trim()||(a.killed?"timeout":"failed")});c({ok:!0,out:String(b||"").trim()})});g.stdin.on("error",()=>{}),g.stdin.end(b)}):Promise.resolve({ok:!1,reason:"absent"})}}};
|
|
1
|
+
"use strict";exports.id=8150,exports.ids=[6995,8150],exports.modules={1232:(a,b,c)=>{c.d(b,{dK:()=>e,fI:()=>function a(b,c=0){if("string"==typeof b)return e(b);if(null===b||"object"!=typeof b)return b;if(c>=12)return"[too deeply nested for af360 to mask - not shown]";if(Array.isArray(b))return b.map(b=>a(b,c+1));let d={};for(let[f,g]of Object.entries(b))d[e(f)]=a(g,c+1);return d}});let d="[secret masked]";function e(a){let b=a;return(b=(b=(b=(b=(b=(b=(b=(b=(b=b.replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,d)).replace(/\b([A-Za-z0-9_.-]*(?:SECRET|TOKEN|PASSWORD|PASSWD|API[_-]?KEY|APIKEY|ACCESS[_-]?KEY|PRIVATE[_-]?KEY|CLIENT[_-]?SECRET|AUTH|CREDENTIAL|[A-Z0-9]_KEY|^KEY)[A-Za-z0-9_.-]*)(\s*[:=]\s*)(["'`]?)([^\s"'`,;]{4,})\3/gi,(a,b,c)=>`${b}${c}${d}`)).replace(/\b([A-Za-z0-9_.-]*(?:URL|URI|DSN|CONN)[A-Za-z0-9_.-]*)(\s*[:=]\s*)(["'`]?)([^\s"'`,;]{4,})\3/gi,(a,b,c)=>/[A-Za-z]/.test(b)&&(b.includes("_")||b===b.toUpperCase())?`${b}${c}${d}`:a)).replace(/\b([A-Za-z][A-Za-z0-9+.-]*):\/\/([^\s/:@]{1,128}):([^\s/@]{1,256})@/g,(a,b,c)=>`${b}://${c}:${d}@`).replace(/(^|[\s(<'"`=,])([A-Za-z0-9._%+-]{1,64}):([^\s:@/\\]{4,128})@((?:[A-Za-z0-9-]+\.)+[A-Za-z]{2,}|\d{1,3}(?:\.\d{1,3}){3}|localhost)(?=[:/?\s'"`)>,]|$)/g,(a,b,c,e,f)=>`${b}${c}:${d}@${f}`)).replace(/gh[pousr]_[A-Za-z0-9]{16,}|github_pat_[A-Za-z0-9_]{20,}/g,d)).replace(/(?<![A-Za-z0-9])(AKIA[0-9A-Z]{12,}|ASIA[0-9A-Z]{12,}|sk_(?:live|test)_[0-9A-Za-z]{10,}|rk_(?:live|test)_[0-9A-Za-z]{10,}|pk_live_[0-9A-Za-z]{10,}|glpat-[A-Za-z0-9_-]{16,}|AIza[0-9A-Za-z_-]{30,}|ya29\.[0-9A-Za-z_-]{20,}|xox[baprs]-[0-9A-Za-z-]{8,}|npm_[A-Za-z0-9]{30,}|dop_v1_[a-f0-9]{40,}|SG\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}|hf_[A-Za-z0-9]{30,}|sk-ant-[A-Za-z0-9_-]{20,}|sk-[A-Za-z0-9]{32,})(?![A-Za-z0-9])/g,d)).replace(/\b(bearer|basic)\s+[A-Za-z0-9._~+/=-]{12,}/gi,(a,b)=>`${b} ${d}`)).replace(/(?<![A-Za-z0-9])eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}(?![A-Za-z0-9])/g,d)).replace(/(?<![A-Za-z0-9])[0-9a-f]{32,}(?![A-Za-z0-9])/gi,d)).replace(/(?<![A-Za-z0-9])[A-Za-z0-9+/]{40,}={0,2}(?![A-Za-z0-9+/=])/g,d)}},4683:(a,b,c)=>{c.d(b,{APP_CONFIGURED:()=>h,II:()=>k,f2:()=>l,Zd:()=>t,Re:()=>s});var d=c(73024),e=c(76760);let f=["githubClientId"],g=process.env.AF360_GITHUB_CLIENT_ID??function(){let a=function(){let a,b;try{a=(0,d.readFileSync)(function(){let a=process.env.AF360_APP_IDENTITY;return a||e.join(void 0,"app-identity.json")}(),"utf8")}catch{return{ok:!1,reason:"af360 could not read its own app identity file"}}try{b=JSON.parse(a)}catch{return{ok:!1,reason:"af360's app identity file is not readable JSON"}}if(!b||"object"!=typeof b||Array.isArray(b))return{ok:!1,reason:"af360's app identity file is not a JSON object"};let c=Object.keys(b).filter(a=>!f.includes(a));if(c.length>0)return{ok:!1,reason:`af360's app identity file carries a key that may not ship: ${c.join(", ")}`};let g=b.githubClientId;return"string"!=typeof g||0===g.length?{ok:!1,reason:"af360's app identity file carries no GitHub client id"}:{ok:!0,githubClientId:g}}();return a.ok&&a.githubClientId?a.githubClientId:"REPLACE_WITH_APP_CLIENT_ID"}(),h=!g.startsWith("REPLACE_WITH"),i="https://github.com",j=`${i}/login/device`,k=process.env.AF360_GITHUB_APP_SLUG??"af360-app",l=Object.freeze({arrived:"GitHub's answer arrived on this machine",declined:"you declined the authorization on GitHub - nothing was stored",refused:"GitHub refused the authorization - nothing was stored",expired:"the sign-in code expired before it was used, so af360 stopped asking - nothing was stored",cancelled:"you cancelled the authorization in af360 - nothing was stored",issued:"GitHub issued a sign-in code and af360 is waiting for you to enter it","slow-down":"GitHub asked af360 to check less often, and af360 slowed down"});Object.freeze(["issued","slow-down"]);let m=Object.freeze({expired_token:"that sign-in code had expired before it was used - press Connect to get a fresh one",access_denied:"the sign-in was declined on GitHub, so nothing was stored",incorrect_device_code:"GitHub did not recognise this sign-in attempt, so nothing was stored - press Connect to start a fresh one",unsupported_grant_type:"GitHub would not accept the way af360 asked, so nothing was stored - this is af360's own registration and not something to fix here",device_flow_disabled:"GitHub says device sign-in is turned off for af360, so nothing was stored - this is af360's own registration and not something to fix here",incorrect_client_credentials:"GitHub did not recognise af360 itself, so nothing was stored - this is af360's own registration and not something to fix here",unverified_user_email:"GitHub needs a verified email address on your account before it will complete this"});function n(a){return m[a]??"GitHub refused to complete the sign-in, so nothing was stored - press Connect to try again"}let o=Object.freeze({access_denied:"declined",expired_token:"expired"});async function p(a,b){let c=new AbortController,d=setTimeout(()=>c.abort(),15e3);try{return await q(a,b,c)}finally{clearTimeout(d)}}async function q(a,b,c){let d,e;try{d=await fetch(`${i}${a}`,{method:"POST",signal:c.signal,redirect:"error",headers:{accept:"application/json","content-type":"application/x-www-form-urlencoded","user-agent":"af360"},body:new URLSearchParams(b).toString()})}catch(a){return{ok:!1,reason:a?.name==="AbortError"?"GitHub did not answer in time":"this machine could not reach GitHub"}}if(!d.ok){var f;return{ok:!1,reason:404===(f=d.status)?"GitHub did not recognise af360's app registration":401===f||403===f?"GitHub would not accept af360's app credentials":`GitHub answered ${f}`}}try{e=await d.json()}catch(a){if(a?.name==="AbortError")return{ok:!1,reason:"GitHub did not answer in time"};return{ok:!1,reason:"GitHub's answer was not readable"}}return e&&"object"==typeof e?{ok:!0,json:e}:{ok:!1,reason:"GitHub's answer was not readable"}}let r=(a,b)=>"number"==typeof a&&Number.isFinite(a)&&a>0?a:b;async function s(){let a=await p("/login/device/code",{client_id:g});if(!a.ok)return a;let b=a.json;if("string"==typeof b.error)return{ok:!1,reason:n(b.error)};let c="string"==typeof b.device_code?b.device_code:"",d="string"==typeof b.user_code?b.user_code:"";return c&&d?{ok:!0,device:{deviceCode:c,userCode:d,verificationUri:"string"==typeof b.verification_uri&&b.verification_uri?b.verification_uri:j,expiresAt:Date.now()+1e3*r(b.expires_in,900),intervalMs:Math.max(5e3,1e3*r(b.interval,5))}}:{ok:!1,reason:"GitHub did not send a sign-in code"}}async function t(a,b={}){let c=b.cancelled??(()=>!1),d=b.sleep??(a=>new Promise(b=>setTimeout(b,a))),e=a.intervalMs;for(;;){if(c())return{ok:!1,ending:"cancelled",reason:l.cancelled};if(Date.now()>=a.expiresAt)return{ok:!1,ending:"expired",reason:l.expired};if(await d(e),c())return{ok:!1,ending:"cancelled",reason:l.cancelled};let f=await p("/login/oauth/access_token",{client_id:g,device_code:a.deviceCode,grant_type:"urn:ietf:params:oauth:grant-type:device_code"});if(!f.ok)continue;let h=f.json,i="string"==typeof h.error?h.error:"";if("authorization_pending"===i)continue;if("slow_down"===i){e=Math.max(5e3,("number"==typeof h.interval&&Number.isFinite(h.interval)&&h.interval>0?1e3*h.interval:0)||e+5e3),b.onEnding?.("slow-down");continue}if(i)return{ok:!1,ending:o[i]??"refused",reason:n(i)};let j="string"==typeof h.access_token?h.access_token:"";if(!j)return{ok:!1,ending:"refused",reason:"GitHub returned no access token"};let k=Date.now();return{ok:!0,ending:"arrived",tokens:{accessToken:j,accessExpiresAt:"number"==typeof h.expires_in&&Number.isFinite(h.expires_in)&&h.expires_in>0?k+1e3*h.expires_in:0,refreshToken:"",refreshExpiresAt:0,refreshOffered:"string"==typeof h.refresh_token&&h.refresh_token.length>0,refreshOfferedLifetimeMs:"number"==typeof h.refresh_token_expires_in&&Number.isFinite(h.refresh_token_expires_in)&&h.refresh_token_expires_in>0?1e3*h.refresh_token_expires_in:0}}}}},18150:(a,b,c)=>{c.d(b,{PC:()=>B,y6:()=>M,github:()=>y,state:()=>J,M_:()=>L,ZL:()=>F,fn:()=>I});var d=c(1232);let e=a=>({ok:!0,value:a}),f=(a,b)=>({ok:!1,kind:a,reason:(0,d.dK)(b)}),g="https://api.github.com";async function h(a,b){let c=new AbortController,d=setTimeout(()=>c.abort(),8e3);try{return await i(a,b,c)}finally{clearTimeout(d)}}async function i(a,b,c){let d,h,i;try{d=await fetch(g+a,{signal:c.signal,redirect:"manual",headers:{authorization:`Bearer ${b}`,accept:"application/vnd.github+json","x-github-api-version":"2022-11-28","user-agent":"af360"}})}catch(c){if(c?.name==="AbortError")return f("timeout","GitHub did not answer in time");let a=c?.code??c?.name,b="string"==typeof a&&/^[A-Z][A-Z0-9_]{2,31}$/.test(a)?a:null;return f("unreachable",b?`af360 could not open a connection to GitHub (${b})`:"af360 could not open a connection to GitHub")}if(301===d.status||308===d.status){let a=function(a){let b;if(!a)return null;try{b=new URL(a,g)}catch{return null}if(b.origin!==new URL(g).origin)return null;let c=b.pathname.replace(/^\/+/,"").split("/").filter(Boolean);if(3!==c.length||"repos"!==c[0])return null;let[,d,e]=c,f=a=>/^[A-Za-z0-9._-]{1,100}$/.test(a)&&"."!==a&&".."!==a;return f(d)&&f(e)?`${d}/${e}`:null}(d.headers.get("location"));return f("moved",a?`GitHub now calls this repository ${a}`:"GitHub says this repository has moved, and did not say where")}let k=d.headers.get("github-authentication-token-expiration"),l=d.headers.get("x-oauth-scopes"),m=d.headers.get("x-ratelimit-remaining"),n=null===m?null:Number.parseInt(m,10);if((403===d.status||429===d.status)&&0===n)return f("ratelimited","your GitHub rate limit is spent - it refills on its own");if(401===d.status)return f("unauthorized","GitHub did not accept the token - it may have been revoked or have expired");if(d.status>=500)return f("down",`GitHub answered ${d.status}`);try{h=await j(d)}catch(a){if(a?.name==="AbortError")return f("timeout","GitHub did not answer in time");throw a}if(null===h)return f("down","GitHub's answer was larger than af360 will read");if(!d.ok)return f(404===d.status||403===d.status?"forbidden":"down",404===d.status?"GitHub has no repository there that this token can see":"GitHub accepted the token but this is outside what it was granted");try{i=JSON.parse(h)}catch{return f("down","GitHub's answer was not readable")}return e({body:i,tokenExpiry:k,oauthScopes:l,rateRemaining:n})}async function j(a){let b=Number.parseInt(a.headers.get("content-length")??"",10);if(Number.isFinite(b)&&b>524288)return null;let c=a.body?.getReader();if(!c)return await a.text();let d=[],e=0;for(;;){let{done:a,value:b}=await c.read();if(a)break;if(b){if((e+=b.byteLength)>524288)return await c.cancel().catch(()=>{}),null;d.push(b)}}let f=new Uint8Array(e),g=0;for(let a of d)f.set(a,g),g+=a.byteLength;return new TextDecoder("utf-8").decode(f)}let k=a=>encodeURIComponent(a),l=(a,b)=>h(`/user/installations/${encodeURIComponent(String(a))}/repositories?per_page=100`,b);var m=c(71011),n=c(46995);let o="dpapi:v1:",p=new Map;async function q(a){if("string"!=typeof a||!a)return{stored:a,encrypted:!1};let b=await (0,n.bridge)("protect",a);if(!b.ok)return{stored:a,encrypted:!1,reason:b.reason};let c=o+b.out;return p.set(c,a),{stored:c,encrypted:!0}}async function r(a){if("string"!=typeof a||!a)return{ok:!1,reason:"empty"};if(!("string"==typeof a&&a.startsWith(o)))return{ok:!0,token:a,encrypted:!1};let b=p.get(a);if(void 0!==b)return{ok:!0,token:b,encrypted:!0};let c=await (0,n.bridge)("unprotect",a.slice(o.length));return c.ok?(p.set(a,c.out),{ok:!0,token:c.out,encrypted:!0}):{ok:!1,reason:c.reason,encrypted:!0}}let s={unreachable:"not checked this scan - af360 could not open a connection to GitHub",down:"not checked this scan - GitHub did not answer properly",expired:"not checked this scan - the GitHub token has expired",unauthorized:"not checked this scan - GitHub would not accept the token",forbidden:"not checked this scan - the token is fine, but this is outside what af360 was granted",ratelimited:"not checked this scan - your GitHub rate limit is spent",timeout:"not checked this scan - GitHub did not answer in time",moved:"not checked - your remote points at a name GitHub has moved, and it will stay unchecked until the remote is updated","past-ceiling":"not checked - af360 asks GitHub about a limited number of repositories each scan, and this one is past that"},t={unreachable:"no connection",down:"GitHub down",expired:"token expired",unauthorized:"token refused",forbidden:"not granted",ratelimited:"rate limit",timeout:"no answer",moved:"remote moved","past-ceiling":"past the scan limit"};Object.fromEntries(Object.keys(t).map(a=>[a,`GitHub not checked (${t[a]})`]));var u=c(4683);let v=new Set(["read:org","read:user","read:packages","read:discussion","read:project","read:audit_log","read:gpg_key","read:public_key","user:email","read:enterprise","read:network"]),w=new Set(["read"]);async function x(a,b,c,d){var g;let i,j=await h(`/repos/${k(b)}/${k(c)}`,d);if(!j.ok)return f(j.kind,j.reason);let l="string"==typeof j.value.body.default_branch?j.value.body.default_branch:null,m=a.branch||l;if(!m)return f("down","GitHub did not name a default branch and local git did not name one either");let[n,o,p]=await Promise.all([h(`/repos/${k(b)}/${k(c)}/actions/runs?branch=${k(m)}&per_page=1&exclude_pull_requests=true`,d),h(`/repos/${k(b)}/${k(c)}/pulls?state=open&per_page=100`,d),(g=a).statusKnown&&0===g.ahead&&0===g.behind&&g.headSha?h(`/repos/${k(b)}/${k(c)}/branches/${k(m)}`,d):Promise.resolve(null)]),q=n.ok?e(function(a,b){if(!a)return null;let c=Date.parse(a.updated_at??a.created_at??""),d=a.conclusion??null;return{state:"success"===d?"passing":"failure"===d||"timed_out"===d||"startup_failure"===d?"failing":null===d?"running":"other",conclusion:d,workflow:"string"==typeof a.name&&a.name?a.name:"a workflow",branch:a.head_branch||b,at:Number.isFinite(c)?c:Date.now(),runNumber:"number"==typeof a.run_number?a.run_number:null}}(n.value.body?.workflow_runs?.[0],m)):f(n.kind,n.reason),r=o.ok?o.value.body??[]:null,s=o.ok?e((o.value.body??[]).length):f(o.kind,o.reason),t=null!==r&&r.length>=100,u="number"==typeof j.value.body.open_issues_count?j.value.body.open_issues_count:null;return i=null===u?f("down","GitHub did not say how many issues are open"):o.ok?e(Math.max(0,u-(r?.length??0))):f(o.kind,"af360 could not separate issues from pull requests this scan"),e({owner:b,name:c,fullName:j.value.body.full_name??`${b}/${c}`,defaultBranch:l,branch:m,ci:q,prCount:s,prCapped:t,issueCount:i,backup:function(a,b,c){if(!a.statusKnown)return{verdict:"unmeasured",reason:"local git did not finish answering, so there was nothing to confirm against"};if(!a.headSha)return{verdict:"unmeasured",reason:"af360 could not read this project's current commit"};if(null===a.ahead||null===a.behind)return{verdict:"unmeasured",reason:"local git did not report this branch's position against its remote"};if(a.ahead>0)return{verdict:"unmeasured",reason:"local git already reports commits that are not pushed - there is no claim to confirm"};if(a.behind>0)return{verdict:"unmeasured",reason:"this machine is behind its remote, so the two tips are expected to differ"};if(!c)return{verdict:"unmeasured",reason:"af360 did not ask GitHub for this branch"};if(!c.ok)return{verdict:"unmeasured",reason:c.reason};let d=c.value.body.commit?.sha;return"string"==typeof d&&d?d===a.headSha?{verdict:"confirmed",sha:d,branch:b}:{verdict:"refuted",localSha:a.headSha,remoteSha:d,branch:b}:{verdict:"unmeasured",reason:"GitHub did not name a commit for that branch"}}(a,m,p)})}let y={id:"github",label:"GitHub",host:"api.github.com",verify:async function a(a){let b,c=await h("/user",a);if(!c.ok)return{kind:"unreached",unreached:c.kind,reason:c.reason};let d="string"==typeof c.value.body.login?c.value.body.login:"";if(!d)return{kind:"unreached",unreached:"down",reason:"GitHub did not say who this token belongs to"};if(c.value.oauthScopes){let b=function(a){let b=a.split(",").map(a=>a.trim()).filter(Boolean);if(0===b.length)return{readOnly:!0,detail:"a classic token with no scopes - it can read public repositories only"};let c=b.filter(a=>!v.has(a));return 0===c.length?{readOnly:!0,detail:`classic token, read-only scopes (${b.join(", ")})`}:{readOnly:!1,detail:`it carries the ${c.join(", ")} scope${1===c.length?"":"s"}, which can write`}}(c.value.oauthScopes);if(!b.readOnly)return{kind:"refused-write",detail:b.detail};let e=await h("/user/repos?per_page=100&sort=pushed",a);if(!e.ok)return{kind:"unreached",unreached:e.kind,reason:`${e.reason} - af360 could not check what this token can reach, so nothing was stored`};let f=function(a){let b=a.filter(a=>a.permissions?.push||a.permissions?.admin||a.permissions?.maintain);if(0===b.length)return{readOnly:!0,detail:`fine-grained token, read-only on all ${a.length} repositor${1===a.length?"y":"ies"} it can see`};let c=b.slice(0,3).map(a=>a.full_name??"a repository").join(", "),d=b.length>3?` and ${b.length-3} more`:"";return{readOnly:!1,detail:`it can push to ${c}${d}`}}(e.value.body??[]);return f.readOnly?{kind:"ok",login:d,scopesRead:!0,expiryKnown:!1,repoNames:(e.value.body??[]).map(a=>a.full_name??"").filter(Boolean)}:{kind:"refused-write",detail:f.detail}}let e=await h("/user/installations?per_page=100",a);if(!e.ok)return{kind:"unreached",unreached:e.kind,reason:`${e.reason} - af360 could not check what it was granted, so nothing was stored`};let f=e.value.body.installations??[],g=f.filter(a=>a.app_slug===u.II);if(f.length>0&&0===g.length)return{kind:"unreached",unreached:"down",reason:`GitHub returned ${f.length} installation${1===f.length?"":"s"}, none of them af360's own, so af360 could not confirm the grant it was reading was its own - nothing was stored`};let i=function(a){if(0===a.length)return{readOnly:!0,detail:"the App is authorized but not installed on any account yet"};let b=[];for(let c of a)for(let[a,d]of Object.entries(c.permissions??{}))w.has(String(d).toLowerCase())||b.push(`${a}: ${d}${c.account?.login?` on ${c.account.login}`:""}`);return 0===b.length?{readOnly:!0,detail:`the App is installed read-only on ${a.length} account${1===a.length?"":"s"}`}:{readOnly:!1,detail:`the installation grants ${b.slice(0,3).join(", ")}${b.length>3?` and ${b.length-3} more`:""}`}}(g);if(!i.readOnly)return{kind:"refused-write",detail:i.detail};let j=[],k=0;for(let c of g){if("number"!=typeof c.id)continue;b??=c.id;let d=await l(c.id,a);if(!d.ok){k++;continue}for(let a of d.value.body.repositories??[])a.full_name&&j.push(a.full_name)}return{kind:"ok",login:d,repoNames:j,scopesRead:!0,expiryKnown:!1,installationId:b,installationCount:g.length,reposUnread:k}},facts:async function a(a){let b,c=Date.now(),d=await I();if(!d)return{at:c,byPath:{},outage:{kind:"unauthorized",reason:"af360 holds no GitHub token"}};if(d.expiresAt&&Date.parse(d.expiresAt)<=c)return{at:c,byPath:{},outage:{kind:"expired",reason:"the GitHub token's expiry date has passed"}};let e=a.map(a=>({s:a,repo:function(a){if(!a)return null;let b=a.trim(),c=null,d=null,e=/^(?:[A-Za-z0-9._-]+@)?([A-Za-z0-9._-]+):(.+)$/.exec(b);if(e&&!/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(b))c=e[1].toLowerCase(),d=e[2];else try{let a=new URL(b);c=a.hostname.toLowerCase(),d=a.pathname}catch{return null}if("github.com"!==c&&"www.github.com"!==c)return null;let f=(d??"").replace(/^\/+/,"").replace(/\.git$/i,"").split("/").filter(Boolean);if(2!==f.length)return null;let[g,h]=f,i=a=>/^[A-Za-z0-9._-]{1,100}$/.test(a)&&"."!==a&&".."!==a;return i(g)&&i(h)?{owner:g,name:h}:null}(a.remoteUrl)})).filter(a=>null!==a.repo),g={},h=e.slice(0,25);for(let a of e.slice(25))g[a.s.path.toLowerCase()]=f("past-ceiling","af360 asks GitHub about at most 25 repositories in one scan, and this one was past that");let i=0,j=Array.from({length:Math.min(4,h.length)},async()=>{for(;;){if(b)return;let a=i++;if(a>=h.length)return;let{s:c,repo:e}=h[a],f=await x(c,e.owner,e.name,d.token);if(!f.ok&&("ratelimited"===f.kind||"expired"===f.kind)){b={kind:f.kind,reason:f.reason};return}g[c.path.toLowerCase()]=f}});return await Promise.all(j),{at:c,byPath:g,outage:b}},expiry:function(a){return a.connected&&a.expiryKnown&&a.expiresAt&&Number.isFinite(Date.parse(a.expiresAt))?{id:"connector:github",name:"GitHub token (af360 stops seeing CI, PRs and issues)",date:a.expiresAt}:null},unmeasuredLine:a=>s[a]},z=null,A=null,B="This build of af360 has no GitHub App registration, so it cannot renew access",C=0,D=6e4;function E(a,b){C=b+D,D=Math.min(2*D,18e5),A!==a&&(A=a,z={ok:!1,reason:a})}function F(){let a=z;return z=null,a}async function G(a){let b=await r(a.token);if(!b.ok)return null;let c=a.refreshToken;if(c){let a=await r(c);c=a.ok?a.token:void 0}return{...a,token:b.token,refreshToken:c}}async function H(a){let b={...a,token:(await q(a.token)).stored};return a.refreshToken&&(b.refreshToken=(await q(a.refreshToken)).stored),b}async function I(a=Date.now()){try{let b=await (0,m.G5)(),d=b.config?.connectors?.github;if(!d||"string"!=typeof d.token||!d.token)return null;let e=await G(d);if(!e)return null;let f=e.expiresAt?Date.parse(e.expiresAt):NaN;if(!Number.isFinite(f)||f-a>3e5)return A=null,C=0,D=6e4,e;if(!e.refreshToken)return e;let{APP_CONFIGURED:g}=await Promise.resolve().then(c.bind(c,4683));if(!g)return E(B,a),e;if(A&&a<C)return e;return E("af360 cannot renew this sign-in with GitHub - press Connect to sign in again",a),e}catch{return null}}async function J(){let a,b={id:y.id,label:y.label,connected:!1},d=null;try{let a=await (0,m.G5)();d=a.config?.connectors?.github??null}catch{return b}if(!d?.token)return b;if(!(await r(d.token)).ok)return{...b,connected:!0,unreadable:!0,login:d.login,repoNames:d.repoNames,repoCount:d.repoNames?.length,connectedAt:d.connectedAt};let e=!1;try{let{cachedGithubScan:b}=await c.e(6988).then(c.bind(c,26988)),d=await b(),f=d?.outage?.kind;if(!f){for(let a of Object.values(d?.byPath??{}))if(!a.ok&&("unauthorized"===a.kind||"expired"===a.kind)){f=a.kind;break}}("unauthorized"===f||"expired"===f)&&(a=f),d&&!d.outage&&(e=Object.values(d.byPath??{}).some(a=>a.ok))}catch{}return K&&(e=!0),{...b,connected:!0,refusal:a,verified:e,login:d.login,repoNames:d.repoNames,repoCount:d.repoNames?.length,reposKnown:d.reposKnown,installationCount:d.installationCount,expiryKnown:!1,connectedAt:d.connectedAt}}let K=!1;async function L(a,b,c){let d=await (0,m.G5)();if("unreadable"===d.status||!d.config)throw Error("af360 could not read its own settings, so it did not store anything");let e=d.config;e.connectors={...e.connectors,github:await H({token:a,login:b.login,repoNames:b.repoNames,reposKnown:(b.reposUnread??0)===0,installationId:b.installationId,installationCount:b.installationCount,connectedAt:Date.now(),...c?{expiresAt:new Date(c.expiresAt).toISOString(),refreshToken:c.refreshToken,refreshExpiresAt:new Date(c.refreshExpiresAt).toISOString()}:{}})},await (0,m.ql)(e),K=!0}async function M(){var a;let b=await (0,m.G5)();if("unreadable"===b.status||!b.config)throw Error("af360 could not read its own settings, so it changed nothing");let c=b.config;"string"==typeof(a=c.connectors?.github?.token)?p.delete(a):p.clear(),c.connectors&&delete c.connectors.github,await (0,m.ql)(c),K=!1}},46995:(a,b,c)=>{c.d(b,{$:()=>i,bridge:()=>k});var d=c(79646),e=c(29021),f=c(33873),g=c(79551);let h=f.resolve(f.dirname((0,g.fileURLToPath)("file:///C:/dev/af360/lib/bridge.mjs")),"..");function i(){let a=process.env.AF360_BRIDGE;return a?(0,e.existsSync)(a)?a:null:j()}function j(){for(let a of[f.join(h,"af360-bridge.exe"),f.join(h,"shell","bin","af360-bridge.exe")])if((0,e.existsSync)(a))return a;return null}function k(a,b="",{fixedPath:c=!1,timeout:e=15e3}={}){let f=c?j():i();return f?new Promise(c=>{let g=(0,d.execFile)(f,[a],{windowsHide:!0,timeout:e,maxBuffer:1e6},(a,b,d)=>{if(a)return void c({ok:!1,reason:String(d||"").trim()||(a.killed?"timeout":"failed")});c({ok:!0,out:String(b||"").trim()})});g.stdin.on("error",()=>{}),g.stdin.end(b)}):Promise.resolve({ok:!1,reason:"absent"})}}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
exports.id=9170,exports.ids=[9170],exports.modules={3421:(a,b,c)=>{"use strict";Object.defineProperty(b,"I",{enumerable:!0,get:function(){return g}});let d=c(71237),e=c(55088),f=c(17679);async function g(a,b,c,g){if((0,d.isNodeNextResponse)(b)){var h;b.statusCode=c.status,b.statusMessage=c.statusText;let d=["set-cookie","www-authenticate","proxy-authenticate","vary"];null==(h=c.headers)||h.forEach((a,c)=>{if("x-middleware-set-cookie"!==c.toLowerCase())if("set-cookie"===c.toLowerCase())for(let d of(0,f.splitCookiesString)(a))b.appendHeader(c,d);else{let e=void 0!==b.getHeader(c);(d.includes(c.toLowerCase())||!e)&&b.appendHeader(c,a)}});let{originalResponse:i}=b;c.body&&"HEAD"!==a.method?await (0,e.pipeToNodeResponse)(c.body,i,g):i.end()}}},5731:(a,b,c)=>{"use strict";c.d(b,{G2:()=>j,Mx:()=>l,Q6:()=>g,aC:()=>h,lF:()=>f,vh:()=>i,z_:()=>k}),c(79748);var d=c(23787);c(21820);var e=c(33873);let f=(0,d.M)(),g=e.join(f,"mcp-activity.log"),h=e.join(f,"mcp-activity.1.log"),i=Object.freeze(["estate_status","projects","changed_since","session_verify","sites","blast_radius","ahead","agent_handoff"]),j="unknown",k="unidentified",l=/^[a-z0-9][a-z0-9._+-]{0,31}$/;Object.freeze(["cmd","powershell","pwsh","sh","bash"]),RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z\\t(?:${[...i,j].join("|")})(?:\\t${l.source.replace(/^\^|\$$/g,"")})?$`)},22191:(a,b,c)=>{"use strict";c.d(b,{CL:()=>h,P6:()=>d.P6,logEvent:()=>g});var d=c(80069);let e=globalThis,f=e.__af360Log??(e.__af360Log=[]);function g(a,b){let c=f[f.length-1];if(c&&c.text===a&&Date.now()-c.ts<6e4)return;let e=b?{ts:Date.now(),text:a,kind:b}:{ts:Date.now(),text:a};f.push(e),f.length>200&&f.splice(0,f.length-200),(0,d.xv)(e).catch(()=>{})}async function h(a=Date.now()){let b=await (0,d.Oq)(a).catch(()=>({events:[],oldestTs:null,truncated:!1,spansWindow:!1})),c=new Set(b.events.map(a=>`${a.ts}\0${a.text}`)),e=f.filter(a=>!c.has(`${a.ts}\0${a.text}`)),g=[...b.events,...e].sort((a,b)=>b.ts-a.ts),i=g.length?g[g.length-1].ts:null;return{events:g,coverage:(0,d.ve)({oldestTs:i,truncated:b.truncated,spansWindow:b.spansWindow},a)}}},78335:()=>{},80069:(a,b,c)=>{"use strict";c.d(b,{Oq:()=>r,P6:()=>s,ve:()=>u,xv:()=>n});var d=c(79748),e=c(33873),f=c(5731);let g=e.join(f.lF,"log.jsonl"),h=e.join(f.lF,"log.1.jsonl"),i=new Set(["closed","mcp","connection"]);function j(a){let b;if(!a)return null;try{b=JSON.parse(a)}catch{return null}return b&&"object"==typeof b&&"number"==typeof b.ts&&Number.isFinite(b.ts)&&"string"==typeof b.text&&0!==b.text.length&&(void 0===b.kind||i.has(b.kind))?b.kind?{ts:b.ts,text:b.text,kind:b.kind}:{ts:b.ts,text:b.text}:null}function k(a){return JSON.stringify(a.kind?{ts:a.ts,text:a.text,kind:a.kind}:{ts:a.ts,text:a.text})+"\n"}let l=Promise.resolve();function m(a){let b=l.then(a,a);return l=b.then(()=>{},()=>{}),b}async function n(a){return m(()=>o(a))}async function o(a){let b=k(a),c=!1;try{let a=await (0,d.stat)(g);a.size+b.length>524288?await (0,d.rename)(g,h):c=await p(a.size)}catch{}try{await (0,d.appendFile)(g,c?"\n"+b:b,"utf8")}catch{}}async function p(a){let b;if(0===a)return!1;try{b=await (0,d.open)(g,"r");let c=Buffer.alloc(1);return await b.read(c,0,1,a-1),10!==c[0]}catch{return!1}finally{await b?.close?.().catch(()=>{})}}async function q(a){try{let b=await (0,d.readFile)(a,"utf8"),c=[],e=0;for(let a of b.split("\n")){if(""===a)continue;let b=j(a);b?c.push(b):e++}return{events:c,unreadable:e}}catch{return{events:[],unreadable:0}}}async function r(a=Date.now()){let b=await q(h),c=await q(g),d=b.events,e=[...d,...c.events].sort((a,b)=>a.ts-b.ts),f=b.unreadable+c.unreadable,i=a-6048e5,j=e.filter(a=>a.ts>=i),k=d.length>0&&d[0].ts>=i,l=e.some(a=>a.ts<i);return{events:j.reverse(),oldestTs:j.length?j[j.length-1].ts:null,truncated:k,spansWindow:l,unreadable:f}}async function s(a=Date.now()){return m(()=>t(a))}async function t(a){let b=a-6048e5-864e5;for(let a of[h,g]){let c;try{let e=(await (0,d.readFile)(a,"utf8")).split("\n").map(j).filter(Boolean);if((c=e.filter(a=>a.ts>=b)).length===e.length)continue}catch{continue}try{await (0,d.writeFile)(a,c.map(k).join(""),"utf8")}catch{}}}function u({oldestTs:a,truncated:b,spansWindow:c,unreadable:d=0},e=Date.now()){if(null==a)return{state:"empty",days:0,oldestTs:null,truncated:!1,unreadable:d};let f=Math.floor((e-a)/864e5);return b?{state:"truncated",days:f,oldestTs:a,truncated:!0,unreadable:d}:c?{state:"full",days:7,oldestTs:a,truncated:!1,unreadable:d}:{state:"partial",days:f,oldestTs:a,truncated:!1,unreadable:d}}},95736:(a,b,c)=>{"use strict";a.exports=c(44870)},96487:()=>{}};
|
|
1
|
+
exports.id=9170,exports.ids=[9170],exports.modules={3421:(a,b,c)=>{"use strict";Object.defineProperty(b,"I",{enumerable:!0,get:function(){return g}});let d=c(71237),e=c(55088),f=c(17679);async function g(a,b,c,g){if((0,d.isNodeNextResponse)(b)){var h;b.statusCode=c.status,b.statusMessage=c.statusText;let d=["set-cookie","www-authenticate","proxy-authenticate","vary"];null==(h=c.headers)||h.forEach((a,c)=>{if("x-middleware-set-cookie"!==c.toLowerCase())if("set-cookie"===c.toLowerCase())for(let d of(0,f.splitCookiesString)(a))b.appendHeader(c,d);else{let e=void 0!==b.getHeader(c);(d.includes(c.toLowerCase())||!e)&&b.appendHeader(c,a)}});let{originalResponse:i}=b;c.body&&"HEAD"!==a.method?await (0,e.pipeToNodeResponse)(c.body,i,g):i.end()}}},5731:(a,b,c)=>{"use strict";c.d(b,{G2:()=>j,Mx:()=>l,Q6:()=>g,aC:()=>h,lF:()=>f,vh:()=>i,z_:()=>k}),c(79748);var d=c(23787);c(21820);var e=c(33873);let f=(0,d.M)(),g=e.join(f,"mcp-activity.log"),h=e.join(f,"mcp-activity.1.log"),i=Object.freeze(["estate_status","projects","changed_since","session_verify","sites","blast_radius","ahead","discoveries","agent_handoff"]),j="unknown",k="unidentified",l=/^[a-z0-9][a-z0-9._+-]{0,31}$/;Object.freeze(["cmd","powershell","pwsh","sh","bash"]),RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z\\t(?:${[...i,j].join("|")})(?:\\t${l.source.replace(/^\^|\$$/g,"")})?$`)},22191:(a,b,c)=>{"use strict";c.d(b,{CL:()=>h,P6:()=>d.P6,logEvent:()=>g});var d=c(80069);let e=globalThis,f=e.__af360Log??(e.__af360Log=[]);function g(a,b){let c=f[f.length-1];if(c&&c.text===a&&Date.now()-c.ts<6e4)return;let e=b?{ts:Date.now(),text:a,kind:b}:{ts:Date.now(),text:a};f.push(e),f.length>200&&f.splice(0,f.length-200),(0,d.xv)(e).catch(()=>{})}async function h(a=Date.now()){let b=await (0,d.Oq)(a).catch(()=>({events:[],oldestTs:null,truncated:!1,spansWindow:!1})),c=new Set(b.events.map(a=>`${a.ts}\0${a.text}`)),e=f.filter(a=>!c.has(`${a.ts}\0${a.text}`)),g=[...b.events,...e].sort((a,b)=>b.ts-a.ts),i=g.length?g[g.length-1].ts:null;return{events:g,coverage:(0,d.ve)({oldestTs:i,truncated:b.truncated,spansWindow:b.spansWindow},a)}}},78335:()=>{},80069:(a,b,c)=>{"use strict";c.d(b,{Oq:()=>r,P6:()=>s,ve:()=>u,xv:()=>n});var d=c(79748),e=c(33873),f=c(5731);let g=e.join(f.lF,"log.jsonl"),h=e.join(f.lF,"log.1.jsonl"),i=new Set(["closed","mcp","connection"]);function j(a){let b;if(!a)return null;try{b=JSON.parse(a)}catch{return null}return b&&"object"==typeof b&&"number"==typeof b.ts&&Number.isFinite(b.ts)&&"string"==typeof b.text&&0!==b.text.length&&(void 0===b.kind||i.has(b.kind))?b.kind?{ts:b.ts,text:b.text,kind:b.kind}:{ts:b.ts,text:b.text}:null}function k(a){return JSON.stringify(a.kind?{ts:a.ts,text:a.text,kind:a.kind}:{ts:a.ts,text:a.text})+"\n"}let l=Promise.resolve();function m(a){let b=l.then(a,a);return l=b.then(()=>{},()=>{}),b}async function n(a){return m(()=>o(a))}async function o(a){let b=k(a),c=!1;try{let a=await (0,d.stat)(g);a.size+b.length>524288?await (0,d.rename)(g,h):c=await p(a.size)}catch{}try{await (0,d.appendFile)(g,c?"\n"+b:b,"utf8")}catch{}}async function p(a){let b;if(0===a)return!1;try{b=await (0,d.open)(g,"r");let c=Buffer.alloc(1);return await b.read(c,0,1,a-1),10!==c[0]}catch{return!1}finally{await b?.close?.().catch(()=>{})}}async function q(a){try{let b=await (0,d.readFile)(a,"utf8"),c=[],e=0;for(let a of b.split("\n")){if(""===a)continue;let b=j(a);b?c.push(b):e++}return{events:c,unreadable:e}}catch{return{events:[],unreadable:0}}}async function r(a=Date.now()){let b=await q(h),c=await q(g),d=b.events,e=[...d,...c.events].sort((a,b)=>a.ts-b.ts),f=b.unreadable+c.unreadable,i=a-6048e5,j=e.filter(a=>a.ts>=i),k=d.length>0&&d[0].ts>=i,l=e.some(a=>a.ts<i);return{events:j.reverse(),oldestTs:j.length?j[j.length-1].ts:null,truncated:k,spansWindow:l,unreadable:f}}async function s(a=Date.now()){return m(()=>t(a))}async function t(a){let b=a-6048e5-864e5;for(let a of[h,g]){let c;try{let e=(await (0,d.readFile)(a,"utf8")).split("\n").map(j).filter(Boolean);if((c=e.filter(a=>a.ts>=b)).length===e.length)continue}catch{continue}try{await (0,d.writeFile)(a,c.map(k).join(""),"utf8")}catch{}}}function u({oldestTs:a,truncated:b,spansWindow:c,unreadable:d=0},e=Date.now()){if(null==a)return{state:"empty",days:0,oldestTs:null,truncated:!1,unreadable:d};let f=Math.floor((e-a)/864e5);return b?{state:"truncated",days:f,oldestTs:a,truncated:!0,unreadable:d}:c?{state:"full",days:7,oldestTs:a,truncated:!1,unreadable:d}:{state:"partial",days:f,oldestTs:a,truncated:!1,unreadable:d}}},95736:(a,b,c)=>{"use strict";a.exports=c(44870)},96487:()=>{}};
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
"wasm": [],
|
|
18
18
|
"assets": [],
|
|
19
19
|
"env": {
|
|
20
|
-
"__NEXT_BUILD_ID": "
|
|
21
|
-
"NEXT_SERVER_ACTIONS_ENCRYPTION_KEY": "
|
|
22
|
-
"__NEXT_PREVIEW_MODE_ID": "
|
|
23
|
-
"__NEXT_PREVIEW_MODE_SIGNING_KEY": "
|
|
24
|
-
"__NEXT_PREVIEW_MODE_ENCRYPTION_KEY": "
|
|
20
|
+
"__NEXT_BUILD_ID": "0b943e6aa8d5ffe860588",
|
|
21
|
+
"NEXT_SERVER_ACTIONS_ENCRYPTION_KEY": "YdPu++v3t7SL5B92FFPux6ElqWEv+lhsJGojuIFAPjA=",
|
|
22
|
+
"__NEXT_PREVIEW_MODE_ID": "3f8a0dcf64bbfddbe99a7782cf3ab463",
|
|
23
|
+
"__NEXT_PREVIEW_MODE_SIGNING_KEY": "9446ae6ca7d23334de6523ce60710bef803c8dcf2dd3e4b64212d97995231f9f",
|
|
24
|
+
"__NEXT_PREVIEW_MODE_ENCRYPTION_KEY": "0d4cd96639484e34ea687a06b45ddf113ca07c1412d1a90e80423cf7392da419"
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><!--
|
|
1
|
+
<!DOCTYPE html><!--0b943e6aa8d5ffe860588--><html lang="en" dir="ltr" class="__variable_01ae00 __variable_f367f3 __variable_46fe82 __variable_c5564f"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="/_next/static/css/94d302c686de7e23.css" data-precedence="next"/><link rel="stylesheet" href="/_next/static/css/9b639a814d15c5ff.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-c271465961823a3e.js"/><script src="/_next/static/chunks/4bd1b696-f785427dddbba9fb.js" async=""></script><script src="/_next/static/chunks/1255-612df69cb02f2021.js" async=""></script><script src="/_next/static/chunks/main-app-6dcbd7e901d0070a.js" async=""></script><script src="/_next/static/chunks/3192-6b341d547a49fa85.js" async=""></script><script src="/_next/static/chunks/1681-b233404f9ec2fc2e.js" async=""></script><script src="/_next/static/chunks/app/error-37987420de14c10c.js" async=""></script><meta name="robots" content="noindex"/><title>404: This page could not be found.</title><title>af360 - everything you've built, watched from one place</title><script src="/boot.js"></script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-c271465961823a3e.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[9766,[],\"\"]\n3:I[9567,[\"3192\",\"static/chunks/3192-6b341d547a49fa85.js\",\"1681\",\"static/chunks/1681-b233404f9ec2fc2e.js\",\"8039\",\"static/chunks/app/error-37987420de14c10c.js\"],\"default\"]\n4:I[8924,[],\"\"]\n5:I[4431,[],\"OutletBoundary\"]\n7:I[5278,[],\"AsyncMetadataOutlet\"]\n9:I[4431,[],\"ViewportBoundary\"]\nb:I[4431,[],\"MetadataBoundary\"]\nc:\"$Sreact.suspense\"\ne:I[7150,[],\"\"]\n:HL[\"/_next/static/css/94d302c686de7e23.css\",\"style\"]\n:HL[\"/_next/static/css/9b639a814d15c5ff.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"b\":\"0b943e6aa8d5ffe860588\",\"p\":\"\",\"c\":[\"\",\"_not-found\"],\"i\":false,\"f\":[[[\"\",{\"children\":[\"/_not-found\",{\"children\":[\"__PAGE__\",{}]}]},\"$undefined\",\"$undefined\",true],[\"\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/94d302c686de7e23.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}],[\"$\",\"link\",\"1\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/9b639a814d15c5ff.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"dir\":\"ltr\",\"suppressHydrationWarning\":true,\"className\":\"__variable_01ae00 __variable_f367f3 __variable_46fe82 __variable_c5564f\",\"children\":[[\"$\",\"head\",null,{\"children\":[\"$\",\"script\",null,{\"src\":\"/boot.js\"}]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$3\",\"errorStyles\":[],\"errorScripts\":[],\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}]]}]]}],{\"children\":[\"/_not-found\",[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L4\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[\"__PAGE__\",[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L5\",null,{\"children\":[\"$L6\",[\"$\",\"$L7\",null,{\"promise\":\"$@8\"}]]}]]}],{},null,false]},null,false]},null,false],[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[[\"$\",\"$L9\",null,{\"children\":\"$La\"}],null],[\"$\",\"$Lb\",null,{\"children\":[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$c\",null,{\"fallback\":null,\"children\":\"$Ld\"}]}]}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$e\",[]],\"s\":false,\"S\":true}\n"])</script><script>self.__next_f.push([1,"a:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n6:null\n"])</script><script>self.__next_f.push([1,"8:{\"metadata\":[[\"$\",\"title\",\"0\",{\"children\":\"af360 - everything you've built, watched from one place\"}]],\"error\":null,\"digest\":\"$undefined\"}\n"])</script><script>self.__next_f.push([1,"d:\"$8:metadata\"\n"])</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><title data-next-head="">500: Internal Server Error</title><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-c271465961823a3e.js" defer=""></script><script src="/_next/static/chunks/framework-6dcb94a73b69c7a9.js" defer=""></script><script src="/_next/static/chunks/main-6828c74376f2b965.js" defer=""></script><script src="/_next/static/chunks/pages/_app-55d77747009218cb.js" defer=""></script><script src="/_next/static/chunks/pages/_error-72c0e9c72b90d370.js" defer=""></script><script src="/_next/static/
|
|
1
|
+
<!DOCTYPE html><html><head><meta charSet="utf-8" data-next-head=""/><meta name="viewport" content="width=device-width" data-next-head=""/><title data-next-head="">500: Internal Server Error</title><noscript data-n-css=""></noscript><script defer="" noModule="" src="/_next/static/chunks/polyfills-42372ed130431b0a.js"></script><script src="/_next/static/chunks/webpack-c271465961823a3e.js" defer=""></script><script src="/_next/static/chunks/framework-6dcb94a73b69c7a9.js" defer=""></script><script src="/_next/static/chunks/main-6828c74376f2b965.js" defer=""></script><script src="/_next/static/chunks/pages/_app-55d77747009218cb.js" defer=""></script><script src="/_next/static/chunks/pages/_error-72c0e9c72b90d370.js" defer=""></script><script src="/_next/static/0b943e6aa8d5ffe860588/_buildManifest.js" defer=""></script><script src="/_next/static/0b943e6aa8d5ffe860588/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">500</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">Internal Server Error<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":500}},"page":"/_error","query":{},"buildId":"0b943e6aa8d5ffe860588","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"node":{},"edge":{},"encryptionKey":"
|
|
1
|
+
{"node":{},"edge":{},"encryptionKey":"YdPu++v3t7SL5B92FFPux6ElqWEv+lhsJGojuIFAPjA="}
|