863863 .sidebar nav a { justify-content : center; padding : 10px ; }
864864 .main { margin-left : 60px ; padding : 20px 16px ; }
865865}
866+ .contributor-list { display : flex; flex-direction : column; gap : 12px ; }
867+ .contributor-card { display : flex; gap : 16px ; padding : 16px ; border : 1px solid var (--border ); border-radius : var (--radius ); background : var (--surface ); transition : border-color .15s ; }
868+ .contributor-card : hover { border-color : var (--accent ); }
869+ .contributor-card .avatar { width : 64px ; height : 64px ; border-radius : 50% ; flex : none; border : 2px solid var (--border ); background : var (--surface-2 ); object-fit : cover; }
870+ .contributor-card .meta { display : flex; flex-direction : column; gap : 4px ; flex : 1 ; min-width : 0 ; }
871+ .contributor-card .meta-top { display : flex; align-items : center; gap : 10px ; flex-wrap : wrap; }
872+ .contributor-card .meta-top .name { color : var (--accent ); font-weight : 600 ; font-size : 15px ; text-decoration : none; }
873+ .contributor-card .meta-top .name : hover { text-decoration : underline; }
874+ .contributor-card .meta-top .pr-link { font-size : 12px ; color : var (--text-dim ); text-decoration : none; padding : 2px 8px ; border : 1px solid var (--border ); border-radius : 4px ; }
875+ .contributor-card .meta-top .pr-link : hover { color : var (--accent ); border-color : var (--accent ); }
876+ .contributor-card .meta-top .merged-at { font-size : 11px ; color : var (--text-dim ); }
877+ .contributor-card .pr-title { font-weight : 500 ; margin-top : 4px ; font-size : 13px ; }
878+ .contributor-card .summary { font-size : 13px ; color : var (--text-muted ); line-height : 1.65 ; margin-top : 6px ; }
866879</ style >
867880< script type ="module ">
868881import { initializeApp } from 'https://www.gstatic.com/firebasejs/11.6.0/firebase-app.js' ;
944957 < span data-i18n ="nav.experimental "> 实验性功能</ span >
945958 </ a >
946959 </ div >
960+ < div class ="nav-group ">
961+ < div class ="nav-group-label " data-i18n ="nav.group.about "> 关于</ div >
962+ < a href ="#credits " data-panel ="credits ">
963+ < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-linecap ="round " stroke-linejoin ="round "> < path d ="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z "/> </ svg >
964+ < span data-i18n ="nav.credits "> 致谢</ span >
965+ </ a >
966+ </ div >
947967 </ nav >
948968 < div class ="footer ">
949969 < button class ="btn btn-ghost btn-xs " onclick ="App.toggleLang() " title ="Switch language " style ="margin-right:8px ">
@@ -1443,6 +1463,41 @@ <h1 class="page-title" data-i18n="page.bans">异常监测</h1>
14431463 </ div >
14441464 </ section >
14451465
1466+ < section class ="panel " id ="p-credits ">
1467+ < div class ="page-header ">
1468+ < div >
1469+ < h1 class ="page-title " data-i18n ="page.credits "> 致谢</ h1 >
1470+ < div class ="page-subtitle " data-i18n ="page.credits.sub "> 感谢以下朋友为项目提交 PR / 审计代码 / 修复问题</ div >
1471+ </ div >
1472+ </ div >
1473+ < div class ="section ">
1474+ < div class ="section-header ">
1475+ < div class ="section-title " data-i18n ="credits.contributors "> 核心贡献者</ div >
1476+ </ div >
1477+ < div class ="section-body " id ="credits-body ">
1478+ < div class ="text-sm text-dim "> 加载中…</ div >
1479+ </ div >
1480+ </ div >
1481+ < div class ="section ">
1482+ < div class ="section-header ">
1483+ < div class ="section-title " data-i18n ="credits.cta "> 想加入这份名单?</ div >
1484+ </ div >
1485+ < div class ="section-body ">
1486+ < div class ="section-desc " data-i18n ="credits.cta.desc "> 欢迎到 GitHub 提 issue 或 pull request — 不管是修 bug、加模型、改 UI 还是发现安全问题,都会被记录在这里。</ div >
1487+ < div style ="margin-top:12px ">
1488+ < a class ="btn btn-outline btn-sm " target ="_blank " rel ="noopener " href ="https://github.com/dwgx/WindsurfAPI/issues ">
1489+ < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-linecap ="round " stroke-linejoin ="round " style ="width:14px;height:14px;margin-right:6px "> < circle cx ="12 " cy ="12 " r ="10 "/> < line x1 ="12 " y1 ="8 " x2 ="12 " y2 ="12 "/> < line x1 ="12 " y1 ="16 " x2 ="12.01 " y2 ="16 "/> </ svg >
1490+ < span data-i18n ="credits.cta.issue "> 提 issue</ span >
1491+ </ a >
1492+ < a class ="btn btn-outline btn-sm " target ="_blank " rel ="noopener " href ="https://github.com/dwgx/WindsurfAPI/pulls " style ="margin-left:8px ">
1493+ < svg viewBox ="0 0 24 24 " fill ="none " stroke ="currentColor " stroke-linecap ="round " stroke-linejoin ="round " style ="width:14px;height:14px;margin-right:6px "> < circle cx ="18 " cy ="18 " r ="3 "/> < circle cx ="6 " cy ="6 " r ="3 "/> < path d ="M13 6h3a2 2 0 0 1 2 2v7 "/> < line x1 ="6 " y1 ="9 " x2 ="6 " y2 ="21 "/> </ svg >
1494+ < span data-i18n ="credits.cta.pr "> 提 PR</ span >
1495+ </ a >
1496+ </ div >
1497+ </ div >
1498+ </ div >
1499+ </ section >
1500+
14461501 < section class ="panel " id ="p-experimental ">
14471502 < div class ="page-header ">
14481503 < div >
@@ -1539,6 +1594,8 @@ <h3>控制台登录</h3>
15391594 'nav.proxy' : 'Proxy' ,
15401595 'nav.logs' : 'Logs' ,
15411596 'nav.experimental' : 'Experimental' ,
1597+ 'nav.group.about' : 'About' ,
1598+ 'nav.credits' : 'Credits' ,
15421599 'page.overview' : 'Dashboard' ,
15431600 'page.stats' : 'Statistics' ,
15441601 'page.windsurf-login' : 'Account Login' ,
@@ -1548,6 +1605,13 @@ <h3>控制台登录</h3>
15481605 'page.proxy' : 'Proxy Config' ,
15491606 'page.logs' : 'Runtime Logs' ,
15501607 'page.experimental' : 'Experimental Features' ,
1608+ 'page.credits' : 'Credits' ,
1609+ 'page.credits.sub' : 'Thanks to contributors who submitted PRs / audited code / reported issues' ,
1610+ 'credits.contributors' : 'Core Contributors' ,
1611+ 'credits.cta' : 'Want to join this list?' ,
1612+ 'credits.cta.desc' : 'Open an issue or pull request on GitHub — bug fixes, new models, UI improvements, or security findings all get recognised here.' ,
1613+ 'credits.cta.issue' : 'Open Issue' ,
1614+ 'credits.cta.pr' : 'Open PR' ,
15511615} ;
15521616
15531617const App = {
@@ -1634,6 +1698,7 @@ <h3>控制台登录</h3>
16341698 accounts : 'loadAccounts' , models : 'loadModels' , proxy : 'loadProxy' ,
16351699 logs : 'loadLogs' , stats : 'loadStats' , bans : 'loadBans' ,
16361700 experimental : 'loadExperimental' ,
1701+ credits : 'loadCredits' ,
16371702 } ;
16381703 if ( loaders [ panel ] ) this [ loaders [ panel ] ] ( ) ;
16391704 } ,
@@ -3048,6 +3113,41 @@ <h3>控制台登录</h3>
30483113 fallback ( ) ;
30493114 }
30503115 } ,
3116+ // Hand-maintained roster of external contributors. Update here when a
3117+ // new PR lands; the dashboard Credits panel renders straight from this.
3118+ CONTRIBUTORS : [
3119+ {
3120+ login : 'dd373156' ,
3121+ pr : 1 ,
3122+ mergedAt : '2026-04-20' ,
3123+ title : 'fix(models): make pro tier include dynamically merged cloud models' ,
3124+ summary : '发现 Pro 层级只看到硬编码的模型清单,拉自云端的动态扩展模型没合并进 tier 表,导致 Cursor / Cherry Studio 等客户端在 Pro 账号下也看不见最新上线的模型。修了 mergeCloudModels 的合并路径,让云端扩展模型进入 Pro 的可用清单。' ,
3125+ } ,
3126+ {
3127+ login : 'colin1112a' ,
3128+ pr : 13 ,
3129+ mergedAt : '2026-04-21' ,
3130+ title : 'fix: 一次性审计并提交 15 个安全 / 并发 / 资源管理 bug' ,
3131+ summary : '系统性扫了一遍仓库,围绕 XSS 转义、shell 注入、OOM 防护、auth 路由位置、gRPC 双回调、LS pool 竞态、HTTP/2 frame 上限等方向提 PR。我们在这个基础上再加固了 JS-level escJsAttr、_pending 合并 ensureLs、LS 退出时释放 pooled session,以及一些后续 Antigravity 审计发现的延伸修复。感谢提醒项目该重视 issues 了。' ,
3132+ } ,
3133+ ] ,
3134+ loadCredits ( ) {
3135+ const body = document . getElementById ( 'credits-body' ) ;
3136+ if ( ! body ) return ;
3137+ body . innerHTML = `<div class="contributor-list">${ this . CONTRIBUTORS . map ( c => `
3138+ <div class="contributor-card">
3139+ <img class="avatar" src="https://github.com/${ this . esc ( c . login ) } .png?size=128" alt="${ this . esc ( c . login ) } " loading="lazy" onerror="this.style.visibility='hidden'">
3140+ <div class="meta">
3141+ <div class="meta-top">
3142+ <a class="name" target="_blank" rel="noopener" href="https://github.com/${ this . esc ( c . login ) } ">@${ this . esc ( c . login ) } </a>
3143+ <a class="pr-link" target="_blank" rel="noopener" href="https://github.com/dwgx/WindsurfAPI/pull/${ c . pr } ">PR #${ c . pr } </a>
3144+ <span class="merged-at">${ this . esc ( c . mergedAt ) } </span>
3145+ </div>
3146+ <div class="pr-title">${ this . esc ( c . title ) } </div>
3147+ <div class="summary">${ this . esc ( c . summary ) } </div>
3148+ </div>
3149+ </div>` ) . join ( '' ) } </div>`;
3150+ } ,
30513151 esc ( s ) { return String ( s == null ? '' : s ) . replace ( / & / g, '&' ) . replace ( / < / g, '<' ) . replace ( / > / g, '>' ) . replace ( / " / g, '"' ) . replace ( / ' / g, ''' ) ; } ,
30523152 // For values interpolated into an inline `onclick="App.f('${...}')"`
30533153 // string: the HTML attribute parser will decode ' back to ', which
0 commit comments