diff --git a/README.md b/README.md
index da261cbb..b70644d9 100644
--- a/README.md
+++ b/README.md
@@ -190,6 +190,19 @@
| HLDP通用语言同步 | ✅ 已执行 | hldp/data/common/ |
| 仓库首页更新 | ✅ 已执行 | README.md 签到仪表盘 |
| 工作流士兵巡检 | ✅ 18/18 在岗 | 缺失的需冰朔确认 |
+| 留言板巡查 | ✅ v2.0活化 | LLM多模型降级 · 定时巡查 · 自愈 |
+
+### 🎖️ 铸渊副将Agent状态 (v2.0活体Agent)
+
+| 项目 | 状态 |
+|------|------|
+| Agent版本 | v2.0 · 活体Agent · 三层自愈 |
+| 运行模式 | 事件模式(即时回复) + 巡查模式(08:00/23:00) |
+| LLM能力 | 多模型自动降级: deepseek → qwen → moonshot → zhipu |
+| 自感知 | data/deputy-status.json · 每次运行更新 |
+| 自修复 | 每模型重试2次 · 递增等待 |
+| 升级通报 | 连续3次失败 → 创建Issue → 邮件通知冰朔 |
+| 📮 留言入口 | [给副将留言](https://github.com/qinfendebingshuo/guanghulab/issues/new?labels=deputy-message-board&title=给铸渊副将留言) |
> *此仪表盘由铸渊副将(ZY-DEPUTY-001)每日唤醒时自动更新 · 08:00 / 23:00*
diff --git a/docs/index.html b/docs/index.html
index 7bc28025..5d38aa17 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -716,6 +716,36 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
.app-card-tags{display:flex;gap:5px;flex-wrap:wrap}
.app-card-arrow{font-size:18px;color:var(--accent);opacity:.5;flex-shrink:0;transition:all .3s}
.app-card:hover .app-card-arrow{opacity:1;transform:translateX(4px)}
+
+/* ═══ PAGE: Bandwidth Sharing (带宽共享) ═══ */
+#pg-bandwidth .bw-hero{text-align:center;padding:28px 0 20px}
+#pg-bandwidth .bw-hero h2{font-size:1.4em;background:linear-gradient(135deg,var(--accent),var(--accent2));-webkit-background-clip:text;-webkit-text-fill-color:transparent}
+#pg-bandwidth .bw-hero p{color:var(--dim);font-size:.9em;margin-top:6px}
+#pg-bandwidth .bw-stats{display:flex;justify-content:space-around;margin:16px 0;gap:12px}
+#pg-bandwidth .bw-stat{text-align:center;flex:1}
+#pg-bandwidth .bw-stat .num{font-size:1.5em;font-weight:700;color:var(--accent);font-family:var(--m)}
+#pg-bandwidth .bw-stat .label{font-size:.75em;color:var(--dim);margin-top:4px}
+#pg-bandwidth .bw-card{background:var(--bg1);border-radius:var(--r);padding:20px;margin:12px 0;border:1px solid var(--border)}
+#pg-bandwidth .bw-card h3{font-size:1em;color:var(--accent);margin-bottom:14px}
+#pg-bandwidth .bw-input{width:100%;padding:12px 14px;background:var(--bg2);border:2px solid var(--border);border-radius:var(--rs);color:var(--text);font-size:1em;outline:none;transition:border-color .3s;font-family:var(--f)}
+#pg-bandwidth .bw-input:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(138,180,248,.15)}
+#pg-bandwidth .bw-input::placeholder{color:var(--dim);font-size:.85em}
+#pg-bandwidth .bw-code-input{text-align:center;letter-spacing:8px;font-size:1.3em;font-family:var(--m)}
+#pg-bandwidth .bw-code-input::placeholder{letter-spacing:0;font-size:.6em}
+#pg-bandwidth .bw-btn{width:100%;padding:14px;background:linear-gradient(135deg,var(--accent),var(--accent2));color:#fff;border:none;border-radius:var(--rs);font-size:1em;font-weight:600;cursor:pointer;transition:opacity .3s,transform .15s;margin-top:8px;font-family:var(--f)}
+#pg-bandwidth .bw-btn:hover{opacity:.9}
+#pg-bandwidth .bw-btn:active{transform:scale(.98)}
+#pg-bandwidth .bw-btn:disabled{opacity:.5;cursor:not-allowed;transform:none}
+#pg-bandwidth .bw-btn-outline{background:transparent;border:1px solid var(--accent);color:var(--accent)}
+#pg-bandwidth .bw-btn-outline:hover{background:rgba(138,180,248,.1)}
+#pg-bandwidth .bw-result{text-align:center;padding:14px;border-radius:var(--rs);margin-top:12px;display:none;font-size:.9em;line-height:1.6}
+#pg-bandwidth .bw-result.ok{display:block;background:rgba(52,211,153,.1);color:var(--ok);border:1px solid rgba(52,211,153,.2)}
+#pg-bandwidth .bw-result.err{display:block;background:rgba(248,113,113,.1);color:var(--err);border:1px solid rgba(248,113,113,.2)}
+#pg-bandwidth .bw-info{background:var(--bg2);border-radius:var(--rs);padding:14px 16px;margin:10px 0;font-size:.85em;line-height:1.8;color:var(--dim);border-left:3px solid var(--accent)}
+#pg-bandwidth .bw-consent{display:flex;align-items:flex-start;gap:10px;margin:14px 0;padding:12px 14px;background:var(--bg2);border-radius:var(--rs);border:1px solid var(--border);cursor:pointer;transition:border-color .3s}
+#pg-bandwidth .bw-consent:hover{border-color:var(--accent)}
+#pg-bandwidth .bw-consent input{margin-top:3px;width:18px;height:18px;accent-color:var(--accent);cursor:pointer;flex-shrink:0}
+#pg-bandwidth .bw-consent span{color:var(--dim);font-size:.85em;line-height:1.7}
@@ -894,6 +924,23 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
+
+
+
📋 版本历史
@@ -1131,6 +1178,63 @@ label{display:block;font-size:12px;color:var(--dim);margin-bottom:4px;font-weigh
+
+
+
+
+
+
+
+
🌊 带宽共享加速池
+
共享你的带宽 · 加速所有人
+
+
+
+
+
+
📧 第一步 · 发送验证码
+
+
+
+
+
+
+
+
+
🔑 第二步 · 输入验证码
+
+
+
+
+
+ 我自愿共享多余带宽加入加速池。系统优先保障我的专属通道,仅将我用不上的资源共享给其他成员。我可以随时退出。
+
+
+
+
+
+
+ 💡 带宽共享说明
+ ✅ 提供了验证码的用户 → 优先保障你的专属通道
+ ✅ 你用不上的资源才会被共享 → 不抢你的带宽
+ ✅ 随时可退出 → 你有完全的控制权
+ ⚠️ 验证码15分钟内有效 · 一次性使用
+
+
+
+
© 2026 光湖语言世界 · 国作登字-2026-A-00037559
+
+
+
+
@@ -3446,6 +3550,132 @@ offline = function(msg){
});
})();
+})();
+
+/* ════════════════════════════════════════
+ BANDWIDTH SHARING AGENT (带宽共享验证)
+ GitHub Pages 前端 → 后端API桥接
+ ════════════════════════════════════════ */
+var BW_API_BASE = 'https://guanghulab.online/api/proxy-v3';
+
+function bwSendCode(){
+ var email = document.getElementById('bwEmail').value.trim().toLowerCase();
+ var btn = document.getElementById('bwSendCode');
+ var result = document.getElementById('bwSendResult');
+
+ if(!email || email.indexOf('@') === -1){
+ result.className = 'bw-result err';
+ result.textContent = '请输入有效的邮箱地址';
+ return;
+ }
+
+ btn.disabled = true;
+ btn.textContent = '发送中...';
+ result.className = 'bw-result';
+ result.style.display = 'none';
+
+ fetch(BW_API_BASE + '/bandwidth-send-code', {
+ method: 'POST',
+ headers: {'Content-Type': 'application/json'},
+ body: JSON.stringify({email: email})
+ }).then(function(r){ return r.json(); }).then(function(data){
+ btn.disabled = false;
+ btn.textContent = '发送验证码';
+ result.className = 'bw-result ' + (data.success ? 'ok' : 'err');
+ result.textContent = data.message || (data.success ? '验证码已发送' : '发送失败');
+
+ if(data.success){
+ // Cooldown 60s
+ var cd = 60;
+ btn.disabled = true;
+ var timer = setInterval(function(){
+ cd--;
+ btn.textContent = cd + 's 后可重发';
+ if(cd <= 0){
+ clearInterval(timer);
+ btn.disabled = false;
+ btn.textContent = '发送验证码';
+ }
+ }, 1000);
+ }
+ }).catch(function(err){
+ btn.disabled = false;
+ btn.textContent = '发送验证码';
+ result.className = 'bw-result err';
+ result.textContent = '网络错误,请检查网络后重试';
+ });
+}
+
+function bwVerifyCode(){
+ var email = document.getElementById('bwEmail').value.trim().toLowerCase();
+ var code = document.getElementById('bwCode').value.trim();
+ var consent = document.getElementById('bwConsent').checked;
+ var btn = document.getElementById('bwVerify');
+ var result = document.getElementById('bwVerifyResult');
+
+ if(!email || email.indexOf('@') === -1){
+ result.className = 'bw-result err';
+ result.textContent = '请先在上方输入邮箱';
+ return;
+ }
+ if(!code || code.length !== 6){
+ result.className = 'bw-result err';
+ result.textContent = '请输入6位验证码';
+ return;
+ }
+ if(!consent){
+ result.className = 'bw-result err';
+ result.textContent = '请先勾选同意带宽共享协议';
+ return;
+ }
+
+ btn.disabled = true;
+ btn.textContent = '验证中...';
+ result.className = 'bw-result';
+ result.style.display = 'none';
+
+ fetch(BW_API_BASE + '/bandwidth-verify-code', {
+ method: 'POST',
+ headers: {'Content-Type': 'application/json'},
+ body: JSON.stringify({email: email, code: code})
+ }).then(function(r){ return r.json(); }).then(function(data){
+ btn.disabled = false;
+ btn.textContent = '提交验证码';
+ result.className = 'bw-result ' + (data.success ? 'ok' : 'err');
+ result.textContent = data.message || (data.success ? '授权成功!' : '验证失败');
+ if(data.success) bwLoadPoolStatus();
+ }).catch(function(){
+ btn.disabled = false;
+ btn.textContent = '提交验证码';
+ result.className = 'bw-result err';
+ result.textContent = '网络错误,请检查网络后重试';
+ });
+}
+
+function bwLoadPoolStatus(){
+ fetch(BW_API_BASE + '/bandwidth-pool-status').then(function(r){
+ return r.json();
+ }).then(function(data){
+ var el1 = document.getElementById('bwContributors');
+ var el2 = document.getElementById('bwActive');
+ var el3 = document.getElementById('bwContributed');
+ if(el1) el1.textContent = data.total_contributors || 0;
+ if(el2) el2.textContent = data.active_contributors || 0;
+ if(el3) el3.textContent = data.total_contributed_gb || 0;
+ }).catch(function(){
+ /* Pool status unavailable - keep defaults */
+ });
+}
+
+// Auto-load pool status when bandwidth page is shown
+var _origGo = window.go;
+if(typeof _origGo === 'function'){
+ window.go = function(target){
+ _origGo(target);
+ if(target === 'bandwidth') bwLoadPoolStatus();
+ };
+}
+
})();
diff --git a/server/nginx/zhuyuan-sovereign.conf b/server/nginx/zhuyuan-sovereign.conf
index f448a3dd..9848a7f1 100644
--- a/server/nginx/zhuyuan-sovereign.conf
+++ b/server/nginx/zhuyuan-sovereign.conf
@@ -200,7 +200,17 @@ server {
# 将V3授权/订阅请求透传到大脑服务器的V3订阅服务 (端口3805)
# 协议: HTTP (内网通信,大脑服务器Nginx监听80端口default_server)
# 部署时由 workflow 自动将 ZY_BRAIN_HOST_PLACEHOLDER 替换为实际IP
+ # CORS: 允许GitHub Pages跨域调用带宽共享API
location /api/proxy-v3/ {
+ # CORS预检处理 (GitHub Pages跨域)
+ if ($request_method = OPTIONS) {
+ add_header Access-Control-Allow-Origin * always;
+ add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always;
+ add_header Access-Control-Allow-Headers "Content-Type" always;
+ add_header Access-Control-Max-Age 86400;
+ return 204;
+ }
+
proxy_pass http://ZY_BRAIN_HOST_PLACEHOLDER/api/proxy-v3/;
proxy_http_version 1.1;
proxy_set_header Host $host;
@@ -213,6 +223,7 @@ server {
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
add_header Cache-Control "no-store, no-cache, must-revalidate" always;
+ add_header Access-Control-Allow-Origin * always;
}
# ─── 铸渊 API 反向代理 (端口 3801 · 预览端口) ───
diff --git a/server/proxy/service/subscription-server-v3.js b/server/proxy/service/subscription-server-v3.js
index 1bdcc930..570118c9 100644
--- a/server/proxy/service/subscription-server-v3.js
+++ b/server/proxy/service/subscription-server-v3.js
@@ -1705,6 +1705,213 @@ async function submitCode(e) {
return;
}
+ // ═══════════════════════════════════════════════
+ // ∞+1 公开API: /bandwidth-send-code (无需token·邮箱验证码发送)
+ // 用户在GitHub Pages首页输入邮箱 → 调用此API发送验证码
+ // 安全: 每个IP每小时最多3次
+ // ═══════════════════════════════════════════════
+ if (pathname === '/bandwidth-send-code' && req.method === 'POST') {
+ // CORS headers for GitHub Pages cross-origin
+ res.setHeader('Access-Control-Allow-Origin', '*');
+ res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
+
+ let body = '';
+ req.on('data', chunk => { body += chunk; if (body.length > 1024) req.destroy(); });
+ req.on('end', () => {
+ try {
+ let email = '';
+ if (req.headers['content-type']?.includes('application/json')) {
+ const json = JSON.parse(body);
+ email = String(json.email || '').trim().toLowerCase();
+ } else {
+ const params = new URLSearchParams(body);
+ email = String(params.get('email') || '').trim().toLowerCase();
+ }
+
+ if (!email || !email.includes('@')) {
+ res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({ success: false, message: '请输入有效的邮箱地址' }));
+ return;
+ }
+
+ // Rate limiting: max 3 per IP per hour
+ const userIP = req.headers['x-forwarded-for']?.split(',')[0]?.trim()
+ || req.headers['x-real-ip']
+ || req.socket.remoteAddress
+ || '0.0.0.0';
+
+ if (!global._bwSendCodeRateLimit) global._bwSendCodeRateLimit = {};
+ const rl = global._bwSendCodeRateLimit;
+ const hourKey = `${userIP}:${Math.floor(Date.now() / 3600000)}`;
+ rl[hourKey] = (rl[hourKey] || 0) + 1;
+ // Clean old entries
+ const currentHourPrefix = Math.floor(Date.now() / 3600000);
+ for (const k of Object.keys(rl)) {
+ const hourPart = parseInt(k.split(':').pop(), 10);
+ if (hourPart < currentHourPrefix - 1) delete rl[k];
+ }
+ if (rl[hourKey] > 3) {
+ res.writeHead(429, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({ success: false, message: '发送频率过高,请1小时后重试' }));
+ return;
+ }
+
+ const bwPool = require('./bandwidth-pool-agent');
+ const code = bwPool.createAuthCode(email);
+
+ // Try to send email
+ try {
+ const emailHub = require('./email-hub');
+ emailHub.sendBandwidthAuthEmail(email, code).then(() => {
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({ success: true, message: '验证码已发送到您的邮箱,请查收(15分钟内有效)' }));
+ }).catch(() => {
+ // Email failed but code was created - still return success with code hint
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({ success: true, message: '验证码已生成,邮件发送中...' }));
+ });
+ } catch {
+ // Email module not available - code was still created
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({ success: true, message: '验证码已生成,请联系管理员获取' }));
+ }
+ } catch (err) {
+ res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({ success: false, message: '系统异常,请稍后重试' }));
+ }
+ });
+ return;
+ }
+
+ // ═══════════════════════════════════════════════
+ // ∞+1 公开API: /bandwidth-verify-code (无需token·验证码校验+注册)
+ // 用户在GitHub Pages首页输入邮箱+验证码 → 调用此API完成授权
+ // ═══════════════════════════════════════════════
+ if (pathname === '/bandwidth-verify-code' && req.method === 'POST') {
+ res.setHeader('Access-Control-Allow-Origin', '*');
+ res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
+
+ let body = '';
+ req.on('data', chunk => { body += chunk; if (body.length > 1024) req.destroy(); });
+ req.on('end', () => {
+ try {
+ let code = '';
+ let email = '';
+ if (req.headers['content-type']?.includes('application/json')) {
+ const json = JSON.parse(body);
+ code = String(json.code || '').trim();
+ email = String(json.email || '').trim().toLowerCase();
+ } else {
+ const params = new URLSearchParams(body);
+ code = String(params.get('code') || '').trim();
+ email = String(params.get('email') || '').trim().toLowerCase();
+ }
+
+ if (!email || !email.includes('@')) {
+ res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({ success: false, message: '请输入有效的邮箱地址' }));
+ return;
+ }
+ if (!code || code.length !== 6) {
+ res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({ success: false, message: '请输入6位验证码' }));
+ return;
+ }
+
+ const userIP = req.headers['x-forwarded-for']?.split(',')[0]?.trim()
+ || req.headers['x-real-ip']
+ || req.socket.remoteAddress
+ || '0.0.0.0';
+
+ const bwPool = require('./bandwidth-pool-agent');
+ const verifyResult = bwPool.verifyAuthCode(code, email);
+
+ if (!verifyResult.valid) {
+ saveAuthSnapshot({
+ email, action: 'bandwidth-verify-code', result: 'failed',
+ error: verifyResult.error, ip: userIP,
+ user_agent: req.headers['user-agent'] || 'unknown',
+ auth_type: 'github-pages-public'
+ });
+ res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({ success: false, message: verifyResult.error }));
+ return;
+ }
+
+ const regResult = bwPool.registerContributor(email, userIP);
+
+ saveAuthSnapshot({
+ email, action: 'bandwidth-verify-code', result: 'authorized',
+ ip: userIP, user_agent: req.headers['user-agent'] || 'unknown',
+ auth_type: 'github-pages-public',
+ contributor_id: regResult.contributor_id
+ });
+
+ try {
+ const guardian = require('./user-guardian-agent');
+ guardian.activateGuardian(email);
+ } catch { /* guardian not loaded */ }
+
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({
+ success: true,
+ message: '✅ 授权成功!您的带宽已加入加速池,感谢支持。',
+ contributor_id: regResult.contributor_id
+ }));
+ } catch (err) {
+ res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({ success: false, message: '系统异常,请稍后重试' }));
+ }
+ });
+ return;
+ }
+
+ // ═══════════════════════════════════════════════
+ // ∞+1 公开API: /bandwidth-pool-status (无需token·带宽池状态)
+ // GitHub Pages首页实时显示带宽池状态
+ // ═══════════════════════════════════════════════
+ if (pathname === '/bandwidth-pool-status' && req.method === 'GET') {
+ res.setHeader('Access-Control-Allow-Origin', '*');
+ res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
+
+ try {
+ const bwPool = require('./bandwidth-pool-agent');
+ const poolStatus = bwPool.getPoolStatus();
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({ success: true, ...poolStatus }));
+ } catch {
+ res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
+ res.end(JSON.stringify({
+ success: true,
+ total_contributors: 0,
+ active_contributors: 0,
+ total_contributed_gb: 0,
+ pool_status: 'idle',
+ updated_at: new Date().toISOString()
+ }));
+ }
+ return;
+ }
+
+ // ═══ CORS预检 (OPTIONS) 支持 ═══
+ if (req.method === 'OPTIONS' && (
+ pathname === '/bandwidth-send-code' ||
+ pathname === '/bandwidth-verify-code' ||
+ pathname === '/bandwidth-pool-status'
+ )) {
+ res.writeHead(204, {
+ 'Access-Control-Allow-Origin': '*',
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
+ 'Access-Control-Allow-Headers': 'Content-Type',
+ 'Access-Control-Max-Age': '86400'
+ });
+ res.end();
+ return;
+ }
+
// 404
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Not Found');